[Dovecot] (no subject)
I'm working on a Dovecot plugin, but I'm pretty new to Dovecot, so there's a LOT to learn about the code base and it's pretty slow going. I've got a few things coded so far, but I want to make sure I'm headed down the right path and get some advice before I go too much further.
A couple years ago, I wrote some code for our Courier implementation that sent a magic UDP packet to a small server each time a user modified their voicemail IMAP folder. That UDP server would then connect back to Courier via IMAP again and check whether the folder had any unread messages left in it. Finally, it would contact our phone switches to modify the state of the message waiting indicator (MWI) on that user's phone line appropriately.
Fast forward to now, and we want to migrate wholesale to Dovecot 2.x. The servers are all in place, they've been well tested and burned in (with Dovecot 2.0.15 I believe), and the final migration is pretty much waiting on a port to Dovecot of the MWI update functionality.
The good news is that I originally spent some effort to isolate the UDP packet generation and delivery, and I used purely standard portable code as per APUE2, so I think that chunk of code should be reusable with only minor modifications. I'm aware that internally Dovecot has its own memory, buffer, and string management functions, but it doesn't feel like a win to try to convert the existing code. It's small, completely isolated, and well reviewed -- I'd be more afraid of using the new (to me) Dovecot API incorrectly than I am that the existing code has bugs in buffer handling.
By cribbing from other plugins and editing appropriately, I've also created the skeleton for my plugin: Makefile, docs, conf snippet, .spec (I'll be deploying the plugin as an RPM), and so on. I've got the beginnings of the .h and .c written, just enough to init and deinit the plugin by calling mail_storage_hooks_{add,remove}() with some stub hook functions. This all seems good so far; test builds are error-free and seem sane.
So now the hard part is writing the piece that I can't just crib from elsewhere -- making sure that I hook every place in Dovecot that the user's voicemail folder can be changed in a way that would change it between having one or more unread messages, and not having any unread messages at all (or vice-versa, of course). At the same time, I want to minimize the performance impact to Dovecot (and the load on the UDP server) by only hooking the places I need to, filtering out as many false positives as I can without introducing massive complexity, and only pinging the UDP server when it's most likely to notice a change in the state of that user's voicemail server.
It seems to me that I need to at least capture mailbox_allocated from the mail_storage hooks, for a couple reasons:
1. The state of the voicemail folder could be changed because
the entire folder is created, destroyed, or renamed.
2. I want to only do further checks when I'm sure I'm looking at
the voicemail folder. There's no reason to do work when the
user is working with any other folder.
So now the questions:
Does all of the above seem sane so far?
Do I need to hook mail_allocated as well, or will I be able to see any change I need to monitor just from the mailbox?
Finally, I'm lost about what operations on the mailbox and the mails within it I need to check. Can anyone offer some advice (or doc pointers) on this?
Thank you!
-'f
My sincere apologies for the subjectless email (my MUA should have caught that!); the above is the corrected subject line.
-'f
On Wed, 2012-01-11 at 10:53 -0800, Geoffrey Broadwell wrote:
I'm working on a Dovecot plugin, but I'm pretty new to Dovecot, so there's a LOT to learn about the code base and it's pretty slow going. I've got a few things coded so far, but I want to make sure I'm headed down the right path and get some advice before I go too much further.
A couple years ago, I wrote some code for our Courier implementation that sent a magic UDP packet to a small server each time a user modified their voicemail IMAP folder. That UDP server would then connect back to Courier via IMAP again and check whether the folder had any unread messages left in it. Finally, it would contact our phone switches to modify the state of the message waiting indicator (MWI) on that user's phone line appropriately.
Fast forward to now, and we want to migrate wholesale to Dovecot 2.x. The servers are all in place, they've been well tested and burned in (with Dovecot 2.0.15 I believe), and the final migration is pretty much waiting on a port to Dovecot of the MWI update functionality.
The good news is that I originally spent some effort to isolate the UDP packet generation and delivery, and I used purely standard portable code as per APUE2, so I think that chunk of code should be reusable with only minor modifications. I'm aware that internally Dovecot has its own memory, buffer, and string management functions, but it doesn't feel like a win to try to convert the existing code. It's small, completely isolated, and well reviewed -- I'd be more afraid of using the new (to me) Dovecot API incorrectly than I am that the existing code has bugs in buffer handling.
By cribbing from other plugins and editing appropriately, I've also created the skeleton for my plugin: Makefile, docs, conf snippet, .spec (I'll be deploying the plugin as an RPM), and so on. I've got the beginnings of the .h and .c written, just enough to init and deinit the plugin by calling mail_storage_hooks_{add,remove}() with some stub hook functions. This all seems good so far; test builds are error-free and seem sane.
So now the hard part is writing the piece that I can't just crib from elsewhere -- making sure that I hook every place in Dovecot that the user's voicemail folder can be changed in a way that would change it between having one or more unread messages, and not having any unread messages at all (or vice-versa, of course). At the same time, I want to minimize the performance impact to Dovecot (and the load on the UDP server) by only hooking the places I need to, filtering out as many false positives as I can without introducing massive complexity, and only pinging the UDP server when it's most likely to notice a change in the state of that user's voicemail server.
It seems to me that I need to at least capture mailbox_allocated from the mail_storage hooks, for a couple reasons:
1. The state of the voicemail folder could be changed because the entire folder is created, destroyed, or renamed. 2. I want to only do further checks when I'm sure I'm looking at the voicemail folder. There's no reason to do work when the user is working with any other folder.
So now the questions:
Does all of the above seem sane so far?
Do I need to hook mail_allocated as well, or will I be able to see any change I need to monitor just from the mailbox?
Finally, I'm lost about what operations on the mailbox and the mails within it I need to check. Can anyone offer some advice (or doc pointers) on this?
Thank you!
-'f
A couple years ago, I wrote some code for our Courier implementation that sent a magic UDP packet to a small server each time a user modified their voicemail IMAP folder. That UDP server would then connect back to Courier via IMAP again and check whether the folder had any unread messages left in it. Finally, it would contact our phone switches to modify the state of the message waiting indicator (MWI) on that user's phone line appropriately.
Using a Dovecot plugin for this would require mail delivery to go through Dovecot as well as all mail access. So, no postfix or exim or whatever doing mail delivery by itself (mbox/maildir), and no MUAs accessing mail locally.
With courier, you probably had everything going through courier, but with Dovecot, that need not always be the case. So, using a dovecot-plugin for this may not even catch everything.
Of course I don't know anything about the details of the project (number of users, requirements for speed of MWI updates, mail storage type, etc.) but if it's not a very large setup and mail storage is mbox or maildir, I'd probably go for cron-based external monitoring using find and stuff like that. Maybe even with login scripting for extra triggering.
HTH...
-- Maarten
On 2012-01-12 6:10 PM, Maarten Bezemer mcbdovecot@robuust.nl wrote:
Of course I don't know anything about the details of the project (number of users, requirements for speed of MWI updates, mail storage type, etc.) but if it's not a very large setup and mail storage is mbox or maildir, I'd probably go for cron-based external monitoring using find and stuff like that. Maybe even with login scripting for extra triggering.
I know that dovecot supports inotify (not sure how or in what way, and ianap, so may be totally off base), so maybe that could be leveraged?
--
Best regards,
Charles
On 11.1.2012, at 20.53, Geoffrey Broadwell wrote:
So now the hard part is writing the piece that I can't just crib from elsewhere -- making sure that I hook every place in Dovecot that the user's voicemail folder can be changed in a way that would change it between having one or more unread messages, and not having any unread messages at all (or vice-versa, of course). At the same time, I want to minimize the performance impact to Dovecot (and the load on the UDP server) by only hooking the places I need to, filtering out as many false positives as I can without introducing massive complexity, and only pinging the UDP server when it's most likely to notice a change in the state of that user's voicemail server.
I think notify plugin would help you do this the easiest way. See mail_log plugin for an example of how to use it.
On 2012-01-12 6:17 PM, Timo Sirainen tss@iki.fi wrote:
On 11.1.2012, at 20.53, Geoffrey Broadwell wrote:
So now the hard part is writing the piece that I can't just crib from elsewhere -- making sure that I hook every place in Dovecot that the user's voicemail folder can be changed in a way that would change it between having one or more unread messages, and not having any unread messages at all (or vice-versa, of course). At the same time, I want to minimize the performance impact to Dovecot (and the load on the UDP server) by only hooking the places I need to, filtering out as many false positives as I can without introducing massive complexity, and only pinging the UDP server when it's most likely to notice a change in the state of that user's voicemail server.
I think notify plugin would help you do this the easiest way. See mail_log plugin for an example of how to use it.
Oops, should have read all messages before replying (I usually skip messages with (no subject), but I try to read everything on some lists (dovecot is one of them)...
Timo - searching on 'inotify' or 'notify' on both wiki1 and wiki2 has 'no results'... maybe the search indexes need to be updated? Or, is it just that there really is no documentation of inotify on either of the wikis?
--
Best regards,
Charles
participants (4)
-
Charles Marcus
-
Geoffrey Broadwell
-
Maarten Bezemer
-
Timo Sirainen