-
Notifications
You must be signed in to change notification settings - Fork 15.4k
KAFKA-2669; Fix LogCleanerIntegrationTest #327
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
Closed
Closed
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
39c356a
KAFKA-2669; Fix LogCleanerIntegrationTest
2616cad
improve awaitCleaned as reviewers suggested
6cbb4a5
add timeout for awaitCleaned
74cd5e7
replace return with nested function
0f4d1cf
minor change
lindong28 69ffb13
address comments
lindong28 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -149,12 +149,25 @@ class LogCleaner(val config: CleanerConfig, | |
| } | ||
|
|
||
| /** | ||
| * For testing, a way to know when work has completed. This method blocks until the | ||
| * For testing, a way to know when work has completed. This method waits until the | ||
| * cleaner has processed up to the given offset on the specified topic/partition | ||
| * | ||
| * @param topic The Topic to be cleaned | ||
| * @param part The partition of the topic to be cleaned | ||
| * @param offset The first dirty offset that the cleaner doesn't have to clean | ||
| * @param maxWaitMs The maximum time in ms to wait for cleaner | ||
| * | ||
| * @return A boolean indicating whether the work has completed before timeout | ||
| */ | ||
| def awaitCleaned(topic: String, part: Int, offset: Long, timeout: Long = 30000L): Unit = { | ||
| while(!cleanerManager.allCleanerCheckpoints.contains(TopicAndPartition(topic, part))) | ||
| Thread.sleep(10) | ||
| def awaitCleaned(topic: String, part: Int, offset: Long, maxWaitMs: Long = 60000L): Boolean = { | ||
| def isCleaned = cleanerManager.allCleanerCheckpoints.get(TopicAndPartition(topic, part)).fold(false)(_ >= offset) | ||
| var remainingWaitMs = maxWaitMs | ||
| while (!isCleaned && remainingWaitMs > 0) { | ||
| val sleepTime = math.min(100, remainingWaitMs) | ||
| Thread.sleep(sleepTime) | ||
| remainingWaitMs -= sleepTime | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The following is more idiomatic: while (cleanerManager.allCleanerCheckpoints.get(TopicAndPartition(topic, part)).fold(true)(_ < offset)
Thread.sleep(10)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice approach. I will follow your suggestion. |
||
| isCleaned | ||
| } | ||
|
|
||
| /** | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for implementing the timeout. I, personally, prefer the following implementation:
It avoids
return, which is discouraged in Scala, makes the loop condition clearer and the timeout only controls when to exit the loop, the return value is based onisCleanedonly.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. This is a very nice usage of nested function in Scala:) I have updated the patch as you suggested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, thanks. Sorry to nitpick, but you don't need the
math.maxinremainingWaitMs = ...since we check for > 0 (that is, it's OK for the value to be negative). Looks good otherwise.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One question: is there a reason why we are reducing the
remainingWaitMsby 100 instead of the actual sleep time like in my suggested version (just curious)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ijuma Thanks for your suggestion:) I have replaced that statement by
remainingWaitMs -= 100.I think, w.r.t. functionality, my
Thread.sleep(math.min(100, remainingWaitMs))is exactly the same as yourval sleepTime = math.min(100, remainingWaitMs)andThread.sleep(sleepTime), right? I think the only difference is that my implementation used 1 less lines here and avoided extra variablesleepTime.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for updating it!
There are two differences:
100in two places. If someone decides that the sleep time should be a different value, they may miss the fact that they have to update it in two places.100even if sleep time was lower because ofmath.min. This won't have any effect with the current loop condition, but it could change in a future update.These minor issues add-up and make refactoring harder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the first problem is minor and it is OK to change it twice. But I agree it is a valid problem. In stead of following either of our approach, I think it is better to do
sleepInterval = 100to make this an explicit configuration to solve the problem here.I am a bit confused by your comments on the 2nd problem... I had this implementation previously that didn't have this problem:
Then you made the following comment:
Therefore I change the implementation to do
remainingWaitMs -= 100. Actually I am fine with both solutions. But now I am confused by your latest comment that "it is not OK to have remainingWaitMs < 0". Did I misunderstand your comment?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sleepInterval = 100is better if you want to make it possible for callers to configure that parameter. It seems to me that it's unnecessary, but up to you. It is not the worst thing in the world to have to change two things in adjacent lines, so you can also keep it as is if committers are fine with the code (there is also a slight readability penalty as users have to figure out that the100in both cases represent the same thing). It is a minor thing for sure, but personally I try to write code so that there are no minor things when the solution is easy. :)I think I didn't explain myself well regarding point 2, but let's just drop it as it's subtle and it's not worth spending the time discussing it in this context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ijuma Thanks:) I have updated patch to follow the code you suggested. Please have a look.