22require 'concurrent/concern/dereferenceable'
33require 'concurrent/concern/observable'
44require 'concurrent/atomic/atomic_boolean'
5+ require 'concurrent/atomic/atomic_fixnum'
56require 'concurrent/executor/executor_service'
67require 'concurrent/executor/ruby_executor_service'
78require 'concurrent/executor/safe_task_executor'
@@ -236,6 +237,7 @@ def execute
236237 synchronize do
237238 if @running . false?
238239 @running . make_true
240+ @age . increment
239241 schedule_next_task ( @run_now ? 0 : @execution_interval )
240242 end
241243 end
@@ -309,6 +311,7 @@ def ns_initialize(opts, &task)
309311 @task = Concurrent ::SafeTaskExecutor . new ( task )
310312 @executor = opts [ :executor ] || Concurrent . global_io_executor
311313 @running = Concurrent ::AtomicBoolean . new ( false )
314+ @age = Concurrent ::AtomicFixnum . new ( 0 )
312315 @value = nil
313316
314317 self . observers = Collection ::CopyOnNotifyObserverSet . new
@@ -328,13 +331,15 @@ def ns_kill_execution
328331
329332 # @!visibility private
330333 def schedule_next_task ( interval = execution_interval )
331- ScheduledTask . execute ( interval , executor : @executor , args : [ Concurrent ::Event . new ] , &method ( :execute_task ) )
334+ ScheduledTask . execute ( interval , executor : @executor , args : [ Concurrent ::Event . new , @age . value ] , &method ( :execute_task ) )
332335 nil
333336 end
334337
335338 # @!visibility private
336- def execute_task ( completion )
339+ def execute_task ( completion , age_when_scheduled )
337340 return nil unless @running . true?
341+ return nil unless @age . value == age_when_scheduled
342+
338343 start_time = Concurrent . monotonic_time
339344 _success , value , reason = @task . execute ( self )
340345 if completion . try?
0 commit comments