Session handler and garbage collection strange issue

197 views
Skip to first unread message

Domas Sungaila

unread,
Jul 12, 2017, 4:30:32 AM7/12/17
to Fat-Free Framework
I found session handler issue.
I noticed strange session handler behavior:
1. When I want get SESSION value by $f3->get('SESSION') session_start() is called. It's OK.
2. When session_start() is called, first thing is session handler open() method is called. It's OK.
3. After that read() method is called.
4. And finaly starts session garbage collection and destroy all old sessions (I have setted gc to run allways for testing). Why garbage collection starts after read()? I think it must be before read().
5. At the end when trying to save session to DB nothing happens. Current session record from DB is deleted by garbage collection. Session handler tries to update deleted record. And my session is gone. Oh yeah!

FatFree  3.6.1
PHP 5.6.16

ikkez

unread,
Jul 12, 2017, 9:05:54 AM7/12/17
to Fat-Free Framework
Usually the garbage collector is called randomly by PHP. F3 doesn't do anything here, only defines the cleanup method itself for PHP. When you configurated your GC to always wipe everything, then why you wonder that the session is deleted? You use the Cache-bases Session handler, yes?

One could argue that the cache->reset method is not working correctly, or that you haven't set an expiration time for sessions, which could lead your observed behaviour?!

Domas Sungaila

unread,
Jul 12, 2017, 10:26:10 AM7/12/17
to Fat-Free Framework
I'm using SQL session handler. First handler read session from DB (if session was saved before) and then PHP run GC. I confugurated GC to run allways for this issue tesing. So readed session record from DB can be deletted by GC if that session record expire.
Problem 1: I have readed expired session record.
Problem2: when I modifying same session record ant it saves DB it did not saving, becuse SQL UPDATE query trying to update deleted record.
SQL log:
(1.0ms) SET NAMES 'utf8mb4'
(0.0ms) SHOW columns FROM `gk`.`sessions`
(1.0ms) SELECT `session_id`,`data`,`csrf`,`ip`,`agent`,`stamp` FROM `sessions` WHERE session_id='v6ofq22erjob3ouqjqqb4qo745'
(0.0ms) DELETE FROM `sessions` WHERE stamp+30<1499869348;
(1.0ms) UPDATE `sessions` SET `data`='foo|s:4:"bar.";',`stamp`=1499869348 WHERE `session_id`='v6ofq22erjob3ouqjqqb4qo745'

ikkez

unread,
Jul 15, 2017, 10:42:58 AM7/15/17
to Fat-Free Framework
I see your point. so we should probably reset the session and try to reload the currently active record when the GC is calling the cleanup method, right?!

ikkez

unread,
Aug 9, 2017, 5:41:43 AM8/9/17
to Fat-Free Framework
I tried to recreate your issue and came to the following conclusion:

I don't know how you have configurated your php to run the gc all the time, but
"session.gc_probability" should be adjusted.. I've set it equal to "session.gc_divisor"

session.gc_probability = 100
session.gc_divisor     = 100

so there is a chance of 100% that the garbage collection is called.
However, "session.gc_maxlifetime" should be at least as big as your session lifetime (cookie lifetime) or bigger.

If you have F3's "JAR.expire" at 5min but the gc_maxlifetime at 1min, you'll run into the problem you've described above.
After investigating the session handler code, I think that we should not try to fix anything there, because it's more like a php configuration issue than a bug in the framework.
Imagine you load a valid session and in the middle of the code execution the GC deletes your valid session (because gc_maxlifetime < JAR.expire) - we cannot just create a new session or tell your business code that the user isn't logged in anymore, even if you have already passed that check in your controller... that doesn't make any sense to me.
Just set gc_maxlifetime accordingly and it won't delete valid sessions.
Reply all
Reply to author
Forward
0 new messages