[Twisted-Python] Another nit on "Generalization of Deferred Execution in Python"

http://cumulo-nimbus.mit.edu/deferex.xhtml You call this "pretty"? def prettyRequest(server, requestName): return server.makeRequest(requestName ).addCallback( lambda result: ', '.join(result.asList()) ).addErrback( lambda failure: failure.printTraceback()) How about def prettyRequest(server, requestName): d=server.makeRequest(requestName) d.addCallback(lambda result: ', '.join(result.asList())) d.addErrback(lambda failure: failure.printTraceback()) return d I'm pretty sure everyone will consider that more readable.

On Friday, Jan 17, 2003, at 10:34 America/New_York, Tommi Virtanen wrote:
http://cumulo-nimbus.mit.edu/deferex.xhtml def prettyRequest(server, requestName): d=server.makeRequest(requestName) d.addCallback(lambda result: ', '.join(result.asList())) d.addErrback(lambda failure: failure.printTraceback()) return d
How about calling it prettyWorthlessRequest :) You'll never see the result, just failures! How about throwing a print statement in the callback lambda or something? -bob

On Friday 17 January 2003 09:34 am, Tommi Virtanen wrote:
http://cumulo-nimbus.mit.edu/deferex.xhtml
You call this "pretty"?
def prettyRequest(server, requestName): return server.makeRequest(requestName ).addCallback( lambda result: ', '.join(result.asList()) ).addErrback( lambda failure: failure.printTraceback())
How about
def prettyRequest(server, requestName): d=server.makeRequest(requestName) d.addCallback(lambda result: ', '.join(result.asList())) d.addErrback(lambda failure: failure.printTraceback()) return d
I'm pretty sure everyone will consider that more readable.
You've raised an issue I've wondered about as I've looked at some of the Twisted source. There seems to be a fondness for returning large expressions, rather than building up a return value in a more piecemeal (and more easily read and understood) fashion. Is this simply a matter of style, or is there something substantial going on here related to the nature of Twisted? My own code tends to look more like your second example. -- Patrick K. O'Brien Orbtech http://www.orbtech.com/web/pobrien ----------------------------------------------- "Your source for Python programming expertise." -----------------------------------------------

On Friday, January 17, 2003, at 02:32 PM, Patrick K. O'Brien wrote:
On Friday 17 January 2003 09:34 am, Tommi Virtanen wrote:
def prettyRequest(server, requestName): d=server.makeRequest(requestName) d.addCallback(lambda result: ', '.join(result.asList())) d.addErrback(lambda failure: failure.printTraceback()) return d
I'm pretty sure everyone will consider that more readable.
You've raised an issue I've wondered about as I've looked at some of the Twisted source. There seems to be a fondness for returning large expressions, rather than building up a return value in a more piecemeal (and more easily read and understood) fashion. Is this simply a matter of style, or is there something substantial going on here related to the nature of Twisted? My own code tends to look more like your second example.
My code as well, favoring more, shorter lines for clarity. I suspect the Twisted wizards don't even have to think about deferreds anymore, they just flow directly from mind to keyboard... : ) Jason

On Fri, Jan 17, 2003 at 02:32:36PM -0600, Patrick K. O'Brien wrote:
On Friday 17 January 2003 09:34 am, Tommi Virtanen wrote:
http://cumulo-nimbus.mit.edu/deferex.xhtml
You call this "pretty"?
def prettyRequest(server, requestName): return server.makeRequest(requestName ).addCallback( lambda result: ', '.join(result.asList()) ).addErrback( lambda failure: failure.printTraceback())
How about
def prettyRequest(server, requestName): d=server.makeRequest(requestName) d.addCallback(lambda result: ', '.join(result.asList())) d.addErrback(lambda failure: failure.printTraceback()) return d
I'm pretty sure everyone will consider that more readable.
You've raised an issue I've wondered about as I've looked at some of the Twisted source. There seems to be a fondness for returning large expressions, rather than building up a return value in a more piecemeal (and more easily read and understood) fashion. Is this simply a matter of style, or is there something substantial going on here related to the nature of Twisted? My own code tends to look more like your second example.
I find d.addCallback(processResult).addErrback(reportError) to be a nice and readable... but as soon as lambdas are involved, it tends to get too messy, so I'll tend to use the piecemeal approach then. So my answer is "it depends" :) -Andrew.

I've noticed that there isn't really a good/standard way to do timeouts (without bad things happening) or cancel deferreds in Twisted [without subclassing everything you use, which isn't good in my book]. In the attached code sample (and log, so you don't need to run it to see its output), I demonstrate the problem, a quick-fix temporary solution (to prevent unhandleable exceptions from being raised), and a longer term proposed convention for refactoring existing classes to take advantage of this new functionality. As radix mentioned, my proposed solution does make the meaning of errback somewhat ambiguous. However if you add a new CancelledOperation exception to deferred, and addCanceller/cancel methods (addCanceller = addErrback, cancel = errback) then it'd be pretty transparent. -bob

On Fri, Jan 17, 2003 at 07:04:01PM -0500, Bob Ippolito wrote:
I've noticed that there isn't really a good/standard way to do timeouts (without bad things happening) or cancel deferreds in Twisted [without subclassing everything you use, which isn't good in my book].
I've glanced at your code and log, but it's not immediately clear to me what the problem is... For timeouts, what's wrong with the Deferred.setTimeout method? For cancelling a Deferred, what's wrong with "d.errback(CancelledError(...))"? There's no standard "CancelledError" exception in Twisted, admittedly, but that could be easily fixed. -Andrew.

On Sat, Jan 18, 2003 at 11:26:38PM +1100, Andrew Bennetts wrote:
On Fri, Jan 17, 2003 at 07:04:01PM -0500, Bob Ippolito wrote:
I've noticed that there isn't really a good/standard way to do timeouts (without bad things happening) or cancel deferreds in Twisted [without subclassing everything you use, which isn't good in my book].
I've glanced at your code and log, but it's not immediately clear to me what the problem is...
Nevermind me, I shouldn't try to read code and post when I'm tired. Your problem (if I'm understanding correctly :), is that exceptions are raised by calling Deferred.callback, if that Deferred has timed out, or otherwise been "cancelled" (by having its errback called). I'm tempted to argue that this is a feature: the code attempting to fire the callback probably should know that the Deferred has already expired due to an error. The obvious problem with this is that alot of the time you don't care if the Deferred has already fired or not, and wrapping d.callback(x) in a try/except AlreadyCalledError is hardly convenient. So I'd still like at least the option for an exception to be raised, even if it's disabled by default. I can't shake the feeling that some apps will need to know that it succeeds... although I guess they could just register their own .errback if they really care? For that matter, perhaps another solution would be to mandate that a method creating a Deferred is responsible for configuring it with an errback that will cancel pending operations so that .callback won't be called. Ugh, that's a confusing sentence. What I'm trying to say is that similarly to how when FTP opens a port and waits for a connection, it must set an errback to close that port if the connection never comes (e.g. due to an error on the control connection), whatever "owns" the Deferred should also cancel whatever would call .callback if an error occured -- this is probably necessary in general, not just for timeouts and cancels. Interesting problem :) -Andrew.
participants (5)
-
Andrew Bennetts
-
Bob Ippolito
-
Jason Asbahr
-
Patrick K. O'Brien
-
Tommi Virtanen