-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Executor.asCoroutineDispatcher()
may not use its input for Delay
#2601
Comments
Thanks for the detailed write-up!
Cancellation is much more common in coroutines than in Java's delay tasks, so getting rid of |
… ExecutorService.asCoroutineDispatcher * Document it properly * Make it more robust to signature changes and/or delegation (e.g. see the implementation of java.util.concurrent.Executors.newScheduledThreadPool) * Give a public way to reduce the memory pressure via ScheduledFuture.cancel Fixes #2601
… ExecutorService.asCoroutineDispatcher * Document it properly * Make it more robust to signature changes and/or delegation (e.g. see the implementation of java.util.concurrent.Executors.newScheduledThreadPool) * Give a public way to reduce the memory pressure via ScheduledFuture.cancel Fixes #2601
… ExecutorService.asCoroutineDispatcher (Kotlin#2727) * Get rid of ThreadPoolDispatcher and PoolThread classes * Reuse the same class for both asCoroutineDispatcher and newFixedThreadPoolContext * Replace 3-classes hierarchy by a single impl class * Copy the auto-closing logic to test source * Document and tweak the contract of Executor.asCoroutineDispatcher and ExecutorService.asCoroutineDispatcher * Document it properly * Make it more robust to signature changes and/or delegation (e.g. see the implementation of java.util.concurrent.Executors.newScheduledThreadPool) * Give a public way to reduce the memory pressure via ScheduledFuture.cancel Fixes Kotlin#2601
Executor.asCoroutineDispatcher()
does a couple troubling things:DefaultExecutor
for scheduling delays - even if its input inherits fromScheduledExecutorService
setRemoveOnCancelPolicy()
on its input - a method with side-effects - and doesn't document doing soThe
Executor
type hierarchy is messy, butScheduledExecutorService
is the type that adds support for delaying function execution. My reading ofasCoroutineDispatcher()
was that it would use the threads belonging to its inputScheduledExecutorService
to implement theDelay
functions.As implemented though,
asCoroutineDispatcher()
doesn't detect the capabilities of its input. If the runtime type of theExecutor
passed toasCoroutineDispatcher()
isn't exactlyScheduledThreadPoolExecutor
- which isn't the only way to implement a pool-backedScheduledExecutorService
-asCoroutineDispatcher()
will ignore that its input can be used to run delayed continuations. It'll silently fall back to a statically allocated thread pool and run delayed continuations on those threads instead.We experienced bugs because the statically allocated
Threads
weren't configured with necessaryThreadLocal
state and monitoring. Both calls todelay()
and reading theThreadLocals
are individually rare enough that the creation of new threads escaped notice in automated testing.I propose the following fixes:
setRemoveOnCancelPolicy()
on the function, why it was added, and that it's subject to changesetRemoveOnCancelPolicy()
asCoroutineDispatcher()
to implementDelay
using its input, if the input is any subtype ofScheduledExecutorService
Something like this:
I’m happy to draft some patches to get this working more effectively.
The text was updated successfully, but these errors were encountered: