[Twisted-Python] inlineCallbacks: multiple yielding same Defferred behaviour

It's not intuitively clear why multiple yielding the same Defferred in function decorated with defer.inlineCallbacks get different results: @defer.inlineCallbacks def f(): d = defer.succeed(1) result = yield d print result result = yield d print result Output: 1 None Probably we SHOULD NOT think if "d" was or was not yielded before when using inlineCallbacks.. Are they some workarounds?

I'm not entirely sure why you feel this is unintuitive or why you should need a workaround; in any other case, deferreds work pretty much the same way. When reading this code, the first question that pops up in my head is: why are you doing this instead of just using the result that you already have (and assigned to a name)? How did this waiting-twice-on-one-deferred happen? On Mon, Jan 28, 2013 at 8:47 AM, Sergey V. Gerasimov <sergun@gmail.com>wrote:
-- cheers lvh

Hi Laurens, Thanks for your reply! I need something like this. A server that processes requests and handles situation when there are 2 requests with same key. class Server(object): def __init__(self): self.requestsInProgress = {} # dict: key -> Deferred with result @defer.inlineCallbacks def request(self, key): in_progress = key in self.requests if in_progress: d = self.requestsInProgress [key] result = yield d else: d = process_request(key) self.requests[key] = d result = yield d del self.requestsInProgress [key] defer.returnValue(result) How can I implement the logic correctly? In my opinion it's very simple and clear concept to consider Deferred just like deferred execution of some action. In this case you should be able to get it's result (doing yield) many times (why not?). I have deal with Task-based programming and async functions (mechanism similar to Deferred and inlineCallbacks decorated functions in Twisted) in Microsoft .NET. MS people have implemented Task (analogue of Deferred) in the way I described. From: Laurens Van Houtven [mailto:_@lvh.cc] Sent: Monday, January 28, 2013 12:47 PM To: sergun@gmail.com; Twisted general discussion Subject: Re: [Twisted-Python] inlineCallbacks: multiple yielding same Defferred behaviour I'm not entirely sure why you feel this is unintuitive or why you should need a workaround; in any other case, deferreds work pretty much the same way. When reading this code, the first question that pops up in my head is: why are you doing this instead of just using the result that you already have (and assigned to a name)? How did this waiting-twice-on-one-deferred happen? On Mon, Jan 28, 2013 at 8:47 AM, Sergey V. Gerasimov <sergun@gmail.com> wrote: It's not intuitively clear why multiple yielding the same Defferred in function decorated with defer.inlineCallbacks get different results: @defer.inlineCallbacks def f(): d = defer.succeed(1) result = yield d print result result = yield d print result Output: 1 None Probably we SHOULD NOT think if "d" was or was not yielded before when using inlineCallbacks.. Are they some workarounds? _______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python -- cheers lvh

I'm not entirely sure why you feel this is unintuitive or why you should need a workaround; in any other case, deferreds work pretty much the same way. When reading this code, the first question that pops up in my head is: why are you doing this instead of just using the result that you already have (and assigned to a name)? How did this waiting-twice-on-one-deferred happen? On Mon, Jan 28, 2013 at 8:47 AM, Sergey V. Gerasimov <sergun@gmail.com>wrote:
-- cheers lvh

Hi Laurens, Thanks for your reply! I need something like this. A server that processes requests and handles situation when there are 2 requests with same key. class Server(object): def __init__(self): self.requestsInProgress = {} # dict: key -> Deferred with result @defer.inlineCallbacks def request(self, key): in_progress = key in self.requests if in_progress: d = self.requestsInProgress [key] result = yield d else: d = process_request(key) self.requests[key] = d result = yield d del self.requestsInProgress [key] defer.returnValue(result) How can I implement the logic correctly? In my opinion it's very simple and clear concept to consider Deferred just like deferred execution of some action. In this case you should be able to get it's result (doing yield) many times (why not?). I have deal with Task-based programming and async functions (mechanism similar to Deferred and inlineCallbacks decorated functions in Twisted) in Microsoft .NET. MS people have implemented Task (analogue of Deferred) in the way I described. From: Laurens Van Houtven [mailto:_@lvh.cc] Sent: Monday, January 28, 2013 12:47 PM To: sergun@gmail.com; Twisted general discussion Subject: Re: [Twisted-Python] inlineCallbacks: multiple yielding same Defferred behaviour I'm not entirely sure why you feel this is unintuitive or why you should need a workaround; in any other case, deferreds work pretty much the same way. When reading this code, the first question that pops up in my head is: why are you doing this instead of just using the result that you already have (and assigned to a name)? How did this waiting-twice-on-one-deferred happen? On Mon, Jan 28, 2013 at 8:47 AM, Sergey V. Gerasimov <sergun@gmail.com> wrote: It's not intuitively clear why multiple yielding the same Defferred in function decorated with defer.inlineCallbacks get different results: @defer.inlineCallbacks def f(): d = defer.succeed(1) result = yield d print result result = yield d print result Output: 1 None Probably we SHOULD NOT think if "d" was or was not yielded before when using inlineCallbacks.. Are they some workarounds? _______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python -- cheers lvh
participants (2)
-
Laurens Van Houtven
-
Sergey V. Gerasimov