lib/async/task.rb in async-2.14.0 vs lib/async/task.rb in async-2.14.1

- old
+ new

@@ -11,10 +11,12 @@ require 'console/event/failure' require_relative 'node' require_relative 'condition' +Fiber.attr_accessor :async_task + module Async # Raised when a task is explicitly stopped. class Stop < Exception # Used to defer stopping the current task until later. class Later @@ -184,10 +186,19 @@ if @status == :initialized @status = :running schedule do @block.call(self, *arguments) + rescue => error + # I'm not completely happy with this overhead, but the alternative is to not log anything which makes debugging extremely difficult. Maybe we can introduce a debug wrapper which adds extra logging. + if @finished.nil? + Console::Event::Failure.for(error).emit("Task may have ended with unhandled exception.", severity: :warn) + # else + # Console::Event::Failure.for(error).emit(self, severity: :debug) + end + + raise end else raise RuntimeError, "Task already running!" end end @@ -314,17 +325,17 @@ # Lookup the {Task} for the current fiber. Raise `RuntimeError` if none is available. # @returns [Task] # @raises[RuntimeError] If task was not {set!} for the current fiber. def self.current - Thread.current[:async_task] or raise RuntimeError, "No async task available!" + Fiber.current.async_task or raise RuntimeError, "No async task available!" end # Check if there is a task defined for the current fiber. # @returns [Interface(:async) | Nil] def self.current? - Thread.current[:async_task] + Fiber.current.async_task end # @returns [Boolean] Whether this task is the currently executing task. def current? Fiber.current.equal?(@fiber) @@ -356,16 +367,10 @@ # State transition into the failed state. def failed!(exception = false) @result = exception @status = :failed - - if $DEBUG - Fiber.blocking do - $stderr.puts "Task #{self} failed:", exception.full_message - end - end end def stopped! # Console.info(self, status:) {"Task #{self} was stopped with #{@children&.size.inspect} children!"} @status = :stopped @@ -392,15 +397,12 @@ finish! end def schedule(&block) @fiber = Fiber.new(annotation: self.annotation) do - set! - begin completed!(yield) - # Console.debug(self) {"Task was completed with #{@children.size} children!"} rescue Stop stopped! rescue StandardError => error failed!(error) rescue Exception => exception @@ -412,15 +414,11 @@ # Console.info(self) {"Task ensure $! = #{$!} with #{@children&.size.inspect} children!"} finish! end end + @fiber.async_task = self + self.root.resume(@fiber) - end - - # Set the current fiber's `:async_task` to this task. - def set! - # This is actually fiber-local: - Thread.current[:async_task] = self end end end