From: "ioquatix (Samuel Williams)" Date: 2022-10-26T20:47:12+00:00 Subject: [ruby-core:110519] [Ruby master Feature#19078] Introduce `Fiber#storage` for inheritable fiber-scoped variables. Issue #19078 has been updated by ioquatix (Samuel Williams). Does Ruby provide any "Hash" -> "Symbol Table" object or mapping/conversion? Otherwise we have to do it ourselves which is O(N) vs O(1) or less for hash dup (CoW) internally. So it will be worse performance to force all keys to be symbols (not better). However, if Ruby has some kind of "Symbol Table" that we can trust, it is possible to be better performance, slightly. In addition, I've seen some questionable code as a result of this design decision, things like: ```ruby def thing Thread.current[:"#{self.class}_#{self.object_id}"] ||= ... end ``` I feel like this encourages bad practices because people are forced to convert objects to the hash. Maybe a better option would be to require the hash to be compare-by-identity or equivalent. This should be equally fast, and from the PoV of the internal storage, equivalent to using a symbol table (now it's literally just a pointer comparison). ---------------------------------------- Feature #19078: Introduce `Fiber#storage` for inheritable fiber-scoped variables. https://bugs.ruby-lang.org/issues/19078#change-99842 * 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: