Class: Async::Task

Inherits:
Node
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/async/task.rb

Overview

A task represents the state associated with the execution of an asynchronous block.

Instance Attribute Summary collapse

Attributes inherited from Node

#annotation, #children, #parent

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Node

#annotate, #consume, #description, #print_hierarchy, #reap, #traverse

Constructor Details

#initialize(reactor, parent = Task.current?, &block) ⇒ Task

Create a new task.

Parameters:

  • reactor (Async::Reactor)

    the reactor this task will run within.

  • parent (Async::Task) (defaults to: Task.current?)

    the parent task.

  • propagate_exceptions (Boolean)

    whether exceptions raised in the task will propagate up the reactor stack.



61
62
63
64
65
66
67
68
69
70
71
# File 'lib/async/task.rb', line 61

def initialize(reactor, parent = Task.current?, &block)
  super(parent || reactor)
  
  @reactor = reactor
  
  @status = :initialized
  @result = nil
  @finished = nil
  
  @fiber = make_fiber(&block)
end

Instance Attribute Details

#fiberObject (readonly)



87
88
89
# File 'lib/async/task.rb', line 87

def fiber
  @fiber
end

#reactorObject (readonly)



78
79
80
# File 'lib/async/task.rb', line 78

def reactor
  @reactor
end

#statusObject (readonly)



91
92
93
# File 'lib/async/task.rb', line 91

def status
  @status
end

Class Method Details

.currentAsync::Task

Lookup the Async::Task for the current fiber. Raise RuntimeError if none is available.

Returns:

Raises:

  • (RuntimeError)

    if task was not #set! for the current fiber.



142
143
144
# File 'lib/async/task.rb', line 142

def self.current
  Thread.current[:async_task] or raise RuntimeError, "No async task available!"
end

.current?Async::Task?

Check if there is a task defined for the current fiber.

Returns:



148
149
150
# File 'lib/async/task.rb', line 148

def self.current?
  Thread.current[:async_task]
end

.yield {|result| ... } ⇒ Object

Yield the unerlying result for the task. If the result is an Exception, then that result will be raised an its exception.

Yields:

  • (result)

    result of the task if a block if given.

Returns:

  • (Object)

    result of the task

Raises:

  • (Exception)

    if the result is an exception



43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/async/task.rb', line 43

def self.yield
  if block_given?
    result = yield
  else
    result = Fiber.yield
  end
  
  if result.is_a? Exception
    raise result
  else
    return result
  end
end

Instance Method Details

#async(*args, &block) ⇒ Object



103
104
105
106
107
108
109
# File 'lib/async/task.rb', line 103

def async(*args, &block)
  task = Task.new(@reactor, self, &block)
  
  task.run(*args)
  
  return task
end

#failed?Boolean

Returns:

  • (Boolean)


164
165
166
# File 'lib/async/task.rb', line 164

def failed?
  @status == :failed
end

#finished?Boolean

Whether we can remove this node from the reactor graph.

Returns:

  • (Boolean)


160
161
162
# File 'lib/async/task.rb', line 160

def finished?
  super && @status != :running
end

#run(*args) ⇒ Object

Begin the execution of the task.



94
95
96
97
98
99
100
101
# File 'lib/async/task.rb', line 94

def run(*args)
  if @status == :initialized
    @status = :running
    @fiber.resume(*args)
  else
    raise RuntimeError, "Task already running!"
  end
end

#running?Boolean

Check if the task is running.

Returns:

  • (Boolean)


154
155
156
# File 'lib/async/task.rb', line 154

def running?
  @status == :running
end

#stopvoid

This method returns an undefined value.

Stop the task and all of its children.



131
132
133
134
135
136
137
# File 'lib/async/task.rb', line 131

def stop
  @children.each(&:stop)
  
  if @fiber.alive?
    @fiber.resume(Stop.new)
  end
end

#stopped?Boolean

Returns:

  • (Boolean)


168
169
170
# File 'lib/async/task.rb', line 168

def stopped?
  @status == :stopped
end

#to_sObject



73
74
75
# File 'lib/async/task.rb', line 73

def to_s
  "<#{self.description} #{@status}>"
end

#waitObject Also known as: result

Retrieve the current result of the task. Will cause the caller to wait until result is available.

Returns:

  • (Object)

    the final expression/result of the task's block.

Raises:

  • (RuntimeError)

    if the task's fiber is the current fiber.



114
115
116
117
118
119
120
121
122
123
# File 'lib/async/task.rb', line 114

def wait
  raise RuntimeError, "Cannot wait on own fiber" if Fiber.current.equal?(@fiber)
  
  if running?
    @finished ||= Condition.new
    @finished.wait
  else
    Task.yield{@result}
  end
end

#yieldObject

Yield back to the reactor and allow other fibers to execute.



82
83
84
# File 'lib/async/task.rb', line 82

def yield
  reactor.yield
end