[PHP] Garbage collection and strange session behaviour

2006-06-04 Thread BNR - IT Department
Hi,
Here is a simple script:

? // BEGIN OF A SCRIPT
/* #1 */ ini_set('session.gc_maxlifetime', '3');
/* #2 */ ini_set('session.gc_probability',1);
/* #3 */ ini_set('session.gc_divisor',1);
/* #4 */ sleep(5);
/* #5 */ session_start();

$sessvar = empty;
if (!isset($_SESSION['a_sess_string'])) { /* #6 */
/* #7 */ $_SESSION['a_sess_string']= abcd;
/* #8 */ echo This is a newly created session, so we put a fresh
variable in it!;
} else {
$sessvar = $_SESSION['a_sess_string'];
/* #9 */ print(We have sessvar = '.$sessvar.' here, so - Is the
session OK??? Maybe, but the session file '/tmp/sess_?' has been
deleted!);
}
/* #10 */ print(br.session_id(). -that's our session id, hmmm);
? // END OF A SCRIPT

The lines from #1 to #3 intentionally set these parameters to the garbage 
collector just to speed up the results of the problem.
#4 - we're sleeping 

So, after first run we have: after #5 - a new session, #7 puts a variable 
in the session and #8 tells us about that.
After #5 we also have the session file /tmp/sess_? written out
there anywhere.

On second run after #5 (we've been sleeping enough on #4 to have our
session announced old, ...dead-man-walking... - quotation from 'The
Green Mile' movie), the gc-monster is awaken and hungry for eating old
session files. Finally we have the session file /tmp/sess_? deleted 
by the garbage collector after #5.
That's guaranteed by #1 - #4.

[If we put another 'sleep' after /* #5 */session_start(),
we may have time to switch to '/tmp' directory and persuade ourselves
that there is no session file any more after the execution of #5.]

No session file - no session variables anymore, no session at all???
WRONG ANSWER!
We are sent to the 'else' clause, so $_SESSION['a_sess_string] is set
and alive , and its value - additionally - is the one before the session
file has gone (deleted) - abcd in my example.

Obviously 'session_start()' first fills all of the sesion variables into
memory, and after that shoots the garbage collector to go to finish its
cleaning work. The session file is deleted, but inside the session, in
our script, we are not acquainted with that... Until the end of script we 
are happy that everything is all right, but probably this self-confidence 
could lead us to some troubles later.

Is there a workaround? Without going to the file system to check if the
file still exists? A smart and elegant PHP session way, without any
if-file-exists-checking functions?

P.S. (To the administrators/moderators/whatever of this mailing list) - Please 
tell the people - write it somewhere on http://www.php.net/mailing-lists.php - 
that there is no chance to get subscribed if they are using any public mail 
address like @yahoo.com. It took me 2 days, I struggled like a pig with a 
pumpkin to find out...

-
Bulgarian National Radio
IT Department
(+359 2) 9336 615
BNR - Sofia, Bulgaria

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Garbage collection and strange session behaviour

2006-06-04 Thread Rasmus Lerdorf
Are you actually hitting this race condition in the real world?  With a 
decently long maxlifetime setting I can't really see this being a 
realistic problem.  Remember the timer is reset on every access.


-Rasmus

BNR - IT Department wrote:

Hi,
Here is a simple script:

? // BEGIN OF A SCRIPT
/* #1 */ ini_set('session.gc_maxlifetime', '3');
/* #2 */ ini_set('session.gc_probability',1);
/* #3 */ ini_set('session.gc_divisor',1);
/* #4 */ sleep(5);
/* #5 */ session_start();

$sessvar = empty;
if (!isset($_SESSION['a_sess_string'])) { /* #6 */
/* #7 */ $_SESSION['a_sess_string']= abcd;
/* #8 */ echo This is a newly created session, so we put a fresh
variable in it!;
} else {
$sessvar = $_SESSION['a_sess_string'];
/* #9 */ print(We have sessvar = '.$sessvar.' here, so - Is the
session OK??? Maybe, but the session file '/tmp/sess_?' has been
deleted!);
}
/* #10 */ print(br.session_id(). -that's our session id, hmmm);
? // END OF A SCRIPT

The lines from #1 to #3 intentionally set these parameters to the garbage 
collector just to speed up the results of the problem.

#4 - we're sleeping 

So, after first run we have: after #5 - a new session, #7 puts a variable 
in the session and #8 tells us about that.

After #5 we also have the session file /tmp/sess_? written out
there anywhere.

On second run after #5 (we've been sleeping enough on #4 to have our
session announced old, ...dead-man-walking... - quotation from 'The
Green Mile' movie), the gc-monster is awaken and hungry for eating old
session files. Finally we have the session file /tmp/sess_? deleted 
by the garbage collector after #5.

That's guaranteed by #1 - #4.

[If we put another 'sleep' after /* #5 */session_start(),
we may have time to switch to '/tmp' directory and persuade ourselves
that there is no session file any more after the execution of #5.]

No session file - no session variables anymore, no session at all???
WRONG ANSWER!
We are sent to the 'else' clause, so $_SESSION['a_sess_string] is set
and alive , and its value - additionally - is the one before the session
file has gone (deleted) - abcd in my example.

Obviously 'session_start()' first fills all of the sesion variables into
memory, and after that shoots the garbage collector to go to finish its
cleaning work. The session file is deleted, but inside the session, in
our script, we are not acquainted with that... Until the end of script we 
are happy that everything is all right, but probably this self-confidence 
could lead us to some troubles later.


Is there a workaround? Without going to the file system to check if the
file still exists? A smart and elegant PHP session way, without any
if-file-exists-checking functions?

P.S. (To the administrators/moderators/whatever of this mailing list) - Please 
tell the people - write it somewhere on http://www.php.net/mailing-lists.php - 
that there is no chance to get subscribed if they are using any public mail 
address like @yahoo.com. It took me 2 days, I struggled like a pig with a 
pumpkin to find out...

-
Bulgarian National Radio
IT Department
(+359 2) 9336 615
BNR - Sofia, Bulgaria



--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php