<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=windows-1252"
http-equiv="Content-Type">
<title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
Thanks to all!<br>
<div dir="ltr" style="">
<div id="tts_button" title="Прослушать этот перевод"
style="display: block;" class=" "><object
type="application/x-shockwave-flash"
data="http://www.gstatic.com/translate/sound_player2.swf"
id="tts_flash" width="18" height="18"><param
value="http://www.gstatic.com/translate/sound_player2.swf" name="movie"><param
value="sound_name=translate_tts%3Fq%3Dspecific%26tl%3Den&sound_name_cb=_TTSSoundFile"
name="flashvars"><param value="transparent" name="wmode"><param
value="always" name="allowScriptAccess"></object></div>
<span id="result_box" class="short_text"><span
style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);"
title="">Especially</span></span> to Yaroslav Fedevych who explain me
my misstake in my native language :)<br>
I was wrong with deferreds usage.<br>
<br>
<span id="result_box" class="short_text"><span
style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);"
title=""></span></span><span id="result_box" class="short_text"><span
style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);"
title=""></span></span><span id="result_box" class="short_text"><span
style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);"
title="">Cascading cancelling of inlineCallbacks is still needed to
me, but it can be realized with current Deferred API.<br>
<br>
This way for example:<br>
<br>
class InlineCallbacksManagerWithCascadeCancelling(object):<br>
_cancellation = False<br>
_wait_result = None<br>
<br>
def __init__(self):<br>
self.deferred = defer.Deferred()<br>
self.deferred.addBoth(self._cleanup)<br>
<br>
def _cleanup(self, result):<br>
if self._wait_result is not None:<br>
self._cancellation = True<br>
self._wait_result.cancel()<br>
self._wait_result = None<br>
self.deferred = None<br>
return result<br>
<br>
def _inlineCallbacks(self, result, g):<br>
"""<br>
See L{inlineCallbacks}.<br>
"""<br>
# This function is complicated by the need to prevent unbounded
recursion<br>
# arising from repeatedly yielding immediately ready
deferreds. This while<br>
# loop and the waiting variable solve that by manually
unfolding the<br>
# recursion.<br>
<br>
waiting = [True, # waiting for result?<br>
None] # result<br>
<br>
deferred = self.deferred<br>
<br>
while 1:<br>
if self._cancellation:<br>
g.close()<br>
return<br>
<br>
try:<br>
# Send the last result back as the result of the yield
expression.<br>
isFailure = isinstance(result, Failure)<br>
if isFailure:<br>
result = result.throwExceptionIntoGenerator(g)<br>
else:<br>
result = g.send(result)<br>
except StopIteration:<br>
# fell off the end, or "return" statement<br>
deferred.callback(None)<br>
return deferred<br>
except defer._DefGen_Return, e:<br>
# returnValue() was called; time to give a result to
the original Deferred.<br>
deferred.callback(e.value)<br>
return deferred<br>
except:<br>
deferred.errback()<br>
return deferred<br>
<br>
if isinstance(result, defer.Deferred):<br>
# a deferred was yielded, get the result.<br>
def gotResult(r):<br>
if waiting[0]:<br>
waiting[0] = False<br>
waiting[1] = r<br>
else:<br>
self._wait_result = None<br>
self._inlineCallbacks(r, g)<br>
<br>
result.addBoth(gotResult)<br>
if waiting[0]:<br>
# Haven't called back yet, set flag so that we get
reinvoked<br>
# and return from the loop<br>
waiting[0] = False<br>
self._wait_result = result<br>
return deferred<br>
<br>
result = waiting[1]<br>
# Reset waiting to initial values for next loop.
gotResult uses<br>
# waiting, but this isn't a problem because gotResult
is only<br>
# executed once, and if it hasn't been executed yet,
the return<br>
# branch above would have been taken.<br>
<br>
waiting[0] = True<br>
waiting[1] = None<br>
<br>
def inlineCallbacksWithCascadeCancelling(f):<br>
def unwind_generator(*args, **kwargs):<br>
manager = InlineCallbacksManagerWithCascadeCancelling(*args,
**kwargs)<br>
return manager._inlineCallbacks(None, f(*args, **kwargs))<br>
return mergeFunctionMetadata(f, unwind_generator)<br>
<br>
This </span></span><span id="result_box" class="short_text"><span
style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);"
title="">inlineCallbacksWithCascadeCancelling cancels</span></span><span
id="result_box" class="short_text"><span
style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);"
title=""> immediately "child" (wait result) deferred when "parent"
deferred finished (canceled for example) and stops generator.<br>
<br>
May be this behaviour must be default for </span></span><span
id="result_box" class="short_text"><span
style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);"
title="">inlineCallbacks (i.e. defer.</span></span><span
id="result_box" class="short_text"><span
style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);"
title="">inlineCallbacks</span></span><span id="result_box"
class="short_text"><span
style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);"
title=""> = </span></span><span id="result_box" class="short_text"><span
style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);"
title="">inlineCallbacksWithCascadeCancelling</span></span><span
id="result_box" class="short_text"><span
style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);"
title="">)?<br>
<br>
I am happy with this behaviour :)<br>
</span></span><span id="result_box" class="short_text"><span
style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);"
title=""><br>
</span></span></div>
</body>
</html>