<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>> On Mar 3, 2011, at 7:31 AM, Fantix King wrote:<br>
> <br>> > Hi,<br>> ><br>> > I tried to make python.context work in asynchronous code between main loops. Anyone has similar experience to share please?<br>> ><br>> > Not sure if I am rebuilding a wheel :P<br>
> ><br>> > <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>> <br>
> This is something I've often thought about doing in Twisted itself, actually :). But I wasn't sure that chaining context would actually do anything practically useful most of the time. Have you found that it's actually useful? Have you managed to leverage this to, for example, get more informative error messages out of Deferred failures?<br>
> <br>> 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'd have to deal with the places that the reactor passes itself through to things like Process and Port, so you'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'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'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="'courier new', monospace">from twisted.internet import reactor</font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace">from twisted.internet.task import deferLater</font></span></div>
<div><span style="border-collapse:collapse"><font face="'courier new', monospace">reactor.usingAsyncTraceback = True</font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace"><br>
</font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace">def g():</font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace"> raise Exception('Something happened inside.')</font></span></div>
<div><span style="border-collapse:collapse"><font face="'courier new', monospace"><br></font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace">def f():</font></span></div>
<div><span style="border-collapse:collapse"><font face="'courier new', monospace"> return g()</font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace"><br>
</font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace">def e():</font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace"> return f()</font></span></div>
<div><span style="border-collapse:collapse"><font face="'courier new', monospace"><br></font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace">def d():</font></span></div>
<div><span style="border-collapse:collapse"><font face="'courier new', monospace"> return e()</font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace"><br>
</font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace">def c():</font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace"> deferred = deferLater(reactor, 1, lambda: None)</font></span></div>
<div><span style="border-collapse:collapse"><font face="'courier new', monospace"> deferred.addCallback(lambda x: d())</font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace"> return deferred</font></span></div>
<div><span style="border-collapse:collapse"><font face="'courier new', monospace"><br></font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace">def b():</font></span></div>
<div><span style="border-collapse:collapse"><font face="'courier new', monospace"> return c()</font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace"><br>
</font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace">def a():</font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace"> return b()</font></span></div>
<div><span style="border-collapse:collapse"><font face="'courier new', monospace"><br></font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace">if __name__ == '__main__':</font></span></div>
<div><span style="border-collapse:collapse"><font face="'courier new', monospace"> deferred = a()</font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace"> def errback(failure):</font></span></div>
<div><span style="border-collapse:collapse"><font face="'courier new', monospace"> failure.printTraceback()</font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', monospace"> deferred.addErrback(errback)</font></span></div>
<div><span style="border-collapse:collapse"><font face="'courier new', monospace"> deferred.addBoth(lambda x: reactor.stop())</font></span></div><div><span style="border-collapse:collapse"><font face="'courier new', 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="'courier new', monospace">Traceback (most recent call last):</font></div><div><font face="'courier new', monospace"> File "test.py", line 31, in <module></font></div>
<div><font face="'courier new', monospace"> deferred = a()</font></div><div><font face="'courier new', monospace"> File "test.py", line 28, in a</font></div>
<div><font face="'courier new', monospace"> return b()</font></div><div><font face="'courier new', monospace"> File "test.py", line 25, in b</font></div>
<div><font face="'courier new', monospace"> return c()</font></div><div><font face="'courier new', monospace"> File "test.py", line 20, in c</font></div>
<div><font face="'courier new', monospace"> deferred = deferLater(reactor, 1, lambda: None)</font></div><div><font face="'courier new', monospace"> File "/home/fantix/ac/twisted/internet/task.py", line 751, in deferLater</font></div>
<div><font face="'courier new', monospace"> delayedCall = clock.callLater(delay, d.callback, None)</font></div><div><font face="'courier new', monospace"> File "/home/fantix/ac/twisted/internet/base.py", line 701, in callLater</font></div>
<div><font face="'courier new', monospace"> _f, args, kw = self._chainContext(_f, args, kw)</font></div><div><font face="'courier new', monospace"><b>--- <asynchronous break point> ---</b></font></div>
<div><font face="'courier new', monospace"> File "/home/fantix/ac/twisted/python/context.py", line 59, in callWithContext</font></div><div><font face="'courier new', monospace"> return self.currentContext().callWithContext(ctx, func, *args, **kw)</font></div>
<div><font face="'courier new', monospace"> File "/home/fantix/ac/twisted/python/context.py", line 37, in callWithContext</font></div><div><font face="'courier new', monospace"> return func(*args,**kw)</font></div>
<div><font face="'courier new', monospace"> File "/home/fantix/ac/twisted/internet/defer.py", line 361, in callback</font></div><div><font face="'courier new', monospace"> self._startRunCallbacks(result)</font></div>
<div><font face="'courier new', monospace"> File "/home/fantix/ac/twisted/internet/defer.py", line 455, in _startRunCallbacks</font></div><div><font face="'courier new', monospace"> self._runCallbacks()</font></div>
<div><font face="'courier new', monospace">--- <exception caught here> ---</font></div><div><font face="'courier new', monospace"> File "/home/fantix/ac/twisted/internet/defer.py", line 542, in _runCallbacks</font></div>
<div><font face="'courier new', monospace"> current.result = callback(current.result, *args, **kw)</font></div><div><font face="'courier new', monospace"> File "test.py", line 21, in <lambda></font></div>
<div><font face="'courier new', monospace"> deferred.addCallback(lambda x: d())</font></div><div><font face="'courier new', monospace"> File "test.py", line 17, in d</font></div>
<div><font face="'courier new', monospace"> return e()</font></div><div><font face="'courier new', monospace"> File "test.py", line 14, in e</font></div>
<div><font face="'courier new', monospace"> return f()</font></div><div><font face="'courier new', monospace"> File "test.py", line 11, in f</font></div>
<div><font face="'courier new', monospace"> return g()</font></div><div><font face="'courier new', monospace"> File "test.py", line 8, in g</font></div>
<div><font face="'courier new', monospace"> raise Exception('Something happened inside.')</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 "request" 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>