Re: [Imap-protocol] Re: Suspend/Restore feature proposal
Michael M Slusarz <[email protected]>
| Newsgroups | gmane.mail.imap.general |
|---|---|
| Message-ID | <20121121155417.Horde.ZeW7JqTPNxTAI-hTtrAT-Q9@bigworm.curecanti.org> |
Jan, Thanks for the input. My responses are below. Quoting Jan Kundrát <[email protected]>: > Hi Michael, > I've read your draft, it's an interesting extension. However, it > seems to me that the whole point here is to save a few roundtrips by > skipping the process of activating/configuring various optional > features. I'll discuss each extension separately. I would strongly disagree with this statement. As written, the draft is only minimally concerned with saving on network round-trips. E.g. a webmail implementation: for any even reasonably sized setup, interaction between the webmail backend and the IMAP server will almost certainly be done through a private network. Such a setup has the added benefit that the IMAP connection does not need any sort of security [TLS] overhead. I have assumed in the draft that the client/server round-trip is negligible or, in the very least, not the bottleneck in the IMAP interaction. However, client/server round-trip *is* most likely an issue for a whole category of disconnected-like clients: those running on mobile hardware. Pipelining in this environment in no way guarantees that a server can or will return the response in the same network packet. In other words, this draft becomes *more* important the more that client/server round-trip time becomes the bottleneck/limiting factor, whether pipelined or not. Sidebar: I'm not a huge fan in general of pipelining as a performance since it is not always a feasible option for clients. For example, a client may use an OO-library to connect to the IMAP server. This library may not provide a reasonable (or any) way of allowing multiple commands to be sent at once via the API. For example, to start compression, enable QRESYNC, and set the language, it is more than reasonable to expect this kind of pseudocode: $result = $imap->useCompression(true); // Check for success $imap->useQresync(true); // Check for success $imap->setLanguage([LANGUAGE]); // Check for success In any OO IMAP interface the order of IMAP commands to allow for efficient pipelining, or the fact that pipelining even exists, should obviously not be a part of the API. Thus pipelining is fairly useless in the real world as a way to guarantee an increase in performance. There are other, more important reasons why a mechanism to restore configuration is useful: - It prevents the need to re-parse the CAPABILITY list. Note that parsing the CAPABILITY list involves *MUCH* more than just the actual string tokenization of the list, although this alone may not be a trivial task (see below). A client may, depending on the capabilities returned, need to perform various internal initialization tasks. For example - if CONDSTORE/QRESYNC is listed, a client may have to then parse a separate configuration file to grab the details of the local cache where it is storing this information, and then connect to this cache, etc. Or if language is listed, a client might have to parse a local list of language availability to determine if it can/should change the language. And CAPABILITY parsing is more than just determining what capabilities are listed. It is also determining which capabilities SHOULD not be listed. Just today, Cyrus was fixed due to a bug that our code was triggering: APPENDing binary data via a literal8 caused Cyrus to immediately terminate the connection with a BYE response. Our code is smart enough to catch this broken behavior by removing BINARY appending from the list of available capabilities. But without a way to ensure that every subsequent connection is a continuation of the current session, we have to do this detection EVERY SINGLE TIME. This is potentially a huge performance hit, since we may be appending MBs of data to the server before the BYE response can be returned (e.g. appending a sent-mail message containing attachments). - As mentioned above, sending an initialization command to the server may take quite a bit of work on the client side to prepare. It's not as easy as hardcoding 'ENABLE QRESYNC' in client code - it may take quite a bit of CPU cycles to get to that point in a given client. Another example: a client keeps all of its imap initialization code in a separate dynamically-loadable module. If the session is successfully resumed, this module does not need to be loaded/interpreted/run. - From the server side, it may be much more expensive to initiate an IMAP session as compared with resuming one. This draft allows the server to optimize if possible. I believe Timo's post indicates that resuming in Dovecot is more efficient than creating a new session. - Even when pipelining commands, they still need to be sent, the incoming command needs to be tokenized (server), the command is performed (server), the response sent back, any untagged responses are tokenized (client), the untagged responses are interpreted (client), the tagged response is tokenized (client), and the tagged response is processed (client). None of this is "free". Pipelining eliminates none of this. >> COMPRESS=DEFLATE > > I was wondering if this one actually provides any benefit for a > webmail client. But you're right that it indeed has an overhead and > requires a full roundtrip to set up. However, please note that your > extension also requires a full roundtrip, so you aren't any better > here. First a point of clarification: the draft is not specific to webmail clients. It is intended for any disconnected client that may have need to initiate multiple IMAP connections during the client's lifetime. Granted, it is extremely useful for webmail clients due to extreme disconnected nature of the connections, but it would also be highly useful for clients on any device that does not have a constant (or reliable) network connection to the server. e.g. smartmobile clients; ActiveSync polling. Whether or not COMPRESS is beneficial to a webmail implementation is beyond the scope of this discussion. Second, you are partially right. A successful restoration of the configuration state does require a round-trip to the server. But a RESUME command sent before initialization is an example of a command that CAN be easily pipelined with an authentication command. And the full round-trip is offset somewhat by the fact that upon a successful RESUME, the CAPABILITY string will not be sent-back to the client if the server normally does this automatically on authentication. And if the server doesn't normally return CAPABILITY information, then this is a complete win (RESUME/tagged OK vs. CAPABILITY command/CAPABILITY untagged response/tagged OK). >> ENABLE (CONDSTORE/QRESYNC) >> LANGUAGE >> COMPARATOR > > It looks to me that you can easily pipeline all of these and that > you do not risk anything by doing so. Yes, I'm aware of the wording > of the ENABLE RFC which sounds like one really MUST check its return > code, but a subsequent thread on this list indicated that this was > not the desired outcome and that it is completely legal to pipeline > ENABLE QRESYNC with SELECT ... QRESYNC. I would argue that the language of the RFC still controls despite what an e-mail on this list says. A client shouldn't be punished for interpreting it that way either. > As of the LANGUAGE -- how often do you expect to hit an error > condition which is not described by an appropriate response code? I > don't think that blocking for its result would be a good design > choice. That could be your decision as a client author. I would vehemently disagree. > And finally, what IMAP servers support the LANGUAGE extension? Why does this matter? RFC 5255 is a Standards Track extension. A year from now, every IMAP server and 200 new ones may support it. >> CONVERSIONS >> saved CONTEXTs >> NOTIFY > > Are you actually aware of a single IMAP server supporting any of > these (besides CONTEXT=SEARCH, which again can easily be pipelined > without any race conditions, and is specific to a mailbox state > anyway, which is outside of scope of your extensions)? Again, why does this matter? All of these are Standards Track extensions (your argument might hold a bit more water if these were Experimental documents). And what about future extensions? Those obviously aren't supported by ANY server yet. A given client may not support any of these extensions. This client could make the decision that SUSPEND/RESUME is pointless. That doesn't mean the SUSPEND feature is pointless since another client may support ALL of these extensions. > In general, all of the items which you included as an example look > like easily pipelineable items. Have you tried to use pipelining for > these? What was the total time spent waiting for their completion in > that case? What would be the best theoretical time which you could > get by RESTORE? It would be impossible to determine benchmarks since there is no defined protocol yet. And, as mentioned above, any given client/server interaction may provide different results based on their own internal optimizations and extension support. About the only thing you could do is look at network traffic savings. The following is an example of the possible savings giving a moderate use of IMAP configuration state (this is a more real-world example of Examples 1 & 2 in the draft): Initial session: [User authenticated] A1 CAPABILITY * CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE ACL RIGHTS=texk [This is the CAPABILITY list from Dovecot 2.1.10] A1 OK Capability completed. A2 ENABLE QRESYNC * ENABLED QRESYNC A2 OK Enabled. A3 LANGUAGE DE * LANGUAGE (DE) * NAMESPACE (("" "/")) (("Other Users/" "/" "TRANSLATION" ("Andere Ben&APw-tzer/"))) (("Public Folders/" "/" "TRANSLATION" ("Gemeinsame Postf&AM8-cher/"))) A3 Sprachwechsel durch LANGUAGE-Befehl ausgefuehrt [...] A20 SUSPEND * SUSPEND c3RhdGUgdG9rZW4= * BYE Server logging out. A20 OK Logout completed. Additional network data required by SUSPEND commands: 29 bytes (LOGOUT vs. SUSPEND; SUSPEND untagged response) [However, this command will only normally be run the FIRST time the session is accessed, so this is a one-time only hit] Additional round-trips required: 0 Subsequent sessions: A1 RESUME c3RhdGUgdG9rZW4= A1 OK A2 LOGIN joe passwd A2 OK [RESUME c3RhdGUgdG9rZW4=] LOGIN completed and configuration restored. [...] Additional network data required by RESUME commands: 61 bytes (RESUME command, RESUME response code) Additional round-trips required: 1 Network data saved by RESUME: ~650 bytes Round-trips saved: 3 Server parsed commands saved: 3 Client issued commands saved: 3 Untagged responses that do not need to be re-parsed: 4 In this example, the one-time addition of 29 bytes of network traffic (1 additional untagged response parse) results in the savings of 2 round-trips, ~600 bytes of network traffic, and 3 additional commands that need to be parsed on the client/server side. And remember this doesn't factor in any initialization code that needs to be run within the server/client to perform these commands. To me, that is substantial savings, especially when the connection may be re-established every 10 seconds. Hope this response identifies the reason and necessity of the proposal. Thanks again for the constructive input. michael _______________________________________________ Imap-protocol mailing list [email protected] http://mailman2.u.washington.edu/mailman/listinfo/imap-protocol