Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CFFI bindings for c-ares #580

Closed
thedrow opened this issue Jun 18, 2015 · 15 comments · Fixed by #1088
Closed

CFFI bindings for c-ares #580

thedrow opened this issue Jun 18, 2015 · 15 comments · Fixed by #1088
Labels
Interp: pypy Type: Enhancement We can do better through adding this

Comments

@thedrow
Copy link
Contributor

thedrow commented Jun 18, 2015

It might be nice to provide better DNS resolving engines for PyPy as well.

@jamadden jamadden added the Type: Enhancement We can do better through adding this label Jul 2, 2015
@jamadden
Copy link
Member

The existing Cython-based c-ares bindings seem to work fine, as far as the test-suite is concerned. I've enabled them for PyPy (as an option, not as a default, the same for cpython). Note that I haven't attempted any performance comparisons because That Would Be Hard.

@thedrow
Copy link
Contributor Author

thedrow commented Jul 21, 2015

CPython extensions are generally slower on PyPy so I think that there is value in creating a CFFI extension for it.
I also don't know how to measure performance of c-ares in PyPy with a C extension and a CFFI extension.
Maybe we could use the vmprof for that?

@jamadden
Copy link
Member

CPython extensions are generally slower on PyPy so I think that there is value in creating a CFFI extension for it.

That can certainly be true, depending on how much time is spent interfacing between C and Python. Given that's it's cython-ized code, my guess is "quite a lot". But then again, it's DNS lookups. How often is that actually a bottleneck in a Python program? More to the point, how often is the local interpreter overhead a bottleneck compared to network overhead in DNS resolution?

That said, I wasn't trying to say that a CFFI binding would never be useful (although it does double the maintenance requirements). I was just happy to be able to say that the functionality does exist and can be used, even if it doesn't perform optimally.

@jamadden
Copy link
Member

jamadden commented Feb 3, 2016

I wasn't trying to say that a CFFI binding would never be useful (although it does double the maintenance requirements)

Hmm. After having gotten the corecffi loop running on CPython, it appears there's very little performance penalty relative to the Cython loop (~5-10%, depending on platform). If that turns out to hold true (and it looks like it should) then I would be in favor of dropping the Cython c-ares bindings in favor of CFFI bindings that are usable and stable on both platforms (assuming we don't run into any windows-related issues, as I did with the CFFI loop). (That's certainly where I intend to start investigating a libuv loop :) )

@thedrow
Copy link
Contributor Author

thedrow commented Feb 4, 2016

Sounds like a plan.

@jamadden
Copy link
Member

#774 is probably a bit of a blocker for this. And as a side note, a libuv loop could dispense with c-ares altogether in favor of the async DNS builtin to libuv.

@thedrow
Copy link
Contributor Author

thedrow commented Mar 30, 2016

Are there plans to move from libev to libuv?

@jamadden
Copy link
Member

I wouldn't call them exactly plans at this point, but it's something I want to take a serious look at.

@jgehrcke
Copy link
Contributor

IMO one of the nicest things libuv would bring along is IOCP support.
Also see
https://gehrcke.de/gipc/#notes-for-windows-users
https://github.com/saghul/uvent
https://twitter.com/gevent/status/251870755187478529

@jamadden
Copy link
Member

jamadden commented Apr 7, 2016

I've been looking at libuv, and it's not quite the panacea one would hope.

First, what's relevant for this thread, the DNS support, sadly, is also no better: it just shoves requests off onto its own internal threadpool. Making it no different than gevent's default resolver.

Other minor problems include no support for fork watchers or child watchers; those can both be handled at the gevent level though, at least on POSIX (but the situation with children and SIGCHLD won't get any better).

The biggest impedance mismatch, though, is in the handling of IO. The libuv equivalent to libev's IO watchers, "poll" watchers, pretty much matches exactly what libev does, including only working for sockets on Windows (and not using IOCP, AFAICS). If you want the much-vaunted Windows improvements you have to use functions and types specific to TCP, UDP or pipes, and these do not have (exposed) read or write events, relying instead on a series of non-blocking callbacks that are handled internally to the event loop. This doesn't fit well with gevent's "wait for a read event then try to read again" approach (in fact, gevent wouldn't be able to use the Python-level socket object at all). It may be possible to paper over this with some higher-level abstractions, but they don't currently exist.

So in the short term, I'm still interested in looking into a libuv port based on the poll watchers. I think that's pretty low hanging fruit, and I'm interested to compare performance. For another thing, this should make CFFI possible on Windows. But any other Windows-specific improvements that would come from redesigning the socket abstractions are further down the line.

@jamadden jamadden mentioned this issue Apr 10, 2016
@jamadden
Copy link
Member

Moved libuv discussion to #790. Short sad story: I hit a wall with libuv breaking terribly on a fork().

@jamadden
Copy link
Member

Perhaps another option is to adopt dnspython, a pure-python DNS implementation, to replace c-ares. That's what eventlet just did.

@thedrow
Copy link
Contributor Author

thedrow commented Dec 13, 2016

It'd be a shame since it's a very good opportunity to release the GIL earlier in case you are working with both gevent and threading.
We can fallback to dnspython in PyPy if there's no other choice.

@thedrow
Copy link
Contributor Author

thedrow commented Dec 13, 2016

I see that we're currently not releasing the GIL anyway. No idea why though.

@thedrow
Copy link
Contributor Author

thedrow commented Dec 13, 2016

See #910 :)

hashbrowncipher pushed a commit to hashbrowncipher/gevent that referenced this issue Oct 20, 2018
fix invalid pytest reference, and do not ignore Sphinx warnings anymore
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Interp: pypy Type: Enhancement We can do better through adding this
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants