diff --git a/lib/concurrent-ruby/concurrent/timer_task.rb b/lib/concurrent-ruby/concurrent/timer_task.rb index fadb6140..866282f6 100644 --- a/lib/concurrent-ruby/concurrent/timer_task.rb +++ b/lib/concurrent-ruby/concurrent/timer_task.rb @@ -278,24 +278,26 @@ def ns_initialize(opts, &task) # @!visibility private def ns_shutdown_execution @running.make_false + @running = Concurrent::AtomicBoolean.new(false) super end # @!visibility private def ns_kill_execution @running.make_false + @running = Concurrent::AtomicBoolean.new(false) super end # @!visibility private def schedule_next_task(interval = execution_interval) - ScheduledTask.execute(interval, args: [Concurrent::Event.new], &method(:execute_task)) + ScheduledTask.execute(interval, args: [Concurrent::Event.new, @running], &method(:execute_task)) nil end # @!visibility private - def execute_task(completion) - return nil unless @running.true? + def execute_task(completion, continue_running) + return nil unless continue_running.true? _success, value, reason = @executor.execute(self) if completion.try? self.value = value diff --git a/spec/concurrent/timer_task_spec.rb b/spec/concurrent/timer_task_spec.rb index 44cc3e22..f5086e1b 100644 --- a/spec/concurrent/timer_task_spec.rb +++ b/spec/concurrent/timer_task_spec.rb @@ -1,5 +1,6 @@ require_relative 'concern/dereferenceable_shared' require_relative 'concern/observable_shared' +require 'concurrent/atomic/atomic_fixnum' require 'concurrent/timer_task' module Concurrent @@ -94,12 +95,24 @@ def trigger_observable(observable) end context '#shutdown' do - it 'returns true on success' do task = TimerTask.execute(run_now: false) { nil } sleep(0.1) expect(task.shutdown).to be_truthy end + + it 'will cancel pre-shutdown task even if restarted to avoid double-runs' do + counter = Concurrent::AtomicFixnum.new(0) + task = TimerTask.execute(execution_interval: 0.2, run_now: true) { counter.increment } + sleep 0.05 + expect(counter.value).to eq 1 + + task.shutdown + task.execute + + sleep 0.25 + expect(counter.value).to eq 3 + end end end