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