Feature #22139
closedProhibit `END{}`/`Kernel#at_exit` in non-main Ractor
Description
Let's prohibit END{}/Kernel#at_exit on non-main Ractor.
The current behavior is strange:
Ractor.new{
at_exit{ p [self, Ractor.current] }
}
sleep 1
#=> [#<Ractor:#2 t.rb:2 terminated>, #<Ractor:#1 running>]
There are some options:
- prohibit them. Simple.
- invoke the block at the end of the Ractor.
- invoke the block at the end of the process on main Ractor. It is similar idea of the current behavior.
2 is rejected clearly by Matz because of the semantic gap with current behavior.
3 is no problem because the block and reachable objects from the block can be inherited to main Ractor.
However, to make it simple, now let's prohibit them (1), and revisit if we found the (3) is needed.
Updated by ko1 (Koichi Sasada) 25 days ago
Updated by ko1 (Koichi Sasada) 17 days ago
This change was approved by Matz.
Updated by ko1 (Koichi Sasada) 17 days ago
- Status changed from Open to Closed
Applied in changeset git|7896d376fb9cb602e2f5b26436c2ed8412b1ab9b.
Prohibit at_exit and END{} in non-main Ractors
Registering an exit handler with Kernel#at_exit or END{} in a non-main
Ractor behaved confusingly: the block ran in the main Ractor at process
exit even though it was registered from another Ractor. Raise
Ractor::IsolationError instead.
[Feature #22139]
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Updated by matz (Yukihiro Matsumoto) 16 days ago
I agree with prohibiting END{} and at_exit in non-main Ractors (option 1).
The current behavior is accidental rather than designed, and as I said before, invoking the block at the end of the Ractor (option 2) changes the meaning of at_exit too much. Option 3 is semantically consistent, but I doubt anyone actually wants blocks registered in a Ractor to fire on the main Ractor at process exit; the sharing/inheritance of reachable objects is also subtle. Starting with the simple prohibition is the right move. If real use cases emerge, we can relax it toward option 3 later, since going from an error to defined behavior is compatible.
Matz.