Re: [Evolution-hackers] PIM server synchronization and Evolution online/offline state



Hi Milan,

thanks a lot for joining us and for writing the nice summary!
This is much appreciated. If the mail thread becomes too long
and overly complicated, it may make sense to drop the findings
into a wiki page and work it out from there.

First of all, no, the things discussed here are not going to be
easy, and it raises the question what Evolution actually wants
to be. Does it want to be a fully offline-capable PIM/groupware
client? That means, does it want to support backends which are or
strive to be?

Which is the long-term vision for Evolution in this regard?


Am Mittwoch 04 April 2012, um 12:24:58 schrieb Milan Crha:
> On Tue, 2012-04-03 at 13:33 -0400, Matthew Barnes wrote:
> > On Tue, 2012-04-03 at 19:10 +0200, Christian Hilberg wrote:
> > > Just rough thinking, nothing elaborate as yet - I'll be meditating
> > > this. :)
> > 
> > Rough thinking here too.  I'll let it simmer.
> 
> 	Hi,
> this thread is getting quite complicated, and I confess I'm rather lost
> here (the final outcome should be clear, right). But to summarize which
> things are discussed here a bit (or better those I understood):
> 
> a) Add an explicit method to synchronize local changes into the server
> b) Add some mechanism to ask user for conflict resolution during a)
> c) Tell backend to work in "offline mode" - do no network operations
> d) Notify client about current "offline mode" being used by the backend

That pretty much sums it up.

> --------------------------------------------------------------------------
> 
> ad a) There is agreed about the method addition, and I agree too. Maybe
> a different method prototype would be used (more parameters, see below).
> I suppose, you still tries to write the changes to the server as soon as
> possible, when in online mode, right? It makes sense, I'm only checking.

Trying to bulk-sync as soon as network comes back online may interfere
with the user's planned workflow (just reading latest mails on a shaky
line), so I would suggest to either leave that to the user (by pressing
the sync button), or to provide a config option. The latter could also
be done on a per-backend basis.

> --------------------------------------------------------------------------
> 
> ad b) This is quite complicated, the backend cannot rely on gtk+,
> because it would bring the dependency on the factory and the factory may
> not depend on the gtk+, it should be runnable without live desktop, only
> from a terminal. Correct me if I'm wrong. The idea of "another process
> taking care of the user interaction" is, apart of quite complicated,
> also not easy to do, what if you run the server without live desktop, or
> if you run on thin clients, or ... I'm afraid there can be many ways how
> to break this approach. Thus, what about adding a DBus signal on the
> backend for conflict resolution, something like:
>    void resolve_sync_conflict (
> 		guint sync_op_id,
> 		const gchar *server_object,
> 		const gchar *local_object);
> which backend will throw and the client side should response through
> something like this method:
>    void sync_conflict_resolved (
> 		guint sync_op_id,
> 		ESyncConflictResolution resolution);
> where ESyncConflictResolution will contain values like:
> 	Unknown
> 	ServerWins
> 	LocalWins
> 	... (maybe more, Christian may advise better)
> Of course, the client part should implement this, which is basically
> undoable for all of them (and some even do not use gtk or any user
> interaction at all), thus I would add one parameter to the "synchronize"
> method, the ESyncConflictResolution value, which will pick the desired
> strategy. If it is "Unknown", then the backend can use the signal and
> wait for the method to resolve conflicts (better name from "Unknown"
> would be "Ask"). Of course, clients without user interface will not call
> the "synchronize" method, most likely.
> 
> The resolve_sync_conflict() uses strings for objects, and based on the
> EClient type it's either ECalComponent or EVCard as string.

You are right, it is too easy to forget that E-D-S better not depend
on UI. As for evolution-kolab, if there is no client connected, then
no synchronize() action would be triggered, hence no sync conflict would
occur. Only if there is a client actually requesting objects or a server
synchronization, then the backend would become active and actually *do*
something. Otherwise it would be sitting idle and not be trying to keep
up with server changes (object changed on server -- backend pulls --
object is changed back on server -- backend pulls --- ... I think a lazy
approach would be the better one here).

