Class: Concurrently::Evaluation

Inherits:
Object
  • Object
show all
Defined in:
lib/all/concurrently/evaluation.rb,
lib/all/concurrently/evaluation/error.rb

Overview

Note:

Evaluations are not thread safe. They are operating on a fiber. Fibers cannot be resumed inside a thread they were not created in.

Concurrently::Evaluation represents the evaluation of the main thread outside of any concurrent evaluations.

An instance will be returned by Evaluation.current if called by the root evaluation.

Since:

  • 1.0.0

Direct Known Subclasses

Proc::Evaluation

Defined Under Namespace

Classes: Error, TimeoutError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#waiting?Boolean (readonly)

Checks if the evaluation is not running and not resumed.

Returns:

  • (Boolean)

Since:

  • 1.0.0


57
58
59
# File 'lib/all/concurrently/evaluation.rb', line 57

def waiting?
  !!@waiting
end

Class Method Details

.currentEvaluation

The evaluation that is currently running in the current thread.

This method is thread safe. Each thread returns its own currently running evaluation.

Examples:

concurrently do
  Concurrently::Evaluation.current # => #<Concurrently::Proc::Evaluation:0x00000000e56910>
end

Concurrently::Evaluation.current # => #<Concurrently::Evaluation:0x00000000e5be10>

Returns:

Since:

  • 1.0.0


26
27
28
# File 'lib/all/concurrently/evaluation.rb', line 26

def self.current
  EventLoop.current.run_queue.current_evaluation
end

Instance Method Details

#__resume__!(result = nil) ⇒ :resumed Also known as: resume!

Note:

The exclamation mark in its name stands for: Watch out! This method is potentially dangerous and can break stuff. It also needs to be complemented by an earlier call of Kernel#await_resume!.

Schedules the evaluation to be resumed

It needs to be complemented by an earlier call of Kernel#await_resume!.

This method is potentially dangerous. Kernel#wait, IO#await_readable, IO#await_writable and Proc::Evaluation#await_result are implemented with Kernel#await_resume!. Concurrent evaluations waiting because of them are resumed when calling #resume! although the event they are actually awaiting has not happened yet:

evaluation = concurrent_proc do
  wait 1
  await_resume!
end.call_nonblock

conproc.resume! # resumes the wait call prematurely

To use this method safely, make sure the evaluation to resume is waiting because of a manual call of Kernel#await_resume!.

Examples:

# Control flow is indicated by (N)

# (1)
evaluation = concurrent_proc do
  # (2)
  await_resume!
  # (4)
end.call_nonblock

# (3)
evaluation.resume! :result
# (5)
evaluation.await_result # => :result

Returns:

  • (:resumed)

Raises:

  • (Error)

    if the evaluation is not waiting or is already scheduled to be resumed

Since:

  • 1.0.0


116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/all/concurrently/evaluation.rb', line 116

def __resume__!(result = nil)
  raise self.class::Error, "already scheduled\n#{Debug.notice_for @fiber}" if @scheduled
  raise self.class::Error, "not waiting\n#{Debug.notice_for @fiber}" unless @waiting
  @waiting = false
  @scheduled = true

  run_queue = Concurrently::EventLoop.current.run_queue

  # Cancel running the fiber if it has already been scheduled to run; but
  # only if it was scheduled with a time offset. This is used to cancel the
  # timeout of a wait operation if the waiting fiber is resumed before the
  # timeout is triggered.
  run_queue.cancel(self, true)

  run_queue.schedule_immediately(self, result)
  :resumed
end