Skip to content
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

Store sessions in database #3165

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from
Open

Store sessions in database #3165

wants to merge 6 commits into from

Conversation

jiru
Copy link
Member

@jiru jiru commented Mar 1, 2025

Solves #3160.

jiru added 6 commits September 4, 2023 12:50
Sessions are currently saved to memcached. The drawback of this setup is that
sessions disappear on reboot or restart of memcached daemon, which makes server
updates not very seamless. Besides, this setup prevents us from invalidating
existing sessions, such as after a password update or user ban.

So we need to store sessions to databse instead. Enters ComboSession,
copied from CakePHP docs [1]. It both reads sessions from memcached
and database, which allows seamless transition from memcached to database
(strictly speaking, from memcached to memcached-assisted database).

Not sure why, but I had to remove PHP-FPM ini session config in order to have
session_set_save_handler() work and get this whole thing to work.

The sessions table schema comes from CakePHP [2].

[1] https://book.cakephp.org/3/en/development/sessions.html#creating-a-custom-session-handler
[2] https://github.com/cakephp/app/blob/d2d6a243a4a975bb89355d083ee2e9fd8315f308/config/schema/sessions.sql
This will allow invalidating sessions for a given user.
Since Cache::gc() returns void, parent::gc() was never called
and garbage collection was never executed.
Sessions are going to pile up in the database, so we need to clean them up regularly.
PHP has a built-in probability-based garbage collector triggered randomly,
the probability equals to session.gc_probability / session.gc_divisor. The downside
of that approach is that some unlucky request will have to do all the cleanup work
for everybody every now and then. By the way, Debian purposely sets the probability
to zero and provides its own garbage collection script (in /usr/lib/php/sessionclean),
but that script is for the built-in file-based session handler that uses
/var/lib/php/sessions by default. Since we use a custom session handler,
here is a custom cleanup script, which should work for any CakePHP app in theory.
localhost resolves to both ::1 and 127.0.0.1, but our memcached is configured
to only listen on IPv4. As a result, when using localhost as value for host,
CakePHP tries connecting to ::1 first, which fails, and then tries connecting
to 127.0.0.1. This commits avoids the unnecessary connection to ::1.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant