Permalink
Browse files

Improve behaviour when posting to a shutdown thread pool

If an executor has a handle_overflow method defined, use that in the case where we post to an executor which is not running. If no handle_overflow method is defined (e.g. for the single-thread executor), preserve the current behaviour of returning false.

Fixes Github issue #192.
  • Loading branch information...
rkday committed Dec 7, 2014
1 parent df20680 commit 8bea918f0d949c3a13d74864efaa3c53c3cbc6ad
Showing with 59 additions and 1 deletion.
  1. +10 −1 lib/concurrent/executor/executor.rb
  2. +49 −0 spec/concurrent/executor/ruby_thread_pool_executor_spec.rb
@@ -78,7 +78,16 @@ module RubyExecutor
def post(*args, &task)
raise ArgumentError.new('no block given') unless block_given?
mutex.synchronize do
return false unless running?
unless running?
# The executor is shut down - figure out how to reject this task
if self.respond_to?(:handle_overflow, true)
# Reject this task in the same way we'd reject an overflow
return handle_overflow(*args, &task)
else
# No handle_overflow method defined - just return false
return false
end
end
execute(*args, &task)
true
end
@@ -80,6 +80,18 @@ module Concurrent
}.to raise_error(Concurrent::RejectedExecutionError)
end
specify '#post raises an error when the executor is shutting down' do
expect {
subject.shutdown; subject.post{ sleep(1) }
}.to raise_error(Concurrent::RejectedExecutionError)
end
specify '#<< raises an error when the executor is shutting down' do
expect {
subject.shutdown; subject << proc { sleep(1) }
}.to raise_error(Concurrent::RejectedExecutionError)
end
specify 'a #post task is never executed when the queue is at capacity' do
executed = Concurrent::AtomicFixnum.new(0)
10.times do
@@ -134,6 +146,29 @@ module Concurrent
sleep(0.1)
expect(executed.value).to be < 1000
end
specify 'a #post task is never executed when the executor is shutting down' do
executed = Concurrent::AtomicFixnum.new(0)
subject.shutdown
subject.post{ executed.increment }
sleep(0.1)
expect(executed.value).to be 0
end
specify 'a #<< task is never executed when the executor is shutting down' do
executed = Concurrent::AtomicFixnum.new(0)
subject.shutdown
subject << proc { executed.increment }
sleep(0.1)
expect(executed.value).to be 0
end
specify '#post returns false when the executor is shutting down' do
executed = Concurrent::AtomicFixnum.new(0)
subject.shutdown
ret = subject.post{ executed.increment }
expect(ret).to be false
end
end
context ':caller_runs' do
@@ -165,6 +200,20 @@ module Concurrent
5.times{|i| subject.post{ latch.count_down } }
latch.wait(0.1)
end
specify '#post executes the task on the current thread when the executor is shutting down' do
latch = Concurrent::CountDownLatch.new(1)
subject.shutdown
subject.post{ latch.count_down }
latch.wait(0.1)
end
specify '#<< executes the task on the current thread when the queue is at capacity' do
latch = Concurrent::CountDownLatch.new(1)
subject.shutdown
subject << proc { latch.count_down }
latch.wait(0.1)
end
end
end
end

0 comments on commit 8bea918

Please sign in to comment.