Hello folks,
It has been 3 weeks that I've worked on my weekends and nights to
rewrite Folks from scratch. Yes I'm expecting a lot of hate and critics,
but with my experience on N900 and N9 addressbooks I wanted to give a
try to my own design ideas instead of starting from someone else's
design and then spend months to make their wrong design decisions fast
enough to be usable. So even if this turns out to be useless work, I had
a lot of fun writing Folks2 and that's already enough for me :-)
http://cgit.collabora.com/git/user/xclaesse/folks2.git/
Folks2 is entirely written in C/GObject. It has its own soname and
should be parallel installable with Folks. However it reuse the same
namespace and has an API close to the original Folks, so it probably
cannot be used in parallel in the same application (why would you do
that anyway?). It already has telepathy and EDS backends and is able to
load my roster in about 200ms. I've hacked a roster reusing
EmpathyRosterContact and EggListBox widgets on top of Folks2 and GTK is
now clearly the bottleneck. Using an old-school GtkTreeView, Folks2
display my full roster almost instantaneously. Compared to Empathy who
takes 100% CPU for about 15s and its window becomes grey because WM
thinks it crashed.
Pasting Folks2's README for more details. Comments are of course
welcome.
Concepts
========
Backends (e.g. telepathy, eds) provides a set of personas which provides a
common API on top of a backend specific contact (e.g. TpContact, EContact).
Personas have an unique identifier string which is opac to user, but can be
parsed by backends to find its underlying contact. For example a telepathy
persona's ID would looks like "telepathy:<account path>:<contact id>".
Individuals aggregates one or more personas and exposes information gathered
from its personas. For example its presence will be the presence of the "most
available" of its personas, its emails will be the union of the emails of
all its personas, etc. An individual also has an unique identifier string. If
it contains only one persona then it is its persona's identifier. Otherwise it
looks like "individual:<uuid>". An individual id represents an unique set of
personas, adding/removing personas will result in a new individual id.
Folksd is a DBus service centralizing merge information. It maps invididuals
IDs to a set of personas IDs merged together. It does not know any other
information than IDs, so clients must tell explicitly what personas to merge
together. Any implicit merging logic must be done client-side, eventually by
asking the user.
With that design, it is possible to fetch a single individual without fetching
any information about other individuals. Typical use case is the incoming call
UI has the caller's TpContact, it can then ask the telepathy backend to creates
a persona wrapping it. With that persona the client can ask Folksd for the
individual ID and others persona IDs merged together with the given persona, and
creates the needed extra personas.
Expected UI
===========
One very important goal is to limit as much as possible information duplication
between processes. Processes caring about only few individuals (call ui,
chat window, file transfer hanlder, gnome-shell notifications, etc) should not
fetch and get change notifications about any other individuals. Only 1 process
should fetch all individuals: the Contact List UI.
The contact list is expected to know all the details about all individuals, so
it is expected to be the process who will do the merging heuristics and tell
Folksd to merge some personas. It is its responsability to ask user's
confirmation first or not.
The contact list could also implement a DBus searching interface, so other
applications could ask "which individual has email address foo at example.com" and
it would return the individual ID. From that ID the application can ask Folksd
for the list of personas IDs and then fetch the needed information.
Out of scope
============
Compairing with the original Folks project, a few things are out of Folks2'
scope:
- Offline telepathy contacts caching: It is important to still have all
information about individuals regardless of the internet connectivity. It is
thus needed to cache telepathy contacts on disk for offline usage. It is
expected that the Connection Manager will write those information on disk.
When account goes online/offline only the presence of the persona would
change, and internally the persona wrapper would switch from a TpContact to a
TpOfflineContact and vice-versa.
See https://bugs.freedesktop.org/show_bug.cgi?id=62378
- Merging heuristics: It is the UI who decides which personas to merge
together. UI could as well decide to add information into e.g. Google EDS
book that would help its heuristic logics to detect merged contacts on other
devices. It would be his responsability to trust those information and do
implicit merging without asking the user.
- Creating/editing individuals: Currently an application wanting to edit/create
individuals would have to use backend specific APIs directly. This could be
added in the future though.
Regards,
Xavier Claessens.