-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Use shutdown() instead of shutdownNow() when BoundedElasticScheduler call dispose. #3068
Comments
I'm not sure there is a strong rationale behind it, but the core implementations have historically used Pretty much the only change we make is to add a |
one alternative to the above would be to throw
|
Hi @simonbasle , thank you for your reply. I'm trying to provide a simple code snippet recently. In my case, I post hundreds of http request task with I think graceful is more important, in my case there are too many tasks, I can't easily handle all of them. I understand your concern about leaks, if users choose |
@ZejiaJiang I agree that the two separate methods would provide choice. I'm just wondering what's best to happen if you do call
Granted, this is a corner case because none of the core schedulers would rely on the default method body. |
@simonbasle In this case, I prefer 2. |
@ZejiaJiang we are discussing the API that is in draft state in #3089. We are considering two possible behaviours. First the API:
which can either complete successfully or propagate a timeout exception. The exception is thrown when graceful
E.g.
E.g.
Which do you prefer @ZejiaJiang? |
Hi @chemicL , Thanks for your asking. For these two behaviors, I have a discussion with my colleagues. They prefer the sceond one, because they think it's more flexible. But from my side, I prefer the fisrt one, I think when we provide a Hope this can help you decide. |
I also need a graceful alternative to .dispose(). I had to make a custom "uninterruptible scheduler" because the shutdownNow() inside .dispose() was killing my Lucene instances. From the Lucene documentation:
|
@cavallium thank you for sharing. Do you think the proposed solutions can aid in simplifying your code? If you have any comments regarding the |
In my case, I absolutely need to be sure that no task is interrupted via shutdownNow(), so I prefer the 2nd solution, in which If disposeGracefully(Duration) will be able to interrupt some threads with shutdownNow automatically, it would create the same problems that dispose creates for me now. Currently I use a wrapped bounded-elastic scheduler that creates empty disposables, but it's very hacky, it has a huge overhead (reschedules everything two more times), and every time I need to do this: Mono.fromCallable(() -> {
// Interrupting this task kills the file descriptor, making the lucene instance unusable forever.
lucene.thingThatShouldNotBeInterrupted();
})
// Wrap a scheduler with a wrapper that creates empty disposables
.subscribeOn(new FakeDisposablesScheduler(Schedulers.boundedElastic()))
// Publish the result on a scheduler to re-enable task cancellation
.publishOn(Schedulers.parallel()) |
What about adding a boolean parameter |
`Scheduler`s now can be disposed lazily using a new method, `disposeGracefully()`. It returns a `Mono<Void>`, which allows awaiting for the signal that all underlying resources have been properly shut down. In contrast to the existing `dispose()`, which calls `shutdownNow()` on underlying `ExecutorService`s, the lazy variant calls `shutdown()` and sends the termination signal once a monitoring `Thread` successfully observes a positive result from `awaitTermination()`. Fixes ##3068.
@ZejiaJiang @cavallium first of all, thank you for the feedback and ideas. After some back-and-forth we landed on a design, that should be the least surprising to users. A |
Thank you for your effort! Will try it when the new version released. |
Consider experimenting with the snapshot version, we can integrate the feedback in the release. |
It seems good! By the way, if a Flux is cancelled it will still call dispose, is there a way to prevent it? |
@cavallium can you be more specific here?:
Do you mean the |
I've tested it, you are right. It doesn't interrupt anything and doesn't call dispose. thanks |
I post hundreds of http request task with
block()
to scheduler. Sometimes I need to close my application and dispose the scheduler, then it'll throw interruptedException when each task get http response and notice the scheduler is disposed.I'm wondering why not use
shutdown()
instead ofshutdownNow()
indispose()
?reactor-core/reactor-core/src/main/java/reactor/core/scheduler/BoundedElasticScheduler.java
Lines 196 to 206 in 8909005
Motivation
Currently when BoundedElasticScheduler call
dispose()
, it will halt all waiting tasks. Let waiting task finish not halt them toughly.Desired solution
Use
shutdown()
instead ofshutdownNow()
indispose()
.The text was updated successfully, but these errors were encountered: