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.



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

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.



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

def annotation
  @annotation
end

#childrenObject (readonly)

Returns the value of attribute children.



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

def children
  @children
end

#headObject



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

def head
  @head
end

#parentObject

Returns the value of attribute parent.



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

def parent
  @parent
end

#tailObject



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

def tail
  @tail
end

Instance Method Details

#annotate(annotation) ⇒ Object



209
210
211
212
213
214
215
216
217
218
# File 'lib/async/node.rb', line 209

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

#backtrace(*arguments) ⇒ Object



232
233
234
# File 'lib/async/node.rb', line 232

def backtrace(*arguments)
	nil
end

#children?Boolean

Whether there are children?

Returns:

  • (Boolean)


200
201
202
# File 'lib/async/node.rb', line 200

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

#consumeObject

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



284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
# File 'lib/async/node.rb', line 284

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



220
221
222
223
224
225
226
227
228
229
230
# File 'lib/async/node.rb', line 220

def description
	@object_name ||= "#{self.class}:0x#{object_id.to_s(16)}#{@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)


278
279
280
# File 'lib/async/node.rb', line 278

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


347
348
349
350
351
352
353
354
355
# File 'lib/async/node.rb', line 347

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



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

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.



331
332
333
334
# File 'lib/async/node.rb', line 331

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

#stopped?Boolean

Returns:

  • (Boolean)


343
344
345
# File 'lib/async/node.rb', line 343

def stopped?
	@children.nil?
end

#terminateObject

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



318
319
320
321
322
323
324
325
326
# File 'lib/async/node.rb', line 318

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



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

attr :parent

#to_sObject Also known as: inspect



236
237
238
# File 'lib/async/node.rb', line 236

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

#transient?Boolean

Is this node transient?

Returns:

  • (Boolean)


205
206
207
# File 'lib/async/node.rb', line 205

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



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

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