-
Notifications
You must be signed in to change notification settings - Fork 419
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
ThreadPoolExecutor#shutdown? inconsistency in JRuby and C Ruby #1041
Comments
Another discovery here is that in J Ruby, once This is now the shutdown wrapper I'm using: # @param timeout [Numeric, nil] Seconds to wait for active threads.
# * +nil+, the scheduler will trigger a shutdown but not wait for it to complete.
# * +-1+, the scheduler will wait until the shutdown is complete.
# * +0+, the scheduler will immediately shutdown and stop any threads.
# * A positive number will wait that many seconds before stopping any remaining active threads.
def shutdown(timeout: -1)
return if @executor.nil? || (@executor.shutdown? && !@executor.shuttingdown?)
@executor.shutdown if @executor.running?
if @executor.shuttingdown? && timeout # rubocop:disable Style/GuardClause
executor_wait = timeout.negative? ? nil : timeout
unless @executor.wait_for_termination(executor_wait)
@executor.kill
@executor.wait_for_termination
end
end
end This is similar to the usage example given in Java: void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
} |
Thanks! This line does look like the culprit: concurrent-ruby/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb Lines 67 to 69 in eae2851
I missed that last night because I got distracted trying to discover the need for the feature-check in concurrent-ruby/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb Lines 59 to 64 in eae2851
That was introduced 9+ years ago (I couldn't find the exact place), but I'm not sure if |
Aha, it looks like just |
In the scenario in which a ThreadPoolExecutor has received
#shutdown
and there are active threads/tasks, there is an inconsistency between what JRuby and C Ruby return for#shutdown?
:#shutdown? => true
while there are still active threads/tasks, at the same time as#shuttingdown? => true
. Java's executor service narrowly defines#isShutdown
as "no new tasks will be accepted" which is distinct from#isTerminated
which is "all tasks have completed following shut down".#shutdown? => false
while there are still active threads/tasks, at the same time as#shuttingdown? => true
.It's fairly easy to work around this inconsistency using
executor.shutdown? && !executor.shuttingdown?
to achieve the same result in both rubies for determining when there are no more threads/tasks on a shutdown executor. It would be nice if the behavior was aligned.The text was updated successfully, but these errors were encountered: