diff --git a/src/tasker/timer.cr b/src/tasker/timer.cr index dc7ba57..2befc1d 100644 --- a/src/tasker/timer.cr +++ b/src/tasker/timer.cr @@ -7,17 +7,7 @@ class Timer def start_timer : Nil Log.trace { "timer start called, id: #{self.object_id}" } - spawn(same_thread: true) do - Log.trace { "timer waiting for #{@sleep_for} seconds, id: #{self.object_id}" } - select - when @cancel.receive - Log.trace { "timer cancelled, id: #{self.object_id}" } - when timeout(@sleep_for.seconds) - Log.trace { "timer fired, id: #{self.object_id}" } - @cancelled = true - @callback.call - end - end + spawn(same_thread: true) { schedule_wait } Fiber.yield end @@ -25,7 +15,31 @@ class Timer return if @cancelled Log.trace { "timer cancel requested, id: #{self.object_id}" } @cancelled = true - @cancel.send(true) - Fiber.yield + begin + @cancel.send(true) + rescue + end + end + + private def schedule_wait + Log.trace { "timer waiting for #{@sleep_for} seconds, id: #{self.object_id}" } + + select + when @cancel.receive + Log.trace { "timer cancelled, id: #{self.object_id}" } + when timeout(@sleep_for.seconds) + if !@cancelled + Log.trace { "timer fired, id: #{self.object_id}" } + @cancelled = true + @callback.call + else + Log.trace { "timer fired but ignored as cancelled, id: #{self.object_id}" } + end + end + rescue error + Log.warn(exception: error) { "error in tasker scheduler" } + ensure + @cancelled = true + @cancel.close end end