Class: Async::Node

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

Overview

A node in a tree, used for implementing the task hierarchy.

Direct Known Subclasses

Scheduler, 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.



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/async/node.rb', line 147

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.



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

def annotation
  @annotation
end

#childrenObject (readonly)

Returns the value of attribute children.



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

def children
  @children
end

#headObject



170
171
172
# File 'lib/async/node.rb', line 170

def head
  @head
end

#parentObject

Returns the value of attribute parent.



176
177
178
# File 'lib/async/node.rb', line 176

def parent
  @parent
end

#tailObject



173
174
175
# File 'lib/async/node.rb', line 173

def tail
  @tail
end

Instance Method Details

#annotate(annotation) ⇒ Object



194
195
196
197
198
199
200
201
202
203
# File 'lib/async/node.rb', line 194

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

#backtrace(*arguments) ⇒ Object



217
218
219
# File 'lib/async/node.rb', line 217

def backtrace(*arguments)
	nil
end

#children?Boolean

Whether there are children?

Returns:

  • (Boolean)


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

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

#consumeObject

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



269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/async/node.rb', line 269

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



205
206
207
208
209
210
211
212
213
214
215
# File 'lib/async/node.rb', line 205

def description
	@object_name ||= "#{self.class}:#{format '%#018x', object_id}#{@transient ? ' transient' : nil}"
	
	if @annotation
		"#{@object_name} #{@annotation}"
	elsif line = self.backtrace(0, 1)&.first
		"#{@object_name} #{line}"
	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)


263
264
265
# File 'lib/async/node.rb', line 263

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

#rootObject



165
166
167
# File 'lib/async/node.rb', line 165

def root
	@parent&.root || self
end

#stop(later = false) ⇒ Object

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



316
317
318
319
# File 'lib/async/node.rb', line 316

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

#stopped?Boolean

Returns:

  • (Boolean)


328
329
330
# File 'lib/async/node.rb', line 328

def stopped?
	@children.nil?
end

#terminateObject

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



303
304
305
306
307
308
309
310
311
# File 'lib/async/node.rb', line 303

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

#The parent node.=(parentnode. = (value)) ⇒ Object



176
# File 'lib/async/node.rb', line 176

attr :parent

#to_sObject Also known as: inspect



221
222
223
# File 'lib/async/node.rb', line 221

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

#transient?Boolean

Is this node transient?

Returns:

  • (Boolean)


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

def transient?
	@transient
end

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

Traverse the tree.

Yields:

  • (_self, level)

Yield Parameters:

  • _self (Async::Node)

    the object that the method was called on



293
294
295
296
297
298
299
# File 'lib/async/node.rb', line 293

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