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
Replace select()
syscall with Selectors
module to fix filedescriptors out of range
issue
#7880
Comments
This is outstanding research, thanks! I couldn't find the specific place where we set a high I'm definitely on board with using the |
### Problem Twitter was running into the error `filedescriptor out of range in select()` when compiling a large number of targets, per #7880. In the process, we found that it is more efficient and robust to use the more modern syscalls of `epoll()`, `devpoll()`, and `kqueue()` than `select()`. Python 3.4 introduced the Selectors module to choose the best syscall available for us. This will close #7880. ### Solution For Python 3 code, use the new selectors library. Python 2 code stays the same as before, since the library does not exist for it and we are soon going to drop Python 2.
### Problem Twitter was running into the error `filedescriptor out of range in select()` when compiling a large number of targets, per #7880. In the process, we found that it is more efficient and robust to use the more modern syscalls of `epoll()`, `devpoll()`, and `kqueue()` than `select()`. Python 3.4 introduced the Selectors module to choose the best syscall available for us. This will close #7880. ### Solution For Python 3 code, use the new selectors library. Python 2 code stays the same as before, since the library does not exist for it and we are soon going to drop Python 2.
…ld#7882) ### Problem Twitter was running into the error `filedescriptor out of range in select()` when compiling a large number of targets, per pantsbuild#7880. In the process, we found that it is more efficient and robust to use the more modern syscalls of `epoll()`, `devpoll()`, and `kqueue()` than `select()`. Python 3.4 introduced the Selectors module to choose the best syscall available for us. This will close pantsbuild#7880. ### Solution For Python 3 code, use the new selectors library. Python 2 code stays the same as before, since the library does not exist for it and we are soon going to drop Python 2.
Problem
Twitter has 85 targets that fail to compile due to the message:
filedescriptor out of range in select()
, which sometimes traces tonailgun_executor.py
and sometimes toutil/socket.py
:pants/src/python/pants/java/nailgun_executor.py
Line 221 in 640400c
pants/src/python/pants/util/socket.py
Line 67 in 640400c
We don't encounter this in Pants CI, because we don't try to compile as many targets as Twitter does (1500+ for these tests).
In the process of researching this, I found that many view the
select()
syscall as deprecated in favor of the more modernpoll()
and even more modernepoll()
,devpoll()
, andkqueue()
. See https://beesbuzz.biz/code/5739-The-problem-with-select-vs-poll and https://stackoverflow.com/questions/970979/what-are-the-differences-between-poll-and-select.Beyond generally being less desirable to use
select()
, it is very likely this is causing thefiledescriptor out of range
issue, per https://stackoverflow.com/a/41497735.Proposed solution: Selectors library
Python 3.4 introduced the new
selectors
stdlib module via PEP 3156, built right on top of the low-levelselect
stdlib module.Beyond nice abstractions, the main benefit we get is the class
DefaultSelector
, which will choose the best syscall possible for that platform, e.g.kqueue
on macOS / BSD andepoll()
on Ubuntu. It will only revert toselect()
as a last resort, which will allow us to work around the filedescriptor issue, in addition to making the code more robust and easier to understand.Handling Python 2 compatibility
This module was only introduced in Python 3.4, and was not backported. There does exist a 3rdparty backport
selectors2
that we could use.However, because we plan to drop Python 2 any day now—and the Twitter tests were passing when using Python 2 to run Pants—I propose that we keep the Python 2 code exactly how it is using
select.select()
, and only useselectors
for Python 3 via anif PY3
check. In hopefully a week, we can kill off the Python 2 code branch.The text was updated successfully, but these errors were encountered: