From: "lloeki (Loic Nageleisen) via ruby-core" <ruby-core@ml.ruby-lang.org>
To: ruby-core@ml.ruby-lang.org
Cc: "lloeki (Loic Nageleisen)" <noreply@ruby-lang.org>
Subject: [ruby-core:111348] [Ruby master Feature#19078] Introduce `Fiber#storage` for inheritable fiber-scoped variables.
Date: Tue, 20 Dec 2022 13:42:05 +0000 (UTC) [thread overview]
Message-ID: <redmine.journal-100722.20221220134205.3344@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-19078.20221022215641.3344@ruby-lang.org
Issue #19078 has been updated by lloeki (Loic Nageleisen).
This is really nice for some use cases, and I was planning to propose basically exactly what @ioquatix proposed here to tackle these.
One example: we create context objects that allow us to track what happens across a given HTTP request execution. Typically with Rack we can store that in the Rack environment, but it so happens that elements we instrument via module prepending may not have access to the Rack environment. To get the context we then have to store that context object in a thread local (which is actually fiber local). The consequence is that if some bit code then goes async/concurrent (another thread or fiber) then context is (of course) lost. This would allow to keep the context within which we want to track things. As it turns out one of our team members from Sqreen implemented AsyncLocalContext which is incredibly similar in its purpose: https://nodejs.org/api/async_context.html
Another example: [Rails is doing unhappy things to thread locals](https://github.com/rails/rails/blob/1512cf2ba578282c898b8eb68ac401ea5243b7b5/actionpack/lib/action_controller/metal/live.rb#L261-L263) when using `ActionController::Live`: it blindly copies thread locals to the new thread in an attempt to have the new thread behave like the old one. This is not good as it assumes none of these thread locals would be concurrently accessed or mutated, when by design thread locals are supposed to be, well, local to threads, thus can eschew thread safetiness safe nets. With this feature, Rails may be in a position to use it for what it needs and maybe stop its blind copying.
----------------------------------------
Feature #19078: Introduce `Fiber#storage` for inheritable fiber-scoped variables.
https://bugs.ruby-lang.org/issues/19078#change-100722
* 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/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/
next prev parent reply other threads:[~2022-12-20 13:42 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-22 21:56 [ruby-core:110481] [Ruby master Bug#19078] Introduce `Fiber#storage` for inheritable fiber-scoped variables ioquatix (Samuel Williams)
2022-10-24 23:07 ` [ruby-core:110504] [Ruby master Feature#19078] " tenderlovemaking (Aaron Patterson)
2022-10-24 23:09 ` [ruby-core:110505] " tenderlovemaking (Aaron Patterson)
2022-10-26 10:21 ` [ruby-core:110515] " byroot (Jean Boussier)
2022-10-26 20:47 ` [ruby-core:110519] " ioquatix (Samuel Williams)
2022-10-26 20:49 ` [ruby-core:110520] " ioquatix (Samuel Williams)
2022-10-27 10:15 ` [ruby-core:110522] " byroot (Jean Boussier)
2022-10-28 1:06 ` [ruby-core:110526] " ioquatix (Samuel Williams)
2022-11-08 15:48 ` [ruby-core:110658] " Eregon (Benoit Daloze)
2022-11-08 21:04 ` [ruby-core:110660] " byroot (Jean Boussier)
2022-11-09 0:31 ` [ruby-core:110664] " marcotc (Marco Costa)
2022-11-22 12:20 ` [ruby-core:110855] " Eregon (Benoit Daloze)
2022-11-22 17:32 ` [ruby-core:110859] " ioquatix (Samuel Williams)
2022-11-23 10:54 ` [ruby-core:110865] " Eregon (Benoit Daloze)
2022-11-23 19:55 ` [ruby-core:110868] " ioquatix (Samuel Williams)
2022-11-29 21:56 ` [ruby-core:111076] " ivoanjo (Ivo Anjo)
2022-11-30 17:11 ` [ruby-core:111092] " Dan0042 (Daniel DeLorme)
2022-12-01 4:59 ` [ruby-core:111103] " matz (Yukihiro Matsumoto)
2022-12-01 8:44 ` [ruby-core:111120] " ioquatix (Samuel Williams)
2022-12-01 10:05 ` [ruby-core:111125] " ioquatix (Samuel Williams)
2022-12-02 9:34 ` [ruby-core:111147] " ioquatix (Samuel Williams)
2022-12-02 15:00 ` [ruby-core:111158] " nevans (Nicholas Evans)
2022-12-02 16:23 ` [ruby-core:111159] " nevans (Nicholas Evans)
2022-12-20 13:42 ` lloeki (Loic Nageleisen) via ruby-core [this message]
2022-12-20 14:53 ` [ruby-core:111351] " lloeki (Loic Nageleisen) via ruby-core
2022-12-20 16:49 ` [ruby-core:111353] " Eregon (Benoit Daloze) via ruby-core
2022-12-20 17:31 ` [ruby-core:111354] " Eregon (Benoit Daloze) via ruby-core
2022-12-20 18:22 ` [ruby-core:111355] " Eregon (Benoit Daloze) via ruby-core
2022-12-20 21:33 ` [ruby-core:111357] " Eregon (Benoit Daloze) via ruby-core
2022-12-21 13:41 ` [ruby-core:111359] " Eregon (Benoit Daloze) via ruby-core
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.ruby-lang.org/en/community/mailing-lists/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=redmine.journal-100722.20221220134205.3344@ruby-lang.org \
--to=ruby-core@ruby-lang.org \
--cc=noreply@ruby-lang.org \
--cc=ruby-core@ml.ruby-lang.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).