Mercurial > p > roundup > code
changeset 7080:dd15c307c409
bug: fix undefined symbol in exception; limit session update time
Managed to get Redis session update pipeline to fail an update
requiring retry. So exception code redis.Exceptions... got executed,
except its supposed to be redis.exceptions.
Improved error reporting in case where session update fails after
three retries.
updateTimestamp now only updates if old session timestamp was updated
more the 60 seconds ago. Same as other backends. This should reduce
write load on the backend server.
Also spelling fixes and clarification in comments, flake8 fixes.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Fri, 25 Nov 2022 23:16:00 -0500 |
| parents | b34d1808b0aa |
| children | f918351a0fe6 |
| files | roundup/backends/sessions_redis.py |
| diffstat | 1 files changed, 26 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/roundup/backends/sessions_redis.py Fri Nov 25 22:25:17 2022 -0500 +++ b/roundup/backends/sessions_redis.py Fri Nov 25 23:16:00 2022 -0500 @@ -18,7 +18,9 @@ """ __docformat__ = 'restructuredtext' -import marshal, redis, time +import marshal +import redis +import time from roundup.anypy.html import html_escape as escape @@ -177,22 +179,31 @@ try: # assume this works or raises an WatchError # exception indicating I need to retry. - # Since this is not a transaction, an error + # Since this is not a real transaction, an error # in one step doesn't roll back other changes. # so I again ignore the return codes as it is not # clear that I can do the rollback myself. # Format and other errors (e.g. expireat('d', 'd')) - # raise exceptions tht bubble up and result in mail + # raise exceptions that bubble up and result in mail # to admin. transaction.execute() break - except redis.Exceptions.WatchError: + except redis.exceptions.WatchError: self.log_info( _('Key %(key)s changed in %(name)s db' % {"key": escape(infoid), "name": self.name}) ) else: - raise Exception(_("Redis set failed afer 3 retries")) + try: + username = values['user'] + except KeyError: + username = "Not Set" + + raise Exception( + _("Redis set failed after %(retries)d retries for " + "user %(user)s with key %(key)s") % { + "key": escape(infoid), "retries": _retry, + "user": username}) def list(self): return list(self.redis.keys(self.makekey('*'))) @@ -214,18 +225,17 @@ return time.time() + (key_lifetime or self.default_lifetime) def updateTimestamp(self, sessid): - ''' Other backends update only if timestamp would change by more - than 60 seconds. To do this in redis requires: - get data _timestamp - calculate if update needed - if needed, - set new timestamp - why bother. Just set and forget. + ''' Even Redis can be overwhelmed by multiple updates, so + only update if old session key is > 60 seconds old. ''' - # no need to do timestamp calculations - lifetime = self.lifetime() - # note set also updates the expireat on the key in redis - self.set(sessid, __timestamp=lifetime) + sess = self.get(sessid, '__timestamp', None) + now = time.time() + # unlike other session backends, __timestamp is not set to now + # but now + lifetime. + if sess is None or now > sess + 60 - self.default_lifetime: + lifetime = self.lifetime() + # note set also updates the expireat on the key in redis + self.set(sessid, __timestamp=lifetime) def clean(self): ''' redis handles key expiration, so nothing to do here.
