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
ThreadPool concurrency refactoring #2220
Conversation
- Wait for threads to enter waiting loop on ThreadPool startup - Simplify #spawn_thread inner threadpool loop - Refactor TestThreadPool to make tests faster and more stable
8d61027
to
e1daf1b
Compare
@@ -36,6 +36,7 @@ | |||
* Simplify `Runner#start_control` URL parsing (#2111) | |||
* Removed the IOBuffer extension and replaced with Ruby (#1980) | |||
* Update `Rack::Handler::Puma.run` to use `**options` (#2189) | |||
* ThreadPool concurrency refactoring (#2220) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the trim bugfix could also be mentioned
I'll have to find some time to review this proper, but the test changes are gorgeous 😍 |
@@ -99,20 +102,13 @@ def spawn_thread | |||
while true | |||
work = nil | |||
|
|||
continue = true | |||
|
|||
mutex.synchronize do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clever change and much more readable
end | ||
Thread.pass until finish | ||
pool.signal | ||
sleep |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo or are you triggering a context switch?
Well, "fix" might overstate it, but we were able to get them passing by backporting test skips that are currently in Puma master upstream. With these skips, not only does tag `4.3.3.` all pass, but so does our custom branch, so we can be pretty confident we haven't broken anything vs. stock Puma. Some notes on test runs: - Invoke with `bundle exec rake test --trace` - Ctrl-C'ing the tests usually left a zombified version running in the background, which would *cause failures on subsequent runs*. Ensure after killing the a test run that no test processes remain in `jps -lm` - `TestThreadPool` tests are flaky in this release, though this was a known issue, and has been recently fixed here: puma#2220
Well, "fix" might overstate it, but we were able to get them passing by backporting test skips that are currently in Puma master upstream. With these skips, not only does tag `4.3.3.` all pass, but so does our custom branch, so we can be pretty confident we haven't broken anything vs. stock Puma. Some notes on test runs: - Invoke with `bundle exec rake test --trace` - Ctrl-C'ing the tests usually left a zombified version running in the background, which would *cause failures on subsequent runs*. Ensure after killing the a test run that no test processes remain in `jps -lm` - `TestThreadPool` tests are flaky in this release, though this was a known issue, and has been recently fixed here: puma#2220
Description
This PR refactors some tricky concurrency parts of
TestThreadPool
, in order to make the unit tests more stable (all tests pass on jruby), faster (no more 1-second sleeps), and a bit more readable. Many of the tests now use a subclass ofThreadPool
that overrides#<<
to wait on the existing@not_full
condition variable, to ensure work begins executing on a worker thread before continuing the test.There are also some small changes to the
ThreadPool
class itself:#with_mutex
to make it easier to chain multiple@mutex.synchronize
-wrapped methods together, and to extend existing mutex-wrapped methods in unit tests.#initialize
. This fixes a subtle edge-case concurrency bug mostly affecting unit-test reliability, demonstrated by the following simple test that fails onmaster
:puma/test/test_thread_pool.rb
Lines 239 to 242 in 8d61027
#trim
where a trim could still be requested even when enough work to utilize all threads has been queued but not yet picked up by workers (e.g.,waiting > 0
butwaiting - todo.size == 0
). (I believe this was the cause of some jruby test flakiness in sometrim
unit tests.)spawn_thread
to make it a bit simpler and easier to read and reason about.Your checklist for this pull request
[changelog skip]
the pull request title.[ci skip]
to the title of the PR.#issue
" to the PR description or my commit messages.