On Thu, Mar 27, 2014 at 4:09 AM, Saúl Ibarra Corretgé <[email protected]>wrote:

> Maybe I can create a helper function "yield_from" a la six.reraise
> using exec where appropriate. It's ugly, yes, I'll give it a shot and
> see how it goes.
>

I don't think that exec is going to help you here. It cannot cause the
current frame to yield, since it executes in its own frame (only the
locals/globals dicts are shared with the calling frame). Your best if you
want single-source is to avoid yield altogether and use callbacks instead.
The alternative (which Trollius more or less expects you to do) is a
mechanical source-to-source translation. In particular, change "yield
From(x)" --> "yield from x" and change "raise Return(x)" --> "raise x".


> >>> http://code.google.com/p/tulip/issues/detail?id=160
> >>
> >> There is a small problem with that. For the most part, what
> >> people need is getaddrinfo, which c-ares doesn't have, so I'd
> >> have to 'emulate' it by running it on a thread. The problem is
> >> that the parameters that were used to configure the Ares channel
> >> (nameservers, timeout, ... [0]) wouldn't apply to getaddrinfo.
> >
> > I implemented getaddrinfo() using pycares without threads:
> > https://bitbucket.org/haypo/asyncio_staging/src/tip/resolver_cares.py
> >
> >  It's not well tested, I'm not sure that I pass the right flags.
>
> Maybe it can indeed be emulated indeed, I haven't looked into that yet.
>

This looks like the obvious approach to emulating getaddrinfo with asyncio.
But I have one niggling question: why make two separate queries to the DNS
server? All descriptions I've found of the DNS protocol (and even the
Twisted source code) suggest that you can send multiple queries in a single
request. Is that not supported in real life for some reason I fail to see?


> > pycares is used to resolve IPv4 and IPv6 addresses. For other
> > families, the code falls back to socket.getaddrinfo() called in
> > the executor (asyncio default implementation). Maybe an exception
> > could be raised instead?
>
> I'd raise NotImplementedError if the family is not AF_INET/6 or
> AF_UNSPEC (in the latter case we'd do 2 lookups).
>

Agreed. Protocols other than IP and IPv6 are irrelevant here.

>
> >>
> http://daniel.haxx.se/blog/2012/01/03/getaddrinfo-with-round-robin-dns-and-happy-eyeballs/
> >
> >>
> > For the happy eyeball, asyncio API must be modified because
> > create_connection() currently "blocks" until getaddrinfo() returns
> > all IPv4 and all IPv6 addresses. There is an issue but no
> > implementation yet:
> > http://code.google.com/p/tulip/issues/detail?id=86
>

A happy eyeballs implementation would be much appreciated -- perhaps more
than a custom DNS implementation[1]. It should probably start two
concurrent tasks, one responsible for IP, the other for IPv6, and each
doing its own getaddrinfo() call limited to that address family. When one
succeeds the other should be cancelled (and each task should be careful to
clean up when cancelled -- this is where knowing that cancellation can only
raise at a yield is hugely helpful, so it would require only a few
try/finally blocks).

[1] The reason I'm not excited about a custom DNS implementation is that in
my experience getaddrinfo() does a lot more than talk DNS. It usually has
some kind of cache, and I suspect the cache may be shared between different
processes on the same machine. But there's already discussion of this in
issue 160.

-- 
--Guido van Rossum (python.org/~guido)

Reply via email to