<!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="&#1055;&#1088;&#1086;&#1089;&#1083;&#1091;&#1096;&#1072;&#1090;&#1100; &#1101;&#1090;&#1086;&#1090; &#1087;&#1077;&#1088;&#1077;&#1074;&#1086;&#1076;"
 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&amp;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>