Method: Async::Task#stop

Defined in:
lib/async/task.rb

#stop(later = false) ⇒ Object

Stop the task and all of its children.

If later is false, it means that stop has been invoked directly. When later is true, it means that stop is invoked by stop_children or some other indirect mechanism. In that case, if we encounter the “current” fiber, we can’t stop it right away, as it’s currently performing #stop. Stopping it immediately would interrupt the current stop traversal, so we need to schedule the stop to occur later.



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/async/task.rb', line 228

def stop(later = false)
	if self.stopped?
		# If we already stopped this task... don't try to stop it again:
		return
	end
	
	# If the fiber is alive, we need to stop it:
	if @fiber&.alive?
		if self.current?
			# If the fiber is current, and later is `true`, we need to schedule the fiber to be stopped later, as it's currently invoking `stop`:
			if later
				# If the fiber is the current fiber and we want to stop it later, schedule it:
				Fiber.scheduler.push(Stop::Later.new(self))
			else
				# Otherwise, raise the exception directly:
				raise Stop, "Stopping current task!"
			end
		else
			# If the fiber is not curent, we can raise the exception directly:
			begin
				# There is a chance that this will stop the fiber that originally called stop. If that happens, the exception handling in `#stopped` will rescue the exception and re-raise it later.
				Fiber.scheduler.raise(@fiber, Stop)
			rescue FiberError
				# In some cases, this can cause a FiberError (it might be resumed already), so we schedule it to be stopped later:
				Fiber.scheduler.push(Stop::Later.new(self))
			end
		end
	else
		# We are not running, but children might be, so transition directly into stopped state:
		stop!
	end
end