Skip to content

Instantly share code, notes, and snippets.

@deckarep
Created March 28, 2016 02:12
Show Gist options
  • Save deckarep/7e51f3881b090e99916d to your computer and use it in GitHub Desktop.
Save deckarep/7e51f3881b090e99916d to your computer and use it in GitHub Desktop.
Demonstrates how Twisted's Enterprise ADBAPI adapter can be patched to share a global threadpool.
# 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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment