On 8/22/06, Zoran Vasiljevic <[EMAIL PROTECTED]> wrote:
You know, I have this "requirement" is sitting for about 4 years in my todo list. I was not very keen on getting it out as I know that it might bear some security (more important) and locking (less important) issues. But we've come to a point where we either have to abandon the whole ns_config stuff and write everything ourselves OR to get this modification in the core server. Needles to say that I hate reinventing the wheel over and over again. Hence the decision to try to get it done with existing ns_config code. Basically, most important information is: from the two (are there more?) issues (locking and security) which of those two is more important/sensitive/whatever to everybody. So I know where I will have to make tradeoffs. Basically, all this comes down to: a. should I make everything compile-time option so only people who need it would compile-in that code, everybody else being not affected or b. should I make it runtime selectable, because people would like to have both, depending on the site/application or c. should I make it read/write entirely, basically ignoring both locking and security issues. The simplest is of course c. The a. is next, with b. being more/most complex. I would of course not want to invest much work with that and both security/locking are no problem for me, so the logical choice for me would be c. But I do not know if everybody is ok with that. Hence all this email ping-pong.
I think the C code does the right thing: create a struct to hold the config values and use the Ns_Config* routines to populate it at startup. Use the custom struct directly in code. The Tcl level ns_config is kinda broken. *Every* time you call it the code does a linear, case insensitive search for the right set; then it does a linear case insensitive search for the correct key in that set; then it parses the string value and converts it into an int or bool or whatever. ArsDigita figured out this was hurting them back in '99 and created a wrapper which on first access put the config value in an nsv array. And *that* is kinda broken as now you suffer locking overhead on hundreds of config values which are essentially static. So instead you call ns_config at startup and put the result in a name spaced Tcl variable. And *that* is kinda broken as the only reason it works is an accident of implementation -- no one could figure out how to clean out name spaced variables between requests as efficiently as global ones. Anyway, I don't see how you're going to do the locking. Do you have one global lock around the whole config? A lock per section? Do you free updated config values/sets, or do you leak them? The idea is good -- don't reboot the server when config values change. Looks hard to me as there are different locking requirements for different pieces of code. For example, the ns_log code can now be updated at runtime! You turn on/off debug logging, maybe to isolate a specific problem. It's easy, as updating the boolean value is atomic, and even if it's not it doesn't matter as it's just a boolean value. But even there you call ns_logctl -- the underlying config isn't changed. If every time Ns_Log() was called it in turn called Ns_Conf* to figure out whether debug logging was on or off, performance would be unacceptably slow. Yes, the Tcl code at the moment *does* scan the sets every time (unless it doesn't because you hacked around it), but it probably shouldn't. It should also be fast. How do you handle notifying the code which has parsed and stashed away a copy of the config value that the config has been re-written? I don't see how you will handle the locking... :-(