You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Ken Miller <mi...@husky-oil.com> on 2000/05/15 23:01:55 UTC
Access to userland objects in different phases
In the content serving phase I have a Database services object which
manages all access to/from the database. The DB::Services object is
created the first time the handler is hit; the $dbs is made available by
creating a symtab entry, so all my Mason components can get at the database
easily.
I also have a couple of Authen and Authz handlers (ala Apache::AuthCookie),
and I would like to have access to the services object there as well. I
could just create another DB::Services object, but there is quite a bit of
overhead associated with having a Services object in memory, hence I would
like to have a single Services object per Apache process.
Since the auth phases occur before content serving, I would have to create
the DB::Services object in the Auth/Authz handler, and then obtain access
to it in the Mason handler.
So, I think I would do something like this:
Create the DB::Services object in the authentication phase if it hasn't
already been created. (the Services object has to be created in the
auth/authz phase, since that's before the phase in which Mason runs) Once
it's been created, then do something like:
local *HTML::Mason::Commands::dbs = \$dbs;
thus making the DBS available to Mason. By the time the Mason handler
get's invoked, a $dbs is already in the right namespace, and is therefore
ready to use. Any access to $dbs from the actual handler could be obtained
by explicitly referencing the $dbs object via the package global name.
I guess another way of doing it would be to turn the $dbs class into a
Singleton, and provide a class method to get at the instance:
DB::Services->set_uri( 'dbi:Oracle:XXXX' );
DB::Services->set_userid( 'foo' );
DB::Services->set_password( 'bar' );
DB::Services->set_options( { ... } );
my $dbs = DB::Services->get_instance;
get_instance() would create the backing object the first time, then
returned the cached object on subsequent calls.
Thoughts?
Cheers!
-klm.
-------------------------------------------
Ken Miller, Consultant
Shetland Software Services Inc.
Re: Access to userland objects in different phases
Posted by Ken Miller <mi...@husky-oil.com>.
At 05:28 PM 5/15/00 -0400, you wrote:
>I use Class::Singleton in mod_perl apps with *no* problem
>whatsoever. In fact, it's pretty nifty to simply say:
>
> my $obj = $class->instance;
>
>anywhere in my application and have the object (whatever it is) simply
>pop up.
Well, after looking at the Class::Singleton class, I gave it a shot. After
hacking away at a ChildInitHandler, this is what I ended up with:
package X::Y::Apache::ChildInit;
use strict;
use X::Y::DB::SingletonServices;
use Apache;
##--------------------------------------------------------------------------
---------
sub handler
{
my $s = Apache->server;
my $dbs = X::Y::DB::SingletonServices->instance(
{ uri => $s->dir_config( 'DATABASE_URI' ),
userid => $s->dir_config( 'DATABASE_USERID' ),
password => $s->dir_config( 'DATABASE_PASSWORD' ),
options => { AutoCommit => 0,
RaiseError => 1,
PrintError => 0,
ChopBlanks => 1 } } );
$s->log_error( "$$: Services object allocated, handle=$dbs" );
}
1;
Perfect! I now have access to my services object everywhere!
Thanks for the point at Class::Singleton. I would have eventually written
my own, but with CPAN, what's the point?
Cheers!
-klm.
-------------------------------------------
Ken Miller, Consultant
Shetland Software Services Inc.
Re: Access to userland objects in different phases
Posted by Chris Winters <cw...@intes.net>.
* Ken Miller (millerk@husky-oil.com) [000515 17:16]:
> In the content serving phase I have a Database services object which
> manages all access to/from the database. The DB::Services object is
> created the first time the handler is hit; the $dbs is made available by
> creating a symtab entry, so all my Mason components can get at the database
> easily.
>
> ...snip...
>
> I guess another way of doing it would be to turn the $dbs class into a
> Singleton, and provide a class method to get at the instance:
>
> DB::Services->set_uri( 'dbi:Oracle:XXXX' );
> DB::Services->set_userid( 'foo' );
> DB::Services->set_password( 'bar' );
> DB::Services->set_options( { ... } );
>
> my $dbs = DB::Services->get_instance;
>
> get_instance() would create the backing object the first time, then
> returned the cached object on subsequent calls.
I use Class::Singleton in mod_perl apps with *no* problem
whatsoever. In fact, it's pretty nifty to simply say:
my $obj = $class->instance;
anywhere in my application and have the object (whatever it is) simply
pop up.
Good luck!
Chris
--
Chris Winters
Internet Developer INTES Networking
cwinters@intes.net http://www.intes.net/
Integrated hardware/software solutions to make the Internet work for you.