Class: Concurrent::FiberLocalVar

Inherits:
Object
  • Object
show all
Defined in:
lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb

Overview

A FiberLocalVar is a variable where the value is different for each fiber. Each variable may have a default value, but when you modify the variable only the current fiber will ever see that change.

This is similar to Ruby's built-in fiber-local variables (Thread.current[:name]), but with these major advantages:

  • FiberLocalVar has its own identity, it doesn't need a Symbol.
  • Each Ruby's built-in fiber-local variable leaks some memory forever (it's a Symbol held forever on the fiber), so it's only OK to create a small amount of them. FiberLocalVar has no such issue and it is fine to create many of them.
  • Ruby's built-in fiber-local variables leak forever the value set on each fiber (unless set to nil explicitly). FiberLocalVar automatically removes the mapping for each fiber once the FiberLocalVar instance is GC'd.

Examples:

v = FiberLocalVar.new(14)
v.value #=> 14
v.value = 2
v.value #=> 2
v = FiberLocalVar.new(14)

Fiber.new do
  v.value #=> 14
  v.value = 1
  v.value #=> 1
end.resume

Fiber.new do
  v.value #=> 14
  v.value = 2
  v.value #=> 2
end.resume

v.value #=> 14

Constant Summary collapse

LOCALS =
FiberLocals.new

Instance Method Summary collapse

Constructor Details

#initialize(default = nil, &default_block) ⇒ FiberLocalVar

Creates a fiber local variable.

Parameters:

  • default (Object) (defaults to: nil)

    the default value when otherwise unset

  • default_block (Proc)

    Optional block that gets called to obtain the default value for each fiber



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb', line 49

def initialize(default = nil, &default_block)
  if default && block_given?
    raise ArgumentError, "Cannot use both value and block as default value"
  end

  if block_given?
    @default_block = default_block
    @default = nil
  else
    @default_block = nil
    @default = default
  end

  @index = LOCALS.next_index(self)
end

Instance Method Details

#bind(value) { ... } ⇒ Object

Bind the given value to fiber local storage during execution of the given block.

Parameters:

  • value (Object)

    the value to bind

Yields:

  • the operation to be performed with the bound variable

Returns:

  • (Object)

    the value



86
87
88
89
90
91
92
93
94
95
96
# File 'lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb', line 86

def bind(value)
  if block_given?
    old_value = self.value
    self.value = value
    begin
      yield
    ensure
      self.value = old_value
    end
  end
end

#valueObject

Returns the value in the current fiber's copy of this fiber-local variable.

Returns:

  • (Object)

    the current value



68
69
70
# File 'lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb', line 68

def value
  LOCALS.fetch(@index) { default }
end

#value=(value) ⇒ Object

Sets the current fiber's copy of this fiber-local variable to the specified value.

Parameters:

  • value (Object)

    the value to set

Returns:

  • (Object)

    the new value



76
77
78
# File 'lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb', line 76

def value=(value)
  LOCALS.set(@index, value)
end
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy