-
Notifications
You must be signed in to change notification settings - Fork 416
ThreadPoolExecutor#shutdown? inconsistency in JRuby and C Ruby #1041
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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: