[RFC][Discussion] Add session_gc()

php.internals

Yasuo Ohgaki

10 years ago
Hi all, This is very old RFC that adds session_gc(). https://wiki.php.net/rfc/session-gc It simply adds missing session_gc() function. Comments are appreciated. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Andrey Andreev

10 years ago
Hi, On Thu, Apr 7, 2016 at 9:05 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
> Hi all, > > This is very old RFC that adds session_gc(). > https://wiki.php.net/rfc/session-gc > > It simply adds missing session_gc() function. > Comments are appreciated. > >
There are a few question marks raised by the RFC's (lack of) content ... 1. How exactly does the function work? I can see that in the patch, but it should be explained in the RFC too .. even the function signature is missing. 2. What happens if SessionHandler::gc() was triggered by the probability mechanism, but you then call session_gc() manually? It seems odd that you've put "Document calling session_gc() periodically is the best practice" in the RFC itself, but are not addressing this issue. IMO, it is more important to document this and here's an idea: trigger at least an E_NOTICE in that case. Speaking of the documentation part - it's not hard to imagine A LOT of people doing this: session_start(); session_gc(); That's not a small problem. 3. If session_gc() bypasses the gc_probability, gc_divisor INI settings*, then why does it still rely on gc_maxlifetime? The signature for SessionHandlerInterface::gc() accepts a TTL value as a parameter; session_gc() can too: function session_gc($ttl = ini_get('session.gc_maxlifetime')) {} * Note: The current patch doesn't actually ignore gc_probability, but I think that's by mistake (also relevant to my previous point). I'll comment on the PR on GitHub. Cheers, Andrey.

Yasuo Ohgaki

10 years ago
Hi Andrey, On Fri, Apr 8, 2016 at 12:12 AM, Andrey Andreev <narf@devilix.net> wrote:
> On Thu, Apr 7, 2016 at 9:05 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote: >> >> Hi all, >> >> This is very old RFC that adds session_gc(). >> https://wiki.php.net/rfc/session-gc >> >> It simply adds missing session_gc() function. >> Comments are appreciated. >> > > There are a few question marks raised by the RFC's (lack of) content ... > > 1. How exactly does the function work? > > I can see that in the patch, but it should be explained in the RFC too .. > even the function signature is missing.
Added
> > 2. What happens if SessionHandler::gc() was triggered by the probability > mechanism, but you then call session_gc() manually?
It should perform GC w/o condition
> > It seems odd that you've put "Document calling session_gc() periodically is > the best practice" in the RFC itself, but are not addressing this issue. > IMO, it is more important to document this and here's an idea: trigger at > least an E_NOTICE in that case. > > Speaking of the documentation part - it's not hard to imagine A LOT of > people doing this: > > session_start(); > session_gc(); > > That's not a small problem.
Shooting their own foot is not our problem, but leaving obsolete and possibly active session is ours.
> > 3. If session_gc() bypasses the gc_probability, gc_divisor INI settings*, > then why does it still rely on gc_maxlifetime?
It's a mistake. I spend too little time for this. This will be fixed.
> > The signature for SessionHandlerInterface::gc() accepts a TTL value as a > parameter; session_gc() can too: > > function session_gc($ttl = ini_get('session.gc_maxlifetime')) {} > > * Note: The current patch doesn't actually ignore gc_probability, but I > think that's by mistake (also relevant to my previous point). I'll comment > on the PR on GitHub.
Good point. Since session module does the job if module should execute GC or not. It should be 1 or very short time. These are addressed soon. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Yasuo Ohgaki