> --------------------------------------------------------------------------
> 
> ad c) The mailer part does this in global, not per-account bases. Maybe
> the client may have this done in the same way. Nonetheless, in a
> multi-client environment you may make sure that the clients will not
> fight on this (when one requests backend to stay offline while the other
> will require it to run in online). Note the factory uses the same
> backend for each client it connects to it, that's why they can fight.
> The current "online" property works fine for me for these purposes, but
> if you really want, then rename it. Still, this should be, from my point
> of view, just a preference given by the client (user) whether the
> backend should or should not do any network operations. You've right
> that there should be distinguishable whether the offline state was
> initiated by a user, or by connection issues (wifi disconnected, vpn
> dropped and so on), thus the backend can decide whether the connection
> it has currently opened with the server is still alive and it can close
> it properly - otherwise it would just timeout, and these timeouts aren't
> short. New network-related property comes in mind.

Just adding a few bits: If a user wants the backend to be in offline mode,
that would be a good time to do a last synchronize() operation with the
server, before actually switching into offline mode, i.e. not doing network
operations any more (though network may still be available).
  OTOH, if a network failure inhibits further network operations, without
the user having explicitly requested offline mode, then the backends may
need to know this. It may make a difference for a backend whether it has
reached offline mode in an ordered manner (last sync with server was all
good, yes Sir, going offline now), or the offline operation was forced
upon the backend by a network outage (error condition), where some precaution
may be needed.

> --------------------------------------------------------------------------
> 
> ad d) For cases like "network unavailable" or "the network available,
> but the destination server unreachable" the backend can notify clients
> about its online mode. (There is a "special" case when you connect to
> the server for the first time, thus the backend may report an error,
> rather than running in offline mode against the server address which is
> not reachable, because of typo in its URL.) There is currently a
> mechanism to notify about onlinity by the backend towards its clients,
> the only thing is that evolution itself doesn't indicate it in any way
> to the user in its UI. For example CalDAV calendars can run online, and
> after it realizes the server is offline, they switch itself to offline
> mode (it doesn't have any offline mode implemented, it just prevents it
> from doing event changes - by setting itself to readonly mode too), and
> if it realizes later that the server is reachable again, then it
> connects to it and continues online. I do not think the network monitor
> would help here anyhow, the backend will only know for sure when it
> tries to connect. From my point of view, this property should be used
> only for indications on the client side, not to guess from it what
> backend can do and what not when its offline. There is also a "readonly"
> property, which serves for related purposes.

As for evolution-kolab, if there is a network outage, there is an implicit
offline mode, in that the objects stay in the local offline-write-cache
(or their deletion is recorded, for that matter - moving objects around
between Kolab folders just means adding it to one and deleting it from
the other folder - this is recorded by the offline-write-cache). The failure
to write the object to the server is then reported to the client, that's it.

> --------------------------------------------------------------------------
> 
> One more thing, which I didn't get is, what to do when you connect to
> the server and you have objects in your offline cache to be uploaded to
> the server. Christian said they are not trying to upload them, but it
> may also not try to get changes from the server, because that's the
> point where the conflicts happen, say when server has modified the same
> event I modified in offline. Still, you want to get changes from the
> server right after connected to it, to show new events to the user, but
> you cannot synchronize? I would say it's unexpected by most of the users
> (there is opened a bug report where reporter claims that the backend
> updates its changes too often, when he has there set a refresh for one
> day (I do not recall the exact interval value), but the backend updates
> with server changes right after being opened, which is unexpected for
> him - I guess it's rather rare case).

I guess finding a good balance here is difficult. Supplying the user with
a dedicated sync button is a good thing, and should be done, but you're right,
bugreports will come from users who forgot to press the button. A refresh
timeout with a sensible preset seems to be a good thing, too. Maybe it would
be worth it that the refresh can simply be disabled without changing the preset,
that would help users who go on travel and who know that they'll be on shaky
lines for the next week (is it that way already? /me needs to check).
  As for evolution-kolab, sadly, there is no good way to do a "quick check" for
changes, at least I do not have an idea how one could implement one, since the
server does not do any kind of bookkeeping for the clients. One can check IMAP
UIDs, any change on them in a PIM folder indicates that a sync is needed, but
you do have to search for the changed objects then. It could slow down the
open() operation for a cal or book dramatically if the sync was done there,
that's why I did not put a sync point there for evo-kolab (though it could
easily be done, but it may create the impression that the cal/book itself
hangs... and is opening the cal/book cancellable? I don't think so).

> OK, I made this slightly longer and I'm sorry if I wrote anything
> obvious up there (which I surely did). In that case just consider this
> as a little summary for this thread.

Thanks again for the summary Milan. It helps a lot. Seems to me that
these issues are much worth the discussion, and it is better to do it
here than on IRC (it is easier to cherry-pick the bits from mail archive
than from IRC log). :-)

-- 
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.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]