|
# Excerpt from twisted.enterprise.adbapi.py |
|
# Demonstrates a patch of the __init__ constructor to share threadpools for Twisted |
|
# Confirmed that this actually works |
|
# TODO: benchmark various threadpool sizes |
|
|
|
def __init__(self, dbapiName, *connargs, **connkw): |
|
"""Create a new ConnectionPool. |
|
|
|
Any positional or keyword arguments other than those documented here |
|
are passed to the DB-API object when connecting. Use these arguments to |
|
pass database names, usernames, passwords, etc. |
|
|
|
@param dbapiName: an import string to use to obtain a DB-API compatible |
|
module (e.g. 'pyPgSQL.PgSQL') |
|
|
|
@param cp_min: the minimum number of connections in pool (default 3) |
|
|
|
@param cp_max: the maximum number of connections in pool (default 5) |
|
|
|
@param cp_noisy: generate informational log messages during operation |
|
(default False) |
|
|
|
@param cp_openfun: a callback invoked after every connect() on the |
|
underlying DB-API object. The callback is passed a |
|
new DB-API connection object. This callback can |
|
setup per-connection state such as charset, |
|
timezone, etc. |
|
|
|
@param cp_reconnect: detect connections which have failed and reconnect |
|
(default False). Failed connections may result in |
|
ConnectionLost exceptions, which indicate the |
|
query may need to be re-sent. |
|
|
|
@param cp_good_sql: an sql query which should always succeed and change |
|
no state (default 'select 1') |
|
|
|
@param cp_reactor: use this reactor instead of the global reactor |
|
(added in Twisted 10.2). |
|
@type cp_reactor: L{IReactorCore} provider |
|
""" |
|
|
|
self.dbapiName = dbapiName |
|
self.dbapi = reflect.namedModule(dbapiName) |
|
|
|
if getattr(self.dbapi, 'apilevel', None) != '2.0': |
|
log.msg('DB API module not DB API 2.0 compliant.') |
|
|
|
if getattr(self.dbapi, 'threadsafety', 0) < 1: |
|
log.msg('DB API module not sufficiently thread-safe.') |
|
|
|
reactor = connkw.pop('cp_reactor', None) |
|
if reactor is None: |
|
from twisted.internet import reactor |
|
self._reactor = reactor |
|
|
|
self.connargs = connargs |
|
self.connkw = connkw |
|
|
|
for arg in self.CP_ARGS: |
|
cp_arg = 'cp_%s' % arg |
|
if cp_arg in connkw: |
|
setattr(self, arg, connkw[cp_arg]) |
|
del connkw[cp_arg] |
|
|
|
self.min = min(self.min, self.max) |
|
self.max = max(self.min, self.max) |
|
|
|
self.connections = {} # all connections, hashed on thread id |
|
|
|
# these are optional so import them here |
|
from twisted.python import threadpool |
|
import thread |
|
|
|
# 1. To share one threadpool: grab a reference to the reactor |
|
from twisted.internet import reactor |
|
self.threadID = thread.get_ident |
|
#self.threadpool = threadpool.ThreadPool(self.min, self.max) |
|
# 2. set each connections threadpool equal to that of the reactors threadpool |
|
self.threadpool = reactor.getThreadPool() |
|
self.startID = self._reactor.callWhenRunning(self._start) |