comparison roundup/backends/sessions_dbm.py @ 6823:fe0091279f50

Refactor session db logging and key generation for sessions/otks While I was working on the redis sessiondb stuff, I noticed that log_wanrning, get_logger ... was duplicated. Also there was code to generate a unique key for otks that was duplicated. Changes: creating new sessions_common.py and SessionsCommon class to provide methods: log_warning, log_info, log_debug, get_logger, getUniqueKey getUniqueKey method is closer to the method used to make session keys in client.py. sessions_common.py now report when random_.py chooses a weak random number generator. Removed same from rest.py. get_logger reconciles all logging under roundup.hyperdb.backends.<name of BasicDatabase class> some backends used to log to root logger. have BasicDatabase in other sessions_*.py modules inherit from SessionCommon. change logging to use log_* methods. In addition: remove unused imports reported by flake8 and other formatting changes modify actions.py, rest.py, templating.py to use getUniqueKey method. add tests for new methods test_redis_session.py swap out ModuleNotFoundError for ImportError to prevent crash in python2 when redis is not present. allow injection of username:password or just password into redis connection URL. set pytest_redis_pw envirnment variable to password or user:password when running test.
author John Rouillard <rouilj@ieee.org>
date Sun, 07 Aug 2022 01:51:11 -0400
parents 375d40a9e730
children 39c482e6a246
comparison
equal deleted inserted replaced
6822:5053ee6c846b 6823:fe0091279f50
4 Yes, it's called "sessions" - because originally it only defined a session 4 Yes, it's called "sessions" - because originally it only defined a session
5 class. It's now also used for One Time Key handling too. 5 class. It's now also used for One Time Key handling too.
6 """ 6 """
7 __docformat__ = 'restructuredtext' 7 __docformat__ = 'restructuredtext'
8 8
9 import os, marshal, time, logging, random 9 import marshal, os, random, time
10 10
11 from roundup.anypy.html import html_escape as escape 11 from roundup.anypy.html import html_escape as escape
12 12
13 from roundup import hyperdb 13 from roundup import hyperdb
14 from roundup.i18n import _ 14 from roundup.i18n import _
15 from roundup.anypy.dbm_ import anydbm, whichdb 15 from roundup.anypy.dbm_ import anydbm, whichdb
16 16 from roundup.backends.sessions_common import SessionCommon
17 17
18 class BasicDatabase: 18
19 class BasicDatabase(SessionCommon):
19 ''' Provide a nice encapsulation of an anydbm store. 20 ''' Provide a nice encapsulation of an anydbm store.
20 21
21 Keys are id strings, values are automatically marshalled data. 22 Keys are id strings, values are automatically marshalled data.
22 ''' 23 '''
23 _db_type = None 24 _db_type = None
86 finally: 87 finally:
87 db.close() 88 db.close()
88 89
89 def set(self, infoid, **newvalues): 90 def set(self, infoid, **newvalues):
90 db = self.opendb('c') 91 db = self.opendb('c')
91 timestamp=None 92 timestamp = None
92 try: 93 try:
93 if infoid in db: 94 if infoid in db:
94 values = marshal.loads(db[infoid]) 95 values = marshal.loads(db[infoid])
95 try: 96 try:
96 timestamp = values['__timestamp'] 97 timestamp = values['__timestamp']
145 146
146 # open the database with the correct module 147 # open the database with the correct module
147 dbm = __import__(db_type) 148 dbm = __import__(db_type)
148 149
149 retries_left = 15 150 retries_left = 15
150 logger = logging.getLogger('roundup.hyperdb.backend.sessions')
151 while True: 151 while True:
152 try: 152 try:
153 handle = dbm.open(path, mode) 153 handle = dbm.open(path, mode)
154 break 154 break
155 except OSError as e: 155 except OSError as e:
156 # Primarily we want to catch and retry: 156 # Primarily we want to catch and retry:
157 # [Errno 11] Resource temporarily unavailable retry 157 # [Errno 11] Resource temporarily unavailable retry
158 # FIXME: make this more specific 158 # FIXME: make this more specific
159 if retries_left < 10: 159 if retries_left < 10:
160 logger.warning('dbm.open failed on ...%s, retry %s left: %s, %s'%(path[-15:],15-retries_left,retries_left,e)) 160 self.log_warning(
161 'dbm.open failed on ...%s, retry %s left: %s, %s' %
162 (path[-15:], 15-retries_left, retries_left, e))
161 if retries_left < 0: 163 if retries_left < 0:
162 # We have used up the retries. Reraise the exception 164 # We have used up the retries. Reraise the exception
163 # that got us here. 165 # that got us here.
164 raise 166 raise
165 else: 167 else:
166 # stagger retry to try to get around thundering herd issue. 168 # stagger retry to try to get around thundering herd issue.
167 time.sleep(random.randint(0,25)*.005) 169 time.sleep(random.randint(0, 25)*.005)
168 retries_left = retries_left - 1 170 retries_left = retries_left - 1
169 continue # the while loop 171 continue # the while loop
170 return handle 172 return handle
171 173
172 def commit(self): 174 def commit(self):

Roundup Issue Tracker: http://roundup-tracker.org/