10 years ago
Hi Andrey, On Fri, Apr 8, 2016 at 12:46 PM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
>> >> The signature for SessionHandlerInterface::gc() accepts a TTL value as a >> parameter; session_gc() can too: >> >> function session_gc($ttl = ini_get('session.gc_maxlifetime')) {} >> >> * Note: The current patch doesn't actually ignore gc_probability, but I >> think that's by mistake (also relevant to my previous point). I'll comment >> on the PR on GitHub. > > Good point. > Since session module does the job if module should execute GC or not. > It should be 1 or very short time.
PS(gc_maxlifetime) is needed, so I fixed the last commit. Regards, P.S. I'm having bad cold. So it may be better not to commit a while :(
-- Yasuo Ohgaki yohgaki@ohgaki.net

Andrey Andreev

10 years ago
Hi, On Fri, Apr 8, 2016 at 8:12 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
> Hi Andrey, > > On Fri, Apr 8, 2016 at 12:46 PM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote: > >> > >> The signature for SessionHandlerInterface::gc() accepts a TTL value as a > >> parameter; session_gc() can too: > >> > >> function session_gc($ttl = ini_get('session.gc_maxlifetime')) {} > >> > >> * Note: The current patch doesn't actually ignore gc_probability, but I > >> think that's by mistake (also relevant to my previous point). I'll > comment > >> on the PR on GitHub. > > > > Good point. > > Since session module does the job if module should execute GC or not. > > It should be 1 or very short time. >
I don't understand what you're saying here. Is it that gc_maxlifetime should be 1 second? o.O
> > PS(gc_maxlifetime) is needed, so I fixed the last commit. > >
It is necessary for probability-triggered GC because you don't have another way of giving a TTL value then, but that's not the case for a direct session_gc() call. Cheers, Andrey.

Yasuo Ohgaki

10 years ago
Hi Andrey, On Fri, Apr 8, 2016 at 4:57 PM, Andrey Andreev <narf@devilix.net> wrote:
>> >> PS(gc_maxlifetime) is needed, so I fixed the last commit. >> > > It is necessary for probability-triggered GC because you don't have another > way of giving a TTL value then, but that's not the case for a direct > session_gc() call.
PS(gc_maxlifetime) is not related directly to probability based GC, but it's about which session should be deleted. Save handlers are supposed to delete inactive sessions exceeds PS(gc_maxlifetime) when GC is issued. Save handlers are not suppose to use PS(vars) directly and should use passed TTL parameter. Therefore, the parameter is passed. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Andrey Andreev

10 years ago
Hi, On Fri, Apr 8, 2016 at 11:33 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
> Hi Andrey, > > On Fri, Apr 8, 2016 at 4:57 PM, Andrey Andreev <narf@devilix.net> wrote: > >> > >> PS(gc_maxlifetime) is needed, so I fixed the last commit. > >> > > > > It is necessary for probability-triggered GC because you don't have > another > > way of giving a TTL value then, but that's not the case for a direct > > session_gc() call. > > PS(gc_maxlifetime) is not related directly to probability based GC, > but it's about which session should be deleted. > > Save handlers are supposed to delete inactive sessions exceeds > PS(gc_maxlifetime) when GC is issued. Save handlers are not suppose to > use PS(vars) directly and should use passed TTL parameter. Therefore, > the parameter is passed. > >
It is not directly related to gc_probability it is very obviously the result gc_probability-based design. Still, even if we agree to disagree on that, it's not a blocker for maxlifetime being overridable via a parameter. Cheers, Andrey.

Yasuo Ohgaki

10 years ago
Hi Andrey, On Fri, Apr 8, 2016 at 6:20 PM, Andrey Andreev <narf@devilix.net> wrote:
> On Fri, Apr 8, 2016 at 11:33 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote: >> >> Hi Andrey, >> >> On Fri, Apr 8, 2016 at 4:57 PM, Andrey Andreev <narf@devilix.net> wrote: >> >> >> >> PS(gc_maxlifetime) is needed, so I fixed the last commit. >> >> >> > >> > It is necessary for probability-triggered GC because you don't have >> > another >> > way of giving a TTL value then, but that's not the case for a direct >> > session_gc() call. >> >> PS(gc_maxlifetime) is not related directly to probability based GC, >> but it's about which session should be deleted. >> >> Save handlers are supposed to delete inactive sessions exceeds >> PS(gc_maxlifetime) when GC is issued. Save handlers are not suppose to >> use PS(vars) directly and should use passed TTL parameter. Therefore, >> the parameter is passed. >> > > It is not directly related to gc_probability it is very obviously the result > gc_probability-based design. > > Still, even if we agree to disagree on that, it's not a blocker for > maxlifetime being overridable via a parameter.
We need TTL value and the TTL is gc_maxlifetime. How would you specify session data to be removed? TTL value is mandatory.
-- Yasuo Ohgaki yohgaki@ohgaki.net

