You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(19) |
Nov
(22) |
Dec
(19) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
(35) |
Feb
(5) |
Mar
(13) |
Apr
(9) |
May
(3) |
Jun
(16) |
Jul
|
Aug
(6) |
Sep
(15) |
Oct
(5) |
Nov
(3) |
Dec
(7) |
2003 |
Jan
(16) |
Feb
(10) |
Mar
(19) |
Apr
(13) |
May
(5) |
Jun
(20) |
Jul
(33) |
Aug
(9) |
Sep
(1) |
Oct
(12) |
Nov
(17) |
Dec
(2) |
2004 |
Jan
(3) |
Feb
(9) |
Mar
(7) |
Apr
(16) |
May
(6) |
Jun
(6) |
Jul
(18) |
Aug
(8) |
Sep
(27) |
Oct
(8) |
Nov
(14) |
Dec
(29) |
2005 |
Jan
(1) |
Feb
(11) |
Mar
(33) |
Apr
(2) |
May
(4) |
Jun
(21) |
Jul
(41) |
Aug
(6) |
Sep
|
Oct
(1) |
Nov
|
Dec
(1) |
2006 |
Jan
(8) |
Feb
(3) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
From: Chris W. <ch...@cw...> - 2005-02-24 14:55:00
|
Perrin Harkins said: > Most admins will tell you they don't want to hear about it unless they > need to do something about it, and most developers will tell you they > take out their debugging stuff when they find the bug, so my advice is > to have very minimal logging in general. Excessive attention to logging > is usually a sign of trouble in my opinion. I agree with you on administrators. And the error browser + files is mainly intended for them. But regarding developers I think there are differences between good logging messages and the quick-iteration debugging messages ("got here", data structure dumps) that usually take the place of the debugger. log4perl makes it awfully easy to assign different logging levels to different logging categories; combined with a consistent logging strategy for a framework people can peer into the innards of what's going on in a particular area of the system. I compare it to turning on DBI's trace functionality. IMO this is extremely useful -- moreso because it's externally configurable. The trick is to get the logging at least roughly consistent, otherwise you'll get too little/too much whenever you change a logging level. Chris -- Chris Winters (ch...@cw...) Building enterprise-capable snack solutions since 1988. |
From: Salve J N. <sal...@me...> - 2005-02-24 11:57:43
|
Chris Winters wrote: > I've been rewriting the error module to work with the filesystem instead > of the database. That part is (mostly) done, but my initial idea of > hooking this to log4perl with a custom appender has hit a little snag. > > - If we set the threshold to 'FATAL' we don't store anything -- nothing > is logged with a 'FATAL' level. This doesn't necessary have to be a bad thing... Are there any situations that should be fatal to OI2? e.g. missing critical dependencies, inability to contact critical databases, badly broken (truncated?) primary config files, inability to access local files at all (broken filesystem.) At this level, I hope never to get any output to the log files. :) > - If we set the threshold to 'ERROR' we store a ton of messages, too > many to be useful. Do _all_ these messages deserve an "ERROR" status, or are some of them only informational? The ones that actually _are_ errors, should of course be fixed. :) > This is my fault for not setting guidelines in the beginning as to what > the different logging levels should mean. I don't have a good feel for > how other people do this, so before I go through and try and make > everything at least roughly consistent I'd like to hear what you think: > > What are appropriate messages to log at these levels? Ok, here's my interpretation (With "most important" first :) > FATAL Fatalities (death). Situations where the system/application cannot continue safely and must abort. Manual intervention is necessary to get things running again. (Hopefully, this is something you'll never need to see. :) > ERROR Actual errors that need to be looked into. The application should be able to continue running despite having these errors, but should probably tell the user why the expected data can't be delivered. > WARN For situations that at some point later may lead to errors. E.g. missing directories, use of default values in system-dependent configuration (e.g. when using a default IP address of 127.0.0.1, when it should have been defined explicitly in some config file.) > INFO High/Coarse-level status messages. I try to use this to tell when important subsystems are used, and what data they recieve/pass along. > DEBUG Detailed status messages, debugging, and all the rest. Personally I'd like several debug levels, but existing logging frameworks like syslog(1) and log4* seem to disagree with me. :) > PS - Would it be useful to post here a periodic status message as to how > OI2 is doing? Yes, please do! :) - Salve -- Salve J. Nilsen <salvejn at met dot no> / Systems Developer Norwegian Meteorological Institute http://met.no/ Information Technology Department / Section for Development |
From: Perrin H. <pe...@el...> - 2005-02-24 05:05:56
|
On Wed, 2005-02-23 at 23:48 -0500, Chris Winters wrote: > That's very useful, thanks. They have more granularity but it's still > helpful. Most admins will tell you they don't want to hear about it unless they need to do something about it, and most developers will tell you they take out their debugging stuff when they find the bug, so my advice is to have very minimal logging in general. Excessive attention to logging is usually a sign of trouble in my opinion. > I'll look into doing this and not relying on people to just read my > blog and follow JIRA :-) I do follow your journal, but I wouldn't mind a brief OI2 update in my mailbox now and then. - Perrin |
From: Chris W. <ch...@cw...> - 2005-02-24 04:48:47
|
On Feb 23, 2005, at 11:35 PM, Perrin Harkins wrote: > Hmmm, that doesn't sound good. Maybe the Apache loglevel docs would > help you: > http://httpd.apache.org/docs/mod/core.html#loglevel That's very useful, thanks. They have more granularity but it's still helpful. >> PS - Would it be useful to post here a periodic status message as to >> how OI2 is doing? > > Yes, I think so. I'll look into doing this and not relying on people to just read my blog and follow JIRA :-) Chris -- Chris Winters Creating enterprise-capable snack systems since 1988 |
From: Perrin H. <pe...@el...> - 2005-02-24 04:35:39
|
On Wed, 2005-02-23 at 23:24 -0500, Chris Winters wrote: > - If we set the threshold to 'ERROR' we store a ton of messages, too > many to be useful. Hmmm, that doesn't sound good. Maybe the Apache loglevel docs would help you: http://httpd.apache.org/docs/mod/core.html#loglevel > PS - Would it be useful to post here a periodic status message as to > how OI2 is doing? Yes, I think so. - Perrin |
From: Chris W. <ch...@cw...> - 2005-02-24 04:25:01
|
I've been rewriting the error module to work with the filesystem instead of the database. That part is (mostly) done, but my initial idea of hooking this to log4perl with a custom appender has hit a little snag. - If we set the threshold to 'FATAL' we don't store anything -- nothing is logged with a 'FATAL' level. - If we set the threshold to 'ERROR' we store a ton of messages, too many to be useful. This is my fault for not setting guidelines in the beginning as to what the different logging levels should mean. I don't have a good feel for how other people do this, so before I go through and try and make everything at least roughly consistent I'd like to hear what you think: What are appropriate messages to log at these levels? DEBUG INFO WARN ERROR FATAL FWIW, related JIRA issues are at: http://jira.openinteract.org/browse/OIN-46 http://jira.openinteract.org/browse/OIN-35 Thanks, Chris PS - Would it be useful to post here a periodic status message as to how OI2 is doing? In theory this should be on the wiki and I'll put it there if people find it useful, but I didn't get much feedback... -- Chris Winters Creating enterprise-capable snack systems since 1988 |
From: Andrew H. <ste...@ci...> - 2005-02-14 19:10:39
|
The docs state that a class that wants a custom security model should redefine the get_security() method to return access levels based upon that state of the object. This doesn't work for fetch() unless the only record state you must have is the ID. Now, for efficiency's sake, this is good, or at least mostly good. However, for the guy who wants a custom security model (namely me), this is not so good. I have access to none of the other state. Of course, that's not strictly true, as I can do something like this: sub get_security { my ($self, $p) = @_; my $item; if ($p->{id}) { # I'm assuming that this indicates the object's state isn't yet loaded $item = $self->fetch($id, { security_level => SEC_LEVEL_READ, skip_security => 1 }); } else { $item = $self; } # run my checks against $item } With the record cache, this should be relatively efficient and thus prevent a double-select, but I could be wrong. Caching is one of the features I haven't really fully investigated at this point. Anyway, I think better documentation might be in order to note this issue. Cheers, Sterling -- <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> Andrew Sterling Hanenkamp Systems Coordinator Computing and Information Sciences Kansas State University ste...@ci... http://www.cis.ksu.edu/~sterling/ Please send all requests for help to he...@ci.... My Inbox is too perilous a place. |
From: <ton...@on...> - 2005-01-27 13:45:06
|
DQoNCjEuIGhhc19hDQoNCkluIFNQT1BTOjpNYW51YWw6OlJlbGF0aW9uc2hpcCwgdGhlIGZvcm1h dCBpcyBkZWZpbmVkIGFzOg0KICAgICAgICAgIGhhc19hID0+IHsgY2xhc3MtbmFtZSA9PiB7IG1l dGhvZC1uYW1lID0+ICdpZC1maWVsZCcgfSB9DQpXaGlsZSBpbiBzb3VyY2UgU1BPUFM6OkNsYXNz RmFjdG9yeTo6RGVmYXVsdEJlaGF2aW9yLCBpdCBpcyBjb2RlZCBhcw0KICAgICAgICAgICAgICAg ICR1c2VhX2lkX2ZpZWxkID0gKCBrZXlzICV7ICR1c2VhX2lkX2luZm8gfSApWzBdOw0KICAgICAg ICAgICAgICAgICRoYXNhX2FsaWFzICAgID0gJHVzZWFfaWRfaW5mby0+eyAkdXNlYV9pZF9maWVs ZCB9Ow0KV2hpY2ggbWVhbnMgDQogICAgICAgICAgaGFzX2EgPT4geyBjbGFzcy1uYW1lID0+IHsg aWQtZmllbGQgPT4gbWV0aG9kLW5hbWUgfSB9DQoNCg0KMi4gZXZhbCBkYmkgZXJyb3INCg0KSW4g U1BPUFM6OlNRTEludGVyZmFjZSwgcHJlcGFyZSBhbmQgZXhjdXRlIGFyZSBhbGwgZXZhbGVkLCBh bmQgJEAgYXJlIGFsbCBjaGVja2VkIGFmdGVyLiBCdXQgaW4gbWFueSBjYXNlcywgIHdoZW4gdGhl cmUgd2FzIGEgU1FMIGVycm9yIGdlbmVyYXRlZCwgdGhlIHByb2dyYW0gd29uJ3QgZGllLCBzbyB0 aGUgZXJyb3Igd291bGQgbm90IGJlIGNhcHR1cmVkIGJ5IGV2YWwuIElmIHRoZSBjb2RlIGNoZWNr IG5vdCBvbmx5ICRAIGJ1dCBhbHNvICRkYmgtPmVycnN0ciwgdGhlIHByb2JsZW0gd2lsbCBiZSBm aXhlZC4NCg0KDQozLiBmZXRjaF9ieQ0KDQpUaGlzIGlzIG5vdCByZWFsbHkgYSBidWcuICBJbiBt eSBjYXNlLCBzb21lIGZpZWxkcyBhcmUgbmFtZWQgbGlrZSAiY3VzdG9tZXIjIiBpbiBzdGVhZCBv ZiBjdXN0b21lck51bWJlci4gVGhpcyBpcyByZWFsbHkgZHVtcCwgYnV0IGl0IGlzIHRoZXJlIGFs cmVhZHksIEkgaGF2ZSBubyBjaG9pY2UuIEFueXdheSB0aGlzIGlzIHdoYXQgZmllbGRfbWFwIGNv bWUgaW4gZm9yLiBJZiBJIGRpcmVjdGx5IHB1dCBjdXN0b21lciMgaW50byBmZXRjaF9ieSwgU1BP UFM6OkNsYXNzRmFjdG9yeTo6RGVmYXVsdEJlaGF2aW9yIHdpbGwgYmUgYnJva2VuLiBTbyBpZiBm aWVsZCBhbGlhcyBpcyBhbGxvd2VkIGluIGZldGNoX2J5LCB0aGUgcHJvYmxlbSB3aWxsIGJlIGZp eGVkLg0KDQoNCg0K |
From: <And...@Be...> - 2004-12-24 10:31:43
|
Hello all, there is one detail of the caching of group objects in the user session, = that might have negative effects. What I noticed is, that the whole = group object is cached and not only the ID of the group, which is needed = for the security check. Therefore, if you have a group with a few = hundred Users in it, you add quite some size to the session.=20 I my case, this is currently 85k only for the group cache ! Still I am = convinced, that caching the data needed for the sys_security check makes = sense. If I remember right, the code uses s th like $theuser->groups to = get all group objects, which then loads all groups including their = members, although the members will never be needed here for the security = check.=20 Does anyone have a good idea, who to change this ? How about lazy = loading the members ? How about changing the group check in the security = implementation ? Mit freundlichen Gr=FC=DFen Andreas Nolte=20 Leitung IT ------------------------------------------------- arvato direct services Olympiastra=DFe 1 26419 Schortens Germany http://www.arvato.com/ and...@be... Telefon +49 (0) 44 21 - 76-84002 Telefax +49 (0) 44 21 - 76-84111 |
From: Sam V. <sa...@vi...> - 2004-12-20 03:05:29
|
Did you guys get anywhere with that sample code for Simon? I'll be sending in the Tangram entry shortly. -- Sam Vilain, sam /\T vilain |><>T net, PGP key ID: 0x05B52F13 (include my PGP key ID in personal replies to avoid spam filtering) |
From: Vsevolod (S. I. <si...@cs...> - 2004-12-11 15:14:54
|
Ray, > (I just looked back at my original proposal and I see that to be > consistent with what I just said, I would need to change the 'manual_by' > option so that the fetch method does NOT store the retrieved objects in > the primary object. We have 'lazy_by' to handle the "fetch into the > object on-demand" case.) Right, then it will precisely mirror the way SPOPS currently works. > We already talked about changing *_by to reverse_*, so how about > renaming my proposed fetch types to something like the following? > > manual => manual > auto => auto_object > lazy => lazy_object > manual_by => reverse_manual > auto_by => reverse_auto_object > lazy_by => reverse_lazy_object > > Does that help? This is clearer. > If so, I think that having the id in the persistent field and the > corresponding object stored under some other key, with the id being > read-only leads to more potential confusion than just storing the object > in the persistent field like I propose. But I suppose this is a matter > of opinion. In this case, if you want to set a new value for the > secondary object you have to change the object if it's auto/lazy-fetch > (since the id is read only), but you change the id if it's manual (since > you don't even have the object). That's another example of config-change-influencing-code that bothers me. After looking at Hibernate, I think I appreciate the consistency of the auto/lazy approach. The problem is that I like the manual approach too, but supporting them both makes the framework confusing. I think I'll go ahead and start implementing the dual approach, as things can be thrown out if needed, but this definitely has to run by Chris. I probably did not explain well the read-only id approach in Hibernate. There are no ids that are foreign keys at all. The only ids visible are the proper object ids, and even they are read-only. Also, Hibernate does let you to add/remove children without saving to the database. Once you save the primary object, all the changes to dependent objects and collections are saved, and if collection members have not changed, they are not re-saved. This actually makes the auto/lazy case more consistent, I think. > Suppose, we change the 'list_field' key to something like 'object_field' > and in addition to it's current meaning for reverse direction fetches, > we use it for forward direction fetches to optionally specify the key > under which to store the auto/lazy-fetched object (i.e. the name of the > object accessor). If not specified, the object would be fetched into the > same field (just like the original proposal). For saves and removes in > the auto/lazy-fetch case, I think the auto-fetched object should still > override the id (and we could make the id field read-only in this case > as you mentioned). Sounds good, and see above on ids. > I'm not sure I understand your example (are you modifying any > relationships or just the data?), Just the data. > so it's difficult to say which is more > suited, but it seems to me if you are going to do manual fetching and > updating, then manual saving should not be such a burden. If the book > objects haven't been fetched yet, then they haven't been modified and > don't need to be saved either, right? I'm saying that presumably the framework will generate for me an auto-save method that looks like: sub Author::save() { SUPER::save(); #Calling SPOPS methods for a single object foreach my $book ($self->books) { $book-save(); } } This will only work correctly with cache, though. If the books have been fetched before, I will get the same instances. But if you say that the code should function equally well with and without cache, than this will indeed make no sense in the manual-fetch case. > If you think the changes I proposed here will satisfy your requirements, > I'll be happy to update my proposed spec to incorporate them. For me, > having a design written up in nitty gritty detail helps in keeping > everyone on the same page and might make it easier for Chris to keep up > with all of our discussions. This may not be a bad thing. Simon -- Simon (Vsevolod ILyushchenko) si...@cs... http://www.simonf.com Terrorism is a tactic and so to declare war on terrorism is equivalent to Roosevelt's declaring war on blitzkrieg. Zbigniew Brzezinski, U.S. national security advisor, 1977-81 |
From: Chris W. <ch...@cw...> - 2004-12-07 22:17:17
|
> On Dec 7, 2004, at 4:09 PM, Chris Winters wrote: >> Did I mention it's still ongoing? :-) > > Well, yes ... you did ... I just thought maybe I was doing something > wrong. > >> That's a weird error tho. I'll have to try with mysql tonight. What >> version are you using? > > mysql-4.1.7 on Panther This isn't a mysql thing, it's a stupid Chris thing. Sorry about that. Fix is in CVS. I'll try out the other mysql stuff now too... Chris -- Chris Winters (ch...@cw...) Building enterprise-capable snack solutions since 1988. |
From: Chris W. <ch...@cw...> - 2004-12-07 21:55:00
|
> On Dec 7, 2004, at 4:09 PM, Chris Winters wrote: >> Did I mention it's still ongoing? :-) > > Well, yes ... you did ... I just thought maybe I was doing something > wrong. What I meant to say: "I've only tested this with Postgres so far." >> That's a weird error tho. I'll have to try with mysql tonight. What >> version are you using? > > mysql-4.1.7 on Panther That's probably the same version I have. I probably just forgot something dumb. I'll try it out. C -- Chris Winters (ch...@cw...) Building enterprise-capable snack solutions since 1988. |
From: Ray Z. <rz...@co...> - 2004-12-07 21:19:19
|
On Dec 7, 2004, at 4:09 PM, Chris Winters wrote: > Did I mention it's still ongoing? :-) Well, yes ... you did ... I just thought maybe I was doing something wrong. > That's a weird error tho. I'll have to try with mysql tonight. What > version are you using? mysql-4.1.7 on Panther Ray |
From: Chris W. <ch...@cw...> - 2004-12-07 21:04:44
|
> On Dec 7, 2004, at 9:23 AM, Chris Winters wrote: >> $ cvs -d ':pserver:ano...@cw...:/opt/cvsdocs' co >> persistathon > > OK, I grabbed it, but I can't seem to get past step 0 ... > > I'm using mysql and have edited db.perl accordingly. > > % perl create_tables.pl > DBD::mysql::st execute failed: Table 'persistathon.cd' doesn't exist at > /usr/local/perl-5.8.2/lib/site_perl/5.8.2/SPOPS/Tool/DBI/ > DiscoverField.pm line 36. > ... Did I mention it's still ongoing? :-) > Can't set DBI::st=HASH(0x93150c)->{NAME}: unrecognised attribute or > invalid value at > /usr/local/perl-5.8.2/lib/site_perl/5.8.2/SPOPS/Tool/DBI/ > DiscoverField.pm line 42. > Can't use an undefined value as an ARRAY reference at > /usr/local/perl-5.8.2/lib/site_perl/5.8.2/SPOPS/Tool/DBI/ > DiscoverField.pm line 43. That's a weird error tho. I'll have to try with mysql tonight. What version are you using? Chris -- Chris Winters (ch...@cw...) Building enterprise-capable snack solutions since 1988. |
From: Ray Z. <rz...@co...> - 2004-12-07 19:56:51
|
On Dec 7, 2004, at 9:23 AM, Chris Winters wrote: > $ cvs -d ':pserver:ano...@cw...:/opt/cvsdocs' co > persistathon OK, I grabbed it, but I can't seem to get past step 0 ... I'm using mysql and have edited db.perl accordingly. % perl create_tables.pl DBD::mysql::st execute failed: Table 'persistathon.cd' doesn't exist at /usr/local/perl-5.8.2/lib/site_perl/5.8.2/SPOPS/Tool/DBI/ DiscoverField.pm line 36. Can't set DBI::st=HASH(0x93150c)->{NAME}: unrecognised attribute or invalid value at /usr/local/perl-5.8.2/lib/site_perl/5.8.2/SPOPS/Tool/DBI/ DiscoverField.pm line 42. Can't use an undefined value as an ARRAY reference at /usr/local/perl-5.8.2/lib/site_perl/5.8.2/SPOPS/Tool/DBI/ DiscoverField.pm line 43. Ray Zimmerman Director, Laboratory for Experimental Economics and Decision Research 428-B Phillips Hall, Cornell University, Ithaca, NY 14853 phone: (607) 255-9645 |
From: Ray Z. <rz...@co...> - 2004-12-07 18:24:48
|
Simon, On Dec 6, 2004, at 9:11 PM, Vsevolod (Simon) Ilyushchenko wrote: > Another weirdness-inducing thing is that with your auto- or > lazy-fetching, we effectively have a limited cache, as the fetched > objects are stored in the hidden fields, but with manual fetching we > do not have a hidden cache. Thus, simply changing SPOPS config will > change the code behavior, and it may not even be noticed at once > during compilation (unlike the id-to-object change), because the lack > of caching only rears its head when you fetch the same object more > than once. No matter how much you document this, it's not obvious for > a beginner, and thus the warnings will be ignored. I don't see why this is so difficult, even for beginners. I think you are confusing things by thinking of it as a cache. A cache is something that sits between you and the database and intercepts fetch requests to avoid going to the database. That is not what we have here. We have two types of methods, accessor methods and fetch methods. In both the manual and the auto/lazy case, the object's accessor methods simply return what is stored in the Perl object. In the auto/lazy case, you expect these to be secondary objects that were fetched previously and stashed. In the manual case, you are simply saying that you don't want to store any secondary objects inside your primary object. So you don't expect to have any accessors that return objects. You still have convenience methods to fetch these objects, but these are "fetch" methods, not accessors. (I just looked back at my original proposal and I see that to be consistent with what I just said, I would need to change the 'manual_by' option so that the fetch method does NOT store the retrieved objects in the primary object. We have 'lazy_by' to handle the "fetch into the object on-demand" case.) > Your example with DateConvert which is also a configuration change is > not quite in the same league, because then you are clearly changing a > datum type. But a switch from auto- to manual fetching would look very > innocent to a beginner. I think that putting the "manual implies id, auto/lazy implies object" very prominently in the documentation should be sufficient, but you seem to think not. Can we come up with something other than 'manual/auto/lazy' for the fetch type that captures the differences in data type as well as differences in fetch behavior? We already talked about changing *_by to reverse_*, so how about renaming my proposed fetch types to something like the following? manual => manual auto => auto_object lazy => lazy_object manual_by => reverse_manual auto_by => reverse_auto_object lazy_by => reverse_lazy_object Does that help? >> No storing objects in fields? You mean you want to eliminate >> auto/lazy-fetch as an option? >> Ah ... wait a minute ... are you assuming a cache? > > No, that would be even more weird. However, note my comment in the > previous email that the foreign key ids may be made read-only. This > will eliminate a way to create inconsistencies. OK, now I am confused ... I must have missed what you mean by not storing objects in fields. If you're auto-fetching something that isn't going into cache and you're not storing it in the object, where is it going? Or did you just mean that you store it in the object under a key that isn't a persistent field? If so, I think that having the id in the persistent field and the corresponding object stored under some other key, with the id being read-only leads to more potential confusion than just storing the object in the persistent field like I propose. But I suppose this is a matter of opinion. In this case, if you want to set a new value for the secondary object you have to change the object if it's auto/lazy-fetch (since the id is read only), but you change the id if it's manual (since you don't even have the object). How about this ... would the following change to my proposal allow you to do exactly what you want? Suppose, we change the 'list_field' key to something like 'object_field' and in addition to it's current meaning for reverse direction fetches, we use it for forward direction fetches to optionally specify the key under which to store the auto/lazy-fetched object (i.e. the name of the object accessor). If not specified, the object would be fetched into the same field (just like the original proposal). For saves and removes in the auto/lazy-fetch case, I think the auto-fetched object should still override the id (and we could make the id field read-only in this case as you mentioned). I don't personally see the need for the additional complexity introduced with this option, but I guess it's not so bad ... just more to document and more for new users to digest. I *think* this would let you do what you want without preventing me from doing what I want, right? >>> How do we deal, though, with manual fetch (when a dependent object >>> is not stored) plus auto-save (when a dependent object/id should be >>> stored to be saved)? >> This issue is also addressed in my proposal in the e-mail referenced >> above. Since you can't auto-save an object you don't have, >> auto-saving with manual fetch makes no sense, and attempting to >> configure a field that way should throw an error. > > Actually, I can think of a situation when it does make sense. Suppose > you edit a web page listing info for an author and all the books he > wrote. First you retrieve the old author and book objects from the > database, then you replace some values, then you save the author > objects and would like the book objects become updated to. Even if > they have not been fetched yet, they would get fetched when get an > array of children to iterate over. > > You'll say that this is more suited for auto-fetching, but I may still > want to use the manual fetching for the "neatness" reasons. :) I'm not sure I understand your example (are you modifying any relationships or just the data?), so it's difficult to say which is more suited, but it seems to me if you are going to do manual fetching and updating, then manual saving should not be such a burden. If the book objects haven't been fetched yet, then they haven't been modified and don't need to be saved either, right? If you think the changes I proposed here will satisfy your requirements, I'll be happy to update my proposed spec to incorporate them. For me, having a design written up in nitty gritty detail helps in keeping everyone on the same page and might make it easier for Chris to keep up with all of our discussions. Ray Zimmerman Director, Laboratory for Experimental Economics and Decision Research 428-B Phillips Hall, Cornell University, Ithaca, NY 14853 phone: (607) 255-9645 |
From: Chris W. <ch...@cw...> - 2004-12-07 14:18:53
|
> On Nov 29, 2004, at 11:27 PM, Sam Vilain wrote: >> Simon Cozens is including a chapter on POOP in _Advanced Programming >> Perl, 2nd edition_, an O'Reilly book. >> >> As he is busy with a new direction in his life, I have agreed to >> co-ordinate gathering material and code for possible inclusion in the >> chapter from authors and users of POOP frameworks. > ... > Just curious ... Chris, are you submitting something for this? I am. I'm not going as fast as I'd like though (recent surge for OpenInteract coding + daily job have left my hands sore, even with my magic keyboard). If anyone's interested you can get the code with: $ cvs -d ':pserver:ano...@cw...:/opt/cvsdocs' login (use 'oi' as password) $ cvs -d ':pserver:ano...@cw...:/opt/cvsdocs' co persistathon Since the data structures are SPOPSx::Ginsu-friendly (I think) it would be interesting to see how you'd approach this, and if you were thinking of creating an implementation I'd highly encourage it. If nothing else it would give us a good sample base to test out new relationship functionality :-) Chris -- Chris Winters (ch...@cw...) Building enterprise-capable snack solutions since 1988. |
From: Vsevolod (S. I. <si...@cs...> - 2004-12-07 02:11:59
|
Chris, Your approval is eventually needed here. Ray, > Again, I think you're just saying that you want manual fetching. Why > would you configure it for auto/lazy fetch if all you wanted was the > id? If you only need the object sometimes and want the parent() method > to always return an id, you can still always get to the object using > the fetch_parent() method (which you can even rename if you like). I think this finally got through. Even before reading the end of your email, I realized that, indeed, I am describing what you call "manual fetching". I was objecting to the presence of the word 'fetch', but I should be able to rename the method in the config. > Unless I don't understand what you're suggesting, I think this goes > back to our previous discussion about what to use for the config key, > alias (old has_a syntax) or field name (new has_a syntax). Those > aliases are only unique to the class, but we need something unique to > the field to be able to handle the case where you have two fields which > belong to the same class. Well, class alias and field name can be combined. My point is that a field is an integer and an object is an object, and I don't like mixing their names. In fact, the idea of substituting objects for ids (in your auto-save case) still weirds me out, even though I see where you are going with it. I'd like Chris's input on this. Another weirdness-inducing thing is that with your auto- or lazy-fetching, we effectively have a limited cache, as the fetched objects are stored in the hidden fields, but with manual fetching we do not have a hidden cache. Thus, simply changing SPOPS config will change the code behavior, and it may not even be noticed at once during compilation (unlike the id-to-object change), because the lack of caching only rears its head when you fetch the same object more than once. No matter how much you document this, it's not obvious for a beginner, and thus the warnings will be ignored. Your example with DateConvert which is also a configuration change is not quite in the same league, because then you are clearly changing a datum type. But a switch from auto- to manual fetching would look very innocent to a beginner. > No storing objects in fields? You mean you want to eliminate > auto/lazy-fetch as an option? > > Ah ... wait a minute ... are you assuming a cache? No, that would be even more weird. However, note my comment in the previous email that the foreign key ids may be made read-only. This will eliminate a way to create inconsistencies. >> How do we deal, though, with manual fetch (when a dependent object is >> not stored) plus auto-save (when a dependent object/id should be >> stored to be saved)? > > > This issue is also addressed in my proposal in the e-mail referenced > above. Since you can't auto-save an object you don't have, auto-saving > with manual fetch makes no sense, and attempting to configure a field > that way should throw an error. Actually, I can think of a situation when it does make sense. Suppose you edit a web page listing info for an author and all the books he wrote. First you retrieve the old author and book objects from the database, then you replace some values, then you save the author objects and would like the book objects become updated to. Even if they have not been fetched yet, they would get fetched when get an array of children to iterate over. You'll say that this is more suited for auto-fetching, but I may still want to use the manual fetching for the "neatness" reasons. :) Simon -- Simon (Vsevolod ILyushchenko) si...@cs... http://www.simonf.com Terrorism is a tactic and so to declare war on terrorism is equivalent to Roosevelt's declaring war on blitzkrieg. Zbigniew Brzezinski, U.S. national security advisor, 1977-81 |
From: Ray Z. <rz...@co...> - 2004-12-06 19:36:46
|
On Dec 4, 2004, at 10:57 AM, Vsevolod (Simon) Ilyushchenko wrote: >> Again, the purpose of this is to allow me to think of my book's >> publisher field as a Publisher object. > > I don't think you can persuade me that this approach is neater. Maybe not ... but I hope you don't mind my trying :-) > One of the best things about SPOPS is that it lets me think accurately > in terms of my tables and my objects at the same time. Each database > field name corresponds to an object variable name, period. Having the > 'publisher' id column correspond to a 'publisher' object will break > the neat mental picture. Your mental picture is a totally valid one, and may often be the best one, but IMHO it is not the only valid one. The value in the database is the persistent version of the corresponding field in the objects, but need not be in an identical form. Developers should be able to define how one maps to the other in a way that is most useful to them. Take a look at SPOPS::Tool::DateConvert for an example of how SPOPS already allows this type of behavior as an option. (Btw, Chris, this a good example of where changing configuration forces you to change what you expect to find in that particular field of your object ... which I still find quite reasonable). I would say that if you want the "value in database eq value in object" mental picture, then all you're saying is that you want to configure for manual fetching. > Plus, there is a huge downside that if I want to find out parent_id > from a child (for the auto/lazy fetch), I'll have to call > child->parent->id, which means that for the lazy fetch I have to > retrieve the parent to get parent's id, though it's present in the > child anyway. However, see more below. Again, I think you're just saying that you want manual fetching. Why would you configure it for auto/lazy fetch if all you wanted was the id? If you only need the object sometimes and want the parent() method to always return an id, you can still always get to the object using the fetch_parent() method (which you can even rename if you like). >> - What do you call the field where you stash the auto-fetched >> object? Always specify explicit name in config? > > This can be auto-deduced from class names (config hash keys, not Perl > names). Currently SPOPS supports the config key {main_alias} to be > used in such cases. Unless I don't understand what you're suggesting, I think this goes back to our previous discussion about what to use for the config key, alias (old has_a syntax) or field name (new has_a syntax). Those aliases are only unique to the class, but we need something unique to the field to be able to handle the case where you have two fields which belong to the same class. >> - When auto-saving how should SPOPS handle inconsistencies between >> the id of the object in the publisher field and the value in the >> publisher_id field? Or to put it another way, if I want to re-assign >> a book's publisher, do I assign a new id to the publisher_id field or >> do I assign a new object to the publisher field? > > It's possible to generate methods in such a way that all related id > fields and objects are updated when a change happens. However, this is > implementing caching all over again. This makes me think that maybe > storing objects in fields is not such a good idea after all. > (Currently SPOPS does not do it, and the code that I've written before > Ray's objections does not do it either.) No storing objects in fields? You mean you want to eliminate auto/lazy-fetch as an option? Ah ... wait a minute ... are you assuming a cache? I suppose with a cache you could do auto/lazy-fetching without storing the auto-fetched objects in the primary object. But as I mentioned before (and I seem to remember Chris saying the same), I think caching and the new has_a (or relates_to) functionality should be treated separately. I have certainly been thinking of these as completely separate. For the purposes of designing this new functionality, I've *always* assumed no caching. Caching can be added as an independent option later. > This brings up another problem, though. How should save() work in the > many-to-many configuration when the parent is saved? Currently > links_to calling addChild() method already causes an update of the > linking table. Hence, when parent->save() is called, there is no need > to update the linking table, though the framework can go ahead and > save the children objects if auto-save is specified. Oh, wait! We > don't have the children objects because we don't like storing objects > in the fields! We have to re-fetch the children and then save them. > Fortunately, I have the "cache_only" option for fetch_group() which > will only return objects in cache, but we still have to make a > database call because we don't know what IDs we want. In my proposal, auto-saving is off by default for 'link'. So you don't save either the link or the child object. Details are in <http://sourceforge.net/mailarchive/forum.php? thread_id=110632&forum_id=3222>. > In the one-to-many configuration, the addChild method updates the > parent_id field in the child object and saves it, which amounts to > auto-save, even though it may not have been requested. The code can be > changed, though, to only save the new parent_id of the child object. It's only an auto-save if it happens automatically as a result of saving the object that fetched it. I view calling an add_*() method as an explicit (i.e. "manual") save operation on the child and think it should be documented as such. > The problem lies in the fact that we perform database saves not just > in the save() method, but also in the add/removeChild operations. What > happens if the add/remove operations do not access the database? We > have to either 1) maintain a hidden list of dependent ids and work > with it, or 2) go Ray's way and maintain a list of dependent objects. > To maintain consistency we can either A) add logic to generated > methods to keep those ids in sync, or B) prohibit saying > child->parent_id if it can be obtained as child->parent->id. I think all of these options are ugly, which is why I propose that we stick with saving the child object in the add_*() methods and documenting that clearly. > How do we deal, though, with manual fetch (when a dependent object is > not stored) plus auto-save (when a dependent object/id should be > stored to be saved)? This issue is also addressed in my proposal in the e-mail referenced above. Since you can't auto-save an object you don't have, auto-saving with manual fetch makes no sense, and attempting to configure a field that way should throw an error. >> Seems much more messy to me for something that I consider to be >> completely new functionality (no backward compatibility issues to >> worry about). While it does eliminate the need for the manual fetch >> option, as Simon mentioned earlier (and probably even lazy fetch), it >> also eliminates one of the main features for me, which is the ability >> to take an existing field and treat it conceptually as an object. > > But I like having parent_id() and parent() methods separate, because I > should not completely forget that I'm dealing with a database. So why not just use ... relates_to => { parent_id => { class => 'Parent::Class', fetch => { type => 'manual' name => 'parent' } } } Doesn't that give you what you want? Turn on caching and you even have your version of lazy-loading, right? The parent_id() method always gives you the id and the parent() method always gives you the (possibly cached) object. I think the only thing missing is auto-fetching (into cache only) without stashing the objects in a field. This 'auto-cache' option, to give it a name, obviously requires that caching be turned on and would have to either throw an error or revert to 'manual' if a cache were not present. But, I honestly don't see the need for this option. If you ALWAYS want to auto-fetch the secondary object(s), then you're never in the situation where you need to fetch them just to get the id. Both are always available. So why not just auto-fetch them into the field as I proposed? I think it's clear that there are differences in the way you and I like to think about our objects/data and the way we intend to use SPOPS, and this new functionality in particular. And this is all perfectly reasonable. My hope is that we can find a clean, consistent, easy-to-document/understand design that is as flexible as possible, and in particular, flexible enough to encompass both of our requirements. After all this discussion, I still think my original design, in all of its gory detail, accomplishes this. If there is a favorite mental picture or usage scenario that is excluded by my proposed design (or even made more difficult or confusing to configure), I don't yet see it. ( And I am trying :-) Ray Zimmerman Director, Laboratory for Experimental Economics and Decision Research 428-B Phillips Hall, Cornell University, Ithaca, NY 14853 phone: (607) 255-9645 |
From: Vsevolod (S. I. <si...@cs...> - 2004-12-04 18:47:31
|
Okay, I've looked at what Hibernate does. (Using big Java projects like this makes be feel very good that I am not working in Java, but at the same time makes me envious of what's available there. ) Hibernate is much more complicated than SPOPS, I must say. However, IT DOES NOT FREAKING GENERATE OBJECT METHODS!!! What good is a persistence framework if it does not do that??? They actually have a point, though. By providing your own accessors you can convert objects before persisting (from string to dates, for example). SPOPS can do it through rulesets, which actually makes more sense, as the conversion needs to happen only during fetch/save, not every time accessors are called. Rulesets feel kludgier, though. Ray would have liked it. :) The foreign key fields are called "parent", not "parent_id". The instance variables referring to other objects are either of the type List or the relevant object's. Even their main id() method is read only (in SPOPS ids are mutable, as defined in DefaultBehavior). I still think that this is too abstracted for my taste. I like having access to foreign key ids. Chris - what do you think? Simon -- Simon (Vsevolod ILyushchenko) si...@cs... http://www.simonf.com Terrorism is a tactic and so to declare war on terrorism is equivalent to Roosevelt's declaring war on blitzkrieg. Zbigniew Brzezinski, U.S. national security advisor, 1977-81 |
From: Vsevolod (S. I. <si...@cs...> - 2004-12-04 15:57:29
|
Hi, > For auto/lazy fetch configuration, the publisher field in the book > object is ALWAYS the publisher OBJECT whose ID is stored in the > publisher column in the database. > $book->publisher == object > In the case of auto-fetch, the assignment, $book->{publisher} = > $book->fetch_publisher, is executed when the $book object is fetched. In > the lazy-fetch case it happens the first time $book->publisher is called > (or $book->{publisher} is accessed). Again, the purpose of this is to > allow me to think of my book's publisher field as a Publisher object. I don't think you can persuade me that this approach is neater. One of the best things about SPOPS is that it lets me think accurately in terms of my tables and my objects at the same time. Each database field name corresponds to an object variable name, period. Having the 'publisher' id column correspond to a 'publisher' object will break the neat mental picture. Plus, there is a huge downside that if I want to find out parent_id from a child (for the auto/lazy fetch), I'll have to call child->parent->id, which means that for the lazy fetch I have to retrieve the parent to get parent's id, though it's present in the child anyway. However, see more below. > - What do you call the field where you stash the auto-fetched object? > Always specify explicit name in config? This can be auto-deduced from class names (config hash keys, not Perl names). Currently SPOPS supports the config key {main_alias} to be used in such cases. > - When auto-saving how should SPOPS handle inconsistencies between the > id of the object in the publisher field and the value in the > publisher_id field? Or to put it another way, if I want to re-assign a > book's publisher, do I assign a new id to the publisher_id field or do I > assign a new object to the publisher field? It's possible to generate methods in such a way that all related id fields and objects are updated when a change happens. However, this is implementing caching all over again. This makes me think that maybe storing objects in fields is not such a good idea after all. (Currently SPOPS does not do it, and the code that I've written before Ray's objections does not do it either.) This brings up another problem, though. How should save() work in the many-to-many configuration when the parent is saved? Currently links_to calling addChild() method already causes an update of the linking table. Hence, when parent->save() is called, there is no need to update the linking table, though the framework can go ahead and save the children objects if auto-save is specified. Oh, wait! We don't have the children objects because we don't like storing objects in the fields! We have to re-fetch the children and then save them. Fortunately, I have the "cache_only" option for fetch_group() which will only return objects in cache, but we still have to make a database call because we don't know what IDs we want. In the one-to-many configuration, the addChild method updates the parent_id field in the child object and saves it, which amounts to auto-save, even though it may not have been requested. The code can be changed, though, to only save the new parent_id of the child object. The problem lies in the fact that we perform database saves not just in the save() method, but also in the add/removeChild operations. What happens if the add/remove operations do not access the database? We have to either 1) maintain a hidden list of dependent ids and work with it, or 2) go Ray's way and maintain a list of dependent objects. To maintain consistency we can either A) add logic to generated methods to keep those ids in sync, or B) prohibit saying child->parent_id if it can be obtained as child->parent->id. How do we deal, though, with manual fetch (when a dependent object is not stored) plus auto-save (when a dependent object/id should be stored to be saved)? I'll try to install Hibernate this weekend and see what they do there. I've looked at Fowler's "Patterns of Enterprise Application Architechture", but I don't think he brings up the problem of saves. Fowler gave me an idea, though - the various id fields pointing to other objects should be read-only. This way there is less chance of creating confusion. Currently the methods that return objects (parent() or children()) are only getters, but if we want to be really object-oriented, it would be nice to make them setters too, and if we can't set ids directly any more, setters may become manageable. > Seems much more messy to me for something that I consider to be > completely new functionality (no backward compatibility issues to worry > about). While it does eliminate the need for the manual fetch option, as > Simon mentioned earlier (and probably even lazy fetch), it also > eliminates one of the main features for me, which is the ability to take > an existing field and treat it conceptually as an object. But I like having parent_id() and parent() methods separate, because I should not completely forget that I'm dealing with a database. Simon -- Simon (Vsevolod ILyushchenko) si...@cs... http://www.simonf.com Terrorism is a tactic and so to declare war on terrorism is equivalent to Roosevelt's declaring war on blitzkrieg. Zbigniew Brzezinski, U.S. national security advisor, 1977-81 |
From: Ray Z. <rz...@co...> - 2004-12-03 23:12:55
|
Just curious ... Chris, are you submitting something for this? Ray On Nov 29, 2004, at 11:27 PM, Sam Vilain wrote: > Simon Cozens is including a chapter on POOP in _Advanced Programming > Perl, 2nd edition_, an O'Reilly book. > > As he is busy with a new direction in his life, I have agreed to > co-ordinate gathering material and code for possible inclusion in the > chapter from authors and users of POOP frameworks. <snip> > I'm also very keen to get submissions from Alzabo and SPOPS/ESPOPS > experts. |
From: Ray Z. <rz...@co...> - 2004-12-03 19:43:17
|
Chris, I only got a chance to skim over your e-mails the other day. Now that I've looked at your example more carefully, I don't think you got exactly what I'm proposing yet, so I'll try to clarify and then respond to some of your points. On Dec 1, 2004, at 2:27 PM, Chris Winters wrote: > book: > book_id, title, publisher_id > > publisher: > publisher_id, name > > book_author: > book_id, author_id > > author: > author_id, name > > Book 1 ---> 1 Publisher > Book 1 ---> * Author > > my $book = Book->fetch(42); > $book->publisher == object (whether manual/lazy fetch) > $book->publisher_id == ID > $book->author == list of objects (whether manual/lazy fetch) > > Is that right? Because it sounds from the discussion as if: > > $book->publisher == sometimes ID, sometimes object, > depending on the configuration > > which IMO is very confusing. In this example it appears that book has a 'publisher_id' field only, so there would be no 'publisher' method. For the sake of describing my proposal let me rename the 'publisher_id' field to 'publisher', which will still hold the publisher's id in the database. My proposal is as follows: First, regardless of the configuration ... 1. The publisher column in the database holds the ID of a publisher object. 2. The book object has a fetch_publisher() method for fetching the object (config can optionally specify different method name). $book->fetch_publisher == object 3. The book object has a publisher() method which always returns the value of the field in the book object. i.e. $book->publisher == $book->{publisher} For manual fetch configuration, the publisher field in the book object is ALWAYS the ID stored in publisher column in the database. $book->publisher == ID For auto/lazy fetch configuration, the publisher field in the book object is ALWAYS the publisher OBJECT whose ID is stored in the publisher column in the database. $book->publisher == object In the case of auto-fetch, the assignment, $book->{publisher} = $book->fetch_publisher, is executed when the $book object is fetched. In the lazy-fetch case it happens the first time $book->publisher is called (or $book->{publisher} is accessed). Again, the purpose of this is to allow me to think of my book's publisher field as a Publisher object. On Dec 1, 2004, at 5:24 PM, Chris Winters wrote: > I believe I read through everything. I just think you're overestimating > how much time and effort people are willing to spend to sort these > out. We > who have been using SPOPS for a while see the relationship between the > configuration and the code as blindingly obvious. > > But for new people -- or even people who only use SPOPS occasionally -- > it's not. And the idea that the behavior of an existing method could > change based on configuration is very disconcerting. People like to > think > of their objects as somewhat stable -- even Perl people! -- and when we > change the meaning under the hood like that it's untrustworthy. > > OTOH, the idea that something *new* happens -- like adding new methods > -- > as a result of configuration changes isn't so bad because you have the > choice if you want to use the new feature or not. I agree completely. But we are not changing the behavior of any existing methods. The publisher method has always returned the value held in the publisher field of the Perl object and that is what it still returns. What we are doing is adding the *new* ability to configure a field to be an auto/lazy-fetched object instead of simply the ID. This is a new feature which is why I agree that it is a good idea to use a name other than 'has_a' for this config. I really don't like the idea of a 'publisher_id' field configured to auto-fetch an object into a 'publisher' field. I think using two fields clutters up the object unnecessarily and creates other ambiguities that have to be resolved/documented. Since this wasn't envisioned when I wrote up the detailed description of my original design, I haven't thought through this in detail, but here are two issues off the top of my head: - What do you call the field where you stash the auto-fetched object? Always specify explicit name in config? - When auto-saving how should SPOPS handle inconsistencies between the id of the object in the publisher field and the value in the publisher_id field? Or to put it another way, if I want to re-assign a book's publisher, do I assign a new id to the publisher_id field or do I assign a new object to the publisher field? Seems much more messy to me for something that I consider to be completely new functionality (no backward compatibility issues to worry about). While it does eliminate the need for the manual fetch option, as Simon mentioned earlier (and probably even lazy fetch), it also eliminates one of the main features for me, which is the ability to take an existing field and treat it conceptually as an object. I suppose if someone insisted on being able to auto-fetch into a second field I wouldn't object too strongly to permitting that as an option, but I think it adds unnecessary complexity which would need to be documented. Ray Zimmerman Director, Laboratory for Experimental Economics and Decision Research 428-B Phillips Hall, Cornell University, Ithaca, NY 14853 phone: (607) 255-9645 |
From: Salve J N. <sal...@me...> - 2004-12-02 16:24:01
|
Chris Winters wrote: > Salve J. Nilsen wrote: >> >> * Package-related config should be placed somewhere very close, but >> seperatly from the server config (e.g. the "fulltext" package >> config has IMHO nothing to do in the conf/server.ini file, and the >> base_user action.ini files are too far away in pkg/base_user/conf.) >> I'd like to suggest that all package config files are accessible >> from a suitable "package.d" directory (e.g. >> "conf/packages.d/fulltext.ini"), and that the main config file >> @INCLUDEs these en-masse. The conf/packages.d/*.ini files need not >> to be more than symlinks to the packages in order to get a positive >> effect. > > That's a really interesting idea. With the global package > configuration override file I've tried to keep everything in one > place, but the global override stuff is probably too confusing for > most people to use. (Then again, most people probably don't need to > modify their package/SPOPS configurations either.) > > The other part we have to balance is package upgrades -- how to allow > the user to keep any changes she's made with the potentially new > package configuration? Maybe with a package upgrade we read in the > existing configurations and compare them to the new ones, writing out > any differences to a separate file? > > I don't think we can do symlinks (not cross-platform), but I like the > idea of keeping all the SPOPS + Action data in one location.... How about using a file that just contain the following lines? =======8<----< $OPENINTERACT2/conf/packages.d/my_package.ini >------- # This is a OI2 config file, belonging to the OI2 package referenced to # below. See the package config files in that directory for more # information. @INCLUDE = $OPENINTERACT2/pkg/my_package-0.01/conf.d -------------->8===================================================== >> * When upgrading some software (OI2 or .zip packages,) I'd like to >> keep my old config, but still get the new features. Splitting up >> files (as you described) may help with this, so do place commonly >> changed config entries in one or more seperate files. > > OI2 should never, never overwrite your server.ini file with an > upgrade. Once we write it at server creation we don't touch it. (In > fact we don't touch anything in conf/ except for repository.ini.) Hm. In that case, there's not much reason for splitting up files, right? We should now only be left with the problem of "how to keep all configuration close together". >> * BTW, I'd like to keep my timezone when I upgrade the server. :) > > This shouldn't get overwritten. Does it? It doesn't. I assumed (in error) it was the server.ini file you wanted to be able to change. But anyway (somewhat unrelated to this) I _do_ have a problem with the timezone enry in server.ini, but only because it is so closely placed to the CVS revision string in the file (making my patch to that config file fail every time server.ini gets updated in CVS. :) >> * s/server_action_info.ini/server_actions.ini/g (Naming consistency >> is good. :) > > Actually 'server_actions.ini' was my first name but I thought it > implied that you'd actually find actions there, which isn't true. Oh. Hm. I got confused by the [box] definition in server_action_info.ini, where it says =========================8<-------------------- [box] action = box_display default_template = base_box::main_box_shell # .... --------------------->8========================= Should it say "use_action", "bind_action" or something other, less confusing then "action"? (See! I'm showing off my ignorance! :) >> * The ini file parser should warn about inconsistencies and >> duplicate entries if they're not allowed. > > > Dupes we can do. Inconsistencies maybe not. But I'd imagine > duplicated configuration would be the main problem. How about checking for legal keywords? IIRC, some config file parsers on CPAN force you to define which keywords and/or value types are legal in a given file. Would that be sensible for OI2? - Salve -- Salve J. Nilsen <salvejn at met dot no> / Systems Developer Norwegian Meteorological Institute http://met.no/ Information Technology Department / Section for Development |