techcode has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks!

Problem is that to use the CGI::Session for CGI::Application I have to configure it during setup time. I need to either pass it DBH which means I already need to be connected to DB, or parameters that will be used to create DBH and connect by the CGI::Session itself.

In first case (giving it DBH):
I'm connecting no matter if it will be needed (say I dont need Session parameters nor DB access).

Second case (giving it parameters):
It solves the problem that it doesn't connect if it's not needed. But then when it's needed from the application also I end up with two DB connections (one mine, mine from CGI::Session).

Any solution for this?

I'm not using DBI directly but from a module that I wrote which is sort of DB abstraction. I've implemented a Singleton pattern in it - so there is only one connection trougths application. And the way I send DBH to CGI::Session is by requesting it from my module.

### Set the configs for Sessions ### $self->session_config( CGI_SESSION_OPTIONS => ["driver:MySQL;serializer:Storab +le", $self->query, {Handle => $DB->dbh()}] );
Obviosly I already need to be connected at the time when I'm sending DBH to it. Maybe there is some way (TIE perhaps?) to catch all calls that CGI::Session would make on that DBH, and first connect and then execute them?

Only solution that I know would work and how to do it (but not the nicest one) is to change CGI::Session just a bit ...

Replies are listed 'Best First'.
Re: Using CGI:App and Session plugin - double DB connection fix.
by Tanktalus (Canon) on Sep 14, 2005 at 23:16 UTC

    If the problem is that you have a number of pages that don't require sessions (or any db access), and a number that do, then simply put the two groups into different CGI scripts, with different setups - one which creates the db handle, the other which doesn't.

    If the problem is that db connection is too expensive, check out Apache::DBI with mod_perl, or you could write your own connection concentrator daemon using DBI::Proxy.

      Splitting them could be problematic and lead to other problems as at this point CGI::Application, CGI::Application::Plugin::AutoRunmode and CGI::Application::Dispatch all together basically act as an Controller (as in M-V-C). I've already divided functions into logical entities - packages that contain related runmodes.

      I just wish I could use mod_perl - and Apache::DBI with it. Just plain CGI for now - if performance becomes a problem at some point since they are on dedicated host that host only another of their sites mod_perl could be possible. But it's very unlikely - while they have large customer base that would use it - it's an tool to make recurring orders. So I imagine that it wont be visited often after you make your order.

      Will see about DBI::Proxy. And will have to make shure my DB abstraction module will work under Apache::DBI.

Re: Using CGI:App and Session plugin - double DB connection fix.
by johnnywang (Priest) on Sep 14, 2005 at 17:22 UTC
    I'm sure you're aware that the session can be stored in files, not necessarily in db. If you do want to store it in db, then you will need the database handle anyway, I'd say create the handle in setup(), store it, then directly use it in the session and in any run-modes, just close it in teardown.
      I am using that now - but then I connect to DB on each request for my site ...
Re: Using CGI:App and Session plugin - double DB connection fix.
by cees (Curate) on Sep 14, 2005 at 23:52 UTC

    The nicest way would be to change the MySQL driver for CGI::Session so that it can accept a reference to a sub (ie a closure) instead of just a $dbh.

    $self->session_config( CGI_SESSION_OPTIONS => [ "driver:MySQL;serializer:Storable", $self->query, { Handle => sub { ... } } ] );
      Exactly what I was thinking.

      Yesterday I needed a way to get a list of all blocks inside config file (ini type) from Config::Simple, and I implemented it ... Will do that now with CGI::Session.

      What's the standard procedure in cases like that? Just send an email to authors/maintainers saying what did you changed and attach the file?

        If there is a mailing list for the module, sign up and send the info there. Usually module maintainers prefer to get changes in the form of a diff file (usually diff -u is the prefered format). If you don't use *nix, and don't have diff, then I'm sure you could send the entire file that you changed.

        Also, module maintainers are usually very happy if you include some new tests for the test suite that make sure your new feature is working properly.

        Before you go an do all that work though, it might be worthwhile bringing it up on the mailing list to see if the maintainer will be receptive to the change or not.