Re: thoughts on GSettingsList

Hi Ryan,

Let me just dump my thoughts on this based on my experience with g-t.  It may
help with your design.

In g-t, the user names a profile and can rename it later.  The name can have
arbitrary Unicode characters.  Logically it means that the name cannot be used
directly in the conf database, so g-t cleans it up.  Moreover, since profile
renames are supported, the conf name for a new item may already be taken.  Say:

  - User creates profile "Remote Server", it shows up in the database as

  - Later on, use renames "Remote Server" to "Old Server".  The database key
remains at profiles/remote-server/

  - User creates new profile called "Remote Server", the database key
profiles/remote-server/ is taken, so we use profiles/remote-server-2/

It would be immensely helpful if GSettingsList can do the cleaning up and
dup-avoiding part.  So, add_item() will in fact get a name *hint*, clean it
[1] up, avoid dup, and return the key name.

Needless to say, the key name is useless for UI use, so at least in g-t we
always have to have at least one non-default key in the profile which would be
its name.

[1] For the actual cleaning, I suggest you transcribe it to ASCII, lower-case,
replace non-alnum with dashes, remove repeated dashes.

Other than that, I know you already know, but is worth stressing: please avoid
magic keys and values if you can :P.


On 05/13/2010 06:01 PM, Ryan Lortie wrote:
> Hi all,
> I've been putting off GSettingsList for a while because of a criticism
> that vuntz raised during the hackfest.  It's a fairly valid criticism
> that I'll describe here, along with my thoughts for a solution.  This is
> a bit of a request for comments and a hopes that the braindumping
> process itself will prove to be useful.
> If you don't know, GSettingsList is a way to have a list of like-typed
> GSettings instances associated with a given parent.  For example, you
> could store your list of gnome-terminal profiles or Telepathy accounts
> using this mechanism.
> The API is something like
>    string add_item ();
>    void rm_item (string name);
>    GSettings get_item (string name);
>    string[] list_items ();
> If gnome-terminal had its list of profiles and had "Default" and
> "bigfont" profiles, the layout in dconf would look something like this:
>   /apps/g-t/stuff...
>   /apps/g-t/profiles/
>   /apps/g-t/profiles/Default/
>   /apps/g-t/profiles/bigfont/
> also, there is a "/apps/g-t/profiles/list" key.  It is a list of
> strings: ['Default', 'bigfont'].
> What vuntz didn't like (and what I don't like) is that you can remove an
> item from the "list" but still have garbage settings left for it in the
> database.
> Going forward it makes sense (and I would like) to tie the existence of
> a item of the list to the result of calling the directory enumeration
> API on dconf (ie: it's impossible to have garbage, because if you have
> garbage then it's not garbage, but recognised as a valid list item).
> The main issue with this is that it goes somewhat against the dynamic
> creation/removing of paths that dconf follows.  Consider, for example,
> that we create a new profile "white" that has all the default settings
> (as per the schema) to start with.  This means that no key in dconf
> starts with
>   /apps/g-t/profiles/white/
> which means that "white" won't show up when we enumerate
> "/apps/g-t/profiles/".
> There are two main solutions here:
>    1) change how dconf works to support explicit empty directories.
>       There are a lot of reasons that I don't like this, and I guess I
>       don't need to explain them.  It's also difficult to express in the
>       file format (but definitely not impossible).
>    2) Store some sort of "/apps/g-t/profiles/.exists" key.  This is what
>       my current line of thinking is (and I guess many people are
>       familiar with this hack from some other semi-related uses).
> The idea then is that you bring a list item into existence using
> ".exists" and remove it using the "reset" call that is implemented by
> the backend (which is a recursive directory removal).
> =====
> There are three main unsolved issues here, though.  This system, when
> compare with the old one, suffers a major feature regression: it is no
> longer possible to permute the order of the items in the list.  I'm not
> sure if anyone cares about this.  I used to think it was important, but
> I'm happy to abandon/ignore it if nobody complains too loudly.
> =====
> The second issue is how we deal with seeding the default contents of the
> list.  There are a few approaches that can be taken here.
>   - null approach: list initially contains zero items.
>       - this is very easy, but probably insufficient.
>   - better approach: list initially contains one item where the default
>     values of that item are taken from the schema for items (ie: the
>     default values of the initially-existing item are equal to the
>     default values that would be applied to newly created items)
>       - maybe a good compromise, but vuntz says he can imagine places
>         where this, also, would be insufficient.
>   - full-on approach: an arbitrary number of initial items can exist,
>     each one with its own set of initial values.
>       - quite difficult, i recon, but probably necessary.
> Option zero is trivial and insufficient.  For both reasons, I don't
> discuss it here.
> The other two options have a significant requirement: the ability to
> remove the initial items from the list.  Keeping in mind that in the
> default state the dconf database is completely empty, we need to build
> the list of available items by consulting both the database and the
> schema.  How do we store into the database a note that says we should
> ignore the information in the schema?
> My main idea here is that if we have an item in the schema called
> "Default" then we could write a key "/apps/g-t/profiles/.anti-Default".
> This would have the effect that listing of the "Default" item based
> solely on its existence in the schema would be suppressed.  If the
> "Default/" item appeared explicitly in the database then I imagine it
> would still appear in the list (ie: in the case that we have "Default/"
> and ".anti-Default" both explicitly in the database, then we ignore the
> ".anti-Default" item).  This furthers the "no garbage" ideal.
> This setup of having ".anti-Default" in the profile directory itself
> means that we can do a single list operation against the backend to get
> all the information that we need in order to tell the user about what's
> there.  I dislike the idea of setting ".exists" to false for this reason
> but also for the reason that it allows for lingering garbage.
> =====
> The last issue is related to lockdown.  What sorts of lockdown do we
> wish to support?
>         (aside) A quick summary of how lockdown works in dconf: first,
>         dconf keys are always given with no '/' at the end, and dconf
>         directories are always given with a trailing '/'.
>         You specify zero or more strings that start with '/' and do not
>         contain '//' (ie: you give keys and directories).
>         For each key specified, you may not write to that key.
>         For each path specified, you may not write to any key under that
>         path (recursively).
>         I'm not particularly interested in changing this part.
> It is clear that we can prevent all changes to the list, its contents
> and the contents of the items by locking down /apps/g-t/profiles/.  Can
> we do finer-grained locks?
>   - prevent removing some of the existing profiles
>   - prevent adding some new profiles
>   - prevent modification to a specific existing profile
> and do some of these things imply others?  For example, preventing
> modification to a given profile probably always implies that it can't be
> removed either (otherwise you could remove it, replace it, make
> modifications to the replacement).
> In the case where we want to lock the user into the schema defaults for
> one item but allow them to add others, we have two main possibilities
> (sysadmins could pick which they prefer):
>   1) Create /apps/g-t/profiles/Defaults/.exists and lock all
>      of /apps/g-t/profiles/Defaults/ (ie: any user attempt to create an
>      anti-Default results in that being ignored by virtue of "Defaults/"
>      explicitly existing)
>   2) Lock /apps/g-t/profiles/.anti-Default itself in addition to locking
>      /apps/g-t/profiles/Default/.  ie: the first one to prevent removes
>      and the second to prevent changes.
> I like #2 since it allows the UI to mark the "Remove" button insensitive
> based on a "is writable?" query against ".anti-Default".
> But how do we prevent adding new items without locking everything down
> entirely?  Maybe some ".no-new-items" key in "/apps/g-t/profiles/" that
> instructs GSettings to ignore any new keys that were added?  The
> sysadmin could create and lock this.  Seems like a bit of a hack?
> What if the sysadmin wants to add some new default items that are not in
> the schema and lock those into existence and prevent the addition of any
> others but still allow removals or modifications?
> ".only-these-new-items" with a list of strings?  Does anybody actually
> care about this?
> I'm OK with ignoring the lockdown issues in the first-pass at a new
> implementation as long as I can feel reasonably confident that I'm not
> designing myself into a corner.
> =====
> Ok.  I lied.  4 items.
> During the GSettings hackfest, the schema format underwent some
> substantial simplification.  It used to support subclassed schemas
> (subclasses could override default values of the parent class).  This
> functionality was removed, but will probably need to be brought back to
> support the case of multiple initial list items with different default
> values (ie: one subclass per initial item).  I very much wonder how that
> will work...
> So that's it.  Those are the big GSettingsList issues.
> Cheers
> _______________________________________________
> gtk-devel-list mailing list
> gtk-devel-list gnome org

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