Skip to content

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

Closed
wants to merge 13 commits into from
Closed

Add session_gc() #1852

wants to merge 13 commits into from

Conversation

yohgaki
Copy link
Contributor

@yohgaki yohgaki commented Apr 7, 2016

Perform GC and return number of deleted sessions */
static PHP_FUNCTION(session_gc)
{
zend_long nrdels;
Copy link
Member

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.

Copy link
Contributor Author

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) {
Copy link
Contributor

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?

Copy link
Contributor

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.

Copy link
Contributor Author

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 :)

@smalyshev smalyshev added the RFC label Apr 7, 2016
}

if (PS(session_status) != php_session_active) {
php_error_docref(NULL, E_WARNING, "Session is not active");
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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?

Copy link
Contributor Author

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 ;)

Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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?

Copy link
Contributor

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?!")

Copy link
Contributor Author

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) /* {{{ */
{
Copy link
Member

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...

Copy link
Contributor Author

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.

Copy link
Member

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.

Copy link
Contributor Author

@yohgaki yohgaki Aug 25, 2016

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...

Copy link
Contributor Author

@yohgaki yohgaki Aug 25, 2016

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)

@yohgaki
Copy link
Contributor Author

yohgaki commented Aug 28, 2016

merged to PHP-7.1 and master branches

@yohgaki yohgaki closed this Aug 28, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants