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
Always remove the right listener from the hub #498
Conversation
Sorry for delay, I'm in road.
…On Fri, Jun 8, 2018, 20:20 Sam Merritt ***@***.***> wrote:
When in hubs.trampoline(fd, ...), a greenthread registers itself as a
listener for fd, switches to the hub, and then calls
hub.remove(listener) to deregister itself. hub.remove(listener)
removes the primary listener. If the greenthread awoke because its fd
became ready, then it is the primary listener, and everything is
fine. However, if the greenthread was a secondary listener and awoke
because a Timeout fired then it would remove the primary and promote a
random secondary to primary.
This commit makes hub.remove(listener) check to make sure listener is
the primary, and if it's not, remove the listener from the
secondaries.
I found this when I saw a process running at 100% CPU and strace showed it
calling poll() in a tight loop. There was a readable file descriptor, but
the process never read it.
------------------------------
You can view, comment on, or merge this pull request online at:
#498
Commit Summary
- Always remove the right listener from the hub
File Changes
- *M* eventlet/hubs/hub.py
<https://github.com/eventlet/eventlet/pull/498/files#diff-0> (26)
- *M* tests/hub_test.py
<https://github.com/eventlet/eventlet/pull/498/files#diff-1> (47)
Patch Links:
- https://github.com/eventlet/eventlet/pull/498.patch
- https://github.com/eventlet/eventlet/pull/498.diff
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#498>, or mute the thread
<https://github.com/notifications/unsubscribe-auth/AABpseqfmCWVCA5RAXduoiYp9fee77sIks5t6rJdgaJpZM4Ugq5d>
.
|
I tried @charmster's suggestion of making that into a |
Codecov Report
@@ Coverage Diff @@
## master #498 +/- ##
======================================
+ Coverage 45% 46% +<1%
======================================
Files 81 81
Lines 7933 8074 +141
Branches 1357 1434 +77
======================================
+ Hits 3595 3730 +135
+ Misses 4096 4093 -3
- Partials 242 251 +9
Continue to review full report at Codecov.
|
When in hubs.trampoline(fd, ...), a greenthread registers itself as a listener for fd, switches to the hub, and then calls hub.remove(listener) to deregister itself. hub.remove(listener) removes the primary listener. If the greenthread awoke because its fd became ready, then it is the primary listener, and everything is fine. However, if the greenthread was a secondary listener and awoke because a Timeout fired then it would remove the primary and promote a random secondary to primary. This commit makes hub.remove(listener) check to make sure listener is the primary, and if it's not, remove the listener from the secondaries.
I opened #645 if we wanted to move in the direction @charmster suggested - I'm confident this patch fixes a gaping hole for folks using multiple readers as written. IMHO this should merge, and any additional improvements should be follow-ons. |
@smerritt now that core of this patch is merged, please decide whether you want to rebase or close this. |
a56a722
to
0443a1f
Compare
Codecov Report
@@ Coverage Diff @@
## master #498 +/- ##
=======================================
+ Coverage 44% 46% +1%
=======================================
Files 87 81 -6
Lines 11831 8074 -3757
Branches 1774 1434 -340
=======================================
- Hits 5254 3730 -1524
+ Misses 6180 4093 -2087
+ Partials 397 251 -146
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
#645 looks good to me, thanks. |
When in hubs.trampoline(fd, ...), a greenthread registers itself as a
listener for fd, switches to the hub, and then calls
hub.remove(listener) to deregister itself. hub.remove(listener)
removes the primary listener. If the greenthread awoke because its fd
became ready, then it is the primary listener, and everything is
fine. However, if the greenthread was a secondary listener and awoke
because a Timeout fired then it would remove the primary and promote a
random secondary to primary.
This commit makes hub.remove(listener) check to make sure listener is
the primary, and if it's not, remove the listener from the
secondaries.
I found this when I saw a process running at 100% CPU and strace showed it calling poll() in a tight loop. There was a readable file descriptor, but the process never read it.