Skip to content

Commit ee0ea41

Browse files
committed
Allow TimerSet to safely handle an executor raising RejectedExecutionError
1 parent 9f40827 commit ee0ea41

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

lib/concurrent-ruby/concurrent/executor/timer_set.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,11 @@ def process_tasks
162162
# queue now must have the same pop time, or a closer one, as
163163
# when we peeked).
164164
task = synchronize { @queue.pop }
165-
task.executor.post { task.process_task }
165+
begin
166+
task.executor.post { task.process_task }
167+
rescue => RejectedExecutionError
168+
# ignore and continue
169+
end
166170
else
167171
@condition.wait([diff, 60].min)
168172
end

spec/concurrent/executor/timer_set_spec.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,19 @@ module Concurrent
122122
expect(task.value).to eq i
123123
end
124124
end
125+
126+
it 'safely handles an executor raising RejectedExecutionError' do
127+
# force a task's executor to raise RejectedExecutionError within the TimerSet
128+
abort_executor = Concurrent::ThreadPoolExecutor.new(max_threads: 0, fallback_policy: :abort)
129+
ScheduledTask.execute(0.2, executor: abort_executor, timer_set: subject){ nil }
130+
abort_executor.shutdown
131+
132+
latch = CountDownLatch.new(1)
133+
ScheduledTask.execute(0.3, timer_set: subject) do
134+
latch.count_down
135+
end
136+
expect(latch.wait(1)).to be_truthy
137+
end
125138
end
126139

127140
context 'resolution' do

0 commit comments

Comments
 (0)