Issue #20081 has been updated by ioquatix (Samuel Williams).
In think clarifying the documentation is a good idea.
And .transfer does return to the caller, as long as
the caller is the main Fiber, for example, this prints out a sequence of messages:
I think that's just intuitively correct based on the semantics.
Actually, one could argue that a fiber that was transferred to, that exits, without an
explicit transfer, should be considered exiting the thread completely and in your case
terminating the program. In this case, Ruby is being a bit generous with
"transferring back to the main fiber" IMHO. Transfer should be seen as a one way
operation.
----------------------------------------
Bug #20081: Transfered Fiber doesn't return to Fiber that started it
https://bugs.ruby-lang.org/issues/20081#change-105897
* Author: rmosolgo (Robert Mosolgo)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-darwin22]
* Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
Hi! I'm trying to figure out how to make sure that Fibers started with `.transfer` end
up _terminated_, not just suspended. (If they're suspended, Rails thinks they're
still alive, and they continue to hold onto database connections, see:
https://github.com/rmosolgo/graphql-ruby/issues/4739#issuecomment-1866930914.)
So, I'm looking for way to make sure that any Fiber I start with `.transfer` will be
properly terminated. But what I noticed is that when a transfer-based Fiber terminates, it
gives control back to the top-most Fiber, not the Fiber which transfered to it. Is this
intended? Here's a script to replicate the issue:
```ruby
manager = Fiber.new do
parent = Fiber.current
worker = Fiber.new do
puts "2. Begin Worker"
parent.transfer
puts "4. End Worker"
end
puts "1. Transfer 1"
worker.transfer
puts "3. Transfer 2"
worker.transfer
puts "5. Finished manager"
end
manager.transfer
puts "6. Finished script"
```
I expect the steps to print in order:
```
1. Transfer 1
2. Begin Worker
3. Transfer 2
4. End Worker
5. Finished manager
6. Finished script
```
But instead, `5. ...` is skipped:
```
1. Transfer 1
2. Begin Worker
3. Transfer 2
4. End Worker
6. Finished script
```
I think that's because my `worker` fiber terminates and passes control back to the
top-level Fiber.
Should it have passed control back to the `manager`? Or is there another way to make sure
`worker` is terminated, and `manager` gets control?
--
https://bugs.ruby-lang.org/