Perl

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • CGI::App 4.0 release pending (was: remove duplicate callbacks?)

    15 answers - 1714 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    2005-05-30, Michael Graham <magog (AT) the-wire (DOT) comwrote:
    Cees Hek <ceeshek (AT) gmail (DOT) comwrote:
    >Somewhere along the line did we loose the ability to register a
    >callback to the object? In the latest patch, it looks like a call to
    >$self->add_callback() will end up registering the callback in
    >ref($self) (or in otherwords, the class, not the object).
    >>

    >This means you will not be able to register a one time callback in a
    >persistent environment.
    >

    I hadn't considered the usefulness of one-time callbacks. I've added
    the feature and made a new tarball:
    Since we're running class-based callbacks in the order of more specific
    (My::App) to less specific (CGI::Application), I made it so that
    object-based callbacks run before class-based callbacks.
    I also renamed the name of the storage variable/key from INSTALLED_HKS
    to INSTALLED_CALLBACKS. Dunno if that's an improvement or not.
    Thanks again for this work Michael.
    Unless there is other feedback soon, I'm inclined to release this as
    CGI::App 4.0, pending my own final review.
    If the callbacks need some refinement after launch, I think we can do
    that fairly safely as this is a new feature that I expect relatively few
    people to begin using heavily just after the release, relative the
    CGI::App installed user base.
    Mark
    Web Archive: @lists.erlbaum.net/
    To unsubscribe, e-mail: cgiapp-unsubscribe (AT) lists (DOT) erlbaum.net
    For additional commands, e-mail: cgiapp-help (AT) lists (DOT) erlbaum.net
  • No.1 | | 1454 bytes | |

    Tue, 31 May 2005, Mark Stosberg wrote:

    Unless there is other feedback soon, I'm inclined to release this as
    CGI::App 4.0, pending my own final review.

    A few comments:

    - I think add_callback() is complex enough to benefit from named
    params rather than positional ones. Ex:

    $self->add_callback(stage ='teardown',
    sub =\&callback,
    order ='FIRST');

    For consistency you might have new_hook and call_hook take a
    single named param as well.

    - I think the docs could be more explicit about exactly when each
    hook is called.

    - Ideas for additional callback hooks: pre_load_tmpl, post_load_tmpl
    (passed the template object?), on_error (called when something
    die()s?), pre_init, post_init.

    , looks pretty sweet. I'm planning to give it a test drive
    this weekend. I've got an idea for a database profiling plugin
    potentially called It would
    setup DBI::ProfileDumper to capture DBI profiling stats for a single
    request then pop up a window with an interactive profile explorer
    using GD::Graph. The new callback stuff should make this possible
    without requiring the app to be a sub-class, which is great.
    -sam

    Web Archive: @lists.erlbaum.net/

    To unsubscribe, e-mail: cgiapp-unsubscribe (AT) lists (DOT) erlbaum.net
    For additional commands, e-mail: cgiapp-help (AT) lists (DOT) erlbaum.net
  • No.2 | | 936 bytes | |

    Fri, 3 Jun 2005, Sam Tregar wrote:

    , looks pretty sweet. I'm planning to give it a test drive
    this weekend. I've got an idea for a database profiling plugin
    potentially called

    which isn't going so well. Maybe I'm being dense but I don't see
    how a plugin gets an object on which to call add_callback(). I would
    have expected something like this to work:

    package Whatever;
    use base 'CGI::Application';

    # turn on DBI profiling
    use ;

    But I guess I'd actually need this too:

    sub cgiapp_init {
    my $self = shift;
    >setup_hooks($self);

    }

    That seems unfortunate. Am I mistaken?
    -sam

    Web Archive: @lists.erlbaum.net/

    To unsubscribe, e-mail: cgiapp-unsubscribe (AT) lists (DOT) erlbaum.net
    For additional commands, e-mail: cgiapp-help (AT) lists (DOT) erlbaum.net
  • No.3 | | 2493 bytes | |

    6/3/05, Sam Tregar <sam (AT) tregar (DOT) comwrote:
    - I think add_callback() is complex enough to benefit from named
    params rather than positional ones. Ex:

    $self->add_callback(stage ='teardown',
    sub =\&callback,
    order ='FIRST');

    For consistency you might have new_hook and call_hook take a
    single named param as well.

    Makes sense to me
    - I think the docs could be more explicit about exactly when each
    hook is called.
    - Ideas for additional callback hooks: pre_load_tmpl, post_load_tmpl
    (passed the template object?), on_error (called when something
    die()s?), pre_init, post_init.

    I have pre and post template hooks already in the TT plugin, but it
    makes a lot of sense for the builtin template support as well.
    Although I think it would be more useful if you could wrap some
    callbacks around $template->output. But that would require some extra
    functionality that doesn't exist yet in CGI::App.

    Sidetracking just a little -- I know that Michael Graham has been
    working on abstracting all the template support in CGI::App into a
    plugin and I believe it already supports pre and post callbacks for
    HTML::Template (some of you may have noticed it on CPAN already, but
    I'll wait for him to announce it).

    on_error could be interesting. I could see a use for that to give
    plugins a place to clean up after a failure.

    , looks pretty sweet. I'm planning to give it a test drive
    this weekend. I've got an idea for a database profiling plugin
    potentially called It would
    setup DBI::ProfileDumper to capture DBI profiling stats for a single
    request then pop up a window with an interactive profile explorer
    using GD::Graph. The new callback stuff should make this possible
    without requiring the app to be a sub-class, which is great.

    That sounds very interesting. I look forward to seeing it. DB
    profiling for me has always meant turning on verbose logging in the
    DB, and then running some scripts over the log files. That is usually
    more work that I am willing to put in which means I dont profile as
    much as I should. This definately sounds like it would simplify
    things

    Cheers,

    Cees

    Web Archive: @lists.erlbaum.net/

    To unsubscribe, e-mail: cgiapp-unsubscribe (AT) lists (DOT) erlbaum.net
    For additional commands, e-mail: cgiapp-help (AT) lists (DOT) erlbaum.net
  • No.4 | | 1949 bytes | |

    6/4/05, Sam Tregar <sam (AT) tregar (DOT) comwrote:
    Fri, 3 Jun 2005, Sam Tregar wrote:

    , looks pretty sweet. I'm planning to give it a test drive
    this weekend. I've got an idea for a database profiling plugin
    potentially called

    which isn't going so well. Maybe I'm being dense but I don't see
    how a plugin gets an object on which to call add_callback(). I would
    have expected something like this to work:

    package Whatever;
    use base 'CGI::Application';

    # turn on DBI profiling
    use ;

    But I guess I'd actually need this too:

    sub cgiapp_init {
    my $self = shift;
    >setup_hooks($self);

    }

    That seems unfortunate. Am I mistaken?

    You don't need $self to setup callbacks or add new hooks. You can
    call them as class methods. So you could put this in your 'import'
    subroutine:

    sub import {
    my $pkg = shift;
    my $callpkg = caller;
    $callpkg->add_callback('cgiapp_init' =>
    \&);
    }

    But if 'setup_hooks' just sets up a bunch of hooks and/or callbacks,
    then you might as well call them as class methods directly

    sub import {
    my $pkg = shift;
    my $callpkg = caller;
    setup_hooks($callpkg);
    }

    sub setup_hooks {
    my $class = shift;
    $class->add_hook('something');
    $class->add_callback('postrun' =\&run_profiler);
    }

    Does that work better?

    By the way, this is exactly what we needed. Someone that wasn't
    involved in coding this stuff to actually sink their teeth into it and
    find out if it works well or not.

    Cheers,

    Cees

    Web Archive: @lists.erlbaum.net/

    To unsubscribe, e-mail: cgiapp-unsubscribe (AT) lists (DOT) erlbaum.net
    For additional commands, e-mail: cgiapp-help (AT) lists (DOT) erlbaum.net
  • No.5 | | 1056 bytes | |

    Sat, 4 Jun 2005, Cees Hek wrote:

    You don't need $self to setup callbacks or add new hooks. You can
    call them as class methods. So you could put this in your 'import'
    subroutine:

    sub import {
    my $pkg = shift;
    my $callpkg = caller;
    $callpkg->add_callback('cgiapp_init' =>
    \&);
    }

    Does that work? It doesn't look like it will. add_callback says:

    # First use? Create new __HKS!
    unless (exists($self->{__HKS})) {
    $self->{__HKS} = {};
    }

    And Perl will say:

    Can't use string "Your::Class::Name" as a HASH reference

    By the way, this is exactly what we needed. Someone that wasn't
    involved in coding this stuff to actually sink their teeth into it and
    find out if it works well or not.

    Glad I can help.
    -sam

    Web Archive: @lists.erlbaum.net/

    To unsubscribe, e-mail: cgiapp-unsubscribe (AT) lists (DOT) erlbaum.net
    For additional commands, e-mail: cgiapp-help (AT) lists (DOT) erlbaum.net
  • No.6 | | 1291 bytes | |

    Hi Sam,

    Thanks for testing the new callbacks stuff!

    Sam Tregar <sam (AT) tregar (DOT) comwrote:
    Sat, 4 Jun 2005, Cees Hek wrote:
    You don't need $self to setup callbacks or add new hooks. You can
    call them as class methods. So you could put this in your 'import'
    subroutine:

    sub import {
    my $pkg = shift;
    my $callpkg = caller;
    $callpkg->add_callback('cgiapp_init' =>
    \&);
    }

    Does that work? It doesn't look like it will. add_callback says:

    # First use? Create new __HKS!
    unless (exists($self->{__HKS})) {
    $self->{__HKS} = {};
    }

    I think you're using version 4.0_2, which didn't support the class-based
    syntax. There's a draft of 4.0.3 here:

    Another feature of this version is that hooks aren't ordered by 'FIRST',
    'MIDDLE', 'LAST', etc.

    Michael

    Michael Graham <magog (AT) the-wire (DOT) com>

    YAPC::NA 2005 Toronto - http://www.yapc.org/America/ - na-help (AT) yapc (DOT) org

    Web Archive: @lists.erlbaum.net/

    To unsubscribe, e-mail: cgiapp-unsubscribe (AT) lists (DOT) erlbaum.net
    For additional commands, e-mail: cgiapp-help (AT) lists (DOT) erlbaum.net
  • No.7 | | 2548 bytes | |

    2005-06-04, Sam Tregar <sam (AT) tregar (DOT) comwrote:

    A few comments:

    Thanks for the feedback.
    - I think add_callback() is complex enough to benefit from named
    params rather than positional ones. Ex:

    $self->add_callback(stage ='teardown',
    sub =\&callback,
    order ='FIRST');

    For consistency you might have new_hook and call_hook take a
    single named param as well.

    Since order has been removed, that leaves us with two arguments, which I
    think is reasonable to leave as positional for now.

    $self->add_callback('teardown', \&callback);

    We can add a named-params interface later if things change.
    - I think the docs could be more explicit about exactly when each
    hook is called.

    I'll look at that some more.
    - Ideas for additional callback hooks:

    pre_init, post_init.

    In general, I think we are trying get rid of positional parameters
    in this initial release to keep things simple. I feel the same way about
    "pre" and "post" hooks. "post_init" sounds a lot like the "prerun" stage.
    It's acknowledged that there may be fighting about who runs "really
    first", but adding "pre_init" just moves the first to different
    location. I think that can be addressed with the current design by being
    careful about which order things are loaded in and/or adding a custom
    hook location.

    pre_load_tmpl, post_load_tmpl, (passed the template object?),

    See above for my thoughts on "pre" and "post". However, I like the idea
    of having a special hook in load_tmpl() that receives the template
    object.

    Here's a "use case":

    I have code which I think is generally useful that adds all my
    configuration variables to each template, naming them like:

    cfg_foo_name

    Now I do this through sub-classing load_tmpl(). But that means to share
    the code that way, people have to replace or create their own load_tmpl
    function. With a hook there, they could simply 'use' a plugin for this,
    assuming they get their config data through one of the other 'config'
    plugins I would support.

    on_error (called when something die()s?),

    We already have error_mode() for this, and people can fuss with signal
    handlers as well.

    Cees, would find you a hook at error_mode() a preferable way to design
    your LogDispatch plugin? Right now you advice people to roll a standard
    signal handler.

    Mark
  • No.8 | | 741 bytes | |

    2005-06-04, Cees Hek <ceeshek (AT) gmail (DOT) comwrote:

    DB profiling for me has always meant turning on verbose logging in
    the DB, and then running some scripts over the log files. That is
    usually more work that I am willing to put in which means I dont
    profile as much as I should. This definately sounds like it would
    simplify things

    There is a tool just for this: PQA, written in ruby.
    It's easy to install and use, and runs surprisingly fast on large logs.

    It was designed for PostgreSQL, but has some MySQL support too.

    My power tip: Be sure to use the 'normalize' option! It's like grouping
    together queries that would all use the same bind variables.

    Mark
  • No.9 | | 591 bytes | |

    Sat, 4 Jun 2005, Mark Stosberg wrote:

    There is a tool just for this: PQA, written in ruby.
    It's easy to install and use, and runs surprisingly fast on large logs.

    Looks a lot like the profiling stuff that comes with DBI (which I
    wrote) - DBI::ProfileDumper and dbiprof. The CGI::App I'm working on
    will just be a graphical interface to those.
    -sam

    Web Archive: @lists.erlbaum.net/

    To unsubscribe, e-mail: cgiapp-unsubscribe (AT) lists (DOT) erlbaum.net
    For additional commands, e-mail: cgiapp-help (AT) lists (DOT) erlbaum.net
  • No.10 | | 733 bytes | |

    Sat, 4 Jun 2005, Michael Graham wrote:

    I think you're using version 4.0_2, which didn't support the class-based
    syntax. There's a draft of 4.0.3 here:

    Right you are. Is there a good reason not to use CPAN to distribute
    this release?

    Another feature of this version is that hooks aren't ordered by 'FIRST',
    'MIDDLE', 'LAST', etc.

    Sounds like a reasonable simplification. I was having trouble
    imagining a use-case for that stuff.
    -sam

    Web Archive: @lists.erlbaum.net/

    To unsubscribe, e-mail: cgiapp-unsubscribe (AT) lists (DOT) erlbaum.net
    For additional commands, e-mail: cgiapp-help (AT) lists (DOT) erlbaum.net
  • No.11 | | 972 bytes | |

    2005-06-04, Sam Tregar <sam (AT) tregar (DOT) comwrote:
    Sat, 4 Jun 2005, Mark Stosberg wrote:
    >
    >There is a tool just for this: PQA, written in ruby.
    >It's easy to install and use, and runs surprisingly fast on large logs.
    >
    >
    >

    Looks a lot like the profiling stuff that comes with DBI (which I
    wrote) - DBI::ProfileDumper and dbiprof. The CGI::App I'm working on
    will just be a graphical interface to those.

    Sam,

    Thanks for your work on the DBI profiling tool. PQA has the fundamental
    feature that is not Perl-specific. For example, it revealed that 7.5% of
    my query time was going to PhpPgAds, which could in theory be moved to
    it's own server since it's completely seperate.

    In other cases, I imagine a Perl-specific tool might be more useful,
    perhaps providing line numbers in the code where a slow query was called
    from.

    Mark
  • No.12 | | 571 bytes | |

    2005-06-04, Sam Tregar <sam (AT) tregar (DOT) comwrote:
    Sat, 4 Jun 2005, Michael Graham wrote:
    >
    >I think you're using version 4.0_2, which didn't support the class-based
    >syntax. There's a draft of 4.0.3 here:
    >
    >
    >

    Right you are. Is there a good reason not to use CPAN to distribute
    this release?

    It's more of a logistical issue. I've got the ability to upload CGI::Application, but
    Michael Graham has put together the last few proposed releases.

    Mark
  • No.13 | | 2332 bytes | |

    See above for my thoughts on "pre" and "post". However, I like the idea
    of having a special hook in load_tmpl() that receives the template
    object.

    Here's a "use case":

    I have code which I think is generally useful that adds all my
    configuration variables to each template, naming them like:

    cfg_foo_name

    Now I do this through sub-classing load_tmpl(). But that means to share
    the code that way, people have to replace or create their own load_tmpl
    function. With a hook there, they could simply 'use' a plugin for this,
    assuming they get their config data through one of the other 'config'
    plugins I would support.

    I was just going to ask for a use case - thanks, Mark!

    Currently CAP::TT and my own AnyTemplate module both just call runmodes
    for the template pre- and post-processing functions, and I was
    struggling to figure out why it would be an improvement to change these
    into callbacks.

    But the idea of being able to create template pre- and post-processors
    as bona fide CA::Plugins answers that question.

    (Also, for the built-in load_tmpl function, there are no pre- and
    post-process hooks at all yet, so that's another reason.)

    on_error (called when something die()s?),

    I like having some kind of error hook. Mucking about with $SIG{__DIE__}
    can be problematic. For instance, if you use CGI::Carp and
    CAP::LogDispatch, you have to be careful to chain your handlers so both
    get called when something dies.

    And even then, it can cause problems with other modules. For instance,
    Apache::SessionX (perhaps foolishly) does some important things at
    DESTRY time, and it got very confused when I set a bunch of custom
    $SIG{__DIE__} handlers.

    As an aside, is there a reason that error_mode only catches errors in
    run modes, and doesn't catch errors elsewhere (e.g. in setup or prerun)?

    Michael

    Michael Graham <magog (AT) the-wire (DOT) com>

    YAPC::NA 2005 Toronto - http://www.yapc.org/America/ - na-help (AT) yapc (DOT) org

    Web Archive: @lists.erlbaum.net/

    To unsubscribe, e-mail: cgiapp-unsubscribe (AT) lists (DOT) erlbaum.net
    For additional commands, e-mail: cgiapp-help (AT) lists (DOT) erlbaum.net
  • No.14 | | 2660 bytes | |

    I've merged Michael's changes with my own tree and republished here:

    It's also available through my darcs archive:

    This is the preferable to use, because it remains up-to-date,
    and is sometimes much easier to merge back changes.

    Even if you don't use darcs for anything else, chances are there is
    a binary for your platform, and it's super-easy to use. Like this:

    $ darcs get
    $ cd cgi-app
    # hack
    $ darcs record
    $ darcs send

    That's all it should take to generate a darcs patch and e-mail it back
    to me.

    I may work some on improving the documentation to make it explicit where
    the callbacks are happening, and adding a hook in load_tmpl.

    >on_error (called when something die()s?),
    >

    I like having some kind of error hook. Mucking about with $SIG{__DIE__}
    can be problematic. For instance, if you use CGI::Carp and
    CAP::LogDispatch, you have to be careful to chain your handlers so both
    get called when something dies.

    And even then, it can cause problems with other modules. For instance,
    Apache::SessionX (perhaps foolishly) does some important things at
    DESTRY time, and it got very confused when I set a bunch of custom
    $SIG{__DIE__} handlers.

    K, I don't mind having an on_error handler then. We should document
    explicitly when it's in effect, though, given the following question

    As an aside, is there a reason that error_mode only catches errors in
    run modes, and doesn't catch errors elsewhere (e.g. in setup or prerun)?

    I don't recall that being an intentional design decision of
    error_mode(), but rather a historical artifact. It used to be that the
    run mode was eval'ed but would then just die anyway. So the ability to
    call error_mode() there was an improvement.

    It does make /some sense/ to the extent that error_mode() is like a run
    mode itself. If the application couldn't get "setup" to display the
    target run mode, it might not be sufficiently functional to display the
    error_mode() either.

    If we try to take the idea to the extreme and catch errors at absolutely
    any point, we have basically recreated Apache's customizable Error500
    feature. ( $SIG{__DIE__} ) .

    Personally, I feel like trapping just the run mode stage is a reasonable
    balance between catching most the most likely errors, and being stable
    enough to actually handle the error.

    If people want complete control, it seems hard to avoid mucking with the
    "die" signal handler anyway.

    Mark
  • No.15 | | 883 bytes | |

    Fri, 3 Jun 2005, Sam Tregar wrote:

    I'm planning to give it a test drive this weekend. I've got an idea
    for a database profiling plugin potentially called
    It would setup
    DBI::ProfileDumper to capture DBI profiling stats for a single
    request then pop up a window with an interactive profile explorer
    using GD::Graph. The new callback stuff should make this possible
    without requiring the app to be a sub-class, which is great.

    I've made some progress with this, in case anyone's interested:

    http://use.perl.org/~samtregar/journal/25051

    The callback stuff is working great now that I'm using 4.0_3.
    -sam

    Web Archive: @lists.erlbaum.net/

    To unsubscribe, e-mail: cgiapp-unsubscribe (AT) lists (DOT) erlbaum.net
    For additional commands, e-mail: cgiapp-help (AT) lists (DOT) erlbaum.net

Re: CGI::App 4.0 release pending (was: remove duplicate callbacks?)


max 4000 letters.
Your nickname that display:
In order to stop the spam: 5 + 4 =
QUESTION ON "Perl"

EMSDN.COM