Feature #21957
openIntroduce `Enumerable#close` to free internal resources.
Description
In some cases, Enumerable has substantial internal state (e.g. Fiber) related to enumeration. There is currently no way to clear up this state besides garbage collection, which means that we can accumulate considerable garbage before cleaning up, even if we know when the enumerable is no longer needed.
I'd like to introduce Enumerable#close which invalidates the enumerable, freeing internal resources. After which, most usage would result in Enumerable::ClosedError.
Updated by Eregon (Benoit Daloze) 4 months ago
+1
Leaking Fibers through an Enumerator is quite common and relying on the GC to clean that up is pretty brittle and it also adds significant complexity on the Ruby implementation (e.g. weakref to the Fiber object).
You're mentioning Enumerable here, but isn't it about Enumerator rather?
ioquatix (Samuel Williams) wrote:
After which, most usage would result in
Enumerable::ClosedError.
Right, and that would work by simply having Enumerator#each for such Enumerators raise a Enumerator::ClosedError.
Updated by ioquatix (Samuel Williams) 5 days ago
Possible implementation: https://github.com/ruby/ruby/pull/17624
Updated by ioquatix (Samuel Williams) 5 days ago
ยท Edited
@mame (Yusuke Endoh) If we decide to use Fiber#kill for terminating the fiber (which seems reasonable), it seems bad that it may not return to the point that rb_fiber_kill was invoked. WDYT?
It would be the same issue as discussed in https://bugs.ruby-lang.org/issues/20081
Alternatively, just setting the internal fiber to nil (as well as other state) may be sufficient for the GC to clean up.