From: "Eregon (Benoit Daloze)" Date: 2022-11-22T12:20:06+00:00 Subject: [ruby-core:110855] [Ruby master Feature#19078] Introduce `Fiber#storage` for inheritable fiber-scoped variables. Issue #19078 has been updated by Eregon (Benoit Daloze). I've been reading https://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part2.html#scope-variables again and parts of the [JEP](https://openjdk.org/jeps/429). For that approach to work it really needs structured concurrency (well explained [here](https://www.davidvlijmincx.com/posts/loom/java_structured_concurrency/#what-is-structured-concurrency)). One issue is we don't currently have a standard way to express structured concurrency in Ruby. Even though that could be very useful, also for e.g. #19141. Maybe it could be something like creating a "concurrency scope" using a block like: ```ruby structured_concurrency do |c| c << Fiber.new { ... } c << Thread.new { ... } # Fiber/Thread could also maybe automatically register in c without `c <<` end ``` and that at the end of the block would wait that every Fiber/Thread created in there finishes (which would mean calling `resume` repetitively for Fibers, and `join` for Threads). I guess `Async` has some similar concepts, right? cc @ioquatix From my previous comment in https://bugs.ruby-lang.org/issues/19062#note-29 in this issue we are defining inheritable fiber locals. I think that makes sense and in some cases it's probably useful the storage is available longer than the parent Fiber lives (even though that can be dangerous too). I just wonder if we might want structured concurrency and related concepts too in Ruby at some point. ---------------------------------------- Feature #19078: Introduce `Fiber#storage` for inheritable fiber-scoped variables. https://bugs.ruby-lang.org/issues/19078#change-100215 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal * Assignee: ioquatix (Samuel Williams) ---------------------------------------- Pull Request: https://github.com/ruby/ruby/pull/6612 This is an evolution of the previous ideas: - https://bugs.ruby-lang.org/issues/19058 - https://bugs.ruby-lang.org/issues/19062 This PR introduces fiber scoped variables, and is a solution for problems like . The main interface is: ```ruby Fiber[key] = value Fiber[key] # => value ``` The variables are scoped (local to) a fiber and inherited into child fibers and threads. ```ruby Fiber[:request_id] = SecureRandom.hex(16) Fiber.new do p Fiber[:request_id] # prints the above request id end ``` The fiber scoped variables are stored and can be accessed: ```ruby Fiber.current.storage # => returns a Hash (copy) of the internal storage. Fiber.current.storage= # => assigns a Hash (copy) to the internal storage. ``` Fiber itself has one new keyword argument: ``` Fiber.new(..., storage: hash, false, undef, nil) ``` This can control how the fiber variables are setup in a child context. To minimise the performance overhead of some of the implementation choices, we are also simultaneously implementing . ## Examples ### Request loop ```ruby Thread.new do while request = queue.pop Fiber.new(storage: {id: SecureRandom.hex(16)}) do handle_request.call(request) end end end ``` OR ```ruby Thread.new do while request = queue.pop Fiber.current.storage = {id: SecureRandom.hex(16)} handle_request.call(request) end end ``` -- https://bugs.ruby-lang.org/ Unsubscribe: