2019-08-15 17:07:03 +00:00
|
|
|
# will submit a PR to CherryPy project - if it gets merged we can remove it. ESH 8/15/2019
|
2019-08-16 17:36:50 +00:00
|
|
|
import cherrypy
|
2019-08-15 17:03:51 +00:00
|
|
|
from cherrypy.lib.sessions import RamSession as cpRamSession
|
|
|
|
|
|
|
|
class RamSession(cpRamSession):
|
|
|
|
def clean_up(self):
|
|
|
|
"""Clean up expired sessions."""
|
|
|
|
|
|
|
|
now = self.now()
|
|
|
|
try:
|
2019-08-16 17:18:02 +00:00
|
|
|
cache_items_copy = self.cache.copy().items()
|
|
|
|
except RuntimeError as re:
|
2019-08-15 17:03:51 +00:00
|
|
|
"""Under heavy load, list(self.cache.items()) will occasionally raise this error
|
|
|
|
for large session caches with message "dictionary changed size during iteration"
|
|
|
|
Better to pause the cleanup than to let the cleanup thread die.
|
|
|
|
"""
|
2019-08-16 17:18:02 +00:00
|
|
|
cherrypy.log(f'Runtime Error happened while copying the cache entries: {re}')
|
|
|
|
cherrypy.log('Ref: https://github.com/cherrypy/cherrypy/pull/1804')
|
|
|
|
return
|
|
|
|
|
|
|
|
for _id, (data, expiration_time) in cache_items_copy:
|
|
|
|
if expiration_time <= now:
|
|
|
|
try:
|
|
|
|
del self.cache[_id]
|
|
|
|
except KeyError:
|
|
|
|
pass
|
|
|
|
try:
|
|
|
|
if self.locks[_id].acquire(blocking=False):
|
|
|
|
lock = self.locks.pop(_id)
|
|
|
|
lock.release()
|
|
|
|
except KeyError:
|
|
|
|
pass
|
|
|
|
|
2019-08-15 17:03:51 +00:00
|
|
|
|
|
|
|
# added to remove obsolete lock objects
|
|
|
|
for _id in list(self.locks):
|
|
|
|
locked = (
|
|
|
|
_id not in self.cache
|
|
|
|
and self.locks[_id].acquire(blocking=False)
|
|
|
|
)
|
|
|
|
if locked:
|
|
|
|
lock = self.locks.pop(_id)
|
|
|
|
lock.release()
|