Maintenance Ruby 3.3 gets fixes, but no new features. Switch to Ruby 4.0 →
Fiber.new
static VALUE
rb_fiber_initialize(int argc, VALUE* argv, VALUE self)
{
return rb_fiber_initialize_kw(argc, argv, self, rb_keyword_given_p());
}
Creates new Fiber. Initially, the fiber is not running and can be resumed with resume. Arguments to the first resume call will be passed to the block:
f = Fiber.new do |initial| current = initial loop do puts "current: #{current.inspect}" current = Fiber.yield end end f.resume(100) # prints: current: 100 f.resume(1, 2, 3) # prints: current: [1, 2, 3] f.resume # prints: current: nil # ... and so on ...
If blocking: false is passed to Fiber.new, and current thread has a Fiber.scheduler defined, the Fiber becomes non-blocking (see “Non-blocking Fibers” section in class docs).
If the storage is unspecified, the default is to inherit a copy of the storage from the current fiber. This is the same as specifying storage: true.
Fiber[:x] = 1 Fiber.new do Fiber[:x] # => 1 Fiber[:x] = 2 end.resume Fiber[:x] # => 1
If the given storage is nil, this function will lazy initialize the internal storage, which starts as an empty hash.
Fiber[:x] = "Hello World" Fiber.new(storage: nil) do Fiber[:x] # nil end
Otherwise, the given storage is used as the new fiber’s storage, and it must be an instance of Hash.
Explicitly using storage: true is currently experimental and may change in the future.
Ruby version changes
-
3.2
-
Introduce
Fiber.[]andFiber.[]=for inheritable fiber storage. IntroduceFiber#storageandFiber#storage=(experimental) for getting and resetting the current storage. IntroduceFiber.new(storage:)for setting the storage when creating a fiber. [Feature #19078]Existing
ThreadandFiberlocal variables can be tricky to use. Thread-local variables are shared between all fibers, making it hard to isolate, while Fiber-local variables can be hard to share. It is often desirable to define unit of execution (“execution context”) such that some state is shared between all fibers and threads created in that context. This is whatFiberstorage provides.Exampledef log(message) puts "#{Fiber[:request_id]}: #{message}" end def handle_requests while request = read_request Fiber.schedule do Fiber[:request_id] = SecureRandom.uuid request.messages.each do |message| Fiber.schedule do log("Handling #{message}") # Log includes inherited request_id. end end end end end
You should generally consider
Fiberstorage for any state which you want to be shared implicitly between all fibers and threads created in a given context, e.g. a connection pool, a request id, a logger level, environment variables, configuration, etc.
-
-
3.0
-
Fiber.new(blocking: true/false) allows you to create non-blocking execution contexts. [Feature #16786]
-