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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.