Re: [cgiapp] Re: [OT] CGI::Session is good, but we can do better (a new project is born?)
On Fri, 17 Jun 2005 09:43:38 -0500, Mark Stosberg wrote: Hi Mark Conversely, I recently spent several /hours/ because of poor naming internal to CGI::Session. It uses ATIME, CTIME, and ETIME. The all lock very similar, and even the values look consistent because they are expressed in seconds. However, ETIME is a relative number of seconds, while the others are absolute values since the Epoch. I tried to improve this in PureSQL with columns named last_access_time, creation_time and duration, which what ETIME really is. Yes. That's exactly the same problem I had every time I looked into CGI::Session when writing CGI::Session::ExpireSessions. But it's a mindset, just like when people write books - each book is (luckily) different. -- Cheers Ron Savage, [EMAIL PROTECTED] on 18/06/2005 http://savage.net.au/index.html Let the record show: Microsoft is not an Australian company - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Re: [OT] CGI::Session is good, but we can do better (a new project is born?)
On Fri, 17 Jun 2005 22:05:33 -0400, Cees Hek wrote: Hi Cees I think we are just using the same tool for different purposes, and hence are looking for different features. It really comes down to semantics I think... I'm up your end of the scale. As I see it - for 'session' info: o Some info is for 1 round trip. I save it and when I get a reply from the user I combine the user's (new) data with the saved data o Some info is for up to when the user somehow indicates they are 'done' o Some info is left over because the user did not explicitly say 'done'. This is what gets zapped by CGI::Session::ExpireSessions and its ilk Each app is slightly different so each data usage pattern is slightly different. Definitely no big deal. -- Cheers Ron Savage, [EMAIL PROTECTED] on 18/06/2005 http://savage.net.au/index.html Let the record show: Microsoft is not an Australian company - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Re: [OT] CGI::Session is good, but we can do better (a new project is born?)
On Sat, 18 Jun 2005 00:15:23 -0400, Michael Graham wrote: Hi Michael I'd like to be able to easily create temporary sessions for specific purposes. For instance, it would be nice to create a session for a multi-page form, and use this to store the state between pages instead of using hidden fields or the user's own session. Exactly. I deal with departmental staff lists, and people's names are displayed in a specific order when staff do a search on a department's name. This order is called Order of Merit (OOM). It's just to make Enquiries phone numbers appear before those of live! staff, with postgrads last :-). Now, in the editing screen, if the user submits a form of 310 staff details, with N fields per person (sigh) I keep the OOMs in the session table, and compare them against the incoming data. That way, if the OOM has not changed I do not hit the database, and visa versa, only update the personnel record when the OOM has changed. Hmmm ... thinks ... I'd better check the code to ensure the session is updated, not just the db (mega-sigh). -- Cheers Ron Savage, [EMAIL PROTECTED] on 18/06/2005 http://savage.net.au/index.html Let the record show: Microsoft is not an Australian company - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Re: [OT] CGI::Session is good, but we can do better (a new project is born?)
On Fri, 17 Jun 2005 09:43:38 -0500, Mark Stosberg wrote: Hi Mark http://savage.net.au/Ron/html/naming-database-objects.html which, of course, I do not expect anyone else to follow... At the moment, I'm eastbound on I-70 without net access, but I'll be curious to read that later. I also believe in the value of DB naming conventions, and Summersault uses one we've published on our corporate intranet. I don't state it explicitly in the article, but one major reason I evolved this design was to compensate for MySQL's lack of support for foreign keys. I had code which would determine foreign keys based on column name alone. An example is sub is_foreign_key() in http://savage.net.au/Ron/html/graphing-database-schema.html Now, even tho MySQL support them, I keep the column-naming system. -- Cheers Ron Savage, [EMAIL PROTECTED] on 18/06/2005 http://savage.net.au/index.html Let the record show: Microsoft is not an Australian company - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Re: [OT] CGI::Session is good, but we can do better (a new project is born?)
On Fri, 17 Jun 2005 09:43:38 -0500, Mark Stosberg wrote: Hi Mark This just turned up on CPAN today: Object::Generic::Session -- Cheers Ron Savage, [EMAIL PROTECTED] on 18/06/2005 http://savage.net.au/index.html Let the record show: Microsoft is not an Australian company - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[cgiapp] Re: RFC: DBI::Session proposed docs (name clarification)
On 2005-06-18, Mark Stosberg [EMAIL PROTECTED] wrote: DBI::Session - Database-driven session management Cees kindly brought to my attention that the 'DBI::' namespace is reserved, which I had forgotten. 'DBIx::Session' would be the preferred alternative. Mark - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] OT: Beer in New York
Gabor Szabo wrote: Last month we talked about the possibility to have a pre-YAPC meeting in New York when I am there. So this is coming now. I'll be in New York between 18-22/June. I'd be glad if a couple of us could get together for a beer or some similar substance. Local people, please set the place and the time on any of those dates. I'm not local, but I'll be in NY the evening of the 21st. If that works for everyone else, then i'm game. I know that Jesse's wife just released child 2.0 so we'll see if he can break away for an evening. -- Michael Peters Developer Plus Three, LP - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] RFC: DBI::Session proposed docs
On Sat, 18 Jun 2005, Mark Stosberg wrote: As a design goal, no database driver layer should be needed. How will you handle locking? This seems to be the hardest thing to do in a database agnostic fashion. -sam - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Re: [OT] CGI::Session is good, but we can do better (a new project is born?)
Now, in the editing screen, if the user submits a form of 310 staff details, with N fields per person (sigh) You really aren't kidding about this stuff, are you? :) I keep the OOMs in the session table, and compare them against the incoming data. That way, if the OOM has not changed I do not hit the database, and visa versa, only update the personnel record when the OOM has changed. Yeah that's the kind of thing I mean. (Assuming I understand you correctly - that you are storing application state in the user's session.) If the user closes the form and comes back to it three days later then the application state from three days ago is reused, right? Bleah. The other option is to use hidden fields, but that's pretty messy too. I guess what I'm looking for is a session with more than one primary key: my $form_session = Session-new( page = 'staff_list', form = 'details', user = $user_session-{'uid'}, ); Like regular sessions, this would either return the existing session or create a new one, based on whether or not it can find a (non-expired) session with that page, form and user combination. Still doesn't solve the problem of one user, one form, two browser windows though. Hmmm Michael --- Michael Graham [EMAIL PROTECTED] YAPC::NA 2005 Toronto - http://www.yapc.org/America/ - [EMAIL PROTECTED] --- - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[cgiapp] Re: Class::Trigger [was Hooks, HTML::Tidy plugin]
Mark Stosberg wrote: On 2005-06-17, Rhesa Rozendaal [EMAIL PROTECTED] wrote: Has anybody ever mentioned Class::Trigger? It would be nice to have 'before_foo' and 'after_foo' triggers, for instance, and Class::Trigger has already proven its usefulness in Class::DBI. I looked it in passing. If you try it with C::A, let us know how you like it. I've taken some time to see if I could rewrite the hook system with Class::Trigger, and it works except for all the tests in t/11callbacks.t (due to the different order in which callbacks are executed): Failed Test Stat Wstat Total Fail Failed List of Failed --- t/11callbacks.t3 768 53 60.00% 2-4 Failed 1/12 test scripts, 91.67% okay. 3/160 subtests failed, 98.12% okay. Before I continue, can I ask some questions about some of the design decisions you guys made? - add_callback() accepts both a coderef and a string. Class::Trigger only accepts coderefs. Why did you decide to accept sub names as well? - CT doesn't have the analog of new_hook(); it just creates the hook point when add_trigger is called for the first time. That looks sensible to me at first sight. What was the reason for the explicit new_hook()? - CT says it executes hooks in the order they were registered. I _think_ this may be a drawback for us in the long run, as it doesn't give us control over the execution order at all. On the other hand, Mark decided to avoid the entire issue for now. I'd like to stress that it's not my intention to change the current implementation. I'm just curious to see if I can get it to work with an already existing framework for triggers. I've read the posts that mentioned CT in the archives. It seems the execution order was the big thing back then, which is why it had never been seriously considered. As Mark noted quite correctly, it would add a dependency that many users wouldn't need. Then again, the callback code is _in_ cgiapp now, so that may not be such a big objection anymore. So far this is just a weekend excursion for me. If there's any feedback, I might start to take it more seriously :-) Rhesa Complete test results: athene:~/.cpan/build/CGI-Application-4.01$ make test PERL_DL_NONLAZY=1 /usr/bin/perl -MExtUtils::Command::MM -e test_harness(0, 'blib/lib', 'blib/arch') t/*.t t/01cgiappok t/02mailform..ok t/03prerunok t/04getquery..ok t/05arrayrefmodes.ok t/06enhancement31.ok t/07postrun...ok t/09zerormok t/10errormode.ok t/11callbacks.NOK 2 # Failed test (t/11callbacks.t at line 370) # Structures begin differing at: # $got-[0] = 'init/My::App::cgiapp_init' # $expected-[0] = 'init/CGI::Application::Plugin::Bar::bar_init1' Actual Event History: $VAR1 = [ 'init/My::App::cgiapp_init', 'init/CGI::Application::Plugin::Foo::foo_init1', 'init/CGI::Application::Plugin::Foo::foo_init2', 'init/My::Project::my_project_init', 'init/CGI::Application::Plugin::Bar::bar_init1', 'bar_hook/CGI::Application::Plugin::Bar::bar_custom', 'init/CGI::Application::Plugin::Bar::bar_init2', 'prerun/My::App::cgiapp_prerun', 'prerun/CGI::Application::Plugin::Foo::foo_prerun', 'prerun/CGI::Application::Plugin::Bar::bar_prerun', 'prerun/My::App::my_app_class_prerun', 'prerun/My::App::my_app_obj_prerun', 'runmode/My::App::begin', 'postrun/My::App::cgiapp_postrun', 'postrun/CGI::Application::Plugin::Foo::foo_postrun', 'postrun/CGI::Application::Plugin::Bar::bar_postrun', 'teardown/My::App::teardown', 'teardown/CGI::Application::Plugin::Foo::foo_teardown', 'foo_hook/CGI::Application::Plugin::Foo::foo_custom', 'teardown/CGI::Application::Plugin::Bar::bar_teardown', 'teardown/My::App::my_app_teardown', 'teardown/My::App::my_app_teardown' ]; t/11callbacks.NOK 3 # Failed test (t/11callbacks.t at line 438) # Structures begin differing at: # $got-[0] = 'init/My::App::cgiapp_init' # $expected-[0] = 'init/CGI::Application::Plugin::Bar::bar_init1' Actual Event History: $VAR1 = [ 'init/My::App::cgiapp_init', 'init/CGI::Application::Plugin::Foo::foo_init1', 'init/CGI::Application::Plugin::Foo::foo_init2', 'init/My::Project::my_project_init', 'init/CGI::Application::Plugin::Bar::bar_init1', 'bar_hook/CGI::Application::Plugin::Bar::bar_custom', 'init/CGI::Application::Plugin::Bar::bar_init2', 'prerun/My::App::cgiapp_prerun', 'prerun/CGI::Application::Plugin::Foo::foo_prerun', 'prerun/CGI::Application::Plugin::Bar::bar_prerun',
Re: [cgiapp] Re: Class::Trigger [was Hooks, HTML::Tidy plugin]
Hi Rhesa, - add_callback() accepts both a coderef and a string. Class::Trigger only accepts coderefs. Why did you decide to accept sub names as well? The whole system of overloadable methods in sub classes depends on that. So an alternate implementation had better preserve it. Cheers, Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[cgiapp] Re: Class::Trigger
Cees Hek wrote: On 6/18/05, Rhesa Rozendaal [EMAIL PROTECTED] wrote: - add_callback() accepts both a coderef and a string. Class::Trigger only accepts coderefs. Why did you decide to accept sub names as well? I did this because runmodes accept a string or a coderef, so it would be consistent with the rest of CGI::Application. Also, it makes subclassing easier. Yes, Thilo just pointed that out as well, and I think that's important. Since I already made add_callback() a wrapper around add_trigger(), I managed to support that after a fashion. Here's the gist of it: use Class::Trigger; sub add_callback { my ($pkg, $hook, $method) = @_; $pkg-add_trigger($hook, sub{ shift()-$method(@_) } ); } sub call_hook { my ($pkg, $hook, @args) = @_; $pkg-call_trigger($hook, @args); } sub new_hook {} # register default triggers __PACKAGE__-add_callback('init', 'cgiapp_init'); __PACKAGE__-add_callback('prerun', 'cgiapp_prerun'); __PACKAGE__-add_callback('postrun', 'cgiapp_postrun'); __PACKAGE__-add_callback('teardown', 'teardown'); I also commented out the original code for the callbacks, of course (there's a complete diff at the end of this post). This works, to a degree. All tests pass, except the more complex cases in t/11callbacks.t. In my runs the order is different, and I see some oddities: certain callbacks are executed more than once; not all expected events actually occur. Maybe I took too much of a shortcut in my add_callback() wrapper, or maybe the cgiapp contains more smarts. I'm not really in the mood anymore to figure it out right now. - CT doesn't have the analog of new_hook(); it just creates the hook point when add_trigger is called for the first time. That looks sensible to me at first sight. What was the reason for the explicit new_hook()? To me it acts more like 'use strict'. It catches typos and silly mistakes that can be very hard to track down. Ah, so it warns if an undefined hook gets called? I suppose that's good, yes. Dependancies don't worry me that much, as long as we are using 60-80% of the functionality of the module. If we are using a tiny piece of a huge module, then I might speak up against it. Class::Trigger itself is roughly 95 lines of code. It in turn depends on Class::Data::Inheritable, of which I don't know the size. So far this is just a weekend excursion for me. If there's any feedback, I might start to take it more seriously :-) Thanks for looking into it. I don't think all of this is set in stone yet (but the cement is drying fast). We have a basic system of callbacks in place that I think will work for most people. It will take some time to cater to every possibility though. Thanks for the reply. I liked the ease with which I was able to refactor it. Class::Trigger is definitely worth considering in general. I'm not all that certain anymore it would win us much for cgiapp though. The current code does the exact same thing, and we're (well, Mark is ;) in full control. I had fun poking around in all this. I'll attach this patch for whoever is interested in taking it further. Have a great weekend! Rhesa --- Application.pm.orig 2005-06-19 04:20:21.0 +0200 +++ Application.pm 2005-06-19 04:53:34.0 +0200 @@ -4,8 +4,11 @@ use Carp; use strict; use Class::ISA; +use Class::Trigger; -$CGI::Application::VERSION = '4.01'; +$CGI::Application::VERSION = '4.01_01'; + +=for old code my %INSTALLED_CALLBACKS = ( # hook name package sub @@ -16,6 +19,23 @@ load_tmpl = { }, ); +=cut + +sub add_callback { + my ($pkg, $hook, $method) = @_; + $pkg-add_trigger($hook, sub{ shift()-$method(@_) } ); +} +sub call_hook { + my ($pkg, $hook, @args) = @_; + $pkg-call_trigger($hook, @args); +} +sub new_hook {} + +__PACKAGE__-add_callback('init', 'cgiapp_init'); +__PACKAGE__-add_callback('prerun', 'cgiapp_prerun'); +__PACKAGE__-add_callback('postrun', 'cgiapp_postrun'); +__PACKAGE__-add_callback('teardown', 'teardown'); + ### INSTANCE SCRIPT METHODS ### @@ -1953,6 +1973,8 @@ =cut +=for old code + sub add_callback { my ($self_or_class, $hook, $callback) = @_; @@ -1974,6 +1996,8 @@ } +=cut + =item new_hook(HOOK) $self-new_hook('pretemplate'); @@ -1989,12 +2013,16 @@ =cut +=for old code + sub new_hook { my ($class, $hook) = @_; $INSTALLED_CALLBACKS{$hook} ||= {}; return 1; } +=cut + =item call_hook(HOOK) $self-call_hook('pretemplate', @args); @@ -2021,6 +2049,8 @@ =cut +=for old code + sub call_hook { my $self = shift; my $app_class = ref $self || $self; @@ -2060,6 +2090,8 @@ } } +=cut + =pod BCallback Ordering - Web Archive: