Module: RSMP::Task

Included in:
Node, Proxy
Defined in:
lib/rsmp/node/task.rb

Overview

Task helpers for starting and managing an Async task lifecycle.

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#taskObject (readonly)

Returns the value of attribute task.



7
8
9
# File 'lib/rsmp/node/task.rb', line 7

def task
  @task
end

Instance Method Details

#initialize_taskObject



9
10
11
# File 'lib/rsmp/node/task.rb', line 9

def initialize_task
  @task = nil
end

#restartObject

initiate restart by raising a Restart exception

Raises:



40
41
42
# File 'lib/rsmp/node/task.rb', line 40

def restart
  raise Restart, "restart initiated by #{self.class.name}:#{object_id}"
end

#runObject

perform any long-running work the method will be called from an async task, and should not return if subtasks are needed, the method should call wait() on each of them once running, ready() must be called



53
54
55
# File 'lib/rsmp/node/task.rb', line 53

def run
  start_subtasks
end

#startObject

start our async tasks and return immediately run() will be called inside the task to perform actual long-running work



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/rsmp/node/task.rb', line 15

def start
  return if @task

  # Use current task context if available, otherwise create new reactor
  if Async::Task.current?
    Async::Task.current.async do |task|
      task.annotate "#{self.class.name} main task"
      @task = task
      run
      stop_subtasks
      @task = nil
    end
  else
    Async do |task|
      task.annotate "#{self.class.name} main task"
      @task = task
      run
      stop_subtasks
      @task = nil
    end
  end
  self
end

#stopObject

stop our task



63
64
65
66
# File 'lib/rsmp/node/task.rb', line 63

def stop
  stop_subtasks
  stop_task if @task
end

#stop_subtasksObject



68
# File 'lib/rsmp/node/task.rb', line 68

def stop_subtasks; end

#stop_taskObject

stop our task and any subtask



71
72
73
74
# File 'lib/rsmp/node/task.rb', line 71

def stop_task
  @task.stop
  @task = nil
end

#task_statusObject

get the status of our task, or nil of no task



45
46
47
# File 'lib/rsmp/node/task.rb', line 45

def task_status
  @task&.status
end

#waitObject

wait for our task to complete



58
59
60
# File 'lib/rsmp/node/task.rb', line 58

def wait
  @task&.wait
end

#wait_for_condition(condition, timeout:, task: Async::Task.current, &block) ⇒ Object

wait for an async condition to signal, then yield to block if block returns true we’re done. otherwise, wait again



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/rsmp/node/task.rb', line 78

def wait_for_condition(condition, timeout:, task: Async::Task.current, &block)
  raise "Can't wait without a task" unless task

  task.with_timeout(timeout) do
    while task.running?
      value = condition.wait
      return value unless block

      result = yield value
      return result if result
    end
    raise "Can't wait for condition because task #{task.object_id} #{task.annotation} is not running"
  end
rescue Async::TimeoutError
  raise RSMP::TimeoutError
end