-
Notifications
You must be signed in to change notification settings - Fork 22
NOTIFY extension and asynchronous events #63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
That's an interesting feature... The way we do this using IDLE is that you cannot simultaneously issue any other requests while an IDLE is ongoing, so every line sent by the server is necessarily a response to the IDLE command. It sounds like that might be how we want to handle NOTIFY too. Maybe have the thing returned by One question here is how the spec says that these untagged responses should be handled? What if you run both |
Yes. When my
For your second question, there is at most one
That makes |
Hmm, yeah, that makes this a little tricky given the way the crate's code is currently set up. Specifically, the I don't know how/if |
As far as I understand the (IMAP4rev1) protocol, you cannot really run multiple commands at once. I haven't really looked into the IDLE and NOTIFY extensions, though, so I'm unfamiliar with how exactly they do things. It looks like the way it would have to work is that any response might include STATUS messages, and then the client caller will just have to handle that. tokio-imap streams each response as it comes in, so the receiver would have to deal with it. At least in tokio-imap, my design choices have really revolved around being a thin layer that implements the protocol, so I would not include any higher-level abstractions that try to make things more convenient, at the risk of the abstractions being leaky. |
Yeah, that's the impression I had too, which is why IDLE is implemented the way it is in rust-imap at the moment. It's interesting that IDLE/NOTIFY work so differently. @jkaessens perhaps a way to work around this is to open two connections? One to subscribe and one to issue commands. If we did it that way, NOTIFY could be implemented pretty much exactly like IDLE.
I think that's probably a good idea, though with rust-imap I believe @mattnenterprise's intention was to provide a slightly higher-level interface. And I think that can be good for some use-cases too. Maybe one day we'll build rust-imap on top of tokio-imap :) |
Actually, many IMAP clients do this. In my IMAP server logfiles, I usually see clients connecting multiple times, i.e. Mozilla Thunderbird's default is 5, and some Android ones open a new connection for every mailbox to be watched (those "push" or "sync" functions). |
Okay, so in that case it seems reasonable for us to do this the same way we do IDLE — |
@djc is there currently support in
|
Other than IDLE, NOTIFY requires a potentially large set of arguments so it would also need a |
Oh, yes, sorry, I left out the arguments for clarity. I think I'd probably make a NOTIFY be issued using either a builder pattern or by giving a struct. Or maybe both, depending on just how complex the arguments are. |
I don't think I'll end up using it in rust-imap, but would it be worthwhile for completeness to also add support for the IDLE responses? From what I can tell, the only valid response lines are:
|
@jkaessens Given that it looks like this can be implemented pretty straightforwardly, you think you might want to write up a PR? I'd be happy to mentor and review. Basically, start by copying the code for doing IDLE, and then implement |
Alright, let's try that! It will take me some days to crawl through the code, though. |
@jkaessens great! Happy to help give you pointers if you need them! https://gitter.im/djc/tokio-imap may also be a useful point of contact. |
@jonhoo So the
The first one would be a little less efficient than the second one while the second one a lot more inconsistent than the first one. And as we're talking about TCP connections, that |
I'm inclined to have two different methods then: fn notify(...) -> NotifyHandle {}
fn status_and_notify(...) -> (Vec<Status>, NotifyHandle) {} |
@jonhoo Please take a look at https://github.com/jkaessens/rust-imap/tree/notify . This includes your PR but when trying to use the |
@jkaessens Overall it looks pretty reasonable! I wouldn't worry too much about On a separate point, isn't the idea of Some minor points:
|
Also, I think it's probably reasonable to open a PR for your changes -- it makes it a little easier to discuss/comment inline. We can deal with rebasing when #58 is merged when that happens. |
@jonhoo Thanks a lot for your feedback. Being a Rust newbie, I'm still struggling to leave my burnt-in C++'isms behind and adopt The Rust Way to do things. As you have certainly noticed, it currently revolves around understanding when to use |
That's fine -- you can just put Another useful tool is |
Let's move further discussion to jonhoo/rust-imap#63. |
@jkaessens Are you still interested in contributing this code? Would you mind if someone else continues your work? |
@freswa the project sort-of moved, see @jonhoo comment above. any new development is at the jonhoo/rust-imap fork only. |
@dario23 I'm aware of that. Though, the NOTIFY extension has not been implemented yet and this is the only approach for jonhoo/rust-imap I could find. I'd like to ask the author first before I start another approach on the recent repo. |
@freswa Thanks for asking. I followed the project quite a while but lost track when there were some movements towards tokio-style workflow. I'm quite busy right now but may pick this up in the future. If someone wants to work on that, I'd be happy to take part in it/assist. So yes, feel free to do whatever you like with that, and I'd might chime in at some point, or even provide test infrastructure for NOTIFY. |
I'm currently looking into writing a tool to monitor mailboxes for status changes. The typical way for this is probably SELECT/IDLE but I have quite a lot of mailboxes that I'd like to check. I could get a list of all mailboxes and check their statuses periodically but when I'm on a low-bandwidth connection with unfortunate and expensive mobile plans, that would also be a bad idea.
Therefore, I would like to use my server's NOTIFY extension (as in RFC5465). After authenticating, I'd issue a notify request for a set of events on a set of mailboxes, that could look like this:
a NOTIFY SET (personal (MessageNew MessageExpunge))
The server responds with
a OK NOTIFY completed.
(at least Dovecot does). After some time, additional (untagged) responses are generated asynchronously, i.e.until I either disconnect or stop them by issuing
NOTIFY NONE
.Well, the notification request can be sent by the current API. However, I don't see a way to collect those untagged status reports. One problem might be that they may be scattered through the whole connection like that (C being the client, S the server):
I haven't looked into the depths of
rust-imap
but I guess that it could probably interfere with the response parsing. My uneducated guess would be that implementing something like theIdleHandle
where all those STATUS messages are collected that are not a direct response to a STATUS command. That might be hard to detect, though, if at all possible.Do you have any ideas how to support this type of operation?
The text was updated successfully, but these errors were encountered: