A UniConfGen is an object which generates values for a UniConf object. From the user's point of view, this works a lot like a the Unix filesystem: you create a UniConf object with a particular path in the hierarchy, and then you mount() a UniConfGen on it. The UniConfGen is given a Moniker telling it where to get information from (for example, "ini:somefilename" for an ini-file, or "tcp:somehost" for a UniConfDaemon).

Things get a little more complicated when we add in cacheing. TODO: Describe how this works here.

--jnc


jnc (2003/01/29): So, I've got a UniConfGen mounted which is talking to the UniConfDaemon on "tcp:themountain:4111". I've got four basic operations: set(), get(), refresh() and commit(). Let me see if I've got these right:

  • get() returns the cached copy of the data (on the first call, of course, it has to go get it)

    • refresh() goes to themountain and gets the latest data, conceptually. In practice it may just mark it invalid and then retreive it at the next get(). (It can also refresh the entire subtree, but lets consider just the single node.)

Upshot: if multiple clients are writing to the same key, get() may return old data, but refresh() and then get() is guaranteed to get the most recent copy. Right?

There's a race condition here - what if someone updates between refresh() and get()? - but let that pass for now. It seems like refresh and then get would be a pretty common thing to do for certain keys. Would a shorthand refreshget() that calls refresh() on for a single node and then get()'s it be a good idea?

Repeat above question for set() and commit(). (I should be calling commit() immediately after set() if I want to be certain to publish a value to other clients watching the same UniConfGen, right?)

  • apenwarr (2003/01/30): IMHO requiring commit() and refresh() is somewhat evil for exactly the reason that you don't need them on the Unix filesystem. When using the UniConfDaemon, it costs you nothing at all to commit-on-set (and refreshes are always sent to you whenever anything changes anyway, so I guess refresh() does nothing). But with ini files, for example, there is quite a lot of efficiency improvement in not rewriting the files each time. Because of that, maybe we have to live with the more complex API...

    • jnc (2003/01/30): So, to sum up - with the daemon, commit() isn't necessary, and get() will become unnecessary once notifications are in. For now, it's sometimes needed to short-circuit the cache.

      • jbrown (2003/01/31): Admittedly it's a little ugly. The Unix filesystem does require open() and close(), and most buffering i/o systems require flush() at some point. Right now the UniConf daemon has a commit-on-set policy, so commit() is not needed. When notifications go in, refresh() won't be needed either unless something gets seriously fubar'd.


jnc (2003/01/29): Not a generator question, but I notice that calling set(WvString?::null) "deletes the key and all of its children." Is this a good idea? What if I just want to make the value null and leave the children alone?

  • apenwarr (2003/01/29): I was also disturbed by this behaviour. There should probably just be a delete_tree() operation or something, but I'm not sure; you can just set it to "" instead, after all, and there will be no crazy tree deletion.

    • jnc (2003/01/30): There is remove(), which currently just calls set(NULL). It shouldn't be have much impact right now to move the code there.
    • jbrown (2003/01/31): This is by design. UniConf does not allow interior nodes to have NULL values. Neither does the MS Windows registry. You can have EMPTY values, but not NULL ones. What condition are you trying to signal anyways?


apenwarr (2003/02/03): jbrown's tutorial on HowToWriteAUniConfGen.