KAFKA-10531: Check for negative values to Thread.sleep call - #9347
Conversation
There was a problem hiding this comment.
Why don't we use a monotonic timer?
There was a problem hiding this comment.
Wanted to make least amount of change. I can update the code to use monotonic 'nanoTime` instead (nanoseconds in Time interface). We will also need to convert that to milli before passing to sleep (unless we want to add nano to those interfaces too, like Utils.sleep)
There was a problem hiding this comment.
In fact I don't like this loop altogether. Going to rewrite it so that it doesn't use these constructs.
There was a problem hiding this comment.
You can use hiResClockMs so that you get the value in ms.
There was a problem hiding this comment.
In fact we don't need value from clock to sleep, only need it to find elapsed time and timeout. I have decoupled these two, and also fixed a minor issue where it was sleeping first time even if topic was present.
Please take a look.
d2b17c3 to
7d73eda
Compare
stanislavkozlovski
left a comment
There was a problem hiding this comment.
LGTM! Thanks for the PR!
There was a problem hiding this comment.
Why not using partitionsFor(String topic, Duration timeout) (https://github.com/apache/kafka/blob/trunk/clients/src/main/java/org/apache/kafka/clients/consumer/KafkaConsumer.java#L1944) to replace while loop?
There was a problem hiding this comment.
I think the semantics needed here is different. The timeout in partitionsFor is the max amount of time the api can block waiting for response before it fails with TimeoutException. However, the api can return within timeout with empty results as newly created topics data has not been propagated yet. We then have to retry again until partitionsFor returns the partition data (upto a max time).
There was a problem hiding this comment.
It seems to me the behavior of timeout is not consistent in consumer methods. The timeout used by other methods (for example: position, offsetsForTimes, beginningOffsets and endOffsets) is to await the result of specify partitions. It means consumer will send a request again if the timer is not expired and the specify partition has no metadata (i.e topics data has not been propagated yet). Maybe partitionsFor should be fixed for consistent behavior.
There was a problem hiding this comment.
Not sure about this, no result for "partitionInfos" is a valid result. There is no point in automatic retrying. While for other apis that retry automatically, they do it if they get an invalid result back. If null was a valid result for them, they shouldn't retry either.
There was a problem hiding this comment.
@soondenana Thanks for responses. This patch LGTM. What I want to discuss is unrelated to this patch.
they do it if they get an invalid result back. If null was a valid result for them, they shouldn't retry either.
If the topic is not exist (or not been propagated yet), partitionFor can return null. By contrast, beginningOffsets (and other methods) throws TimeoutException. In order to make consistent behavior, beginningOffsets (and other methods) should let the topic (or partition) be absent in the returned Map. WDYT?
|
@soondenana if the goal is to minimize the changes, would it be sufficient to change the code to use Are there performance implications of using |
Thanks @rhauch for taking a look. The PR started with only fixing negative sleep vlaue, but as we started looking at code more, there were multiple issue so the "minimize change" idea was dropped. Here are 3 issues with original code:
Considering that I decided to rewrite the loop to fix all three issues. Good question on performance. It seems like |
That makes sense, and I noticed the same when reviewing.
That's probably true. But if |
Yes, makes sense. Updated code to do so. |
rhauch
left a comment
There was a problem hiding this comment.
LGTM. Thanks, @soondenana. And I'm fine removing the Utils.sleep(...) change, too, if that's the preferred approach.
System.currentTimeMillis() is not monotonic, so using that to calculate time to sleep can result in negative values. That will throw IllegalArgumentException. This change checks for that and sleeps for a second (to avoid tight loop) if the value returned is negative.
892e09d to
4054146
Compare
|
There was an error when building The failure is not related to this PR. |
System.currentTimeMillis() is not monotonic, so using that to calculate time to sleep can result in negative values. That will throw IllegalArgumentException. This change checks for that and sleeps for a second (to avoid tight loop) if the value returned is negative. Author: Shaik Zakir Hussain <zhussain@confluent.io> Reviewer: Randall Hauch <rhauch@gmail.com>
System.currentTimeMillis() is not monotonic, so using that to calculate time to sleep can result in negative values. That will throw IllegalArgumentException. This change checks for that and sleeps for a second (to avoid tight loop) if the value returned is negative. Author: Shaik Zakir Hussain <zhussain@confluent.io> Reviewer: Randall Hauch <rhauch@gmail.com>
) System.currentTimeMillis() is not monotonic, so using that to calculate time to sleep can result in negative values. That will throw IllegalArgumentException. This change checks for that and sleeps for a second (to avoid tight loop) if the value returned is negative. Author: Shaik Zakir Hussain <zhussain@confluent.io> Reviewer: Randall Hauch <rhauch@gmail.com>
) System.currentTimeMillis() is not monotonic, so using that to calculate time to sleep can result in negative values. That will throw IllegalArgumentException. This change checks for that and sleeps for a second (to avoid tight loop) if the value returned is negative. Author: Shaik Zakir Hussain <zhussain@confluent.io> Reviewer: Randall Hauch <rhauch@gmail.com>
System.currentTimeMillis() is not monotonic, so using that to calculate
time to sleep can result in negative values. That will throw
IllegalArgumentException.
This change checks for that and sleeps for a second (to avoid tight
loop) if the value returned is negative.
This change need to be backported to older branches that have Connect.
More detailed description of your change,
if necessary. The PR title and PR message become
the squashed commit message, so use a separate
comment to ping reviewers.
Summary of testing strategy (including rationale)
for the feature or bug fix. Unit and/or integration
tests are expected for any behaviour change and
system tests should be considered for larger changes.
Committer Checklist (excluded from commit message)