[Twisted-Python] strange bug with... something :)

Example code 1 {{{ class Example(object): def __init__(self, connection): self.connection = connection self.counter = 0 self.requests = {} def generate_request_id(self): self.counter += 1 return self.counter def request(self, data, timeout=10): deferred = defer.Deferred() request_id = self.generate_request_id() self.requests[request_id] = deferred # ATTENTION: I want to see current traceback when timeout occurs # therefore raise and catch here try: raise failure.TimeoutError() except failure.TimeoutError: failure = failure.Failure() # charge timer timer = reactor.callLater(timeout, self._on_timeout, request_id, failure) # send request self.connection.send_request(request_id, data) return deferred def _on_timeout(self, request_id, failure): deferred = self.requests.pop(request_id, None) if deferred is not None: deferred.errback(failure) def on_response_received(self, request_id, response): deferred = self.requests.pop(request_id, None) if deferred is not None: deferred.callback(response) }}} Disadvantage 1 of this code: We construct failure.Failure() always although timeout may not occur at all. If failure.Failure() was lazy it will be cool. Disadvantage 2 (bug in twisted?) of this code: This code doesn't work in some cases and I don't know why. In some cases deferred.callback(response) does nothing although called. But this code magically works properly in the same cases: Example code 2 (one difference is just "lazy" failure construction using special FailureFactory class) {{{ class FailureFactory(object): def __init__(self, arg): try: raise arg except: exc_info = sys.exc_info() self.exc_info = exc_info def __call__(self): exc_type, exc_value, tb = self.exc_info return Failure(exc_value, exc_type, tb) class Example(object): def __init__(self, connection): self.connection = connection self.counter = 0 self.requests = {} def generate_request_id(self): self.counter += 1 return self.counter def request(self, data, timeout=10): deferred = defer.Deferred() request_id = self.generate_request_id() self.requests[request_id] = deferred # ATTENTION: I want to see current traceback when timeout occurs # therefore raise and catch here failure_factory = FailureFactory(failure.TimeoutError()) # charge timer timer = reactor.callLater(timeout, self._on_timeout, request_id, failure_factory) # send request self.connection.send_request(request_id, data) return deferred def _on_timeout(self, request_id, failure_factory): deferred = self.requests.pop(request_id, None) if deferred is not None: deferred.errback(failure_factory()) def on_response_received(self, request_id, response): deferred = self.requests.pop(request_id, None) if deferred is not None: deferred.callback(response) }}} Example 2 works but Example 1 does not. What is wrong with example 1? Bug in twisted? I have posted this message as ticket but was redirected to mailing-list http://twistedmatrix.com/trac/ticket/4628

On 8/6/10 5:15 AM, Сергей Магафуров wrote: [cut] I'd like to help you, but I don't really get it. First: - What are you trying to do? - What is your expected outcome? - What is, on the contrary your program's output? Second: your example is too long and is not executable (I need to figure out what you're calling. Could you shorten it and make it runnable out of the box? http://sscce.org/
participants (2)
-
Alan Franzoni
-
Сергей Магафуров