[Xfce4-commits] r30417 - in xfconf/trunk: . xfconf

Brian J. Tarricone brian at tarricone.org
Thu Jul 30 00:24:15 CEST 2009


Hey all,

I added transparent caching support for libxfconf in svn trunk.  It 
seems to work ok for me, but it's likely there are bugs, and possible 
there are some weird behaviors I haven't encountered yet.

See the log message below for a short explanation of how it works.

There are a couple of open questions about behavior that I haven't quite 
figured out yet, so comments would be appreciated.

1.  Currently XfconfChannel asks the XfconfCache to prefetch *all* 
properties in the channel on creation (this does at least respect the 
property_base for restricted channels).  For larger channels this may be 
a bad idea.  However, there's no way to request a max number of channels 
from the daemon, or a particular list of properties in one go; the only 
way you can restrict it is by a property subtree.

2.  There's an annoying bit when setting properties: if the property you 
want to set isn't in the cache, it first fetches the property 
(blocking), saves the old property value, stores the new value in the 
cache, and sets the new property (non-blocking).  The idea is that if 
there's an error in the async property set, the cache can synthesize a 
property-changed signal to return the property back to its original 
state in the client.  However, the blocking property get (to handle the 
case where the property isn't cached) defeats one of the important 
purposes of the cache: to avoid blocking.  There are a couple options to 
'fix' this:

a) Remove the blocking property get entirely.  If the set fails, the 
client just doesn't ever find out about the failure.  This is kinda lame.

b) Remove the blocking property get and turn it into a non-blocking get. 
  Then queue up the non-blocking set to occur after the get returns. 
This delays the set somewhat, but that might be ok.  It increases 
complexity quite a bit, which is not great.

c) Remove the blocking property get, and immediately send off the 
non-blocking set.  If an error occurs, *then* we do a non-blocking 
property get, and do a property-changed signal to return the client's 
view of the property back to its pre-set-failure value.  This 
presupposes that the only kind of error we care about is where the 
client attempted to set a locked value, or some other kind of error 
where a set would fail but a get would still succeed.  If both the set 
and get fail, we're kinda royally screwed anyway, so it might not matter 
that the client has an inconsistent view of the world.

I have future plans that make these issues mostly moot.  I'd like to 
have xfconfd create a mmap()able cache file after properties get 
changed, and libxfconf can read the cache directly for property values, 
entirely avoiding dbus for property lookups (property setting and 
checking locking status will still go through the daemon).  I dislike 
that this ties libxfconf to the daemon, but I think it's a reasonable 
tradeoff for performance.  libxfconf can always fall back to dbus if the 
cache file isn't present.  This bit is probably for 4.10 though.

3.  XfconfCache has internal API for setting the max age (in seconds) of 
items in the cache before they get evicted, as well as a max total 
number of items in the cache.  Does that seem useful at all?  For apps 
that use xfconf_channel_get(), the XfconfCache (and all its items) for 
that channel effectively never gets destroyed (at least until you call 
xfconf_shutdown()).  That might be a bad thing.  If you only use 
xfconf_channel_new() and xfconf_channel_new_with_property_base(), then 
the caches will get destroyed when the channels are destroyed.  But if 
you even make one xfconf_channel_get() call with the same channel name, 
that will keep the cache alive forever, because while some XfconfChannel 
objects are destroyable, and some are singletons, all XfconfCache 
objects are singletons (every XfconfChannel with the same channel name, 
regardless of property base, will share the same XfconfCache instance). 
  So... I'm still not sure if expiring stuff from the cache is useful.

Anyway, thoughts?  Please test this if you can.  In theory you shouldn't 
notice anything different, except possibly desktop startup might be a 
little bit faster, and the settings dialogs might come up a little 
faster too.  I suppose I should really attempt to benchmark these 
things... maybe later.

	-brian

On 07/29/2009 02:42 PM, Brian Tarricone wrote:
> Author: kelnos
> Date: 2009-07-29 21:42:58 +0000 (Wed, 29 Jul 2009)
> New Revision: 30417
>
> Added:
>     xfconf/trunk/xfconf/xfconf-cache.c
>     xfconf/trunk/xfconf/xfconf-cache.h
> Modified:
>     xfconf/trunk/NEWS
>     xfconf/trunk/xfconf/Makefile.am
>     xfconf/trunk/xfconf/xfconf-channel.c
>     xfconf/trunk/xfconf/xfconf-private.h
> Log:
> add transparent property prefetching and caching
>
> XfconfCache is a transparent cache that sits behind XfconfChannel,
> and, so far, involves no new API.  this moves most of the dbus code
> from XfconfChannel to XfconfCache.  on creation, XfconfChannel gets
> an XfconfCache object for that channel (the cache objects are
> per-channel-name singletons, regardless of property_base or whether
> or not the XfconfChannel is a singleton).
>
> on creation, XfconfChannel prefetches all properties in the channel.
> this might turn out to be a bad idea for large channels.
>
> property setting does not block if the setting is already in the cache.
> i may change this in the future to not block at all ever, but that
> might make reporting certain kinds of errors impossible.  property
> resets are completely non-blocking.  lookups are non-blocking if
> the setting is already in the cache.  the cache automatically
> updates itself if another application modifies a property.
>
> the cache has hooks to set the maximum age of entries (in seconds)
> and the max number of entries to store in the cache.  currently
> these two are unimplemented, and i'm not sure if there's value to
> exposing these in the public API.



More information about the Xfce4-dev mailing list