[Async-sig] asyncio <-> twisted interoperability

Guido van Rossum guido at python.org
Mon Jun 6 17:21:54 EDT 2016


On Mon, Jun 6, 2016 at 1:54 PM, Glyph <glyph at twistedmatrix.com> wrote:

>
>
> 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?
>

Right. I'm still unclear on what the compelling use case for that is (other
than that Twisted has always done this). Is it performance? Is it callback
ordering?

I suppose Deferred has a method to mark it done. Does that immediately run
the callbacks? Or does it come in two flavors? Can a Deferred that's marked
done ever revert back to being not done? (I believe I once read the
Deferred code enough to be able to find the answers, but I'm afraid I've
never really needed what I learned then, so I've forgotten...)

-- 
--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/async-sig/attachments/20160606/a9124b30/attachment-0001.html>


More information about the Async-sig mailing list