misc: fix locking in clean_sessions (#47127)

This commit is contained in:
Benjamin Dauvergne 2020-09-29 15:01:41 +02:00
parent b8ba687a2e
commit 342ab5251d
1 changed files with 29 additions and 34 deletions

View File

@ -588,42 +588,37 @@ class QommonPublisher(Publisher, object):
def clean_sessions(self):
cleaning_lock_file = os.path.join(self.app_dir, 'cleaning_sessions.lock')
fd = os.open(cleaning_lock_file, os.O_RDONLY | os.O_CREAT, 0o666)
try:
fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError:
# lock is currently held, that is fine.
return
try:
manager = self.session_manager_class(session_class=self.session_class)
now = time.time()
last_usage_limit = now - 3*86400
creation_limit = now - 30*86400
for session_key in manager.keys():
try:
session = manager.get(session_key)
if session._access_time < last_usage_limit or session._creation_time < creation_limit:
del manager[session.id]
except (AttributeError, KeyError):
# the key is impossible to load or the session is malformed
# delete it anyway, but only catch KeyError (other errors could be useful)
with locket.lock_file(cleaning_lock_file, timeout=0):
manager = self.session_manager_class(session_class=self.session_class)
now = time.time()
last_usage_limit = now - 3*86400
creation_limit = now - 30*86400
for session_key in manager.keys():
try:
del manager[session_key]
except KeyError:
pass
continue
# also delete obsolete form_tokens that would have be missed when
# cleaning sessions.
form_tokens_dir = self.form_tokens_dir
if os.path.exists(form_tokens_dir):
for filename in os.listdir(form_tokens_dir):
try:
if os.stat(os.path.join(form_tokens_dir, filename)).st_mtime < creation_limit:
os.unlink(os.path.join(form_tokens_dir, filename))
except FileNotFoundError:
pass
finally:
os.close(fd)
session = manager.get(session_key)
if session._access_time < last_usage_limit or session._creation_time < creation_limit:
del manager[session.id]
except (AttributeError, KeyError):
# the key is impossible to load or the session is malformed
# delete it anyway, but only catch KeyError (other errors could be useful)
try:
del manager[session_key]
except KeyError:
pass
continue
# also delete obsolete form_tokens that would have be missed when
# cleaning sessions.
form_tokens_dir = self.form_tokens_dir
if os.path.exists(form_tokens_dir):
for filename in os.listdir(form_tokens_dir):
try:
if os.stat(os.path.join(form_tokens_dir, filename)).st_mtime < creation_limit:
os.unlink(os.path.join(form_tokens_dir, filename))
except FileNotFoundError:
pass
except locket.LockError:
pass
def clean_afterjobs(self):
now = time.time()