-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Add session_gc() #1852
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add session_gc() #1852
Conversation
Perform GC and return number of deleted sessions */ | ||
static PHP_FUNCTION(session_gc) | ||
{ | ||
zend_long nrdels; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does this means? maybe a simple num
is better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine with me. I'm using nrdels because the name is used for "number of deleted sessions" in the code.
|
||
/* GC must be done before reading session data. */ | ||
if ((PS(mod_data) || PS(mod_user_implemented)) && PS(gc_probability) > 0) { | ||
int nrdels = -1; | ||
|
||
if (immediate) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this beat the point of checking gc_probability
? If so, shouldn't it be outside of the previous if()
condition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, this looks wrong. If you want immediate cleanup, no reason to check probability. Better would be to split the check and cleanup into separate functions and call the latter directly when you need unconditional cleanup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right it does not needed at all. I'll fix it later :)
} | ||
|
||
if (PS(session_status) != php_session_active) { | ||
php_error_docref(NULL, E_WARNING, "Session is not active"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why you need session to be active for GC to happen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because save handler must be activated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How so? And can't that be changed?
IMO it's an ugly hack if I have to call session_start()
from inside a cronjob.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
session_gc() handler is defined in save handlers. Unless save handler storage is initialized, gc function won't work.
If you don't like stray sessions by cron tasks, you can use static session ID for the task.
e.g.
However, since this is C code, I can write code that open, gc, close session. In this case, session must be inactive. Otherwise, I'll destroy save handler data structure.
If above code is written. GC cron tack code would be
Modules should do more work rather than users. I'll implement it. Is this satisfactory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arfbg Andrey, if above code is written
session_start();
session_gc(); // won't work
There may be users write
session_gc();
session_start();
though ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can still check if the session is already active and don't call close()
if that's the case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may work with many save handlers, but I cannot control how 3rd party/user save handlers are implemented. It's risky. Taking risk does not worth, IMO. I've probably seen too many unexpected usages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pseudo-code:
if (session_status() === PHP_SESSION_ACTIVE)
{
$sessionHandler->gc();
}
else
{
$sessionHandler->open();
$sessionHandler->gc();
$sessionHandler->close();
}
How can that be a problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Static session ID" hack looks very ugly. If we need init happen before we run GC, we should hide it from the user, instead of requiring them to write boilerplate code that makes absolutely no sense for them ("why I need to start dummy session to just run GC?!")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll document "session_gc() is supposed to be called from periodical task manager such as cron".
IMHO, users shouldn't care extra new session ID created by session_gc() because many useless session IDs are created by cookie disabled browsers anyway, for example.
@@ -485,19 +485,24 @@ PHPAPI int php_session_valid_key(const char *key) /* {{{ */ | |||
/* }}} */ | |||
|
|||
|
|||
static void php_session_gc(void) /* {{{ */ | |||
static zend_long php_session_gc(zend_bool immediate) /* {{{ */ | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why zend_long here, and lots of casting below...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PHP 7 and up uses zend_long and I would like to get zend_long return value for "num of deleted session" from 3rd party handler in the future.
It could be int for now. If you insist, I don't mind at all using int here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in that case, why you don't use zend_long num? I don't care about zend_long or int, just seems a little ugly you are doing casting without a good reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree casting is ugly.
I'll simply use zend_long. I'll commit changes soon. Please review.
BTW, sorry for the delay. I didn't see notification mails...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated patch so that it can simply use zend_long.
User handlers are modified to be able to return LONG or BOOL. User GC functions are supposed to be implemented just like 3rd party C save handlers by returning LONG (0 > for number of deleted session, negative number of errors). FALSE is treated as negative num of deleted sessions. TRUE is treated as 1. Since return value of user handler should not be used by user code, there is no BC.
NOTE: Negative number is used to indicate GC errors for a long time. (IIRC, it's since session module was introduced)
…to master-rfc-session-gc
merged to PHP-7.1 and master branches |
This PR is for RFC
https://wiki.php.net/rfc/session-gc