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.