<div class="gmail_quote">On Thu, Oct 11, 2012 at 11:18 PM, Guido van Rossum <span dir="ltr"><<a href="mailto:guido@python.org" target="_blank">guido@python.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

> If there's one take away idea from async-pep, it's reusable protocols.<br><div class="im">
<br>
</div>Is there a newer version that what's on<br>
<a href="http://www.python.org/dev/peps/pep-3153/" target="_blank">http://www.python.org/dev/peps/pep-3153/</a> ? It seems to be missing any<br>
specific proposals, after spending a lot of time giving a rationale<br>
and defining some terms. The version on<br>
<a href="https://github.com/lvh/async-pep" target="_blank">https://github.com/lvh/async-pep</a> doesn't seem to be any more complete.<br><div class="im"></div></blockquote><div><br>Correct.<br><br>If I had to change it today, I'd throw out consumers and producers and just stick to a protocol API.<br>

<br>Do you feel that there should be less talk about rationale?<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
> The PEP should probably be a number of PEPs. At first sight, it seems that<br>
> this number is at least four:<br>
><br>
> 1. Protocol and transport abstractions, making no mention of asynchronous IO<br>
> (this is what I want 3153 to be, because it's small, manageable, and<br>
> virtually everyone appears to agree it's a fantastic idea)<br>
<br>
</div>But the devil is in the details. *What* specifically are you<br>
proposing? How would you write a protocol handler/parser without any<br>
reference to I/O? Most protocols are two-way streets -- you read some<br>
stuff, and you write some stuff, then you read some more. (HTTP may be<br>
the exception here, if you don't keep the connection open.)<br><div class="im"></div></blockquote><div><br>It's not that there's *no* reference to IO: it's just that that reference is abstracted away in data_received and the protocol's transport object, just like Twisted's IProtocol.<br>

 </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
> 2. A base reactor interface<br>
<br>
</div>I agree that this should be a separate PEP. But I do think that in<br>
practice there will be dependencies between the different PEPs you are<br>
proposing.<br><div class="im"></div></blockquote><div><br>Absolutely.<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
> 3. A way of structuring callbacks: probably deferreds with a built-in<br>
> inlineCallbacks for people who want to write synchronous-looking code with<br>
> explicit yields for asynchronous procedures<br>
<br>
</div>Your previous two ideas sound like you're not tied to backward<br>
compatibility with Tornado and/or Twisted (not even via an adaptation<br>
layer). Given that we're talking Python 3.4 here that's fine with me<br>
(though I think we should be careful to offer a path forward for those<br>
packages and their users, even if it means making changes to the<br>
libraries).</blockquote><div><br>I'm assuming that by previous ideas you mean points 1, 2: protocol interface + reactor interface.<br><br>I don't see why twisted's IProtocol couldn't grow an adapter for stdlib Protocols. Ditto for Tornado. Similarly, the reactor interface could be *provided* (through a fairly simple translation layer) by different implementations, including twisted.<br>

 </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">But Twisted Deferred is pretty arcane, and I would much<br>
rather not use it as the basis of a forward-looking design. I'd much<br>
rather see what we can mooch off PEP 3148 (Futures).<br><div class="im"></div></blockquote><div><br>I think this needs to be addressed in a separate mail, since more stuff has been said about deferreds in this thread.<br>

 </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
> 4+ adapting the stdlib tools to using these new things<br>
<br>
</div>We at least need to have an idea for how this could be done. We're<br>
talking serious rewrites of many of our most fundamental existing<br>
synchronous protocol libraries (e.g. httplib, email, possibly even<br>
io.TextWrapper), most of which have had only scant updates even<br>
through the Python 3 transition apart from complications to deal with<br>
the bytes/str dichotomy.<br><div class="im"></div></blockquote><div><br>I certainly agree that this is a very large amount of work. However, it has obvious huge advantages in terms of code reuse. I'm not sure if I understand the technical barrier though. It should be quite easy to create a blocking API with a protocol implementation that doesn't care; just call data_received with all your data at once, and presto! (Since transports in general don't provide guarantees as to how bytes will arrive, existing Twisted IProtocols have to do this already anyway, and that seems to work fine.)<br>

 </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
> Re: forward path for existing asyncore code. I don't remember this being<br>
> raised as an issue. If anything, it was mentioned in passing, and I think<br>
> the answer to it was something to the tune of "asyncore's API is broken,<br>
> fixing it is more important than backwards compat". Essentially I agree with<br>
> Guido that the important part is an upgrade path to a good third-party<br>
> library, which is the part about asyncore that REALLY sucks right now.<br>
<br>
</div>I have the feeling that the main reason asyncore sucks is that it<br>
requires you to subclass its Dispatcher class, which has a rather<br>
treacherous interface.<br><div class="im"></div></blockquote><div><br>There's at least a few others, but sure, that's an obvious one. Many of the objections I can raise however don't matter if there's already an *existing working solution*. I mean, sure, it can't do SSL, but if you have code that does what you want right now, then obviously SSL isn't actually needed.<br>

 </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
> Regardless, an API upgrade is probably a good idea. I'm not sure if it<br>
> should go in the first PEP: given the separation I've outlined above (which<br>
> may be too spread out...), there's no obvious place to put it besides it<br>
> being a new PEP.<br>
<br>
</div>Aren't all your proposals API upgrades?<br><div class="im"></div></blockquote><div><br>Sorry, that was incredibly poor wording. I meant something more of an adapter: an upgrade path for existing asyncore code to new and shiny 3153 code.<br>

 </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
> Re base reactor interface: drawing maximally from the lessons learned in<br>
> twisted, I think IReactorCore (start, stop, etc), IReactorTime (call later,<br>
> etc), asynchronous-looking name lookup, fd handling are the important parts.<br>
<br>
</div>That actually sounds more concrete than I'd like a reactor interface<br>
to be. In the App Engine world, there is a definite need for a<br>
reactor, but it cannot talk about file descriptors at all -- all I/O<br>
is defined in terms of RPC operations which have their own (several<br>
layers of) async management but still need to be plugged in to user<br>
code that might want to benefit from other reactor functionality such<br>
as scheduling and placing a call at a certain moment in the future.<br><div class="im"></div></blockquote><div><br>I have a hard time understanding how that would work well outside of something like GAE. IIUC, that level of abstraction was chosen because it made sense for GAE (and I don't disagree), but I'm not sure it makes sense here.<br>

<br>In this example, where would eg the select/epoll/whatever calls happen? Is it something that calls the reactor that then in turn calls whatever?<br><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="im">
> call_every can be implemented in terms of call_later on a separate object,<br>
> so I think it should be (eg twisted.internet.task.LoopingCall). One thing<br>
> that is apparently forgotten about is event loop integration. The prime way<br>
> of having two event loops cooperate is *NOT* "run both in parallel", it's<br>
> "have one call the other". Even though not all loops support this, I think<br>
> it's important to get this as part of the interface (raise an exception for<br>
> all I care if it doesn't work).<br>
<br>
</div>This is definitely one of the things we ought to get right. My own<br>
thoughts are slightly (perhaps only cosmetically) different again:<br>
ideally each event loop would have a primitive operation to tell it to<br>
run for a little while, and then some other code could tie several<br>
event loops together.<br></blockquote><div><br>As an API, that's pretty close to Twisted's IReactorCore.iterate, I think. It'd work well enough. The issue is only with event loops that don't cooperate so well.<br>

<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Possibly the primitive operation would be something like "block until<br>
either you've got one event ready, or until a certain time (possibly<br>
0) has passed without any events, and then give us the events that are<br>
ready and a lower bound for when you might have more work to do" -- or<br>
maybe instead of returning the event(s) it could just call the<br>
associated callback (it might have to if it is part of a GUI library<br>
that has callbacks written in C/C++ for certain events like screen<br>
refreshes).<br>
<br>
Anyway, it would be good to have input from representatives from Wx,<br>
Qt, Twisted and Tornado to ensure that the *functionality* required is<br>
all there (never mind the exact signatures of the APIs needed to<br>
provide all that functionality).<br><div class="HOEnZb"><div class="h5"></div></div><br></blockquote><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb">

<div class="h5">
--<br>
--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)<br>
</div></div></blockquote></div><br>-- <br>cheers<div>lvh</div><br>