at_exit hook sometimes freeze forever when a rails application executes test codes
Your environment
- ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux]
- rdbg 1.11.0
Describe the bug
This issue is related to https://github.com/ruby/debug/issues/1113.
Since the at_exit hook waits for all child processes other than the Ruby process, it leads to the following problem in the test code of a real Rails application.
- Load the debug gem
- The capybara-playwright-driver starts Playwright as a child process
- The capybara-playwright-driver registers an at_exit hook to terminate Playwright when the test ends
- During test code execution, when a fork occurs, the debug gem registers the at_exit hook
- After all test cases have finished, the debug gem's at_exit hook executes first and waits for the child process to terminate, but since the at_exit hook to terminate Playwright does not execute, it continues to wait indefinitely
This can occur normally if the debug gem is required. If it happens in a CI execution environment, it could result in unnecessary costs by holding computing resources for a long time.
I believe that waiting for all child processes(including not Ruby process) after a fork occurs is a significant issue.
To Reproduce
I described above.
Expected behavior
process finishes successfully.
Could you make a repro-scenario with simple script without capybara and so on?
My understanding is correct?
test
-> call capybara-playwright-driver
-> fork Playwright (*)
at the end of the test, wait for termination of (*) and it doesn't terminate, wait forever
It's not exactly correct. I mean the situation like below.
test
-> run browser test (launch playwright with popen3)
-> run other tests
-> fork in a test code or a production code for parallelism
at the end of the test, wait for termination of (*) and it doesn't terminate, wait forever
Normally, the order in which tests are executed is random, and it is difficult to write tests for Rails applications without using Capybara. I think the reason why problems rarely occur is that there are not many situations where forks are used in Rails applications or test code. But if an application that uses forks requires the debug gem, I think it would be difficult to understand the problem without being very familiar with the debug gem. (That's what happened to me. 😅 )
Sorry for late response.
Maybe the combination with fork and debug.gem should be reconsidered again. Currently, waiting for all child process because of TTY.
- User runs a process A, with debugger, on a terminal
- A forks process B
- A terminated before B, but B has debugger context
- The user regains control of the terminal
- B stops at breakpoint and mixing the shell and debugger prompt -> 🔥
I want to hear how to handle that...