Class: Async::Node

Inherits:
Object
  • Object
show all
Defined in:
lib/async/node.rb

Overview

Represents a node in a tree, used for nested Task instances.

Direct Known Subclasses

Reactor, Task

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent = nil, annotation: nil, transient: false) ⇒ Node

Create a new node in the tree.

Parameters:

  • parent (Node, nil) (defaults to: nil)

    This node will attach to the given parent.



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/async/node.rb', line 161

def initialize(parent = nil, annotation: nil, transient: false)
	@parent = nil
	@children = nil
	
	@annotation = annotation
	@object_name = nil
	
	@transient = transient
	
	@head = nil
	@tail = nil
	
	if parent
		parent.add_child(self)
	end
end

Instance Attribute Details

#annotationObject (readonly)

A useful identifier for the current node.



190
191
192
# File 'lib/async/node.rb', line 190

def annotation
  @annotation
end

#childrenObject (readonly)



187
188
189
# File 'lib/async/node.rb', line 187

def children
  @children
end

#headObject

You should not directly rely on these pointers but instead use ‘#children`. List pointers:



180
181
182
# File 'lib/async/node.rb', line 180

def head
  @head
end

#parentObject



184
185
186
# File 'lib/async/node.rb', line 184

def parent
  @parent
end

#tailObject

Returns the value of attribute tail.



181
182
183
# File 'lib/async/node.rb', line 181

def tail
  @tail
end

Instance Method Details

#annotate(annotation) ⇒ Object



202
203
204
205
206
207
208
209
210
211
# File 'lib/async/node.rb', line 202

def annotate(annotation)
	if block_given?
		previous_annotation = @annotation
		@annotation = annotation
		yield
		@annotation = previous_annotation
	else
		@annotation = annotation
	end
end

#backtrace(*arguments) ⇒ Object



223
224
225
# File 'lib/async/node.rb', line 223

def backtrace(*arguments)
	nil
end

#children?Boolean

Whether there are children?

Returns:

  • (Boolean)


193
194
195
# File 'lib/async/node.rb', line 193

def children?
	@children != nil && !@children.empty?
end

#consumeObject

If the node has a parent, and is #finished?, then remove this node from the parent.



273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'lib/async/node.rb', line 273

def consume
	if parent = @parent and finished?
		parent.delete_child(self)
		
		if @children
			@children.each do |child|
				if child.finished?
					delete_child(child)
				else
					# In theory we don't need to do this... because we are throwing away the list. However, if you don't correctly update the list when moving the child to the parent, it foobars the enumeration, and subsequent nodes will be skipped, or in the worst case you might start enumerating the parents nodes.
					delete_child(child)
					parent.add_child(child)
				end
			end
			
			@children = nil
		end
		
		parent.consume
	end
end

#descriptionObject



213
214
215
216
217
218
219
220
221
# File 'lib/async/node.rb', line 213

def description
	@object_name ||= "#{self.class}:0x#{object_id.to_s(16)}#{@transient ? ' transient' : nil}"
	
	if @annotation
		"#{@object_name} #{@annotation}"
	else
		@object_name
	end
end

#finished?Boolean

Whether the node can be consumed safely. By default, checks if the children set is empty.

Returns:

  • (Boolean)


267
268
269
# File 'lib/async/node.rb', line 267

def finished?
	@children.nil? || @children.finished?
end


332
333
334
335
336
337
338
339
340
# File 'lib/async/node.rb', line 332

def print_hierarchy(out = $stdout, backtrace: true)
	self.traverse do |node, level|
		indent = "\t" * level
		
		out.puts "#{indent}#{node}"
		
		print_backtrace(out, indent, node) if backtrace
	end
end

#stop(later = false) ⇒ Object

Attempt to stop the current node immediately, including all non-transient children. Invokes #stop_children to stop all children.



320
321
322
323
# File 'lib/async/node.rb', line 320

def stop(later = false)
	# The implementation of this method may defer calling `stop_children`.
	stop_children(later)
end

#terminateObject

Immediately terminate all children tasks, including transient tasks. Internally invokes ‘stop(false)` on all children.



307
308
309
310
311
312
313
314
315
# File 'lib/async/node.rb', line 307

def terminate
	# Attempt to stop the current task immediately, and all children:
	stop(false)
	
	# If that doesn't work, take more serious action:
	@children&.each do |child|
		child.terminate
	end
end

#to_sObject



227
228
229
# File 'lib/async/node.rb', line 227

def to_s
	"\#<#{description}>"
end

#transient?Boolean

Is this node transient?

Returns:

  • (Boolean)


198
199
200
# File 'lib/async/node.rb', line 198

def transient?
	@transient
end

#traverse(level = 0) {|node, level| ... } ⇒ Object

Traverse the tree.

Yields:

  • (node, level)

    The node and the level relative to the given root.



297
298
299
300
301
302
303
# File 'lib/async/node.rb', line 297

def traverse(level = 0, &block)
	yield self, level
	
	@children&.each do |child|
		child.traverse(level + 1, &block)
	end
end