[WIP] Implement file descriptor removal and waiting in asyncio hub#924
[WIP] Implement file descriptor removal and waiting in asyncio hub#9244383 wants to merge 1 commit intoeventlet:masterfrom
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #924 +/- ##
======================================
- Coverage 56% 54% -2%
======================================
Files 89 89
Lines 9728 9773 +45
Branches 1812 1822 +10
======================================
- Hits 5461 5347 -114
- Misses 3892 4054 +162
+ Partials 375 372 -3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
We recently observed (eventlet#912) difference in the behaviors between the asyncio hub and the other eventlet hubs. The asyncio hub behaved differenly because bad file descriptor were not properly removed from the list of readers and writers listeners. To clean these bad file descriptors we have to implement an awaitable wait method specific to the asyncio hub This patch should fix eventlet#912. I prefer to propose this patch as a separated patch to isolate topics and simplify reviews. eventlet#912
|
I need to address the job errors. Will have a look soon. |
|
The test in error ( If I run this (failing) test in isolated way, it is successful each time I run it... |
|
Again I observes two different behaviors depending on if I run the test (`test_cancelling_future_kills_greenthread``) alone [1] or not [2]. If I run the problematic test among other tests, the test do not seems to run the eventlet/tests/asyncio_test.py Lines 236 to 242 in 0a130e2 eventlet/tests/asyncio_test.py Lines 227 to 232 in 0a130e2 This strange behavior seems introduced by the changes I proposed in this pull request. If I run the same test independently of the other tests, then this test is successful... See my previous comment. [1] |
|
Here is a reproducer by entering a PDB post mortem on the broken test. And which is called in the asyncio hub module: eventlet/eventlet/hubs/asyncio.py Line 141 in b13a262 |
itamarst
left a comment
There was a problem hiding this comment.
I think this approach is fundamentally not the way to do it.
| all_fds = list(self.listeners[self.READ]) + list(self.listeners[self.WRITE]) | ||
| for fd in all_fds: | ||
| try: | ||
| select.select([fd], [], [], 0) |
There was a problem hiding this comment.
Using select() is problematic. It has a fixed max numeric value for file descriptors. So if the max is e.g. 512 and you pass in file descriptor 637, it won't be able to do anything with that descriptor.
To avoid this you want to use poll() if available, and only fall back to select() if poll() is not available (which effectively means Windows).
There was a problem hiding this comment.
oh interesting, I was not aware of that threshold. Indeed poll seems more appropriate.
To be honest, I copy/pasted this logic from the other hubs and I tried to adapt it for asyncio. That mean that all the other hubs are impacted by the limitation of select.
|
|
||
| self.loop.run_until_complete(async_run()) | ||
|
|
||
| async def wait(self, seconds=None): |
There was a problem hiding this comment.
You're duplicating a whole bunch of asyncio logic, and moreover doing it in a way that makes it much less scalable because e.g. you're not using epoll on Linux. And the issues with select()'s max file descriptor limit. This does not seem like the way to solve this problem.
There was a problem hiding this comment.
Or, let me rephrase. You are completely breaking the asyncio event loop by blocking. So now any normal asyncio code will only be run intermittently.
There was a problem hiding this comment.
That could explain the failure I observed on the asyncio tests you originally implemented. See the job failure.
|
I can see if I can implement this a different way. |
Sure, do not hesitate, you are far well skilled than me on asyncio things. I think we need this file descriptor management, but I surely implemented it in a bad way. So do not hesitate to go wild! ;) |
|
I think we decided not to go down this route. |
We recently observed (#912) difference in the behaviors between the asyncio hub and the other eventlet hubs.
The asyncio hub behaved differenly because bad file descriptor were not properly removed from the list of readers and writers listeners.
To clean these bad file descriptors we have to implement an awaitable wait method specific to the asyncio hub
This patch should fix #912.
I prefer to propose this patch as a separated patch to isolate topics and simplify reviews.
#912