Fix flaky specs on TruffleRuby - #597
Open
andrykonchin wants to merge 2 commits into
Open
Conversation
houndci-bot
reviewed
Jul 17, 2026
|
|
||
| def _stop | ||
| @run_thread&.kill | ||
| @run_thread.kill.join if @run_thread |
There was a problem hiding this comment.
Style/SafeNavigation: Use safe navigation (&.) instead of checking if an object exists before calling the method.
|
|
||
| def _stop | ||
| @worker_thread&.kill | ||
| @worker_thread.kill.join if @worker_thread |
There was a problem hiding this comment.
Style/SafeNavigation: Use safe navigation (&.) instead of checking if an object exists before calling the method.
|
我已收到你的邮件,谢谢!
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What/Why
CI fails sporadically on TruffleRuby because background threads are stopped asynchronously, causing different test cases to interfere with one another.
cc @eregon
The Root Cause
In the
listengem, when an adapter is stopped via stop, it invokes the private_stopmethod. InListen::Adapter::Base and Listen::Adapter::Darwin,_stopterminates background adapter threads (like@run_threadand@worker_thread) usingThread#killwithout waiting for them to die. However,Thread#killis asynchronous. In Ruby, target threads do not terminate instantaneously whenkillis called.The Race Condition
In
adapter/linux_spec.rb, a real polling adapter is started, which spawns the background@run_threadusing a mock silencer double. After the test runs,subject.stopis called to kill the thread, and the test immediately concludes. Once the test concludes, RSpec enters its teardown phase and destroys/resets the mock doubles. Because the background thread was not joined, it was still running (navigating directories or building initial state) while the next test files loaded and started executing (e.g.,event/queue_spec.rb). When the leaked thread executed the next check on the (now deregistered/destroyed) silencer double, RSpec raised an unexpected message error (#<InstanceDouble(Listen::Silencer) "silencer"> received unexpected message :silenced? with ("", :dir)).Why it aborted the whole suite
The test helper in
spec/spec_helper.rbsetsThread.abort_on_exception= true. Therefore, when the mock error propagated out of the background thread as an unhandled exception, it immediately aborted the main thread duringevent/queue_spec.rb, causing that test to fail.Failed CI job example
Exception in `adapter/linux_spec.rb`
Failing `event/queue_spec.rb`
https://github.com/andrykonchin/listen/actions/runs/29610077425/job/87982425598?pr=1