Issue #19078 has been updated by nevans (Nicholas Evans).
I'm also a bit late to this. While I do have some nitpicks, I'll leave them for
another ticket (if I ever get around to it). But, to answer a couple of @Dan0042's
questions (and maybe others):
As mentioned by @eregon above, one of the most important use-cases for this is structured
concurrency. If you try to implement structured concurrency, you will eventually wind up
needing and implementing some version of this feature. If you look at the documentation
and API for go's and kotlin's versions of this feature, it's overwhelmingly
about structured concurrency. @eregon included a good link describing structured
concurrency, above. If I remember correctly, this page is also a good introduction to the
idea:
https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-con…
----
Here's a short list of the same basic feature, as implemented in several other
languages (I copied a couple of these links from the other tickets linked in the
description):
* [go's context package](https://pkg.go.dev/context#pkg-overview)
* Maybe the simplest implementation of the idea?
* [Kotlin's Coroutine
Contexts](https://kotlinlang.org/docs/coroutine-context-and-dispatchers.htm…
* [python's
contextvars](https://docs.python.org/3/library/contextvars.html)
(integrated with `asyncio`, etc)
* See [PEP
567](https://peps.python.org/pep-0567/) (and PEP-550 which preceded it) for
more info on design details, etc.
* [JEP 429: Extent-Local
Variables](https://openjdk.org/jeps/429)
This ticket is implemented a little bit differently than these, but is basically in the
same category and has many of the same motivations, etc.
----------------------------------------
Feature #19078: Introduce `Fiber#storage` for inheritable fiber-scoped variables.
https://bugs.ruby-lang.org/issues/19078#change-100441
* Author: ioquatix (Samuel Williams)
* Status: Closed
* 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
<https://github.com/ioquatix/ioquatix/discussions/17>.
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 <https://bugs.ruby-lang.org/issues/19077>.
## 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/