I'm a developer working with Anonymous Monk on this prob, here's a more detailed outline of the issue (or at least a specific test which seems to show up an issue which we think is affecting our web app under load):
I have a script, test-sessions.pl, which uses Parallel::ForkManager to send N simultaneous requests to a cgi script, session.pl. It makes one request first to get a sessionID, then uses that sessionID in each of the forked requests. The cgi script, session.pl, writes a unique value into the session representing the incremental request number. If session locking really works, the session should contain all of those unique values at the end, right?
here's a snippet from test-sessions.pl:
my $loop=8;
my $pm = Parallel::ForkManager->new($loop);
my $url = "http://localhost/cgi-bin/session.pl";
my %sessionopts; # must contain same config as apache has
my $sid;
# get sessionID with initial request to session.pl
# ...
for (my $i = 0; $i < $loop; $i++) {
$pm->start and next;
my $wait = int((rand)*3000000);
# pass loop number, random wait time and sessionID in to script
my $content = "count=$i&wait=$wait&sid=$sid";
my $requrl = $url.'?'.$content;
print "sending req $i [$requrl] at ".join(':',gettimeofday)."\n";
my $req = HTTP::Request->new('GET', $requrl);
my $resp2 = $ua->request($req);
$pm->finish;
}
sleep 10; # be sure last req has finished
print "now what is in the session for [$sid]?\n";
my %session;
tie %session, 'Apache::Session::Flex', $sid, {
%sessionopts
};
print "got session data: ".Dumper(\%session)."\n";
and here's a bit from session.pl, the cgi script:
# ...
# extract cgi args from query string
# open session, either using Apache::SessionManager or Apache::Session
+ directly
# ...
usleep($wait); # wait for a few microseconds to simulate real server d
+oing stuff
$session->{'time'} = join('+',gettimeofday);
$session->{'querystring'} = $query;
$session->{'count'} = $count;
my $now = time();
$session->{"$now:$count"} = $count;
warn "got session ".Dumper($session);
So what this does is insert a unique key for each request, based on its time and loop number. Looking at the apache logs, I can see the values getting put into the sessions.
If locking worked correctly, you would expect to see a value for every request once they have all been processed. What I see is something like this:
now what is in the session for [8f13e7d0f1d140f6a1100510c1f82f6a]?
got session data: $VAR1 = {
'count' => '6',
'1098930095:0' => '0',
'time' => '1098930095+468658',
'_session_start' => 1098930095,
'1098930095:6' => '6',
'1098930095:3' => '3',
'_session_id' => '8f13e7d0f1d140f6a1100510c1f82f6a',
'current_uri' => '/cgi-bin/session.pl',
'querystring' => 'count=6&wait=173631&sid=8f13e7d0f1d140f6a1
+100510c1f8
2f6a',
'previous_uri' => '/cgi-bin/session.pl'
};
Some of the requests are in there and some aren't.
If I comment out the usleep in session.pl, it mostly works, but not always. With it in, often only the data from the first and last of the forked requests is in the session once they're all over. This says to me that without the usleep, the session.pl request can be dealt with in as much time as it takes to fork a new perl process, so they mostly happen in serial. With the usleep, the requests overlap and some of them miss out on writing to the session.
I've tested this with Apache::SessionManager and without, using File, MySQL and Semaphore locking, on Fedora core 1 and RedHat 9. The locking is definitely being done, as I can see lockfiles made, sql statements etc. But somehow it doesn't seem to be doing what I expect. Am I expecting the wrong thing?
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.