Hi everyone.

While porting evolution-kolab from Evolution 2.30 to 3.4.x (and on
to 3.5 later on), I have been stumbling upon an issue regarding
groupware server synchronzation.

Back in version 2.30, Evolution has not had a dedicated "synchronize"
button, but there has been the online/offline button, which, when toggled,
resulted in a synchronize() function being called in the cal/book backends.
Evo's online/offline state was independent of network availability back then.
From a user's point of view, it was okay to have the backend synchronize
with the groupware server when Evo online/offline state was toggled.

In version 3.4 of Evolution, this functionality is no longer existing. As I
learned on IRC yesterday, at least as of GLib version 2.32, the "online"
EBackend property is not even toggled by Evolution itself, but by 
GNetworkMonitor,
depending on network (un)availability. If the network is available, the
EBackend "online" property is set to TRUE by GNetworkMonitor (via the backend
factory), and is set to FALSE once the network becomes unavailable.

Effectively, I am lacking a mechanism which tells my backend that the user
wants to synchronize the local cache (evolution implements a full offline
cache with offline-editing support) with the Kolab server side. If the network
is unavailable and then becomes available, it is debatable whether this would
be a good time to start a synchronization run. However, if GNetworkMonitor 
signals
network is unavailable, obviously, it is too late to try to synchronize with
the server.

It has been proposed to use an asynchronous backend thread to synchronize with
the server. While it could be done, it has the drawback that during sync, sync
conflicts can occur. evolution-kolab presently implements a pre-configurable
sync conflict resolution strategy which does not need user interaction during
sync, but this was a simplification done in 2.30 since we did not have the
capability to ask for user interaction from E-D-S back then. Years of experience
with Kolab (and other groupwares) have shown that automatic conflict resolution
cannot get it right in many cases and user interaction (manual conflict 
resolution
via a dialog) is needed. Implementation for this has started in evolution-kolab.
Back to the topic: A synchronization background thread will run into a sync 
conflict
sooner or later, and a dialog will pop up asking for user interaction. This will
inevitably happen while the user is occupied with something else, like composing
an email, and it will then disturb her workflow, since she was not expecting
some sync conflict dialog to pop up (the principle of least surprise will be
violated), let alone the fact that an async synchronization thread introduces
a nice extra level of complexity.

Kolab server synchronization can become quite bulky, since the Kolab server does
not have some notion of per-client changesets. It is a mere storage, and
synchronization means to grovel through folders in search of emails. This can
take quite some time, depending on how many objects are stored in a given 
folder,
and it can be heavy on CPU usage as well as network bandwidth usage. If that 
starts
grovelling just the moment some network becomes available, that can be much 
annoying to the unexpecting user.

IMHO, you it is a plain impossibility to "guess" the correct time for a server
synchronization. As a backend, I do not know what the user wants to do next. 
Network
may be available, but it may be awfully slow (e.g. some hotel room), and the 
user would
prefer to just check some mails and do the heavy groupware server 
synchronization when
back in the office. Some users prefer to work in offline mode, even when 
networking is
available, and do some bulk sync when the time seems right for them.

This means that the most simple, most straight-forward and least-surprising 
(for the
user) thing to do would be to invent a dedicated sync button, with which the 
user can
direct the backends to do the server synchronization *now*. Once this button is 
pressed,
it is clear to the user that now, things can take their time and she will be 
willing to
wait for as long as the sync run takes. Depending on network availability, this 
sync
button can even be grayed out - it surely makes sense to deactivate that button 
if
there is no network available (maybe some tooltip could show information why 
the sync
button is deactivated). If networking is available, then the sync button can be 
pressed.
The sync, due to multiple reasons, can still fail, but this is something for the
backends to handle.

My proposal would be an EBackend virtual function, which the backends can 
choose to
implement and which is called when the user does a dedicated UI action, like 
pressing a
sync button:


EBackend::synchronize (EBackend *backend, EDataCal *cal, GCancellable 
*cancellable, GError *error);


That would be one part of the issue.


Next part is, that I think network (un)availability and Evolution/E-D-S 
online/offline
state are two separate things, which got mixed in the current implementation. 
Network
unavailability means I cannot write my objects onto the server. In 
evolution-kolab,
whenever a PIM object is saved, it is first stored in the local write cache. If 
in "online"
state (as in Evo 2.30 semantics), evo-kolab would then try to push the object 
onto the server,
which may fail due to a multitude of reasons - server down, network line shaky 
(connection
dropouts), firewall-of-the-day is active or whatsoever. The PIM object then 
simply stays in
the offline cache, waiting for a later successful sync with the server.
  If the evolution-kolab backend is in "offline" state (again, as in Evo 2.30 
semantics),
after writing an object to the offline write cache, *no* attempt will be made 
to push this
object onto the server, and it will sit there in the offline cache until the 
next
synchronization attempt (best done via a dedicated sync button, IMHO) is made.
  This means that "online" or "offline" state for *Evolution* is a setting a 
user
should be able to toggle, as it is a client state, while network 
(un)availability, or even
service unavailability, is a different matter. The current implementation is - 
IMHO - an
oversimplification which does not match the needs of an offline-capable PIM 
client. If the
backend can query network availability (or gets this information via an object 
property),
this is much helpful, but it is not sufficient.


What do you think?


Kind regards,

        Christian


-- 
kernel concepts GmbH       Tel: +49-271-771091-14
Sieghuetter Hauptweg 48
D-57072 Siegen
http://www.kernelconcepts.de/

Attachment: signature.asc
Description: This is a digitally signed message part.

_______________________________________________
evolution-hackers mailing list
[email protected]
To change your list options or unsubscribe, visit ...
http://mail.gnome.org/mailman/listinfo/evolution-hackers

Reply via email to