I'm having a hard time with Apache::Session::DB_File, and I
think I have it narrowed down to a small enough problem to
ask about it. I haven't given up on A::S::Postgres, I'm
just trying to get things working with DB_File before I try
to solve my other problem.
The one-sentence version of my question is: Is there a
problem with tying a session twice during two different
HeaderParserHandlers, as long as your doing the standard
cleanup stuff (untie &| make_modified) in each?
The longer version:
I have managed to boil this problem down to as little code
as possible for reproduction purposes.
I have two PerlHeaderParserHandlers listed in httpd.conf,
to be run one after the other when a particular file is
requested:
<Files handlertest.html>
SetHandler perl-script
PerlHeaderParserHandler LocalSites::TestParser1
LocalSites::TestParser2
</Files>
In the Real World, the first handler is a session manager,
and the second handler is a login form processor. The
login form points to handlertest.html, a dummy file that no
one should ever land on.
I have also added a couple of debug lines to
Apache::Session::Lock::File, so I can track things:
In the beginning of acquire_read_lock:
warn "ARL: Write is: ".$self->{write}." Read is:
".$self->{read}." Opened is: ".$self->{opened};
with similar lines in acquire_write_lock (AWL) and DESTROY.
The first HeaderParserHandler ties the session, puts the
session id into pnotes, and unties.
----------------------------------------------------------------------
package LocalSites::TestParser1;
use strict;
use Apache::Constants qw(DECLINED);
use Apache::Session::DB_File;
use Apache::Log;
sub handler {
my $r = shift;
my $log = $r->server->log();
my $session = $r->header_in('Cookie');
$session =~ s/SESSION_ID=(\w*)/$1/;
my %session = ();
$log->error("TestParser1: tying session");
tie %session, 'Apache::Session::DB_File',$session,
{
FileName=>'/www/data/sessions/sessions.db',
LockDirectory=>'/var/lock/sessions',
};
$r->pnotes('SESSION_ID', %session->{_session_id});
$log->error("TestParser1: untying session");
untie(%session);
$log->error("TestParser1: done");
return DECLINED;
}
1;
__END__;
----------------------------------------------------------------------
The second handler, this one grabs the session id from
pnotes, ties the session, modifies it, saves and unties:
----------------------------------------------------------------------
package LocalSites::TestParser2;
use strict;
use Apache::Constants qw(DECLINED);
use Apache::Session::DB_File;
use Apache::Log;
sub handler {
my $r = shift;
my $log = $r->server->log();
my $session = $r->pnotes('SESSION_ID');
my %session = ();
$log->error("TestParser2: tying session");
tie %session, 'Apache::Session::DB_File',$session,
{
FileName=>'/www/data/sessions/sessions.db',
LockDirectory=>'/var/lock/sessions',
};
%session->{'AUTH'} = 1;
tied(%session)->make_modified();
$log->error("TestParser2: untying session");
untie(%session);
$log->error("TestParser2: done");
return DECLINED;
}
1;
__END__;
----------------------------------------------------------------------
The error log output follows. From the looks of it, the
second module is failing to secure a write lock during the
2nd handler because the 2nd handler already has it marked
open. The second handler does not exhibit this behavior
when it's running by itself (unchanged except "my $session
= undef;").
I'm not sure why I'm not seeing the DESTROY call from the
first handler, but the read lock acquisition in the second
indicates that the file is free for the plundering.
When both handlers are run, the process hangs where
indicated below (acquiring the write lock). Restarting
Apache kills the process and results in the DESTROY calls
below the indicated point. Without a restart the process
will sit indefinitely.
[Fri Jan 19 03:26:50 2001] [error] TestParser1: tying
session
ARL: Write is: 0 Read is: 0 Opened is: 0 at
/usr/lib/perl5/site_perl/5.005/Apache/Session/Lock/File.pm
line 31.
Apache::Session::Lock::File::acquire_read_lock('Apache::Session::Lock::File=HASH(0x8670cf4)',
'Apache::Session::DB_File=HASH(0x8670c70)') called at
/usr/lib/perl5/site_perl/5.005/Apache/Session.pm line 552
Apache::Session::acquire_read_lock('Apache::Session::DB_File=HASH(0x8670c70)')
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm
line 472
Apache::Session::restore('Apache::Session::DB_File=HASH(0x8670c70)')
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm
line 386
Apache::Session::TIEHASH('Apache::Session::DB_File',
'f4a0314ccd0c5e1b84e5670edd924983', 'HASH(0x85ec664)')
called at
/www/boygenius/libraries/LocalSites/TestParser1.pm line 15
LocalSites::TestParser1::handler('Apache=SCALAR(0x85ec6d0)')
called at /dev/null line 0
eval {...} called at /dev/null line 0
[Fri Jan 19 03:26:50 2001] [error] TestParser1: untying
session
[Fri Jan 19 03:26:50 2001] [error] TestParser1: done
[Fri Jan 19 03:26:50 2001] [error] TestParser2: tying
session
ARL: Write is: 0 Read is: 0 Opened is: 0 at
/usr/lib/perl5/site_perl/5.005/Apache/Session/Lock/File.pm
line 31.
Apache::Session::Lock::File::acquire_read_lock('Apache::Session::Lock::File=HASH(0x8685488)',
'Apache::Session::DB_File=HASH(0x8685290)') called at
/usr/lib/perl5/site_perl/5.005/Apache/Session.pm line 552
Apache::Session::acquire_read_lock('Apache::Session::DB_File=HASH(0x8685290)')
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm
line 472
Apache::Session::restore('Apache::Session::DB_File=HASH(0x8685290)')
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm
line 386
Apache::Session::TIEHASH('Apache::Session::DB_File',
'f4a0314ccd0c5e1b84e5670edd924983', 'HASH(0x85ec64c)')
called at
/www/boygenius/libraries/LocalSites/TestParser2.pm line 14
LocalSites::TestParser2::handler('Apache=SCALAR(0x860e330)')
called at /dev/null line 0
eval {...} called at /dev/null line 0
AWL: Write is: 0 Read is: 1 Opened is: 1 at
/usr/lib/perl5/site_perl/5.005/Apache/Session/Lock/File.pm
line 52.
Apache::Session::Lock::File::acquire_write_lock('Apache::Session::Lock::File=HASH(0x8685488)',
'Apache::Session::DB_File=HASH(0x8685290)') called at
/usr/lib/perl5/site_perl/5.005/Apache/Session.pm line 562
Apache::Session::acquire_write_lock('Apache::Session::DB_File=HASH(0x8685290)')
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm
line 490
Apache::Session::save('Apache::Session::DB_File=HASH(0x8685290)')
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm
line 455
Apache::Session::DESTROY('Apache::Session::DB_File=HASH(0x8685290)')
called at /dev/null line 0
eval {...} called at /dev/null line 0
>>>>>>>>>>>>>>>>>It hangs here until
restart<<<<<<<<<<<<<<<<
>>>>Everything from here on is Apache cleaning
up<<<<<<<<<<<
DESTROY: Open = 0 Write = 0 Read = 0 during global
destruction.
Apache::Session::Lock::File::DESTROY('Apache::Session::Lock::File=HASH(0x8685488)')
called at /dev/null line 0
eval {...} called at /dev/null line 0
Apache::Session::Lock::File::acquire_write_lock(undef,
'Apache::Session::DB_File=HASH(0x8685290)') called at
/usr/lib/perl5/site_perl/5.005/Apache/Session.pm line 562
Apache::Session::acquire_write_lock('Apache::Session::DB_File=HASH(0x8685290)')
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm
line 490
Apache::Session::save('Apache::Session::DB_File=HASH(0x8685290)')
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm
line 455
Apache::Session::DESTROY('Apache::Session::DB_File=HASH(0x8685290)')
called at /dev/null line 0
eval {...} called at /dev/null line 0
DESTROY: Open = 0 Write = 0 Read = 0 during global
destruction.
Apache::Session::Lock::File::DESTROY('Apache::Session::Lock::File=HASH(0x8670cf4)')
called at /dev/null line 0
eval {...} called at /dev/null line 0
Apache::Session::Lock::File::acquire_write_lock(undef,
'Apache::Session::DB_File=HASH(0x8685290)') called at
/usr/lib/perl5/site_perl/5.005/Apache/Session.pm line 562
Apache::Session::acquire_write_lock('Apache::Session::DB_File=HASH(0x8685290)')
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm
line 490
Apache::Session::save('Apache::Session::DB_File=HASH(0x8685290)')
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm
line 455
Apache::Session::DESTROY('Apache::Session::DB_File=HASH(0x8685290)')
called at /dev/null line 0
eval {...} called at /dev/null line 0
thanks!
Todd