2
2
require 'concurrent/concern/dereferenceable'
3
3
require 'concurrent/concern/observable'
4
4
require 'concurrent/atomic/atomic_boolean'
5
+ require 'concurrent/atomic/atomic_fixnum'
5
6
require 'concurrent/executor/executor_service'
6
7
require 'concurrent/executor/ruby_executor_service'
7
8
require 'concurrent/executor/safe_task_executor'
@@ -236,6 +237,7 @@ def execute
236
237
synchronize do
237
238
if @running . false?
238
239
@running . make_true
240
+ @age . increment
239
241
schedule_next_task ( @run_now ? 0 : @execution_interval )
240
242
end
241
243
end
@@ -309,6 +311,7 @@ def ns_initialize(opts, &task)
309
311
@task = Concurrent ::SafeTaskExecutor . new ( task )
310
312
@executor = opts [ :executor ] || Concurrent . global_io_executor
311
313
@running = Concurrent ::AtomicBoolean . new ( false )
314
+ @age = Concurrent ::AtomicFixnum . new ( 0 )
312
315
@value = nil
313
316
314
317
self . observers = Collection ::CopyOnNotifyObserverSet . new
@@ -328,13 +331,15 @@ def ns_kill_execution
328
331
329
332
# @!visibility private
330
333
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 ) )
332
335
nil
333
336
end
334
337
335
338
# @!visibility private
336
- def execute_task ( completion )
339
+ def execute_task ( completion , age_when_scheduled )
337
340
return nil unless @running . true?
341
+ return nil unless @age . value == age_when_scheduled
342
+
338
343
start_time = Concurrent . monotonic_time
339
344
_success , value , reason = @task . execute ( self )
340
345
if completion . try?
0 commit comments