Re: Sessions not destroyed

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hendrik Schmieder wrote:

Graham Cossey schrieb:

[snip]


If you are right, then this is a severe design bug.

Depends on your point of view. It is a sideeffect of loading current session (and thus accessing it) before the session gc is called.

So the question is, should the session module give up on current session
just because it should have been garbaged, even if the session file
still exists?


Apologies if I'm way off here, but I'm relatively new to PHP.

Surely it should be down to settings in php.ini, not a point of view or the
probability of the garbage collection possibly having run when a new session
is started. Why can there not be a session_timeout value that is adhered to?
Would it not also save everyone from writing their own code to determine
whether or not they should be using the session that PHP is making
available?


If my site is accessed by few users and I have a session 'timeout' of
30minutes specified, if Bob leaves his PC at 10:00 I would expect that if he
returned at 10:40, and no-one else had accessed the system, his session
would have expired and he would need to re-authenticate to create a new
session.


Short of writing custom session handlers, the current arrangement seems
somewhat haphazard to me.

Those are my current thoughts anyway.

Graham



Graham,

that's also my point.
Unfortunately this isn't happening.
Bob can work on as he never left his PC.

Hendrik


Ok, I think you're all missing a few points here...

First of all,
every time a session is started/accessed/written to/whatever, PHP makes a check, it calculates , using gc_probability/gc_divisor, if it should run the gc (Garbage Collector) on this call or not. If it should, then it checks which sessions are expired, and those that are, are deleted. If the one the user just activated was one of those, then the session is reinstated, as a NEW (blank) session.


The reason for the gc being called with a CHANCE is that when you have 50 people/min visiting your site (that's a bit less than 1 hit/sec), you're calling the Grabage Collector once EVERY SECOND. The garbage collector is pretty slow, especially when many sessions are open, because it needs a lot of filesystem info.

So, instead of calling it with every hit, it's called less, only gc_probability/gc_divisor of those times.

The Garbage collector works on ACCESS TIMES for files, so if you have a sessions lifetime of 5 min, and someone revisits in 4 min. Then the session will last at LEAST another 5 min (and theoretically more as long as the garbage collector isn't ran).

Imagine our situation again. If you have 1hit/sec, and gc_probability=1 and gc_divisor=100, then these are the chances the GC hasn't been run yet:
1 sec: 99%
2 secs: 98.01%
3 secs: 97.0299%
4 secs: 96.059601%
5 secs: 95.09900499%
...
10 secs: 90.438207500880449001%
...
20 secs: ??
...
30 secs: 73.970037338828042273001509231671%
...
40 secs: 66.897175856968051393833859880371%
...
50 secs: 60.500606713753665044791996801256%
...
60 secs: 54.715664239076147619474137084001%


So, after 1 min, you have a 50% chance that the GC has been called at LEAST once. This is a logaritmic equation (1-1/100)^n (n being the amount of secs; making log(n/100)/log(99/100) = secs (n being the chance you want in percent)). This means that after 7 min 38, you have only a 1% chance left that the GC hasn't been ran yet! After 1 hour, this is as far down as 0.000000000000019% !!

Right, back to the point. The higher the hitrate, the lower a gc_probability you need to get the garbage collected regularly. Doubling the amount of users means that you'll have the same chance in a bit LESS than half that time aswell.

Now, in your case, only 1 user every HOUR visits... this means your garbage is collected really really sparsely! Setting a high divisor and probability would be useful for you :)

Ok, so far so good, now the reason why sessions aren't removed automatically without the need to visit the site. The reason is very simple.
PHP works as a "daemon" type of application. It does not, and can not, run on its own initiative :) It either runs all the time, or it does not run till someone starts it.
Having a continuous PHP app running in the background is not very efficient, and thus the only (easy) way to get it to be cleaned is to do it when PHP is running, and thus when a user visits the server.


Please note, it doesn't matter what SITE the user visits for the gc to be ran!! As long as the php engine used is the same on the same machine ;) (and a session is started/written to/called/whatever).

Ok, after that long explenation (which hopefully everyone could follow), I still wouldn't know the answer to the original question (*sighs*). Oh well...

- Tul

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


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux