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 |