You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Matt Sergeant <ma...@sergeant.org> on 2000/08/29 14:37:01 UTC

[ANNOUNCE] Apache::Reload 0.03

Apache::Reload is a drop-in replacement for Apache::StatINC that does so
much more...

It provides two more options beyond StatINC. The first is a way that you
can register modules to be reloaded. To do this, simply add:

  use Apache::Reload;

to your module and it will automatically be detected by Apache::Reload as
one that needs to be checked for changes and reloaded on each request. In
this mode of operation, Apache::Reload only checks the change time of
registered modules, thus reducing the overhead of stat calls on every
module in %INC.

The new option with 0.03 is the ability to have a TouchFile. This is a
file somewhere on your filesystem that Apache::Reload stat()s on each
request to see if it has changed. If not it doesn't bother to check any of
your modules for changes. If it has been changed it will do the checks on
all of your registered modules (or all of %INC in the case where you're
using it as a replacement for StatINC).

0.03 also fixed a bug someone reported where lexical hash contents weren't
copied to the Apache children. Switching to a package hash solved this.

On its way to CPAN now. Have fun.

-- 
<Matt/>

Fastnet Software Ltd. High Performance Web Specialists
Providing mod_perl, XML, Sybase and Oracle solutions
Email for training and consultancy availability.
http://sergeant.org | AxKit: http://axkit.org


Re: Dissappearing Lexicals

Posted by "David E. Wheeler" <Da...@Wheeler.net>.
Okay, my simplified module wouldn't loose the value of the package-level
lexical, but here's some output from my DBI library, which still looses
the value:

DBH Before Prepare: undef
DBH Before Connect: undef
DBH Connecting...
DBH After Connect: Apache::DBI::db=HASH(0x12d2214)
DBH After Prepare Connect: Apache::DBI::db=HASH(0x12d2214)

DBH Before selectcol_arrayref connect: undef
DBH Before Connect: Apache::DBI::db=HASH(0x12d2214)
DBH After Connect: Apache::DBI::db=HASH(0x12d2214)
DBH After selectcol_arrayref connect: undef


The code that triggers these events looks like this:

dbi_prepare($sql);
dbi_selectcol_arraryref($sql, @params);

The dbi_prepare function looks like this:

sub dbi_prepare {
    my $qry = shift;
    print STDERR "DBH Before Prepare: ", $dbh || 'undef', "\n";
    _connect();
    print STDERR "DBH After Prepare Connect: ", $dbh || 'undef', "\n";
    return $dbh->prepare($qry);
} # dbi_prepare()


_connect looks like this:

sub _connect {
    print STDERR "DBH Before Connect: ", $dbh || 'undef', "\n";
    unless ($dbh && $dbh->ping) {
	print STDERR "DBH Connecting...\n" if $DEBUG;
	$dbh = DBI->connect("DBI:$DBD:$DSN", $ID, $PASS, $ATTR) or die
$DBI::errstr;
    }
    print STDERR "DBH After Connect: ", $dbh || 'undef', "\n";
} # _connect()

So what happens is that dbi_prepare calls _connect() before it does
anything else. Then the $dbh can be expected to persist beyond the call
to _connect() because it's a package-level lexical. And indeed, it does
persist in dbi_prepare, where it is used to prepare the SQL statement.
dbi_selectcol_arraryref() looks like this:

sub dbi_selectcol_arrayref {
    my ($qry, @params) = @_;
    print STDERR "DBH Before connect: ", $dbh || 'undef', "\n";
    _connect();
    print STDERR "DBH After selectcol_arrayref connect: ", $dbh ||
'undef', "\n";
    $qry = dbi_prepare($qry) if ref $qry ne 'DBI::st';
    return $dbh->selectcol_arrayref($qry, undef, @params);
} # dbi_selectcol_arrayref()

Simple, eh? Yet the print statments (which I collected form the Apache
Error Log) clearly show that $dbh has no value when we enter
dbi_selectcol_arrayref(), but the first thing dbi_selectcol_arrayref()
does is call _connnect(), where it *does* still have a value! Returning
to dbi_selectcol_arrayref(), the value is missing again.

I'll keep working on trynig to create a simpler script that others can
try on their systems.

Thanks,

David

Re: Dissappearing Lexicals

Posted by "David E. Wheeler" <Da...@Wheeler.net>.
Matt Sergeant wrote:
> 
> On Wed, 30 Aug 2000, mgraham wrote:
> [snip]
> > Personally, I've given up on package-scoped lexicals entirely, and
> > moved everything into "use vars".  It's a pain, because you lose the
> > encapsulation and you have to declare and assign the variables
> > separately.  But it generally seems much more robust and predictable.
> 
> This is a real worry for anyone using the Tie::SecureHash sort of thing to
> hide access to private variables.

Okay, I'll try to whip up a quick example today of this issue and submit
it to the list. It seems worthwhile to me to try to get this bug(?)
squashed for the reason Matt brings up and others.

David

RE: Dissappearing Lexicals

Posted by Matt Sergeant <ma...@sergeant.org>.
On Wed, 30 Aug 2000, mgraham wrote:

> 
> 
> I don't have specific help for your problem, but I have noticed that
> package-scoped lexicals can be somewhat unpredictable under mod_perl.
> 
> 1) If at startup time (pre-fork) you use a function within a package
> to set a lexical variable that is scoped to that package, that
> variable may or may not remain visible to other functions within the
> package, depending on how the module was loaded:
>     a) if the module was loaded via PerlModule in httpd.conf, the
> value will remain visible.
>     b) if the module was loaded via "use Module" in starup.pl, the
> value will disappear.
> 
> 2) Constant assignments to package-scoped lexicals can disappear when
> the module is reloaded (e.g. via Apache::Reload).  For instance:
> 
>     my $CONSTANT_NUMBER = 42;
> 
> If the module is reloaded, this value can disappear!
> 
> Personally, I've given up on package-scoped lexicals entirely, and
> moved everything into "use vars".  It's a pain, because you lose the
> encapsulation and you have to declare and assign the variables
> separately.  But it generally seems much more robust and predictable.

This is a real worry for anyone using the Tie::SecureHash sort of thing to
hide access to private variables.

-- 
<Matt/>

Fastnet Software Ltd. High Performance Web Specialists
Providing mod_perl, XML, Sybase and Oracle solutions
Email for training and consultancy availability.
http://sergeant.org | AxKit: http://axkit.org


RE: Dissappearing Lexicals

Posted by mgraham <mg...@toronto.circadence.com>.

I don't have specific help for your problem, but I have noticed that
package-scoped lexicals can be somewhat unpredictable under mod_perl.

1) If at startup time (pre-fork) you use a function within a package
to set a lexical variable that is scoped to that package, that
variable may or may not remain visible to other functions within the
package, depending on how the module was loaded:
    a) if the module was loaded via PerlModule in httpd.conf, the
value will remain visible.
    b) if the module was loaded via "use Module" in starup.pl, the
value will disappear.

2) Constant assignments to package-scoped lexicals can disappear when
the module is reloaded (e.g. via Apache::Reload).  For instance:

    my $CONSTANT_NUMBER = 42;

If the module is reloaded, this value can disappear!

Personally, I've given up on package-scoped lexicals entirely, and
moved everything into "use vars".  It's a pain, because you lose the
encapsulation and you have to declare and assign the variables
separately.  But it generally seems much more robust and predictable.


Michael



Dissappearing Lexicals

Posted by "David E. Wheeler" <Da...@Wheeler.net>.
Hi All,

I've encounted a strange problem with our mod_perl installation. I have
a library for handling DBI stuff, and store the $dbh in a package-level
lexical. The $dbh is not populated until the first time a DBI call is
made - which is during a request and therefore always after Apache
forks. The $dbh is then used by various functions exported into other
modules.

However, in some of these functions, $dbh seems to be out of scope! In
other words, In some functions, the $dbh works fine, while in others, it
says "cannot call method 'selectcol_arrayref' on an undefined value."
Sure enough, it thinks that $dbh is undefined, even though it will show
up defined in other functions called just prior to or after the function
that attempts to call selectcol_arrayref. I have not my'd it within the
scope of the function - it is only declared at the package-level.

Now, I've managed to solve the problem by simply making $dbh a package
variable (use vars '$dbh';). However, the package-level lexical *was*
working on Friday, but would not as of yesterday!

Anyone got any ideas what the heck is happening to the value stored in
$dbh? I can provide more details about the construction of my DBI
library if you think that will help diagnose the problem.

Details: All DBI calls are made in one request, so there's no chance of
some calls being in different forks where $dbh may not yet have been
defined. Also, the DBI library I've written works fine when run from the
shell - it's only in mod_perl that it fails.

The setup: Solaris 2.4 running Apache 1.3.12 & mod_perl 1.24. DBI is
version 1.14 and DBD::Oracle version 1.06.

TIA!

David