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

Non blocking ReservedThreadExecutor #6535

Merged
merged 36 commits into from Jul 28, 2021

Conversation

gregw
Copy link
Contributor

@gregw gregw commented Jul 23, 2021

This is yet another alternative fix for #6495 replacing #6496
The stack is removed entirely and all the reserved threads poll in parallel on the same synchronous queue.
The tryExecute semantic is simply to do a non-blocking offer to the queue which will either succeed or fail, and no further action is required.

The size and pending counts are important to keep the capacity correct.
The reserved threads are added as beans, but only for the purposes of dumping.
The reserved threads track their state to make the dumps more meaningful.

The only issue with losing the stack is that it may prevent reserved threads idling out as load might be shared over all the reserved threads rather than just the most recent.
However, there are other strategies that could be applied to deal with that (eg looking at recent minimum size before re-polling).

gregw and others added 20 commits July 6, 2021 17:40
Never block waiting for reserved thread.
Dump reserved thread stack if it does not make the rendezvous
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
avoid waiting 1s
If a reserved thread does not rendezvous, put it back on the bottom of the stack.
Even more paranoid checks:
 + test if an missed offer was for a thread that removed itself from the stack
 + test if a reserved thread is already on the stack before adding it.
Even more paranoid checks:
 + try to poll after remove to check for race in remove
Even more paranoid checks:
 + try to poll after remove to check for race in remove
This is a new approach to #6495.    A call to offer must never block, nor even yield, since to do so give an opportunity for the allocated CPU core to change, defeating the whole purpose of the class.

There is also some reasonable level of diagnostic warnings if a reserved thread misses too many offers consecutively, based on tracking the state of the reserved thread.
Use MAX_VALUE rather than -1 as the stopped marker value.
Remove the stack data structure entirely.  ReservedThreads all poll the same SynchronousQueue and tryExecute does a non blocking offer.
Added test for busy shrinking
Remember last time we hit zero reserved threads
Copy link
Contributor

@lorban lorban left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the simplification a lot!

@lorban lorban self-requested a review July 23, 2021 19:08
updates from review
@gregw
Copy link
Contributor Author

gregw commented Jul 23, 2021

@lorban updated

@gregw gregw requested a review from lorban July 25, 2021 00:42
@gregw
Copy link
Contributor Author

gregw commented Jul 25, 2021

@sbordet nudge?

updates from review
@gregw gregw requested a review from lorban July 27, 2021 05:37
@gregw
Copy link
Contributor Author

gregw commented Jul 27, 2021

@sbordet nudge

Signed-off-by: Greg Wilkins <gregw@webtide.com>
@gregw gregw requested a review from sbordet July 27, 2021 12:09
Signed-off-by: Greg Wilkins <gregw@webtide.com>
…:eclipse/jetty.project into jetty-9.4.x-6495-ReservedThreadExecutor3
updates from review
simplified tryExecute
updates from review
updates from review
updates from review
@gregw gregw requested a review from sbordet July 28, 2021 13:49
@gregw gregw merged commit 735e97d into jetty-9.4.x Jul 28, 2021
@gregw gregw deleted the jetty-9.4.x-6495-ReservedThreadExecutor3 branch July 28, 2021 23:46
gregw added a commit that referenced this pull request Jul 28, 2021
A call to offer must never block, nor even yield, since to do so give an opportunity for the allocated CPU core to change, defeating the whole purpose of the class.
There is also some reasonable level of diagnostic warnings if a reserved thread misses too many offers consecutively, based on tracking the state of the reserved thread.

Remove the stack data structure entirely.  ReservedThreads all poll the same SynchronousQueue and tryExecute does a non blocking offer.

Added test for busy shrinking

Remember last time we hit zero reserved threads

Co-authored-by: Simone Bordet <simone.bordet@gmail.com>
gregw added a commit that referenced this pull request Jul 29, 2021
A call to offer must never block, nor even yield, since to do so give an opportunity for the allocated CPU core to change, defeating the whole purpose of the class.
There is also some reasonable level of diagnostic warnings if a reserved thread misses too many offers consecutively, based on tracking the state of the reserved thread.

Remove the stack data structure entirely.  ReservedThreads all poll the same SynchronousQueue and tryExecute does a non blocking offer.

Added test for busy shrinking

Remember last time we hit zero reserved threads

Co-authored-by: Simone Bordet <simone.bordet@gmail.com>
@sbordet sbordet added this to In progress in Jetty 9.4.44 FROZEN via automation Sep 20, 2021
@sbordet sbordet added this to In progress in Jetty 10.0.7/11.0.7 FROZEN via automation Sep 20, 2021
@sbordet sbordet moved this from In progress to Done in Jetty 10.0.7/11.0.7 FROZEN Sep 20, 2021
@sbordet sbordet moved this from In progress to Done in Jetty 9.4.44 FROZEN Sep 20, 2021
@sbordet sbordet removed this from Done in Jetty 10.0.7/11.0.7 FROZEN Sep 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

None yet

3 participants