Doing things in parallel, downloading messages while getting summary

A little bit more technical … some people like that, others don’t.

Today I did a cute hack on the embedded camel of Tinymail, camel-lite: I altered the camel_folder_get_message implementation in such a way that it would create a new CamelImapStore instance.

The CamelImapStore is a type that derives from CamelService and holds the connection lock. It also has the pointers to two CamelStreams who represent the access to the socket filedescriptor. That is your connection with the IMAP server. The CamelStream abstracts away SSL and yadi yada but the principle is the same: it’s the store that can only perform one procedure simultaneously in Camel (and therefore, also in Evolution).

In Camel this meant a lot of locking. Regretfully isn’t the IMAP implementation very fine grained in its locking (and actually, it sucks a little bit). Nor does the IMAP implementation do pipelining or any other such neat tricks. It’s a simple “lock, send query and fetch result, unlock”-concept put in practice. I have broken up some procedures, like getting the summary, into smaller queries: by looping until I have all of the summary. During that loop, the locks get unlocked. A get-message would therefore, in theory, get a chance to occur while the loop is happening in another thread.

That theory actually does work in practice. However, it was a little bit difficult to get it to behave absolutely correct. On top of that is Camel’s “design” far from perfect. Therefore in stead of endlessly trying to get it correct, I decided to make the decision and do a proof of concept that basically creates a new connection each time you download a message and store it locally in the cache.

The final idea for all this is to have a flexible queue mechanism that, for E-mail clients that want this functionality, will in the background download (new) messages while getting summary in parallel. While if the user clicks a message, while summary is being received or after it, the queue will get a high priority item added that will first download the clicked message and display it in the message view component.

I know that this is the core of a lot of E-mail clients. It’s exactly what I want tinymail to provide within the framework, as yet another component.

Next to that I will also implement a folder observer that will act on Push E-mail events by putting the request for getting the new E-mail on the queue. All of this will of course be optional behavior: on a GPRS network you specifically don’t want to retrieve all (new) messages. That would consume shitloads of bandwidth and would cost you a lot of money. But before going offline, you might want to ask your E-mail client to do indeed get all the messages and put them in the offline cache? While it’s doing this, you still want to work normally. And why not? Exactly. That’s why the second connection proof of concept was done.