How to trigger session deletion automatically after it expires?

Question:

I need to delete expired sessions from database.

Similar Stack Overflow threads seem to suggest introducing a scheduled task (cron, Celery etc.) to run a check on expired sessions and delete them.

However, I want to avoid introducing heavy stack for such simple task and am looking for a “native” way to delete a session from a database AS SOON AS it expires.

So I have a pre_delete signal set on Session model that triggers the deletion if model’s instance is expired. But there is one step remaining: I need Django to run delete on the instance as soon as it expires.

Ideally, I would need a method like

request.session.on_expiry(some_function_that_deletes_a_session_from_db).

Is there a way to do this?

Asked By: barciewicz

||

Answers:

So I have a pre_delete signal set on Session model that triggers the deletion if model’s instance is expired. But there is one step remaining: I need Django to run delete on the instance as soon as it expires.

I am not really following what difference this makes. If the pre_delete signal is fired, it means Django will delete the Session object, so deleting that in the pre_delete signal can only result in an error if I understand it. Furthermore signals are useful, but there are several ways to “bypass” signals through ORM calls. So signals should usually only be used if all else fails.

When cleaning up expired sessions, the removals are done in bulk, and usually it will not run the query. Therefore it might be better to just write a management command that frequently checks what data belongs to a session that no longer exists.

Ideally, I would need a method like

request.session.on_expiry(some_function_that_deletes_a_session_from_db).

The Django framework does not “actively” look to the expiration of a session, it simply checks if the session is expired when it needs that session. There are no triggers on expiring.

You could implement such triggers yourself, for example by each time when a session is created/updated, add some sort of asynchronic function that will run when the expiration date is reached. But that would result in a lot of bookkeeping, and furthermore, if the server is restarted and you did not implement these functions in a persistent manner, these triggers will not exist anymore.

In fact you do not need to introduce a heavy stack at all, it is already there. Indeed: Django has a request.session.clear_expired [Django-doc] function that you can call to clear expired sessions. Furthermore it has constructed a clearsessions method that is a managmenet command, so if you enabled the django.contrib.sessions app, then there is a management command named clearsessions [Django-doc] you can run with:

manage.py clearsessions

It is furthermore usually better to remove sessions in bulk than to delete these individually one at a time, since the load on the database will be lower. You can run this command often if you want to reduce the number of expired sessions.

You can easily write a custom management command [Django-doc]. This is more robust, since if a server restarts, it can still actively look for such files, it is also easy to configure how often it will run, and furthermore by doing this in bulk it might be more efficient.

Answered By: Willem Van Onsem

you may want to use
https://github.com/mobolic/django-session-cleanup
(I did not test it, but it seems fine)

Answered By: am70
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.