Class: Phronomy::Task::DeferredBackend Private

Inherits:
Backend
  • Object
show all
Defined in:
lib/phronomy/engine/task/deferred_backend.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Backend for externally-completed Tasks.

DeferredBackend never starts a thread. The owner transitions it to a terminal state by calling Task#transition! and then #unblock.

Instance Method Summary collapse

Methods inherited from Backend

#completed_error, #completed_value

Constructor Details

#initialize(task:) ⇒ DeferredBackend

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of DeferredBackend.



13
14
15
16
17
# File 'lib/phronomy/engine/task/deferred_backend.rb', line 13

def initialize(task:, &)
  super
  @done_queue = Queue.new
  task.transition!(:running)
end

Instance Method Details

#alive?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Deferred tasks have no execution thread of their own.

Returns:

  • (Boolean)


48
49
50
# File 'lib/phronomy/engine/task/deferred_backend.rb', line 48

def alive?
  !@task.done?
end

#cancel!Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Marks the task cancelled without interrupting external work.



54
55
56
# File 'lib/phronomy/engine/task/deferred_backend.rb', line 54

def cancel!
  self
end

#join(limit = nil) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Blocks until externally completed, with optional timeout.



60
61
62
63
64
65
66
67
68
69
70
# File 'lib/phronomy/engine/task/deferred_backend.rb', line 60

def join(limit = nil)
  if limit.nil?
    wait_result
  else
    begin
      Timeout.timeout(limit) { wait_result }
    rescue Timeout::Error
      nil
    end
  end
end

#unblock(value, error) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Unblocks await/join after the task reaches a terminal state.



21
22
23
# File 'lib/phronomy/engine/task/deferred_backend.rb', line 21

def unblock(value, error)
  @done_queue.push([value, error])
end

#wait_resultObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Blocks until externally completed.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/phronomy/engine/task/deferred_backend.rb', line 27

def wait_result
  scheduler = Thread.current.thread_variable_get(Task::SCHEDULER_KEY)
  in_managed_fiber = !Fiber.respond_to?(:main) || Fiber.current != Fiber.main
  if scheduler && in_managed_fiber && !@task.done?
    scheduler.track_blocking_await
    waiting_fiber = Fiber.current
    @task.on_complete do |_value, _error|
      scheduler.complete_blocking_await
      scheduler.enqueue_fiber(-> { waiting_fiber.resume })
    end
    Fiber.yield(:cooperative_suspend)
  end

  value, error = @done_queue.pop
  raise error if error

  value
end