Just a quicky on "what I did this week-end".
And yet another week-end which went away like a blast... of course
it was again the fault of KDE! I went all the way to Osnabrück to
attend the traditional KDE PIM sprint. This one was a first for me
despite the fact that it was its tenth edition.
My plan before flying in was simple and easy to remember: "Sit with
David Faure and fix all his IMAP bugs". It turned out not that easy
to apply in practice. Of course, there's always something unexpected...
sometimes pleasant, sometimes not.
For the unpleasant part, we had a tough luck on Friday: David's travel
wasn't smooth at all so he arrived only during the night, while I had
a terrible headache during the afternoon and the evening which made
me only able to triage bugs (and at a very slow pace even...).
The pleasantly unexpected event which turned me away from my initial
simple plan was the presence of Christian Mollekopf and Björn Balazs.
I work with Christian on Zanshin, and I already interacted with
Björn quite a bit during the Forge 2011 for usability work... one plus
one being equal to lots, we ended up having meetings to discuss
the interaction schemes for Zanshin 0.3. I have to say I'm pleased
with the results so far. There's still a few gray areas but I think
we'll decide on those when we turn the ideas into code.
And for the IMAP support? Well let's say that despite the disturbances
which turned me away from my plan, the bug count went drastically down.
On arrival, there was a bit more than forty bug reports against the
IMAP resource, and between the triaging and the bugfixes we worked on
with David I'm now leaving the sprint with only twenty known bugs (also
a couple will likely get closed shortly since patches are in the work).
And again, a fairly nice and productive sprint, courtesy of KDE. I looove
this community!
I previously blogged about the new IMAP resource in Akonadi. We
were aiminag at getting this resource from the start, but here is
the not so secret story: this effort gave birth to another
component, namely libkimap.
The journey started because we really wanted for KDE to have a
strong and efficient IMAP support. Since we're not really into
reinventing the wheel if we can avoid that the journey started by
looking at existing IMAP solutions we could reuse. The natural
first contender of course was to reuse our old IMAP ioslave which
we currently use in KMail and build the resource on it. But really
it is showing its age now, and the interface such ioslaves expose
are too limited for our needs (for those in the known of KIO
internals: it would require an extensive use of the special()
method, or command encoding in urls...). So we have been evaluating
a few other contenders coming from various mail clients, but
unfortunately most of them are either exposing synchronous API (not
convenient for something event driven like an Akonadi resource), or
very tied to a MIME implementation (which was a no-no as we needed
to use the resource with kdepim's MIME implementation).
Indeed this journey didn't start quite well... We had to produce a
new IMAP implementation. So a new quest started, one for an
adequate API design. At that point we knew we wanted something:
fast, memory efficient, asynchronous and easy to extend (as the
IMAP RFC has plenty of extensions).
First, let's examinate the "fast and memory efficient" constraints.
Around the same time I got started on libkimap, Andras Mantia
(fellow KDABian and hacker extraordinaire) was working on making
the Akonadi server protocol handling faster and more memory
efficient... And as a bonus, the Akonadi protocol for the lowest
level parts, have quite some similarities with IMAP as it was
modelled after it. So far so good, I could reuse Andras work on the
new IMAP stream parser. It has been a two way collaboration as I
also found bugs in there which got fixed. This parser is now the
core of libkimap, although it is hidden from the public API, it is
for a great part responsible of the good performances of the
library.
Then, let's solve the "asynchronous and easy to extend"
constraints, those had a direct impact on the API. For that we rely
on the good old "job based" API. You just need to create a Session
object which holds a connection to an IMAP server and queue Jobs on
it. Jobs are then executed sequentially. We have jobs for a lot of
things: mailbox listing, fetching messages or headers, retrieving
annotations, quota information, ACLs, etc. And that's where the job
based API gets interesting, we need to extend it? Just add a job,
binary compatibility will be kept and so on, it makes it much
easier to manage it over time.
Oh! And of course, since we still care about performances, each job
is equipped to be able to pipeline several IMAP commands to the
server, which dramatically reduces latency. So you guessed it, jobs
don't map 1:1 to IMAP commands, this way we can provide some
convenience to developers because they get pre-shipped micro
behavior (for instance, listing mailboxes and taking care about the
namespace extension results always in the same list of commands, so
we wired it in jobs which pipeline commands).
So we indeed solved our initial problem, we made an asynchronous
IMAP library which is fast, efficient and easy to extend. It also
tries to be clever when that actually makes it more convenient for
developers (see the pipelining example above), but not too much,
allowing to have a fine control on the higher level logic and
strategies you'd need to implement in your application. And thanks
to this strong basement, we could tackle the task of building the
Akonadi IMAP resource on top of it.
As a post scriptum: is our library tied to a MIME implementation?
Well, like others we're tied to one: libkmime, available in
kdepimlibs as well. You can't really get around that in the end.
Indeed, for fetch operations if you try to be independent of any
MIME implementation, you end up implementing your own subset of
MIME. That said we tried hard, and managed to keep that coupling as
minimal as possible, and in fact only the FetchJob really depends
on libkmime, everything else is independent of it. So, it wouldn't
be a big cost to implement your own FetchJob variant using another
MIME implementation.
And finally, as a post post scriptum, if people out there wants to
grab it and play with it, it is in our kdepimlibs module on trunk.
You can browse it online here:
[http://websvn.kde.org/trunk/KDE/kdepimlibs/kimap/](http://websvn.kde.org/trunk/KDE/kdepimlibs/kimap/).
In my previous post, I've been discussing our progresses on some
protocols support, and that Akonadi could now be fed with quite
some mails. That's neat to us developers who can make application
harvesting data in there... But for the user it's not really useful
if he can't see the data. Well, recently I've also been working on
showing up collection statistics we can get from Akonadi, and also
I ported KMail message list view to Akonadi (also making it a
separate library). In the meantime, the fearless Andras has been
porting KMail mail reader view to Akonadi (also making it a
separate library). In fact, it is the current thread in the huge
task which is the porting of KMail to Akonadi. We're ripping KMail
apart, each important set of features are factored out in a library
and ported to Akonadi. In the end we'll have a KMail completely
based on Akonadi. But also, it will be much more modular, reusable
for other mail clients, but also news readers, etc. Which means
that the new architecture will be better suited at supporting a
wide range of devices and a good base for future works. Anyway,
both Andras and me had a small test application for each of our new
frameworks... So I took some time to merge the features of both
into a single application: the Akonadi Mail Reader. This new baby
is mainly a prototype to toy with ideas and try out the components
we're making out of the monolithic KMail. Still, it weights just
under 400 lines of C++ code, and you can completely browse all the
mailboxes you configured in Akonadi thanks to it. Of course, here
is the obligatory screenshot: [caption id="" align="aligncenter"
width="320"][](http://ervin.ipsquad.net/share/akonadimailreader.png)[/caption]
It looks so much like a miniature version of KMail that it is
almost scary. But don't fool yourself, there's a lot to do to have
a full fledged KMail which will be only based on Akonadi. We're not
there yet, still it is nice to see the whole thing taking shape, in
particular to reach the point where you can actually read your mail
over IMAP using this small prototype and feel almost at home with
it thanks to this familiar touch. :-) From my point of view, the
KDE culture of working a lot with components really pays off. KMail
was first created at a time where this KDE culture didn't reach
it's full potential yet, hence why we need to refactor it now. But,
following this culture it is really nice to see that we'll end up
with small packages of mail client functionalities, and, that
thanks to them and to Akonadi, it will be easy to integrate them in
any application. We made a relatively complete mail reader in under
400 lines of code, so simply displaying mail content in your
application or a message list becomes a trivial task.
We got a few posts lately of people recently hired by KDAB, and
suddenly it made me realize that I didn't make such a post when I
got hired... almost two years ago. I guess it's a wee bit late to
write one now. :-) Buuuut... I figured out that I could post
something about what I'm doing in KDAB (OK! OK! Sebas has been
kicking me for days to make it happen). And if that proves to be
enjoyable writing for me, and enjoyable reading for you people I
may do that again from time to time. So what am I doing in KDAB
these days? Well, for a while now I've been helping the pimsters
with the refactoring of our PIM suite toward making it purely
Akonadi-based. There's quite a lot of work going on in this
particular space, and I've been focusing mainly on the IMAP
support. It has been an interesting journey so far which started
with evaluating the IMAP stacks we could reuse. First on the ranks
were obviously our old ioslave which served us well, and some IMAP
code Tom Albers developed for Mailody. It turned out that we had to
abandon the ioslave. It served us well for years, but didn't work
for some of the plans we had (most notably for adding the IDLE
support I'll talk about later). While working on IMAP I had a
couple of ideas on how to still use the old ioslave, but they were
really nasty and hackish... I think it was a clear sign that the
ioslave reached its full potential and keeping it alive was a dead
end for the future. So after this investigation phase it has been
decided to write a small library for IMAP. We already had some
codecs convenience in the KIMAP library from kdepimlibs so we
stepped up to extend it. And for the API we quickly settled on a
job based one because we had strong needs for asynchronous
operations. We clearly don't want to be blocking waiting for some
IMAP command to be processed. So our dear old KJob friend has been
used for that, and it turned out to be a very good choice. We've
been relatively quick at having enough useful jobs implemented in
the library once I wrote the core bits of the API. I got quite some
help from Andras Mantia for that. By the way, I think that just
like our almighty David Faure, Andras is having a few clones
himself, once he gets on a task he going so fast you'd better not
be on his way... something suspect is at play there, I'm sure. ;-)
In any case, Andras (and his hundreds of clones) help was welcome,
as it helped me move higher in the stack and work on the Akonadi
resource itself. I'll just slow down a minute and explain for those
not in the known what an Akonadi resource is (for the ones in the
known, you can skip to the next paragraph). So Akonadi is our grand
unified layer to access data in your desktop, applications talk to
it and then they have to understand only the akonadi concepts (in
short: items, and collections of items). Of course you need to get
your items and collections from somewhere, and that's the role of
Akonadi resources. They just get data from "somewhere" and put it
in the Akonadi cache where the applications can make use of them.
Obviously for a future Akonadi based KDEPIM suite we needed an IMAP
resource to access your mail on IMAP servers. And if you followed
closely, that means that soon applications won't even need to know
where the data comes from, you write just an Akonadi client and it
can go over: POP, IMAP, whatever! It all depends on the resources
your server loaded. Neat huh? Work on the IMAP resource started
only a few days before the Akonadi Sprint in Berlin which I was
attending. And the job based API quickly proved that it was the
right choice. I've been pretty quick at building the resource on
top of it (and Andras was producing new jobs for my own consumption
at a furious pace). At this meeting we had kind of an informal
contest about who would come up first with an Akonadi resource
which can list a mailbox (since at the time POP, IMAP, and maildir
support were all developed and started around the same time)... it
turned out that I heard about this informal contest when I was
putting the finishing touch to the mailbox listing. Sooo... DONE!
:-) I didn't stop there of course as more features were needed to
have a complete resource. And I've been working on that almost
exclusively during the sprint. Discussing with Volker (aka the
Akonadi overlord, the alpha and omega of its design) we came up
with nice design ideas for the groupware support (in particular
Kolab)... but that's probably a story for another time... Some time
after the sprint, I flew over to other tasks in PIM land. And left
the Akonadi IMAP resource untouched for a while. I came back to it
only last week to implement in trunk one long requested feature:
the IDLE extension. -- And obviously that's where the name of this
blog post come from, just like my favorites novels you get the
title only in the last chapter or paragraph. :-) -- Thanks to this
extension, if it is supported by the server, you get notified from
changes by the server itself. For instance, it is not needed
anymore to poll every N minutes to notice that a new mail appeared
(I think this feature is sometimes called "push mail"). For the
user that means, that the IMAP server can now notify the client of
new emails, emails "arrive" faster at the user, and you can save a
lot of unnecessary mail checking. Really handy! I committed IDLE
support in trunk this week, so it will get released with our 4.4
release. In the meantime you can start playing with the Akonadi
resource when our 4.3 release will be out, as we already ship it
there (although it's not used by default, see it more like a
pre-version of what's coming, for instance this one doesn't support
IDLE). That's it for today, I hope you enjoyed those pimsters news
from the trenches of the IMAP battle. See you later!