-
Notifications
You must be signed in to change notification settings - Fork 179
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
The emitter.hasRequests
method does not take into account the buffer size
#2465
Comments
I'll create a reproducer in the upstream repo (https://github.com/smallrye/smallrye-reactive-messaging), where we have tests to inject latency. |
Many thanks @ozangunalp ! I will give my feedback asap (probably tomorrow) |
No worries, I am thinking that if you've the |
I think the problem is that the |
@ozangunalp I took a look into the tests you wrote and it perfectly exercises the use case, super many thanks!
So, it takes into account both capacities (the buffer size and the downstream capacity). With the above change, the tests are now passing. |
I'll push more cases once I finish. I am a bit puzzled how the requested change is fixing the tests. (Doesn't really change for me) For example, why not return the requested.get() directly instead? I still think that you are hitting that error case because of a race condition. I reckon if you do the requested check + send block in a synchronized or a lock you'd not hit the error. |
Because in case of the
This is odd. I could reproduce the issue with the tests you wrote and after I changed the ThrowingEmitter.requested() method, the same tests that were failing worked. Note that the |
This solution has been agreed with Clement (the maintainer of the Quarkus messaging extensions). He suggested to use the emitter.hasRequests method to be sure the broker can handle more messages. The hasRequests works like a capacity barrier: when we send up to 1024 messages (1024 is the default value) without getting an ack from the broker, we wait until sending more messages). Update: there seems to be two upper limits, (1) the one configured by the max-inflight-messages which is the one used by the hasRequests method and default value is 1024; and (2) the buffer limit which is used by the overflow strategy and default value is 128. Therefore, for this solution to work, we need to set the max-inflight-messages limit to the same as the buffer limit. Relates: smallrye/smallrye-reactive-messaging#2465
I just updated the tests and added a couple more of them. In my runs, the only one that's failing is the disabled one with unbounded concurrency with virtual threads without synchronization. Here is what I've learnt from setting up these tests: I think you are misunderstanding how ThrowingEmitter works. However, if the Depending on the level of concurrency and the Kafka send latency, if the hasRequested check is not synchronized you'll eventually hit the race condition, fill the buffer and hit the insufficient downstream requests error. Please tell me if you are having different results running these tests. |
This is indeed our case. We're hitting this issue in our production environment that uses Java 17. |
We need to send a large number of events at the same time to a Kafka topic through an emitter:
Then, when sending a large number of events, we get the following exception:
This is an expected situation and happening because we are suffering some network slowness that we can't control and the Kafka broker does not respond as quickly as we would like.
To address this issue, we're implementing the following back-pressure strategy:
However, we're hitting the same exception than above and the problem seems to be that the
hasRequests
method takes into account only the downstream capacity (which can be configured using themax-inflight-messages
property - default value is 1024), but the exception is being thrown when the buffer limit is exceeded (which can be configured using the annotation@OnOverflow(value = BUFFER, bufferSize = XX)
- default value is 128).Our existing workaround is to configure the
max-inflight-messages
to128
(which is the default value of the buffer size).Implementation ideas
The text was updated successfully, but these errors were encountered: