Expire sessions generated by health checks quickly

The default expiration of sessions is 7 days. With healthchecks run
every few seconds, we quickly have millions of anonymous sessions in
Redis. Allow to define a custom expiration for some sessions and set a
very short one for the monitoring requests.
This commit is contained in:
Guewen Baconnier
2018-01-11 08:24:45 +01:00
committed by jcoux
co-authored by jcoux
parent 3b1a0f4d8e
commit d0afebfa4b
2 changed files with 14 additions and 2 deletions
+9
View File
@@ -19,4 +19,13 @@ class Monitoring(http.Controller):
# queue job, cron, database, ... # queue job, cron, database, ...
headers = {'Content-Type': 'application/json'} headers = {'Content-Type': 'application/json'}
info = {'status': 1} info = {'status': 1}
session = http.request.session
# We set a custom expiration of 1 second for this request, as we do a
# lot of health checks, we don't want those anonymous sessions to be
# kept. Beware, it works only when session_redis is used.
# Alternatively, we could set 'session.should_save = False', which is
# tested in odoo source code, but we wouldn't check the health of
# Redis.
if not session.uid:
session.expiration = 1
return werkzeug.wrappers.Response(json.dumps(info), headers=headers) return werkzeug.wrappers.Response(json.dumps(info), headers=headers)
+5 -2
View File
@@ -39,6 +39,9 @@ class RedisSessionStore(SessionStore):
def save(self, session): def save(self, session):
key = self.build_key(session.sid) key = self.build_key(session.sid)
# allow to set a custom expiration for a session
# such as a very short one for monitoring requests
expiration = session.expiration or self.expiration
if _logger.isEnabledFor(logging.DEBUG): if _logger.isEnabledFor(logging.DEBUG):
if session.uid: if session.uid:
user_msg = "user '%s' (id: %s)" % ( user_msg = "user '%s' (id: %s)" % (
@@ -47,10 +50,10 @@ class RedisSessionStore(SessionStore):
user_msg = "anonymous user" user_msg = "anonymous user"
_logger.debug("saving session with key '%s' and " _logger.debug("saving session with key '%s' and "
"expiration of %s seconds for %s", "expiration of %s seconds for %s",
key, self.expiration, user_msg) key, expiration, user_msg)
if self.redis.set(key, json.dumps(dict(session))): if self.redis.set(key, json.dumps(dict(session))):
return self.redis.expire(key, self.expiration) return self.redis.expire(key, expiration)
def delete(self, session): def delete(self, session):
key = self.build_key(session.sid) key = self.build_key(session.sid)