Closed Bug 141369 Opened 23 years ago Closed 21 years ago

Support IMAP4 IDLE command (RFC 2177)

Categories

(MailNews Core :: Networking: IMAP, enhancement)

enhancement
Not set
normal

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: moz-bugz, Assigned: Bienvenu)

References

()

Details

(Keywords: helpwanted, Whiteboard: parity-oe)

Attachments

(1 file, 1 obsolete file)

From Bugzilla Helper: User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.0rc1) Gecko/20020417 BuildID: 2002041711 Mozilla mail does not seem to use the IMAP IDLE extension specified by RFC 2177. Would be very nice to have and should not be too complicated to implement. Reproducible: Always Steps to Reproduce: 1. add imap account with an IDLE capable imap server (such as cyrus) 2. open inbox 3. send mail 4. wait Actual Results: nothing happens till the "check for new messeges every # minutes" time has passed. Expected Results: There should be a checkbox "Use Imap IDLE command" which causes mozilla mail to use it.
Sounds useful. I can't find any duplicates so I'm marking this NEW.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Summary tweaking. Before: why not RFC2177 ? After: Support IMAP4 IDLE command (RFC 2177)
Summary: why not RFC2177 ? → Support IMAP4 IDLE command (RFC 2177)
Blocks: 46378
Two things to consider here: Biff Support, for this there is an interesting comment in Bug 18266 (comment 154) - direct link http://bugzilla.mozilla.org/show_bug.cgi?id=18266#c154 and whether to open an additional TCP connection which we poll at least every 29 minutes according to the RFC or change nsImapProtocol to leave the TCP connection open, if this is not already done (I don't know the code well enough yet, my feeling is the connection is closed). The latter is the preferred solution.
we do cache connections (i.e., keep them open). This would probably be a fun little project for a mozilla contributor interested in imap.
Keywords: helpwanted
It's on my todo list, but I want to properly fix the namespace issues first.
FYI: Courier-IMAP 1.6 adds significant functionality to its IMAP IDLE implementation. On server platforms that have SGI's File Alteration Monitor installed (Linux, Irix, with partial xBSD support) IDLE generates real-time folder status updates (when multiple client sessions have the same folder selected, all clients are notified immediately when any client makes any changes to the folder, and immediately upon arrival of new mail). I scavenged an old laptop with MS OE 4.0, and opened a folder, then also logged in using pine. Even though pine doesn't do IDLE, I played with it, marking messages as deleted and undeleted, expunging the folder, and copying messages into this folder. On the other monitor, OE 4.0 obediently repeated everything I was doing in pine. Worked rather well. So, the scoreboard right now has two of the top three non-commercial IMAP servers offering value-added IMAP IDLE functionality.
QA Contact: huang → gchan
Re: Comment #6, yes I upgraded my courier-imap server very recently and added in FAM support. Outlook Express works very well with this extension and I would love to see it in Mozilla Mail at some point! Also, just thought I'd point out that Exchange 5.5 Server (and 2000 Server, AFAIK) support this extension.
I would like to have this feature added also It seems that the person that this is assigned to is (gone) ??? and this has been sitting without any additional comments for quite a while.. It seems that Mozilla is one of the few Email clients that do not implement the IDLE functionality yet..
Whiteboard: parity-oe
Add my vote for this... :) Moral support.
Could somebody with adequate permissions change the assignee of this bug. It using Scott MacGregor's old e-mail address. He now uses mscott@mozilla.org. Thanks.
I think I'm more likely to do this at some point - I've looked into it a little. What we'd need to do is set a timer and occasionally poll the transport to see if data was available, when in Idle mode. If data was available, we'd have to parse it. Darin has pointed out that timers like this are death on laptop batteries, so we need a way to turn this off - I've suggested a laptop mode setting that various components that used timers could check...
Assignee: mscott → bienvenu
(In reply to comment #11) > What we'd need to do is set a timer and occasionally poll the transport to see > if data was available, when in Idle mode. Pardon my ignorance but I thought the purpose of IDLE mode is to open up a connection that let the IMAP server know the client could receive updates whenever they happen. I'm unfamiliar with the the inner workings of Mozilla's IMAP communications but is there a way to make this event driven so that the arrival of data after the IDLE command is sent would trigger the parsing activity?
the problem is that we use blocking reads in the imap code, i.e., we can only read data in blocking mode. (This is for performance reasons - it's literally twice as fast). But we can't just issue an OnIdle and then go into a blocking read, because we still need to be able to re-use the connection in case the user wants to do something like read a message in that folder...unless we can actually issue a command on a transport that's in a blocking read - I kinda doubt that, though. If we could change the transport into a non-blocking mode to do OnIdle, then we'd do that, but transports can't do that - as I understand it, there are race conditions when you switch, etc...
david: can we do this: after issuing an OnIdle, periodically have the IMAP thread check Available on the socket transport's nsIInputStream. if it returns non-zero, then begin a blocking read until all of the data has been consumed. if it returns zero, then put the IMAP thread to sleep until another timeout event occurs or until some other user initiated command is issued that requires the IMAP connection. currently, ImapThreadMainLoop waits on m_urlReadyToRunMonitor. we could signal that monitor if there is either an "url ready to run" or an OnIdle Available check to process. wouldn't that be do-able without much hassle?
Darin, yes, that's more or less what I had in mind. I was responding to http://bugzilla.mozilla.org/show_bug.cgi?id=141369#c12 - what Wayne was saying, I think, was that ideally, we'd respond to OnIdle data immediately, instead of when the next timeout fired. I'm not sure how frequently we'd wake up and poll the transport, but I was thinking every 10 or 15 seconds - if we did the old non-blocking reads, we'd handle the data on demand...
hmm.... you just gave me an interesting idea. it turns out that nsIAsyncInputStream::AsyncWait can be called on a _blocking_ input stream just as easily as it can be called on a non-blocking input stream. so, you could continue to open blocking input streams, but then instead of using a timeout, you could just call AsyncWait on the stream. it will notify you when there is something to read (or when the stream closes). from that notification you can do the blocking read. you do not even need an event queue to handle the AsyncWait notification... you will get called on the socket transport thread... from which point you can tickle that monitor that will cause a blocking read to happen. going this route uses poll instead of a timer and should be all around much better. now, hopefully i'm not overlooking something! ;-)
(In reply to comment #11) > parse it. Darin has pointed out that timers like this are death on laptop > batteries, so we need a way to turn this off - I've suggested a laptop mode > setting that various components that used timers could check... David: How do other mail clients with IDLE support handle laptops? (I ask since I don't recall seeing "laptop mode" in a mail client before, but I could be wrong.)
Darin, that sounds like it's worth a try - it also sounds like I don't need to resurrect all the async notification code, which would be nice. Alex, I don't know off the top of my head, but it rings a vague bell that some programs have a laptop mode. It might also be the case that there's some win32 api or some linux api that tells you when you're in battery preservation mode and that's what I'm thinking of...
this is going to be very tricky... when the imap main loop gets notified that it has to do something (will have to change the name of the url ready to run monitor), it will check if there's no url to run, and we're idle - if so, we must have been told there's data to read. So, we'll invoke the imap parser, and tell it to parse a single line. That will cause it to do a blocking read for a single line. Then, we'll need to check if there's more data to parse (either in the input stream or the input stream line buffer - the input stream line buffer consumes all data available in the input stream, so maybe just the input stream line buffer), and if there is more data, we'll need to invoke the parser again, until there's no more data.). Currently, the parser doesn't know how to read just one line for a single unsolicited response, and we need to avoid the situation where the parser ends up doing a blocking read when there's no more data to come, because we need to be able to end the IDLE command whenever the user wants to run a url with that connection. So we need to teach the parser how to read just one line, and to be very careful not to try to do a blocking read when there's no data ready...
There is blog post from one of Microsoft Entourage IMAP engineer: http://blogs.msdn.com/omars/archive/2004/02/19/76061.aspx As soon as this bug is closed it'll be great to post an update on the Mozilla Mail/Thunderbird in his blog entry as it got linked from MozillaZine http://www.mozillazine.org/talkback.html?article=4349 (the way I got here as well).
OS: Windows 2000 → All
Hardware: PC → All
More trickiness - we probably don't want to immediately go into IDLE mode when a url finishes running in the INBOX because we might have another url waiting to run on the inbox, and we don't want to go into IDLE mode if we're just going to get out of it immediately. So I need to figure out if we can tell that there's a url waiting for a connection. We probably want to do IDLE for all idle connections, not just the INBOX connection, but the INBOX connection is the most important one. We could probably use the return value of nsImapIncomingServer::LoadNextQueuedUrl to know if we should go into idle mode. Except that there are some operations that chain urls - we'd need to make sure that the chaining prevents IDLE'ing. I'd really like to avoid using a timer to go into idle mode but I may end up going that way.
Status: NEW → ASSIGNED
Attached patch work in progress (obsolete) — Splinter Review
This is a work-in-progress patch. It doesn't quite work, so don't try it! But it's most of the way there. The big problem is that connections get stuck after a couple operations, which I have to figure out. I also need to figure out if we want a per-server pref to control the use of IDLE (at first, we definitely will, in case there are problems). Do we have a pref UI for using the IDLE command or just use it if the server has it? For keeping connections alive, do we let the user set up biff to do that, or do we do it automatically? I probably also need to only go idle after a certain amount of inactive time, but I can do that later...
Attached patch proposed fixSplinter Review
this seems to work well for me. I put all connections in the idle state when done with them. I immediately go IDLE when done with a url, unless we're going to run another URL immediately. the Check for new mail interval is orthogonal - we still run normal biffs even if IDLE is supported. This way, users can set the biff interval to whatever will keep the server connected, for most servers, 29 minutes. I had to diddle with the parser a little bit so that it knows to just parse a single line of idle response at a time, but it seems to be working fine.
Attachment #141982 - Attachment is obsolete: true
Attachment #142178 - Flags: superreview?(mscott)
Comment on attachment 142178 [details] [diff] [review] proposed fix I had several comments I told david over AIM: 1) I think we will want UI in our account manager to allow laptop users to turn this off. I was searching through google to see if Outlook has the ability to turn it off but have not come up with anything yet. 2) I wonder if we will want to put a cap on the number of connections that can go into the IDLE state? 3) We should file a spin off bug to track having the client re-issue the IDLE command before the server times out. 4) Down the road, we may want to consider hooking up the idle state to a timer so we don't actually go into that state until the user has been idle for a certain period of time. Then again, going into the idle state may be cheap and we won't care.
Attachment #142178 - Flags: superreview?(mscott) → superreview+
On comment 24, item 1 perhaps Outlook might do it differently depending on the current power state of the machine? Perhaps sniffing traffic on Outlook when changing the power state of the macine... comparing a plugged in laptop to a battery mode laptop with a new session might function differntly?
On comment 24: 1- I don't mean to rehash things, but how bad is the IDLE command going to be on a laptop battery? Usually when I'm on battery, I'm either offline (so IDLE is moot) or I'm wireless, since if I'm close enought to be near an ethernet jack, usually power isn't too far off. The IDLE support will actually reduce the amount of traffic I send, since I can back off on the check new messages timer. Less traffic would seem to mean less power used by the wireless NIC. 4- Are we checking the status of the mailbox before we go into IDLE? IDLE will only show us what changes have occurred since the IDLE command started. If a mail message comes in or is modified outside of Mozilla after the last check but before we go in to IDLE, it won't show up until the messages are checked, right? On the other hand, polling the server before every IDLE may be too painful, especially for large mailboxes. Having to wait until the next scheduled poll may be acceptable, especially if the connection spends all it's time while not executing commands in an IDLE state, since that would make the window for unnoticed changes be the length of time to run the command. This would certainly be no worse than current behavior.
On comment 26: 1. The IDLE mode does not generate any server activity unless there are changes to the folder's contents. If the IDLE mode is implemented properly -- by waiting until the file descriptor is readable, instead of polling it -- the IDLE mode will not require any additional CPU. 4. Not true. If there are pending changes to the folder's status, a proper server IDLE implementation will immediately push those changes to the client as soon as the client enters the IDLE mode. To do otherwise will break the entire IMAP protocol itself.
(In reply to comment #24) > 2) I wonder if we will want to put a cap on the number of > connections that can go into the IDLE state? You mean connections to the same server right? Wouldn't it be a problem to have more than a single connection to the same server to be in IDLE state? More than one and we would receive and act on the same notifications multiple times.
Brodie, the notifications are on a per-folder basis. Each connection is for a particular folder, and we never have more than one connection for a particular folder.
fix checked in. bug 236584 spun off for the idle keep-alive issue.
Status: ASSIGNED → RESOLVED
Closed: 21 years ago
Resolution: --- → FIXED
*** Bug 46378 has been marked as a duplicate of this bug. ***
Hi Mozilla People, I've just been writing the code for the other end of this problem, in an IMAP server, and thought I'd pass on some comments. (At the moment, my server does asynchronous notification, but I can't find any clients to test it with!) I think that the IDLE extension is a bit of a red herring. Normal IMAP servers without any extensions can send "unilateral" data AT ANY TIME. (Whether "real" servers actual do or not I don't know, but to quote from the RFC: "A client MUST be prepared to accept any server response at all times.") The difficulty is that normally you (the client) don't know if you're going to get these unilateral updates for new messages and activity on other connections, so you have to poll by sending NOOPs. With the IDLE extension, you KNOW that the server will send you updates without having to poll for them. Good luck - I'm looking forward to seeing this in Thunderbird soon. --Phil.
Phil, this in the nightly/weekly thunderbird builds now, and will be in .6 when it comes out. You do have a point about being prepared to accept input at any time - we should be waiting for input with a quiescent connection, even if we're not in IDLE mode because the server doesn't support IDLE. For the most part, we'll get that input the next time we try to do something with the connection.
hmm, I would like to reopen this because for me it seems buggy: - the idle state does notify the server that changes to the SELECTED mailbox should be pushed to the client. - as you always cache a maximum of 5 connections to the IMAP server the limit for observed folders is 5? If so, this should be communicated somehow. I see no solution for this problem without establishing more connections to the IMAP-Server. If I understand something wrong here, please prove me wrong. But I use the IDLE feature and always have some folders which are not notified unless I use "Check for new messages every ...".
> hmm, I would like to reopen this because for me it seems buggy: this is as designed. If you want, you can go into your advanced imap server prefs and increase the number of connections we'll hold open, but it's not a nice thing to do to your server...The RFC for the IDLE command doesn't say that we should keep open a connection for every folder you open in the UI, which kinda sounds like what you want to happen. If I understand you correctly, I think your complaint really has to do with the IDLE command, and not Mozilla's implementation of it.
The mozilla implementation (or documentation) is not really obvious. mozilla claims that the IDLE command is supported. But for what? There is no information about which folders will be "idled". (INBOX seems to be always IDLED). One IDLE session can only serve one folder. One thing would be a configuration option for every folder (up to max. connections) if it should be served by an idling imap server. The others have to be polled then.
Every cached connection we have (up to the max, default 5) is left in the IDLE state, instead of just idle :-) (assuming the connection is in the selected state, which they almost always are). It generally works out that the last 5 folders you selected in the UI have the 5 cached connections, so the last 5 folders you selected are in the IDLE state - accounting for the fact that we use one of those cached connections for the INBOX.
OK, understood. But this is not what I've expected. One thing is left which could be discussed. If one of the last five selected folders is not marked as "Check for new messages" it doesn't make much sense to IDLE this folder. What do you mean?
that's true, we could simply not IDLE connection that aren't set to be checked for new messages, and just leave them in the selected state...I could be wrong, but I'm getting the impression that you don't want us to cache connections to folders that aren't set to be checked for new messages, so that all the cached connections can be busy doing IDLE, and that's not the way it works - we cache connections to folders because we think you might be using them in the UI again (so that frequently used folders tend to stay cached).
I'm not sure if I'm rehashing what has already been discussed, but one thing I see is the IDLE enhancement detected new mail in folders I have not marked "Check for new messages", but have made active once. Not good. For example, I use server side filters to deliver to 3 folders as so: Inbox |-List1 |-List2 |-Spam I have "Check for new messages" checked on List1 and List2, but not Spam - I only want to check it occasionaly. Yet, as soon as I check "Spam" once, IDLE enhancement acts on it until I re-start Mozilla. This should not be...
To comment #39: I have to admit that your argument is correct. So let me shortly describe what was my initial problem: I've read that IDLE is supported now, so I deactivated the "Check for new mail every ... minutes". (hey, the mails will get pushed to me). After some days using this I observed that some does never notify me about new messages. hmm? Strange! Now I do understand that IDLE is only done in a best effort base and always for every folder which was opened some time before. It doesn't IDLE after startup but only if I accessed them before. That are some things which are confusing if you don't know it. And IMHO this is the word of RFC2177 but not the meaning. I want the IDLE state to get new mails pushed for folders which have the "Check for new mail" flag set. I understand that it's almost impossible to get the caching and the IDLING together. So comment #40 is true and not really wanted. All IMHO. And please note that I really like mozilla/thunderbird as IMAP client. I just want to give constructive feedback.
To fill in the "What would OE do?" question (and what I think is a sensible compromise), OE has one IDLE connection polling the INBOX at all times, and one IDLE connection polling the currently displayed folder. Other folders are updated only when viewed, or when the "Check for New Mail" runs every x minutes.
It does seem like Mozilla should make sure INBOX never gets dropped from the IDLE list...
Obviously, the only sensible response to comment #42 is, "OE sucks".
David, I suppose having IDLE scroll up the list window when (a) you're on the last line of the list and (b) new mail is received would be out of scope here?
yeah - out of scopoe - Idle acts just like get new mail, or biff, in that respect, so it's not particularly an IDLE issue. Re a previous comment, since we cache a connection to the INBOX, we will have an IDLE connection to the INBOX.
Product: MailNews → Core
Product: Core → MailNews Core
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: