<span style="border-collapse:collapse;font-family:arial, sans-serif;font-size:13px">On Mar 3, 2011, at 2:39 PM, Glyph Lefkowitz wrote:</span><div><span style="border-collapse:collapse;font-family:arial, sans-serif;font-size:13px"></span>&gt; On Mar 3, 2011, at 7:31 AM, Fantix King wrote:<br>


&gt; <br>&gt; &gt; Hi,<br>&gt; &gt;<br>&gt; &gt; I tried to make python.context work in asynchronous code between main loops. Anyone has similar experience to share please?<br>&gt; &gt;<br>&gt; &gt; Not sure if I am rebuilding a wheel :P<br>


&gt; &gt;<br>&gt; &gt; <a href="http://code.google.com/p/little-site/source/browse/littlesite/custom_reactor.py" target="_blank">http://code.google.com/p/little-site/source/browse/littlesite/custom_reactor.py</a><br>&gt; <br>

&gt; This is something I&#39;ve often thought about doing in Twisted itself, actually :).  But I wasn&#39;t sure that chaining context would actually do anything practically useful most of the time.  Have you found that it&#39;s actually useful?  Have you managed to leverage this to, for example, get more informative error messages out of Deferred failures?<br>


&gt; <br>&gt; Doing it as a subclass like this is not optimal, as it limits you to one reactor (and the Select reactor is not really the best one).  A wrapper would be slightly more tricky (you&#39;d have to deal with the places that the reactor passes itself through to things like Process and Port, so you&#39;d have to create wrappers for those as well) but much more general.<br>


<div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px"><br></div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px"><br></div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px">


Thanks for replying! :)</div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px"><br></div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px">Yes! That&#39;s a wonderful idea to use this context for asynchronous traceback! I made</div>


<div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px">some small changes to the code and wrote a patch for Twisted (as addReader and</div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px">


addWriter is quite different from one impl to another, I changed SelectReactor only.</div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px">I haven&#39;t got a better idea for this, please advise), please see attachment.</div>


<div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px"><br></div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px">With a simple example of raising exception in deferLater-ed function</div>


<div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px">(a-b-c-deferLater-d-e-f-g):</div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px"><br></div>
<div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">from twisted.internet import reactor</font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">from twisted.internet.task import deferLater</font></span></div>


<div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">reactor.usingAsyncTraceback = True</font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace"><br>


</font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">def g():</font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">    raise Exception(&#39;Something happened inside.&#39;)</font></span></div>


<div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace"><br></font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">def f():</font></span></div>


<div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">    return g()</font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace"><br>
</font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">def e():</font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">    return f()</font></span></div>


<div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace"><br></font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">def d():</font></span></div>


<div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">    return e()</font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace"><br>
</font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">def c():</font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">    deferred = deferLater(reactor, 1, lambda: None)</font></span></div>


<div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">    deferred.addCallback(lambda x: d())</font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">    return deferred</font></span></div>


<div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace"><br></font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">def b():</font></span></div>


<div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">    return c()</font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace"><br>
</font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">def a():</font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">    return b()</font></span></div>


<div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace"><br></font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">if __name__ == &#39;__main__&#39;:</font></span></div>


<div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">    deferred = a()</font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">    def errback(failure):</font></span></div>


<div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">        failure.printTraceback()</font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">    deferred.addErrback(errback)</font></span></div>


<div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">    deferred.addBoth(lambda x: reactor.stop())</font></span></div><div><span style="border-collapse:collapse"><font face="&#39;courier new&#39;, monospace">    reactor.run()</font></span></div>


<div style="border-collapse:collapse;font-family:arial, sans-serif;font-size:13px"><br></div></div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px"><br></div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px">


I could get this:</div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px"><br></div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px"><br></div>
<div style="border-collapse:collapse;font-size:13px"><div><font face="&#39;courier new&#39;, monospace">Traceback (most recent call last):</font></div><div><font face="&#39;courier new&#39;, monospace">  File &quot;test.py&quot;, line 31, in &lt;module&gt;</font></div>


<div><font face="&#39;courier new&#39;, monospace">    deferred = a()</font></div><div><font face="&#39;courier new&#39;, monospace">  File &quot;test.py&quot;, line 28, in a</font></div>
<div><font face="&#39;courier new&#39;, monospace">    return b()</font></div><div><font face="&#39;courier new&#39;, monospace">  File &quot;test.py&quot;, line 25, in b</font></div>
<div><font face="&#39;courier new&#39;, monospace">    return c()</font></div><div><font face="&#39;courier new&#39;, monospace">  File &quot;test.py&quot;, line 20, in c</font></div>
<div><font face="&#39;courier new&#39;, monospace">    deferred = deferLater(reactor, 1, lambda: None)</font></div><div><font face="&#39;courier new&#39;, monospace">  File &quot;/home/fantix/ac/twisted/internet/task.py&quot;, line 751, in deferLater</font></div>


<div><font face="&#39;courier new&#39;, monospace">    delayedCall = clock.callLater(delay, d.callback, None)</font></div><div><font face="&#39;courier new&#39;, monospace">  File &quot;/home/fantix/ac/twisted/internet/base.py&quot;, line 701, in callLater</font></div>


<div><font face="&#39;courier new&#39;, monospace">    _f, args, kw = self._chainContext(_f, args, kw)</font></div><div><font face="&#39;courier new&#39;, monospace"><b>--- &lt;asynchronous break point&gt; ---</b></font></div>


<div><font face="&#39;courier new&#39;, monospace">  File &quot;/home/fantix/ac/twisted/python/context.py&quot;, line 59, in callWithContext</font></div><div><font face="&#39;courier new&#39;, monospace">    return self.currentContext().callWithContext(ctx, func, *args, **kw)</font></div>


<div><font face="&#39;courier new&#39;, monospace">  File &quot;/home/fantix/ac/twisted/python/context.py&quot;, line 37, in callWithContext</font></div><div><font face="&#39;courier new&#39;, monospace">    return func(*args,**kw)</font></div>


<div><font face="&#39;courier new&#39;, monospace">  File &quot;/home/fantix/ac/twisted/internet/defer.py&quot;, line 361, in callback</font></div><div><font face="&#39;courier new&#39;, monospace">    self._startRunCallbacks(result)</font></div>


<div><font face="&#39;courier new&#39;, monospace">  File &quot;/home/fantix/ac/twisted/internet/defer.py&quot;, line 455, in _startRunCallbacks</font></div><div><font face="&#39;courier new&#39;, monospace">    self._runCallbacks()</font></div>


<div><font face="&#39;courier new&#39;, monospace">--- &lt;exception caught here&gt; ---</font></div><div><font face="&#39;courier new&#39;, monospace">  File &quot;/home/fantix/ac/twisted/internet/defer.py&quot;, line 542, in _runCallbacks</font></div>


<div><font face="&#39;courier new&#39;, monospace">    current.result = callback(current.result, *args, **kw)</font></div><div><font face="&#39;courier new&#39;, monospace">  File &quot;test.py&quot;, line 21, in &lt;lambda&gt;</font></div>


<div><font face="&#39;courier new&#39;, monospace">    deferred.addCallback(lambda x: d())</font></div><div><font face="&#39;courier new&#39;, monospace">  File &quot;test.py&quot;, line 17, in d</font></div>
<div><font face="&#39;courier new&#39;, monospace">    return e()</font></div><div><font face="&#39;courier new&#39;, monospace">  File &quot;test.py&quot;, line 14, in e</font></div>
<div><font face="&#39;courier new&#39;, monospace">    return f()</font></div><div><font face="&#39;courier new&#39;, monospace">  File &quot;test.py&quot;, line 11, in f</font></div>
<div><font face="&#39;courier new&#39;, monospace">    return g()</font></div><div><font face="&#39;courier new&#39;, monospace">  File &quot;test.py&quot;, line 8, in g</font></div>
<div><font face="&#39;courier new&#39;, monospace">    raise Exception(&#39;Something happened inside.&#39;)</font></div></div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px">
<br></div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px"><br></div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px">Additionally, in my scenario of a 5 years old asynchronous Twisted web application, we</div>


<div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px">need the &quot;request&quot; object available throughout all code between asynchronous network</div>

<div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px">accesses and database accesses because our global configuration system needs the</div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px">


request object. It would greatly reduce our manual work to pass through the request</div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px">object here and there to have a context working in the asynchronous way.</div>


<div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px"><br></div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px"><br></div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px">


BR,</div><div style="font-family:arial, sans-serif;border-collapse:collapse;font-size:13px">Fantix.</div>


</div>