Andrey Andreev

10 years ago
Hi, On Fri, Apr 8, 2016 at 12:29 PM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
> Hi Andrey, > > On Fri, Apr 8, 2016 at 6:20 PM, Andrey Andreev <narf@devilix.net> wrote: > > On Fri, Apr 8, 2016 at 11:33 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> > wrote: > >> > >> Hi Andrey, > >> > >> On Fri, Apr 8, 2016 at 4:57 PM, Andrey Andreev <narf@devilix.net> > wrote: > >> >> > >> >> PS(gc_maxlifetime) is needed, so I fixed the last commit. > >> >> > >> > > >> > It is necessary for probability-triggered GC because you don't have > >> > another > >> > way of giving a TTL value then, but that's not the case for a direct > >> > session_gc() call. > >> > >> PS(gc_maxlifetime) is not related directly to probability based GC, > >> but it's about which session should be deleted. > >> > >> Save handlers are supposed to delete inactive sessions exceeds > >> PS(gc_maxlifetime) when GC is issued. Save handlers are not suppose to > >> use PS(vars) directly and should use passed TTL parameter. Therefore, > >> the parameter is passed. > >> > > > > It is not directly related to gc_probability it is very obviously the > result > > gc_probability-based design. > > > > Still, even if we agree to disagree on that, it's not a blocker for > > maxlifetime being overridable via a parameter. > > We need TTL value and the TTL is gc_maxlifetime. > How would you specify session data to be removed? > > TTL value is mandatory. >
I wrote this pseudo-code in my very first reply to this thread ... function session_gc($ttl = ini_get('session.gc_maxlifetime')) {} If that's unclear, here's a more verbose way to put it: function session_gc($ttl = null) { if (empty($ttl)) { $ttl = ini_get('session.gc_maxlifetime'); } // ... } It just gives the ability to override the INI value for those who don't want or need it. Cheers, Andrey.

Yasuo Ohgaki

10 years ago
Hi Andrey, On Fri, Apr 8, 2016 at 6:54 PM, Andrey Andreev <narf@devilix.net> wrote:
> On Fri, Apr 8, 2016 at 12:29 PM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote: >> >> Hi Andrey, >> >> On Fri, Apr 8, 2016 at 6:20 PM, Andrey Andreev <narf@devilix.net> wrote: >> > On Fri, Apr 8, 2016 at 11:33 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> >> > wrote: >> >> >> >> Hi Andrey, >> >> >> >> On Fri, Apr 8, 2016 at 4:57 PM, Andrey Andreev <narf@devilix.net> >> >> wrote: >> >> >> >> >> >> PS(gc_maxlifetime) is needed, so I fixed the last commit. >> >> >> >> >> > >> >> > It is necessary for probability-triggered GC because you don't have >> >> > another >> >> > way of giving a TTL value then, but that's not the case for a direct >> >> > session_gc() call. >> >> >> >> PS(gc_maxlifetime) is not related directly to probability based GC, >> >> but it's about which session should be deleted. >> >> >> >> Save handlers are supposed to delete inactive sessions exceeds >> >> PS(gc_maxlifetime) when GC is issued. Save handlers are not suppose to >> >> use PS(vars) directly and should use passed TTL parameter. Therefore, >> >> the parameter is passed. >> >> >> > >> > It is not directly related to gc_probability it is very obviously the >> > result >> > gc_probability-based design. >> > >> > Still, even if we agree to disagree on that, it's not a blocker for >> > maxlifetime being overridable via a parameter. >> >> We need TTL value and the TTL is gc_maxlifetime. >> How would you specify session data to be removed? >> >> TTL value is mandatory. > > > > I wrote this pseudo-code in my very first reply to this thread ... > > function session_gc($ttl = ini_get('session.gc_maxlifetime')) {} > > If that's unclear, here's a more verbose way to put it: > > function session_gc($ttl = null) > { > if (empty($ttl)) > { > $ttl = ini_get('session.gc_maxlifetime'); > } > > // ... > } > > It just gives the ability to override the INI value for those who don't want > or need it.
I thought you claim that use of gc_maxlifetime is wrong. 3. If session_gc() bypasses the gc_probability, gc_divisor INI settings*, then why does it still rely on gc_maxlifetime? Anyway, you're suggesting session_gc() should have $ttl = ini_get('session.gc_maxlifetime') as the TTL parameter. This sounds reasonable and I'll add optional 1st parameter. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Andrey Andreev

10 years ago
Hi, On Fri, Apr 8, 2016 at 6:46 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
> ,,,
> > > Speaking of the documentation part - it's not hard to imagine A LOT of > > people doing this: > > > > session_start(); > > session_gc(); > > > > That's not a small problem. > > Shooting their own foot is not our problem, but leaving obsolete and > possibly active session is ours. > >
If you want to explicitly document something as a best practice, it IS your problem when users shoot their feet with it. Cheers, Andrey.

Yasuo Ohgaki

10 years ago
Hi Andrey, On Fri, Apr 8, 2016 at 5:02 PM, Andrey Andreev <narf@devilix.net> wrote:
> On Fri, Apr 8, 2016 at 6:46 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote: >> >> ,,, >> >> > >> > Speaking of the documentation part - it's not hard to imagine A LOT of >> > people doing this: >> > >> > session_start(); >> > session_gc(); >> > >> > That's not a small problem. >> >> Shooting their own foot is not our problem, but leaving obsolete and >> possibly active session is ours. >> > > If you want to explicitly document something as a best practice, it IS your > problem when users shoot their feet with it
Lack of proper API for required task is our problem. Misuse is not ours. IMHO. The best way to perform GC would be cron task. Low traffic sites can make sure obsolete session is deleted. High traffic site can avoid occasional slow down by GC. I suppose almost all high traffic sites uses memcached or like that does not require PHP's session GC at all, though. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Andrey Andreev

10 years ago
Hi, On Fri, Apr 8, 2016 at 11:38 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
> Hi Andrey, > > On Fri, Apr 8, 2016 at 5:02 PM, Andrey Andreev <narf@devilix.net> wrote: > > On Fri, Apr 8, 2016 at 6:46 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote: > >> > >> ,,, > >> > >> > > >> > Speaking of the documentation part - it's not hard to imagine A LOT of > >> > people doing this: > >> > > >> > session_start(); > >> > session_gc(); > >> > > >> > That's not a small problem. > >> > >> Shooting their own foot is not our problem, but leaving obsolete and > >> possibly active session is ours. > >> > > > > If you want to explicitly document something as a best practice, it IS > your > > problem when users shoot their feet with it > > Lack of proper API for required task is our problem. Misuse is not ours. > IMHO. >
I understand your POV, but you can't advertise something as a best practice and not warn about mistakes that are easy to make - it would be indecent at the very least. Cheers, Andrey.

Yasuo Ohgaki

10 years ago
Hi Andrey, On Fri, Apr 8, 2016 at 6:24 PM, Andrey Andreev <narf@devilix.net> wrote:
> On Fri, Apr 8, 2016 at 11:38 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote: >> >> Hi Andrey, >> >> On Fri, Apr 8, 2016 at 5:02 PM, Andrey Andreev <narf@devilix.net> wrote: >> > On Fri, Apr 8, 2016 at 6:46 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote: >> >> >> >> ,,, >> >> >> >> > >> >> > Speaking of the documentation part - it's not hard to imagine A LOT >> >> > of >> >> > people doing this: >> >> > >> >> > session_start(); >> >> > session_gc(); >> >> > >> >> > That's not a small problem. >> >> >> >> Shooting their own foot is not our problem, but leaving obsolete and >> >> possibly active session is ours. >> >> >> > >> > If you want to explicitly document something as a best practice, it IS >> > your >> > problem when users shoot their feet with it >> >> Lack of proper API for required task is our problem. Misuse is not ours. >> IMHO. > > > I understand your POV, but you can't advertise something as a best practice > and not warn about mistakes that are easy to make - it would be indecent at > the very least.
We were getting bug reports like "Calling save handler function directly crashes PHP". Many of crash bugs by misuse are fixed, but we have to consider such misuses also. We also have to consider service providers. They should be able to use session_gc() properly and mitigate risk of obsolete session being active again. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Lester Caine

10 years ago
On 08/04/16 09:38, Yasuo Ohgaki wrote:
>> If you want to explicitly document something as a best practice, it IS your >> > problem when users shoot their feet with it > Lack of proper API for required task is our problem. Misuse is not ours. IMHO. > > The best way to perform GC would be cron task. Low traffic sites can > make sure obsolete session is deleted. High traffic site can avoid > occasional slow down by GC. I suppose almost all high traffic sites > uses memcached or like that does not require PHP's session GC at all, > though.
Changes to 'defaults' on session handling, and other processes 'improving security' in that area have been a source of problems on many of my sites, so establishing a proper practice would be nice. Many of my sites involve people starting a session at the start of an interview process and the session holds that interview point locked until finished and for complex interviews this can be a couple of hours. Some staff will forget to 'log out' and then the next person kicks them off with a message, or the unfinished sessions get wiped over night. But ideally the interview times get logged accurately, something that becomes a problem when something else terminates the session early. Am I doing anything wrong using sessions in this way and expecting it to work? I have also been 'caught out' by time-outs which seem to be too short on other internet services. They tend to get a complaint when I've spent time putting data together only to find the session has been terminated - and all the data entred is lost! Handling this type of problem is another area where forcing defaults for a mistaken security improvement needs to be handled while looking at the wider context?
-- Lester Caine - G8HFL ----------------------------- Contact - http://lsces.co.uk/wiki/?page=contact L.S.Caine Electronic Services - http://lsces.co.uk EnquirySolve - http://enquirysolve.com/ Model Engineers Digital Workshop - http://medw.co.uk Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

Stas Malyshev

10 years ago
Hi!
> Lack of proper API for required task is our problem. Misuse is not ours. IMHO.
No, it is our problem. We can't just create whatever and throw it over the fence. The properly designed API has to make correct use very easy and incorrect use very hard. That's the point of designing the API, not just giving people means to run random pieces of C code from PHP. With that in mind, the API should be designed so that misuse - especially unintentional misuse - is hard. Not impossible - that we can't do - but hard. It *is* our responsibility.
> The best way to perform GC would be cron task. Low traffic sites can > make sure obsolete session is deleted. High traffic site can avoid > occasional slow down by GC. I suppose almost all high traffic sites > uses memcached or like that does not require PHP's session GC at all, > though.
Please be aware that the use case you are currently considering - whatever it is, does not matter - is about 0.001% of all use cases, or less. Just because PHP runs on millions of sites with wildly different requirements. So we should support big sites, small sites, slow sites, fast sites, etc.
-- Stas Malyshev smalyshev@gmail.com

Yasuo Ohgaki

10 years ago
Hi Stas, On Wed, Apr 13, 2016 at 2:25 AM, Stanislav Malyshev <smalyshev@gmail.com> wrote:
>> Lack of proper API for required task is our problem. Misuse is not ours. IMHO. > > No, it is our problem. We can't just create whatever and throw it over > the fence. The properly designed API has to make correct use very easy > and incorrect use very hard. That's the point of designing the API, not > just giving people means to run random pieces of C code from PHP. > > With that in mind, the API should be designed so that misuse - > especially unintentional misuse - is hard. Not impossible - that we > can't do - but hard. It *is* our responsibility.
I know there are different point views, but I'm against this POV. There _must_ be API that achieves well defined tasks. There are many APIs that do not do this, but I don't think this would be an excuse. There are many examples in security related APIs. Examples are - Database API that lacks basic escape function. Most DB APIs lack "identifier" escape API or even "string literal" escape API. - XPath 1.0 lacks "string literal" escape API at all. I guess the API author's intention is "to avoid misuse of escape API". This approach is proven to create more issues rather than preventing issues. IMHO, there must be API for well defined/mandatory/recommended tasks.
> >> The best way to perform GC would be cron task. Low traffic sites can >> make sure obsolete session is deleted. High traffic site can avoid >> occasional slow down by GC. I suppose almost all high traffic sites >> uses memcached or like that does not require PHP's session GC at all, >> though. > > Please be aware that the use case you are currently considering - > whatever it is, does not matter - is about 0.001% of all use cases, or > less. Just because PHP runs on millions of sites with wildly different > requirements. So we should support big sites, small sites, slow sites, > fast sites, etc.
My proposal is based on previous point of view. All of PHP users _should_ avoid probability based GC whenever it is possible. Why we shouldn't have API that kills custom of probability based usage? Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Stas Malyshev

10 years ago
Hi!
> All of PHP users _should_ avoid probability based GC > whenever it is possible. Why we shouldn't have API that kills > custom of probability based usage?
No, they shouldn't. Just claiming that your favorite use case should fit everybody does not make it so.
-- Stas Malyshev smalyshev@gmail.com

Yasuo Ohgaki

10 years ago
Hi Stas, On Sat, Apr 16, 2016 at 6:38 AM, Stanislav Malyshev <smalyshev@gmail.com> wrote:
> >> All of PHP users _should_ avoid probability based GC >> whenever it is possible. Why we shouldn't have API that kills >> custom of probability based usage? > > No, they shouldn't. Just claiming that your favorite use case should fit > everybody does not make it so.
What's the rationale behind your opinion? I don't see reasonable/logical reasoning. Probability based GC is unreliable and can reactivate very old sessions without "Precise session management RFC" and you opposed the RFC. Reactivating obsoleted/should be deleted session is wrong simply. Why users shouldn't matter? Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Stas Malyshev

10 years ago
Hi!
> Probability based GC is unreliable and can reactivate very old sessions > without "Precise session management RFC" and you opposed the RFC.
You know why I opposed the RFC - because it had huge number of things packed together, some of which I agree with, some of which I disagree and some of which I agree in principle, but would like to do in other ways. I thought that the RFC would be much better to split up, and was arguing so, but you decided it is better to proceed with everything as one package, which is your right as RFC author, but it failed. So now it is time to consider it piece by piece. I think session_gc() would be a good addition, but I oppose the idea that it should be the *only* method of GC. Many sites would have hard time working with this method, either because of not having cron access or not being able to configure it correctly, and would just resort to implementing probabilistic GC anyway, introducing myriad of bugs on the way. And the fact is, for most sites probabilistic GC works nicely. Only sites that have very low traffic and very short session lifetimes would have any issue with probabilistic GC. If you have a site with 10 requests per second, and have GC with probability of 1%, then it is functionally equivalent of doing manual GC once per 10 seconds. Of course, you don't know when exactly, but a) cron doesn't exactly guarantee precise timing either and b) I do not see why it would be so important for a common application if the session is cleaned up after 10 or 12 seconds. There are other questions with regard to old sessions - but those are not very relevant to GC model so I do not discuss them here. We can discuss them separately.
> Reactivating obsoleted/should be deleted session is wrong simply. > Why users shouldn't matter?
I never said "users shouldn't matter", so please do not ascribe it to me. Of course users matter, that's why we are doing all this. The question is how to help them. I appreciate that you think manual GC is superior, and I fully support inclusion of that option into PHP. What I however can not support is to make this the only option, contrary to what worked in PHP for nearly two decades. I want both your opinion and opinions different from yours to be accommodated, and to that goal I propose to support both ways to do GC and let the user choose which one is best for them.
-- Stas Malyshev smalyshev@gmail.com

Andrey Andreev

10 years ago
Hi, On Mon, Apr 18, 2016 at 3:26 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
> > Probability based GC is unreliable and can reactivate very old sessions > without "Precise session management RFC" and you opposed the RFC. > >
While I agree that calling session_gc() on a regular basis is the better option, that doesn't mean probability-based GC is inherently unreliable. The problem you're referring to here is a logical one, not caused by the API, and is easily fixable - we just have to call SessionHandler::gc() before the current session is initialized. That is, before SessionHandler::read(), but after SessionHandler::open(). In fact, I think you've mentioned this before, so it's not like you don't know about it. Cheers, Andrey.

Andrey Andreev

10 years ago
Hi, On Sat, Apr 16, 2016 at 12:15 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
> Hi Stas, > > On Wed, Apr 13, 2016 at 2:25 AM, Stanislav Malyshev <smalyshev@gmail.com> > wrote: > >> Lack of proper API for required task is our problem. Misuse is not > ours. IMHO. > > > > No, it is our problem. We can't just create whatever and throw it over > > the fence. The properly designed API has to make correct use very easy > > and incorrect use very hard. That's the point of designing the API, not > > just giving people means to run random pieces of C code from PHP. > > > > With that in mind, the API should be designed so that misuse - > > especially unintentional misuse - is hard. Not impossible - that we > > can't do - but hard. It *is* our responsibility. > > I know there are different point views, but I'm against this POV. > > There _must_ be API that achieves well defined tasks. There are many APIs > that do not do this, but I don't think this would be an excuse. There are > many > examples in security related APIs. >
I don't believe anybody is questioning the need to introduce this new API. What I am questioning is, at minimum, how it is documented. And that's because you've explicitly stated this in your RFC:
> Document calling session_gc() periodically is the best practice.
If you want to document usage of this new API as the best practice, it would be unfair to the users if you don't also document the caveats that come with it: - That they should NOT e.g. put session_gc() at the top of their front-controllers - That it is ONLY meant to be called by a regularly-executed cron script - That it WILL result in double GC calls if they don't turn off probability-based behavior (and how to do that; based on my observations, the vast majority of users don't know how GC is triggered at all) Documenting these potential problems is the bare minimum to minimize misusage, although I think it's a cop-out. IMO, there should be safe-guards implemented into the function itself: - Trigger warnings when session_gc() is called while gc_probability is not 0. - To avoid re-activating expired sessions, trigger warnings when session_gc() is called after session_start() ... and possibly skip GC execution in these cases. Cheers, Andrey.

Stas Malyshev

10 years ago
Hi!
>> Document calling session_gc() periodically is the best practice. > > If you want to document usage of this new API as the best practice, it > would be unfair to the users if you don't also document the caveats that > come with it:
I also think it's wrong to document it so. While having periodical GC is the best practice, probabilistic GC *is* calling GC periodically. True, for some exceptional scenarios - like sites with very low traffic - the period is unpredictable. And *then* it's recommended to explicitly call session_gc(), and for these cases it is a great addition. But in a typical medium or high traffic site the period is very predictable as as such there's no way to document otherwise.
> probability-based behavior (and how to do that; based on my > observations, the vast majority of users don't know how GC is triggered > at all)
And that's great BTW since majority of users don't need to know that - it just works. We shouldn't ruin that.
> - Trigger warnings when session_gc() is called while gc_probability is > not 0.
This does not sound like a good idea to me. Why we should make it harder for people to use it together? session_gc() has nothing to do with gc_probability.
> - To avoid re-activating expired sessions, trigger warnings when > session_gc() is called after session_start()
Last time I've looked at the patch, session_gc() was required to be called after session start. See: https://github.com/php/php-src/pull/1852/files#diff-2e4264d70a35458a2241e27f76f4a93cR20 I think this is wrong (see my comments there) and in fact we should not expose this complexity to the user - gc() should just do the GC and hide the technical details.
-- Stas Malyshev smalyshev@gmail.com

Yasuo Ohgaki

10 years ago
Hi Stas, On Tue, Apr 19, 2016 at 3:55 AM, Stanislav Malyshev <smalyshev@gmail.com> wrote:
>>> Document calling session_gc() periodically is the best practice. >> >> If you want to document usage of this new API as the best practice, it >> would be unfair to the users if you don't also document the caveats that >> come with it: > > I also think it's wrong to document it so. While having periodical GC is > the best practice, probabilistic GC *is* calling GC periodically. True, > for some exceptional scenarios - like sites with very low traffic - the > period is unpredictable. And *then* it's recommended to explicitly call > session_gc(), and for these cases it is a great addition. But in a > typical medium or high traffic site the period is very predictable as as > such there's no way to document otherwise.
Problem of session GC is not only "when GC is performed" but also "GC affects user experience" i.e. Occasional slow response. Therefore, GC is better to be performed by non user process/thread. IMHO. Exceptions are save handlers do not require GC at all. e.g. memcached
> >> probability-based behavior (and how to do that; based on my >> observations, the vast majority of users don't know how GC is triggered >> at all) > > And that's great BTW since majority of users don't need to know that - > it just works. We shouldn't ruin that.
Since we don't have precise session management (yet), users should aware problems in probability based session GC triggered by user requests. Even if we have precise session management, large number of session data will affect user experience with default session storage. i.e. files save handler. BTW, we already have feature that users must remove obsolete session data files. If user uses multi level dir structure for files save handler, files save handler will not remove obsolete session data at all. PS_GC_FUNC(files) { PS_FILES_DATA; /* we don't perform any cleanup, if dirdepth is larger than 0. we return SUCCESS, since all cleanup should be handled by an external entity (i.e. find -ctime x | xargs rm) */ if (data->dirdepth == 0) { *nrdels = ps_files_cleanup_dir(data->basedir, maxlifetime TSRMLS_CC); } return SUCCESS; }
>> - Trigger warnings when session_gc() is called while gc_probability is >> not 0. > > This does not sound like a good idea to me. Why we should make it harder > for people to use it together? session_gc() has nothing to do with > gc_probability.
session_gc() will have this signature int session_gc(void) // returns number of removed sessions
> >> - To avoid re-activating expired sessions, trigger warnings when >> session_gc() is called after session_start() > > Last time I've looked at the patch, session_gc() was required to be > called after session start. See: > > https://github.com/php/php-src/pull/1852/files#diff-2e4264d70a35458a2241e27f76f4a93cR20 > > I think this is wrong (see my comments there) and in fact we should not > expose this complexity to the user - gc() should just do the GC and hide > the technical details.
I haven't update the patch according to discussion. I'll update the patch soon. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Stas Malyshev

10 years ago
Hi!
> This is very old RFC that adds session_gc(). > https://wiki.php.net/rfc/session-gc > > It simply adds missing session_gc() function. > Comments are appreciated.
No objections except for "Document calling session_gc() periodically is the best practice" - it should be made clear that it is a practice for the low traffic sites.
-- Stas Malyshev smalyshev@gmail.com