Ticket #3504: db_pool_timeout-r3868.patch
| File db_pool_timeout-r3868.patch, 6.2 KB (added by cboos, 6 years ago) |
|---|
-
trac/db/api.py
17 17 import os 18 18 import urllib 19 19 20 from trac.config import Option 20 from trac.config import Option, FloatOption 21 21 from trac.core import * 22 22 from trac.db.pool import ConnectionPool 23 23 … … 57 57 [wiki:TracEnvironment#DatabaseConnectionStrings string] for this 58 58 project""") 59 59 60 timeout = FloatOption('trac', 'timeout', '20.0', 61 """Timeout value for database connection, in seconds. 62 Use '0' to specify ''no timeout''. ''(Since 0.11)''""") 63 60 64 def __init__(self): 61 65 self._cnx_pool = None 62 66 … … 68 72 if not self._cnx_pool: 69 73 connector, args = self._get_connector() 70 74 self._cnx_pool = ConnectionPool(5, connector, **args) 71 return self._cnx_pool.get_cnx( )75 return self._cnx_pool.get_cnx(self.timeout or None) 72 76 73 77 def shutdown(self, tid=None): 74 78 if self._cnx_pool: -
trac/db/pool.py
79 79 break 80 80 except Exception: 81 81 cnx.close() 82 self._cursize -= 1 82 83 elif self._maxsize and self._cursize < self._maxsize: 83 84 cnx = self._connector.get_connection(**self._kwargs) 84 85 self._cursize += 1 85 86 break 86 87 else: 87 88 if timeout: 89 if (time.time() - start) >= timeout: 90 raise TimeoutError('Unable to get database ' 91 'connection within %d seconds' 92 % timeout) 88 93 self._available.wait(timeout) 89 if (time.time() - start) >= timeout: 90 raise TimeoutError, 'Unable to get database ' \ 91 'connection within %d seconds' \ 92 % timeout 93 else: 94 else: # Warning: without timeout, Trac *might* hang 94 95 self._available.wait() 95 96 self._active[tid] = [1, cnx] 96 97 return PooledConnection(self, cnx, tid) … … 116 117 # Note: self._available *must* be acquired 117 118 if tid in self._active: 118 119 cnx = self._active.pop(tid)[1] 119 if cnx not in self._dormant: # hm, how could that happen? 120 if cnx.poolable: # i.e. we can manipulate it from other threads 121 cnx.rollback() 122 self._dormant.append(cnx) 123 elif tid == threading._get_ident(): 124 cnx.rollback() # non-poolable but same thread: close 125 cnx.close() 126 self._cursize -= 1 127 else: # non-poolable, different thread: push it back 128 self._active[tid] = [0, cnx] 129 self._available.notify() 120 assert cnx not in self._dormant 121 if cnx.poolable: # i.e. we can manipulate it from other threads 122 cnx.rollback() 123 self._dormant.append(cnx) 124 elif tid == threading._get_ident(): 125 cnx.rollback() # non-poolable but same thread: close 126 cnx.close() 127 self._cursize -= 1 128 else: # non-poolable, different thread: push it back 129 self._active[tid] = [0, cnx] 130 return # no need to notify other threads 131 self._available.notify() 130 132 131 133 def shutdown(self, tid=None): 132 134 self._available.acquire() -
trac/config.py
25 25 from trac.core import ExtensionPoint, TracError 26 26 from trac.util import sorted, to_unicode 27 27 28 __all__ = ['Configuration', 'Option', 'BoolOption', 'IntOption', 'ListOption', 28 __all__ = ['Configuration', 'Option', 29 'BoolOption', 'IntOption', 'FloatOption', 'ListOption', 29 30 'ExtensionOption', 'OrderedExtensionsOption', 'ConfigurationError', 30 31 'default_dir'] 31 32 … … 89 90 """ 90 91 return self[section].getint(name, default) 91 92 93 def getfloat(self, section, name, default=None): 94 """Return the value of the specified option as a floating number. 95 96 If the specified option can not be converted to an integer, a 97 `ConfigurationError` exception is raised. 98 99 (since Trac 0.11) 100 """ 101 return self[section].getfloat(name, default) 102 92 103 def getlist(self, section, name, default=None, sep=',', keep_empty=False): 93 104 """Return a list of values that have been specified as a single 94 105 comma-separated option. … … 261 272 except ValueError: 262 273 raise ConfigurationError('expected integer, got %s' % repr(value)) 263 274 275 def getfloat(self, name, default=None): 276 """Return the value of the specified option as a floating number. 277 278 If the specified option can not be converted to a float, a 279 `ConfigurationError` exception is raised. 280 """ 281 value = self.get(name, default) 282 if value == '': 283 return default 284 try: 285 return float(value) 286 except ValueError: 287 raise ConfigurationError('expected float, got %s' % repr(value)) 288 264 289 def getlist(self, name, default=None, sep=',', keep_empty=True): 265 290 """Return a list of values that have been specified as a single 266 291 comma-separated option. … … 346 371 """Descriptor for integer configuration options.""" 347 372 accessor = Section.getint 348 373 374 class FloatOption(Option): 375 """Descriptor for floating-point numbers configuration options.""" 376 accessor = Section.getfloat 349 377 350 378 class ListOption(Option): 351 379 """Descriptor for configuration options that contain multiple values
