[Twisted-Python] Connection poolin

Tommi Virtanen tv at twistedmatrix.com
Sun Jul 27 03:00:03 MDT 2003


On Sat, Jul 26, 2003 at 08:38:30PM -0500, John Goerzen wrote:
> imap = self.imapserver.acquireconnection()
> try:
>     # select the appropriate mailbox
>     # do stuff here
>     return result
> finally:
>    self.imapserver.release(imap)

	Here's two quick hacks that differ mostly in where you put
	the connection release, and how you organize the deferreds.

	Method 1: manage the release in the caller, but need to jump
	through hoops to get the connection passed to
	_releaseConnection. self.imapserver.acquireconnection() is
	of the traditional "returns a Deferred" style.

class Something:
    def startDoingStuff(self):
	d = self.imapserver.acquireconnection()
	d.addCallback(self._gotConnection)
	return d

    def _gotConnection(self, connection):
	d = defer.Deferred()
	d.addCallback(self._doStuff)
	d.addBoth(self._releaseConnection, connection)
	d.callback(connection)
	return d

    def _doStuff(self, connection):
	# select the appropriate mailbox
	# do stuff here

    def _releaseConnection(self, stuff, connection):
	connection.release()
	return stuff


	Method 2: manage the release in the connection pool. Needs
	to change the API of acquireconnection into taking a deferred,
	as otherwise it would be impossible to make _doStuff get called
	before the connection release. Note how close this is to the above,
	with just release logic located in the same class as
	acquireconnection.

class SomethingBetter:
    def startDoingStuff(self):
	d = defer.Deferred()
	d.addCallback(self._doStuff)
	self.imapserver.acquireconnection(d)
	return d

    def _doStuff(self, connection):
	# select the appropriate mailbox
	# do stuff here

class ...:
    def acquireconnection(self, d):
	d2 = self._grabConnection()
	d2.addCallback(self._gotConnection, d)
	d2.chainCallback(d)

    def _gotConnection(self, connection, d):
	d.addBoth(self._releaseConnection, connection)
	return connection

    def _releaseConnection(self, stuff, connection):
	connection.release()
	return stuff

> I've thought that in each method I have that needs a connection, I
> could write two methods: one that calls the Twisted version of
> acquireconnection and sets its callback to the second, which does the
> real work (and possibly chains to others via callbacks.)
> 
> There are some problems with that approach.  One is that it is very
> verbose and requires a lot of code all over the place to manage.
> Another is that there's no easy way to tell in Twisted when we are
> done with the given connection.  I suppose I could always add errbacks
> all along the way plus a callback, each of which releases the
> connection, but that seems inconvenient and error-prone.

	I don't think the method 2 above is verbose. And there is no reason
	to add errbacks "all along the way". Just a single addBoth is
	enough. When the .addBoth callback returns it's first arg, it
	pretty much equals python exception handling try: ... finally: ...

-- 
:(){ :|:&};:




More information about the Twisted-Python mailing list