Method: Concurrently::Proc#call_nonblock

Defined in:
lib/all/concurrently/proc.rb

#call_nonblock(*args) ⇒ Object, Evaluation

Evaluates the concurrent proc in a non-blocking manner.

Evaluating the proc this way executes its block of code immediately until the result is available or the evaluation needs to wait.

Dealing with this method is similar to dealing with IO#*_nonblock.

Examples:

The proc can be evaluated without waiting

add = concurrent_proc do |a, b|
  a + b
end

case immediate_result = add.call_nonblock(5, 8)
when Concurrently::Evaluation
  # won't happen here
else
  immediate_result # => 13
end

The proc needs to wait to conclude evaluation

time_in = concurrent_proc do |seconds|
  wait seconds
  Time.now
end

Time.now.strftime('%H:%M:%S.%L') # => "15:18:42.439"

case immediate_result = time_in.call_nonblock(1.5)
when Concurrently::Evaluation
  immediate_result.await_result.strftime('%H:%M:%S.%L') # => "15:18:44.577"
else
  # won't happen here
end

Returns:

  • (Object)

    the result of the evaluation if it can be executed without waiting.

  • (Evaluation)

    if the evaluation needs to wait.

Raises:

  • (Exception)

    if the evaluation raises an error.

Since:

  • 1.0.0



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/all/concurrently/proc.rb', line 219

def call_nonblock(*args)
  event_loop = EventLoop.current
  run_queue = event_loop.run_queue
  evaluation_bucket = []

  result = begin
    fiber = event_loop.proc_fiber_pool.take_fiber
    # ProcFiberPool#take_fiber might have accessed the current evaluation
    # if it needs to wait for the next iteration to get a fiber. Reset the
    # current evaluation afterwards!
    previous_evaluation = run_queue.current_evaluation
    run_queue.current_evaluation = nil
    run_queue.evaluation_class = @evaluation_class
    fiber.resume [self, args, evaluation_bucket]
  ensure
    run_queue.current_evaluation = previous_evaluation
    run_queue.evaluation_class = nil
  end

  case result
  when Evaluation
    # The proc fiber if the proc cannot be evaluated without waiting.
    # Inject the evaluation into it so it can be concluded later.
    evaluation_bucket << result
    result
  when Exception
    raise result
  else
    result
  end
end