[Async-sig] asyncio <-> twisted interoperability

Glyph glyph at twistedmatrix.com
Mon Jun 6 16:54:53 EDT 2016


> On Jun 6, 2016, at 08:29, Guido van Rossum <guido at python.org> wrote:
> 
> On Sun, Jun 5, 2016 at 10:16 PM, Glyph <glyph at twistedmatrix.com> wrote:
>> 
>> On Jun 4, 2016, at 13:25, Ben Darnell <ben at bendarnell.com> wrote:
>> 
>> If things are so sensitive to minor changes in timing, doesn't that set the
>> bar impossibly high for interoperability?
>> 
>> 
>> The sensitivity is not to changes in timing - i.e. when the wall-clock runs,
>> or ordering of non-deterministically ordered events - but rather to
>> reentrancy - whether certain things complete synchronously while the caller
>> is still on the stack and can depend on them having done so upon return.
>> 
>> The recommended way of writing tests within Twisted these days depends
>> heavily on `.callback´ synchronously resolving a Deferred, which is what
>> adding a call_soon breaks.
> 
> That's interesting, and also potentially worrisome (for interop, I'm
> not saying Twisted is wrong here).
> 
> I think asyncio depends on the opposite: that if you add a callback to
> a Future that's ready it does *not* immediately run. Asyncio's promise
> is pretty strongly that callbacks are serialized (no callbacks running
> inside other callbacks). IIRC we experimented with other semantics and
> found that it was harder to reason about. (IMO if you *know* a Future
> is ready why add a callback to it rather than just calling the damn
> thing if that's what you want?)

I don't think Twisted is necessarily right here either.  You're absolutely right that it's easier to reason about reentrancy in some cases if you have a might-be-fired-might-not Future vs. the same sort of Deferred.  I like the property where you can do:

def test(test_case):
    a = asynchronously_something()
    test_case.this_must_not_have_a_result(a)
    cause_a_to_fire()
    test_case.assertEqual(test_case.this_must_have_a_result(a), something)

but this is (somewhat) opposed to the fact that call_soon means you never get the nasty surprise where the callback added in the middle of a function gets run before the rest of it does.  So I think there are good properties in both cases and given some thought it is probably possible to map between them, but Deferred is lower-level here in the sense that it provides a way to do this both with the event loop and without.  You can always call_soon(deferred.callback) but you can't go the other way and force a Future to resolve synchronously - right?

-glyph

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/async-sig/attachments/20160606/c581999c/attachment.html>


More information about the Async-sig mailing list