-
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
Improve Flux.timeout efficiency #2845
Comments
In Netty, it looks like I was going to suggest using a different One thing to keep in mind is that currently the underlying implementation of So unless we get a stronger signal that this causes issues for a majority of users, I'm not keen on dedicating much bandwidth to changing There's an element of team prioritization affecting that decision, so we could still accept a PR. |
Interesting side note: RxJava seems to have a close approach where timeout tasks also always trigger, but the id of the "real" timeout task is captured so that an outdated timeout will be no-op (failing the CAS on their |
a benchmark means actually implementing the new timeout and bombing both impls with signals, then comparing throughput? |
yes, pretty much. I just want to set expectation here in case somebody wants to contribute: it can still get rejected if the benchmark doesn't show enough improvement. |
@simonbasle Hi Simon. I'm the original guy from the Gitter thread. Could you please take a look at my first take of the problem to determine if it deserves PR ? Here is what I use in production now: https://gist.github.com/unoexperto/fe6725a9bf20ff04e0cba0fbbf8a7606 I realize performance benefits are very specific to nature of the application but in my case I have ~3X throughput improvement in my product. In synthetic tests of the pipeline original |
thanks for providing that @unoexperto. I had a bit of trouble comparing that code to the I was surprised to see it still had generic Overall, looking back at this and at the So the only modification we'd need after all would be that The behavior could even be configurable, at least at the constructor level (which would facilitate benchmarking in order to get a clear picture of the throughput improvement vs the gc-pressure/pressure on the scheduler's task queue). wdyt? |
@unoexperto @bruto1 looks like I missed the fact that timeout isn't rescheduled in By just eliminating cancellation of old timeout triggers, we retain the generic single implementation. Question is: does that help with performance? |
it should |
Profiling shows that it's not the cancellation that eats CPU but subscription to Mono in this line. That's why at the expense of precision I moved rescheduling to Do you think it's possible to implement generic |
@pderop is conducting some interesting experiments with HashedWheelTimers. we do see a measurable improvement so we might consider it. the only question is what to expose exactly, and I'm leaning towards making an internal implementation of wheel timer at first, to only be used by the |
Hi, Out of curiosity, can you confirm if performance is better when using the timeout operator with a "single" scheduler (Schedulers.single()) instead of using default parallel scheduler ? for example, instead of using defaut parallel scheduler like:
then replace by:
thanks. |
I don't actually have a mini benchmark for this, @pderop - noticed the effect while profiling the entire service at work
but only one thread instead of several of parallel() to serve the same number of I/O threads - it should result in more contention for work queue's lock, if anything |
@bruto1 @pderop observed in his benchmark there was more time spent in the implicit picking of a it will be interesting to see if contention counterbalances that. But if using |
@pderop can you please share the benchmark code? |
Hello Guys, Any update on this issue? We are using version 3.5.5. The output I get is: start count=100000
|
hi @simonbasle so single scheduler works well as long as there's only 1 thread scheduling and cancelling tasks on it so maybe a new impl would be a good idea after all |
Current implementation uses parallel scheduler by default which is in essence a ScheduledThreadPoolExecutor which has the task queue guarded by ReentrantLock, which means two trips through said lock per signal on average
After looking at Netty's https://github.com/netty/netty/blob/4.1/handler/src/main/java/io/netty/handler/timeout/IdleStateHandler.java there appears to be a way to do fewer timeout task reschedules if you let go of the idea illustrated by the current marble diagrams (new signal cancels the previous timeout task)
WDYT?
this really prevents Flux.timeout from being useful with high-frequency publishers which may occasionally stall
suggestion inspired by https://gitter.im/reactor/reactor?at=61968a44197fa95a1c7adf05
The text was updated successfully, but these errors were encountered: