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

2012-04-04 Thread Matthew Barnes
On Wed, 2012-04-04 at 21:25 +0100, Philip Withnall wrote:
> Nitpicky, but what happens if a backend has to deal with multiple hosts?
> The only example I can think of at the moment, and it's a stretch, is
> the Google Contacts backend. It connects to one host for authentication,
> and a different one for Contacts operations. Most of the time, GOA will
> take care of authentication, so this really is a tiny corner case, but I
> guess it's worth considering.
> 
> I suppose we would just use the Contacts operations host for the
> purposes of "socket-connectable", and treat failure to connect to the
> authentication host as a transient authentication error.

Agreed.  More broadly I'd say "socket-connectable" should point to where
the data lives.  If that's not reachable then there's really no point in
authenticating, whether _that_ host is reachable or not.


> I might be tempted to give the user feedback about why a backend is
> _not_ writeable (somehow, perhaps a "writable-reason" enumerated
> property). This could be useful when setting up a backend: the backend
> might report itself as non-writeable, but the user would not know
> whether this is because they've made a typo in the backend's URI, or
> because they've used a read-only URI instead of a writeable one. Or
> something like that.

That's worth considering, though it might already be partially covered
just by backends returning error messages on failed operations as per
normal.  That includes open().


> Overall, this set of properties seems to simplify things nicely though.
> It also fits in well with the offline buffering stuff Milan and I have
> been discussing (with a few other people CCed).

Good!  That at least validates I'm not _completely_ off the mark.  :)

Matt

___
evolution-hackers mailing list
evolution-hackers@gnome.org
To change your list options or unsubscribe, visit ...
http://mail.gnome.org/mailman/listinfo/evolution-hackers


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

2012-04-04 Thread Philip Withnall
On Wed, 2012-04-04 at 13:11 -0400, Matthew Barnes wrote:
> On Tue, 2012-04-03 at 19:10 +0200, Christian Hilberg wrote:
> > How about the "service-available" to be set much like the to-be
> > "network-available", through GNetworkMonitor, as an EBackend property,
> > which, when changed, emits a signal?
> > 
> > Just rough thinking, nothing elaborate as yet - I'll be meditating
> > this. :)
> 
> We discussed this briefly on IRC, but just to follow up more formally.
> 
> Having stewed on this overnight I think we're coming at the problem
> wrong.  The question boils down to "can the backend operate on its data
> set or not?"  That status is as much as we need to expose to clients, I
> think.  Network availability and remote server availability factor into
> the answer but clients need not care.  If a backend is offline-capable,
> then the answer -- as far as the client is concerned -- is always "yes".
> 
> Here's the set of properties I propose for EBackend to replace the
> current overly simplistic "online" flag:
> 
> 
> "host-reachable"
> 
>type: boolean  perm: read-only  default: false
> 
>EBackend itself updates this as a convenience for subclasses, but
>this status need not be exposed to client applications.
> 
>For network-based backends, this property is the result of running
>g_network_monitor_can_reach() on startup and in response to changing
>network conditions or when the "socket-connectable" property changes.
> 
>For local-file backends, the host is assumed to be "localhost" which
>is always reachable.  So the property will always be TRUE for them.
> 
> 
> "socket-connectable"
> 
>type: GSocketConnectable  perm: read-write  default: (see below)
> 
>This is the GSocketConnectable fed to g_network_monitor_can_reach().
> 
>EBackend itself will initialize this to a GNetworkAddress based on
>the host and port settings in the ESource.  Subclasses do have the
>option of overriding this, however, which is why it's read-write.
> 
>If the pointer is NULL, this is assumed to mean "localhost".
> 
>Setting this property will trigger a "host-reachable" notification
>after EBackend runs g_network_monitor_can_reach() on the new value.
> 
>This property could prove to have additional uses in the future as
>we further embrace GIO's networking APIs.

Nitpicky, but what happens if a backend has to deal with multiple hosts?
The only example I can think of at the moment, and it's a stretch, is
the Google Contacts backend. It connects to one host for authentication,
and a different one for Contacts operations. Most of the time, GOA will
take care of authentication, so this really is a tiny corner case, but I
guess it's worth considering.

I suppose we would just use the Contacts operations host for the
purposes of "socket-connectable", and treat failure to connect to the
authentication host as a transient authentication error.

> "readable"
> 
>type: boolean  perm: read-write  default: false
> 
>This property is exposed to clients.  It indicates the backend's data
>is viewable but not necessarily complete, as in the case of a network
>outage and not having fully synchronized for offline usage.
> 
>Backends are responsible for updating this themselves.
> 
>Clients are responsible for disabling the relevant UI elements when
>this property is FALSE.
> 
> 
> "writable"
> 
>type: boolean  perm: read-write  default: false
> 
>This property is exposed to clients.  It indicates the backend's data
>can be modified, but possibly only locally.  Reasons it may be FALSE
>include the remote host not being reachable, the service running on
>the remote host not being available, or the service forbidding write
>access to the data (such as for "On The Web" calendars).
> 
>Backends are responsible for updating this themselves.
> 
>Clients are responsible for disabling the relevant UI elements when
>this property is FALSE.

I might be tempted to give the user feedback about why a backend is
_not_ writeable (somehow, perhaps a "writable-reason" enumerated
property). This could be useful when setting up a backend: the backend
might report itself as non-writeable, but the user would not know
whether this is because they've made a typo in the backend's URI, or
because they've used a read-only URI instead of a writeable one. Or
something like that.

Overall, this set of properties seems to simplify things nicely though.
It also fits in well with the offline buffering stuff Milan and I have
been discussing (with a few other people CCed).

Philip

> Under this scheme, client applications don't need to know about network
> or service availability -- just whether the backend can currently handle
> a particular user action.  I think this simplifies things greatly.
> 
> Matt
> 
> ___
> evolution-hackers mailing list
> evolution-hackers@gnome.org
> To change your list option

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

2012-04-04 Thread Matthew Barnes
On Tue, 2012-04-03 at 19:10 +0200, Christian Hilberg wrote:
> How about the "service-available" to be set much like the to-be
> "network-available", through GNetworkMonitor, as an EBackend property,
> which, when changed, emits a signal?
> 
> Just rough thinking, nothing elaborate as yet - I'll be meditating
> this. :)

We discussed this briefly on IRC, but just to follow up more formally.

Having stewed on this overnight I think we're coming at the problem
wrong.  The question boils down to "can the backend operate on its data
set or not?"  That status is as much as we need to expose to clients, I
think.  Network availability and remote server availability factor into
the answer but clients need not care.  If a backend is offline-capable,
then the answer -- as far as the client is concerned -- is always "yes".

Here's the set of properties I propose for EBackend to replace the
current overly simplistic "online" flag:


"host-reachable"

   type: boolean  perm: read-only  default: false

   EBackend itself updates this as a convenience for subclasses, but
   this status need not be exposed to client applications.

   For network-based backends, this property is the result of running
   g_network_monitor_can_reach() on startup and in response to changing
   network conditions or when the "socket-connectable" property changes.

   For local-file backends, the host is assumed to be "localhost" which
   is always reachable.  So the property will always be TRUE for them.


"socket-connectable"

   type: GSocketConnectable  perm: read-write  default: (see below)

   This is the GSocketConnectable fed to g_network_monitor_can_reach().

   EBackend itself will initialize this to a GNetworkAddress based on
   the host and port settings in the ESource.  Subclasses do have the
   option of overriding this, however, which is why it's read-write.

   If the pointer is NULL, this is assumed to mean "localhost".

   Setting this property will trigger a "host-reachable" notification
   after EBackend runs g_network_monitor_can_reach() on the new value.

   This property could prove to have additional uses in the future as
   we further embrace GIO's networking APIs.


"readable"

   type: boolean  perm: read-write  default: false

   This property is exposed to clients.  It indicates the backend's data
   is viewable but not necessarily complete, as in the case of a network
   outage and not having fully synchronized for offline usage.

   Backends are responsible for updating this themselves.

   Clients are responsible for disabling the relevant UI elements when
   this property is FALSE.


"writable"

   type: boolean  perm: read-write  default: false

   This property is exposed to clients.  It indicates the backend's data
   can be modified, but possibly only locally.  Reasons it may be FALSE
   include the remote host not being reachable, the service running on
   the remote host not being available, or the service forbidding write
   access to the data (such as for "On The Web" calendars).

   Backends are responsible for updating this themselves.

   Clients are responsible for disabling the relevant UI elements when
   this property is FALSE.


Under this scheme, client applications don't need to know about network
or service availability -- just whether the backend can currently handle
a particular user action.  I think this simplifies things greatly.

Matt

___
evolution-hackers mailing list
evolution-hackers@gnome.org
To change your list options or unsubscribe, visit ...
http://mail.gnome.org/mailman/listinfo/evolution-hackers


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

2012-04-04 Thread Milan Crha
> On Wed, 2012-04-04 at 13:32 +0200, Christian Hilberg wrote: 
> 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?

Hi,
there seems to be a minimum work to be done on evolution's side, the
most work will be done on eds part, in respective backends. From what I
understand you want the "Synchronize" button for evolution. That should
be pretty easy, add clients there based on some capability, with similar
functionality like the Send/Receive button in mailer.

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

We (I'm sorry for the plural) definitely want to be the best, of course :)

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

calendar/book can provide a Refresh interval option, most remote do
that. That's what you call "preset", I suppose. You cannot force "no
checking when I'm on this network" currently.

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

Yes, the whole opening phase is cancellable, and is fully asynchronous
(signal-driven), thus the client says "open me", and it receives
confirmation "your request begun as operation X", then it is waiting for
a confirmation for "I'm (not) opened now", which can come anytime.
Authenticating against the server (asking for a password) is part of the
opening phase. This is there since EClient, thus not for a long time.
You've right having it part of the open itself is too much, that's why
current builtin backends initiate a "delta thread", which takes care of
regular updates (based on the 'refresh' interval) and also possible
upload of changes. Because it runs in its own thread, then there is no
slowdown during the opening phase. Of course, current builtin backends
do not use real offline handling, as far as I know. That's the subject
to change.
Bye,
Milan

___
evolution-hackers mailing list
evolution-hackers@gnome.org
To change your list options or unsubscribe, visit ...
http://mail.gnome.org/mailman/listinfo/evolution-hackers


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

2012-04-04 Thread Philip Withnall
On Wed, 2012-04-04 at 13:32 +0200, Christian Hilberg wrote:
> 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).
> 
> > 

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

2012-04-04 Thread Christian Hilberg
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

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

2012-04-04 Thread 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

--

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.

--

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.

--

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.

--

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 offli