lib/async/task.rb in async-2.0.2 vs lib/async/task.rb in async-2.0.3
- old
+ new
@@ -161,19 +161,19 @@
end
if self.running?
if self.current?
if later
- Fiber.scheduler.push Stop::Later.new(self)
+ Fiber.scheduler.push(Stop::Later.new(self))
else
raise Stop, "Stopping current task!"
end
elsif @fiber&.alive?
begin
Fiber.scheduler.raise(@fiber, Stop)
rescue FiberError
- Fiber.scheduler.push Stop::Later.new(self)
+ 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!
@@ -204,21 +204,17 @@
end
# Whether we can remove this node from the reactor graph.
# @returns [Boolean]
def finished?
- super && @status != :running
+ super && @fiber.nil?
end
def failed?
@status == :failed
end
- def stopping?
- @status == :stopping
- end
-
def stopped?
@status == :stopped
end
def complete?
@@ -226,21 +222,22 @@
end
private
# This is a very tricky aspect of tasks to get right. I've modelled it after `Thread` but it's slightly different in that the exception can propagate back up through the reactor. If the user writes code which raises an exception, that exception should always be visible, i.e. cause a failure. If it's not visible, such code fails silently and can be very difficult to debug.
- # As an explcit choice, the user can start a task which doesn't propagate exceptions. This only applies to `StandardError` and derived tasks. This allows tasks to internally capture their error state which is raised when invoking `Task#result` similar to how `Thread#join` works. This mode makes {ruby Async::Task} behave more like a promise, and you would need to ensure that someone calls `Task#result` otherwise you might miss important errors.
- def fail!(exception = nil, propagate = true)
+ def fail!(exception = false, propagate = true)
@status = :failed
@result = exception
- if propagate
- raise
- elsif @finished.nil?
- # If no one has called wait, we log this as an error:
- Console.logger.error(self) {$!}
- else
- Console.logger.debug(self) {$!}
+ if exception
+ if propagate
+ raise exception
+ elsif @finished.nil?
+ # If no one has called wait, we log this as a warning:
+ Console.logger.warn(self, "Task may have ended with unhandled exception.", exception)
+ else
+ Console.logger.debug(self, exception)
+ end
end
end
def stop!
# Console.logger.info(self, self.annotation) {"Task was stopped with #{@children&.size.inspect} children!"}