On 8/24/06, Zoran Vasiljevic <[EMAIL PROTECTED]> wrote:
On 22.08.2006, at 22:13, Stephen Deasey wrote: > > I don't see how you will handle the locking... :-( And I don't see how I'm going to handle config values returned to caller *per reference* (as for the string values) as this is what happens to be the case now :-( If we *ever* want to make this beast shared read/write then we need copy-on-write and copy-on-read access (I guess ref-counting would be simply overkill). Which means radical change to how the config values are handled throughout the server code *and* extensions. Ah, I really hate it!
That's because it's a bad idea... :-) Ns_Sets allow you to store multiple identically named keys. They also preserve the order of the entries. Finding the 50th element of a 100 element set isn't a representative test. The primary use case for sets is HTTP headers and forms. The sets are as likely to have 6 elements, need to be created quickly, preserve order, and for headers, be case insensitive. Sets are just completely different data structures to hash tables! This is hard because you're writing a database: you have a data model, concurrency, and persistence. Don't do it! Persistence is broken. Config files are Tcl scripts. The 'section' and 'param' form a DOM. But the other parts of the script are also important, from comments to Tcl variables. If you write out the DOM you completely loose all the Tcl. Even so, you're still only tackling a subset of the problem, which seems to be code which runs enfrequently enough that it can be as slow as you like. What about code which needs to be fast? Seems to be out of scope... The Tcl config stuff is *already* too slow, adding locking can only slow it down.
Which leaves me 3 possible choices: 1. Go climb the Eiffel tower and throw myself down 2. Go climb the Empire State Building and throw myself down 3. Write our own module for handling configuration
Maybe the limits stuff is a possible model. Unlike the aols4.5 version, the one is our cvs handles config by default in the standard fashion by looking up values in the config file. However, it does this from Tcl in tcl/limits.tcl. The limits code creates a new tool. The tricky stuff, the locking, is handled in C. The tool is presented as Tcl commands, and Tcl is used to configure it at start up. It looks just like any other server subsystem: ns_section "ns/limits" ns_param default "The default limits" ns_param restrict "A restricted set of limits" ns_section "ns/limits/default" ns_param maxrun 100 ns_param maxwait 100 ns_param maxupload [expr 10*1024*1000] ns_param timeout 60 ns_section "ns/limits/restrict" ... In the majority of cases, that's probably all that's needed. Config goes in the config file, not buried in some Tcl code. However! You can also, at runtime, call: ns_limits_set -maxrun 10 -timeout 30 -- restrict This is what you're trying to achieve with the read/write config. The defaults get set at start up, and then at runtime, you call ns_config_set and everything magicaly updates. The tool based approach is more flexible though. You could, if you wanted, have a very minimal config file to bootstrap the server and config everything yourself, getting the values from an HTTP server (as someone mentioned), from a local SQLite db, whatever you can dream up. A tool based approach also fits in better as a stand alone Tcl module. There's usually not 'config' file when you 'package require' a module. Anyway, the idea is that maybe forcing everything to go through the config system is too restricting, and that the config, as it stands, is a great *default*. And recognising that the locking requirements can be very different for different subsystems. Some config options are dependant on others. A change in some should initiate an action, such as purge a cache down to it's new maximum size. Maybe what we need is to start moving more things to this model. For example, remove the calls to Ns_Config*() from nsd/log.c and instead use ns_logctl from within tcl/init.tcl etc. (move the limits stuff there). It may be the case that not all the logging options can be dynamically adjusted. That's OK, maybe they can be set via ns_logctl only at start up, which is a special single threaded environment. Perhaps there's some helper functions we can add that would make writing config functions easier, in the way that Ns_ParseObjv() makes parsing options easier. Seems like there's a whole bunch of manual twiddling going on in nsproxy/nsproxylib.c:ConfigureObjCmd() for example. Now, climb down off the balcony and have a nice cup of tea and a biscuit!