Module: Psyllium::FiberInstanceMethods

Included in:
Fiber
Defined in:
lib/psyllium/fiber.rb

Overview

A module meant to extend the builtin Fiber class to make it easier to use in a more Thread-like manner.

Instance Method Summary collapse

Instance Method Details

#join(limit = nil) ⇒ Object

Wait until execution completes. Return the Fiber instance. If limit is reached, returns nil instead.

join may be called more than once.



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/psyllium/fiber.rb', line 129

def join(limit = nil) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/AbcSize
  return self if state.joined
  raise Error.new('Cannot join self') if eql?(::Fiber.current)
  raise Error.new('Cannot join when calling Fiber is blocking') if ::Fiber.current.blocking?
  raise Error.new('Cannot join when called Fiber is blocking') if blocking?
  raise Error.new('Cannot join without Fiber scheduler set') unless ::Fiber.scheduler
  raise Error.new('Cannot join unstarted Fiber') unless state.started

  # Once this mutex finishes synchronizing, that means the initial
  # calculation is done and we can return `self`, which is the Fiber
  # instance.
  Timeout.timeout(limit) { state.mutex.synchronize { self } }
rescue Timeout::Error
  # mimic Thread behavior by returning `nil` on timeout.
  nil
end

#statusObject

Mimic Thread status method.

"run" will only be returned if this method is called on Fiber.current.

"sleep" is returned for any Fiber that is alive?, but not Fiber.current.

nil is returned if the Fiber completed with an exception.

false is returned if the Fiber completed without exception.

"abort" status is never returned because a Fiber does not have a state like this that is detectable or observable. If kill is called on a Fiber, the operation will happen immediately; there is not a point in time where status can be called between the call to kill and the point at which the Fiber is killed.



106
107
108
109
110
111
112
113
114
115
116
# File 'lib/psyllium/fiber.rb', line 106

def status
  if self == ::Fiber.current
    'run'
  elsif alive?
    'sleep'
  elsif state(suppress_error: true)&.exception
    nil
  else
    false
  end
end

#stop?Boolean

Mimic Thread stop? method.

Return true if sleeping or completed.

Returns:

  • (Boolean)


121
122
123
# File 'lib/psyllium/fiber.rb', line 121

def stop?
  status == 'sleep' || !alive?
end

#valueObject

Waits for Fiber to complete, using join, and returns its value. If Fiber completed with an exception, raises ExceptionalCompletionError, with the original exception as its cause.



82
83
84
85
86
87
# File 'lib/psyllium/fiber.rb', line 82

def value
  join
  raise ExceptionalCompletionError.new(state.exception) if state.exception

  state.value
end