On 22.11.2012, at 17.06, Richard Platel wrote:
> We use Dovecot for IMAP and POP (but not LDA), we want to do something when
a user has an INBOX that becomes empty, or becomes not empty (set a flag in
memcached, but that's not really important).
>
> I'm writing a plugin (for Dovecot 2.1.7). On mailbox_open() I can use
mailbox_get_status() to get a count of messages in the mailbox, and then
decrement this in expunge() or increment it in mailbox save_finish() (for IMAP
APPEND or COPY commands).
So all mailbox access goes through Dovecot. Nothing else changes the underlying
storage directly?
> However in expunge() and mailbox_save_finish, even after calling the super
function, mailbox_get_status doesn't update the number of messages in the
mailbox.
You'll get the updated count only after mailbox_sync_deinit().
> This is a problem if (for example) there are concurrent POP sessions. Two
POP sessions could get all the messages in INBOX, one could logout, calling
expunge a few times, eventually causing my plugin to note that the inbox is
empty, then our LDA could deliver a message, mark the INBOX not empty, then the
other POP session could log out, call expunge and cause my plugin to mark the
INBOX empty, when it's not.
>
>
> So in summation: how can a plugin be notified of changes to a mailbox, and
then accurately get the real number of messages in that mailbox?
I think if you hook into sync_deinit() and use a local lock file while you send
the notification it would probably be race-free.