[Twisted-Python] a couple of patches
William Waites
ww at groovy.net
Thu Dec 23 18:10:23 EST 2004
greetings, sent this directly to glyph a little while ago,
to deafening silence... perhaps i said the wrong thing ;)
here are a couple of patches:
the first one adds interface support to enterprise.adbapi.ConnectionPool
to make things like IFooBarObject(dbpool) where dbpool is a ConnectionPool
instance work as expected.
the second adds unregistration methods to the python.dispatch.EventDispatcher
cheers,
-w
-------------- next part --------------
diff -uP Twisted-1.3.0/twisted/enterprise/adbapi.py Twisted-Local/twisted/enterprise/adbapi.py
--- Twisted-1.3.0/twisted/enterprise/adbapi.py 2004-02-26 00:45:04.000000000 -0500
+++ Twisted-Local/twisted/enterprise/adbapi.py 2004-12-20 01:11:47.000000000 -0500
@@ -48,7 +48,7 @@
def __getattr__(self, name):
return getattr(self._cursor, name)
-
+from interfaces import IConnectionPool
class ConnectionPool:
"""I represent a pool of connections to a DB-API 2.0 compliant database.
@@ -57,7 +57,8 @@
the noisy arg which determines whether informational log messages are
generated during the pool's operation.
"""
-
+ __implements__ = IConnectionPool,
+
noisy = 1 # if true, generate informational log messages
min = 3 # minimum number of connections in pool
max = 5 # maximum number of connections in pool
@@ -309,7 +310,7 @@
warnings.warn("This is deprecated. Use runInteraction", DeprecationWarning)
self._deferToThread(self._runInteraction, interaction,
*args, **kw).addCallbacks(callback, errback)
-
+del IConnectionPool
class Augmentation:
'''This class is now deprecated. Just use the ConnectionPool directly.
diff -uP Twisted-1.3.0/twisted/enterprise/interfaces.py Twisted-Local/twisted/enterprise/interfaces.py
--- Twisted-1.3.0/twisted/enterprise/interfaces.py 1969-12-31 19:00:00.000000000 -0500
+++ Twisted-Local/twisted/enterprise/interfaces.py 2004-12-20 01:14:15.000000000 -0500
@@ -0,0 +1,86 @@
+from twisted.python import components
+class IConnectionPool(components.Interface):
+ """I represent a pool of connections to a DB-API 2.0 compliant database.
+
+ You can pass cp_min, cp_max or both to set the minimum and maximum
+ number of connections that will be opened by the pool. You can pass
+ the noisy arg which determines whether informational log messages are
+ generated during the pool's operation.
+ """
+ def start(self):
+ """Start the connection pool.
+
+ If you are using the reactor normally, this function does *not*
+ need to be called.
+ """
+ def runInteraction(self, interaction, *args, **kw):
+ """Interact with the database and return the result.
+
+ The 'interaction' is a callable object which will be executed
+ in a thread using a pooled connection. It will be passed an
+ L{Transaction} object as an argument (whose interface is
+ identical to that of the database cursor for your DB-API
+ module of choice), and its results will be returned as a
+ Deferred. If running the method raises an exception, the
+ transaction will be rolled back. If the method returns a
+ value, the transaction will be committed.
+
+ NOTE that the function you pass is *not* run in the main
+ thread: you may have to worry about thread-safety in the
+ function you pass to this if it tries to use non-local
+ objects.
+
+ @param interaction: a callable object whose first argument is
+ L{adbapi.Transaction}. *args,**kw will be passed as
+ additional arguments.
+
+ @return: a Deferred which will fire the return value of
+ 'interaction(Transaction(...))', or a Failure.
+ """
+
+ def runQuery(self, *args, **kw):
+ """Execute an SQL query and return the result.
+
+ A DB-API cursor will will be invoked with cursor.execute(*args, **kw).
+ The exact nature of the arguments will depend on the specific flavor
+ of DB-API being used, but the first argument in *args be an SQL
+ statement. The result of a subsequent cursor.fetchall() will be
+ fired to the Deferred which is returned. If either the 'execute' or
+ 'fetchall' methods raise an exception, the transaction will be rolled
+ back and a Failure returned.
+
+ The *args and **kw arguments will be passed to the DB-API cursor's
+ 'execute' method.
+
+ @return: a Deferred which will fire the return value of a DB-API
+ cursor's 'fetchall' method, or a Failure.
+ """
+ def runOperation(self, *args, **kw):
+ """Execute an SQL query and return None.
+
+ A DB-API cursor will will be invoked with cursor.execute(*args, **kw).
+ The exact nature of the arguments will depend on the specific flavor
+ of DB-API being used, but the first argument in *args will be an SQL
+ statement. This method will not attempt to fetch any results from the
+ query and is thus suitable for INSERT, DELETE, and other SQL statements
+ which do not return values. If the 'execute' method raises an exception,
+ the transaction will be rolled back and a Failure returned.
+
+ The args and kw arguments will be passed to the DB-API cursor's
+ 'execute' method.
+
+ return: a Deferred which will fire None or a Failure.
+ """
+ def close(self):
+ """Close all pool connections and shutdown the pool."""
+ def connect(self):
+ """Return a database connection when one becomes available.
+
+ This method blocks and should be run in a thread from the internal threadpool.
+ Don't call this method directly from non-threaded twisted code.
+
+ @return: a database connection from the pool.
+ """
+
+# keep the namespace tidy
+del components
-------------- next part --------------
--- Twisted-1.3.0/twisted/python/dispatch.py 2003-11-29 00:30:05.000000000 -0500
+++ Twisted-Local/twisted/python/dispatch.py 2004-12-20 16:59:30.000000000 -0500
@@ -31,11 +31,12 @@
self.prefix = prefix
self.callbacks = {}
-
def registerHandler(self, name, meth):
self.callbacks.setdefault(name, []).append(meth)
-
+ def unregisterHandler(self, name, meth):
+ self.callbacks[name].remove(meth)
+
def autoRegister(self, obj):
from twisted.python import reflect
d = {}
@@ -43,7 +44,13 @@
for k,v in d.items():
self.registerHandler(k, v)
-
+ def autoUnregister(self, obj):
+ from twisted.python import reflect
+ d = {}
+ reflect.accumulateMethods(obj, d, self.prefix)
+ for k,v in d.items():
+ self.unregisterHandler(k, v)
+
def publishEvent(self, name, *args, **kwargs):
for cb in self.callbacks[name]:
cb(*args, **kwargs)
More information about the Twisted-Python
mailing list