-
Notifications
You must be signed in to change notification settings - Fork 51
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
Port ConcurrecnyLimiter from FuturesExtra to work with CompletionStage #53
Conversation
This is a pretty straightforward port, and no extra optimizations were made.
Codecov Report
@@ Coverage Diff @@
## master #53 +/- ##
=======================================
Coverage 100% 100%
- Complexity 43 63 +20
=======================================
Files 4 5 +1
Lines 99 162 +63
Branches 3 9 +6
=======================================
+ Hits 99 162 +63
Continue to review full report at Codecov.
|
The coverage has been lowered, so the -1 from codcov. However this line is not covered in FuturesExtra. By my point of view we can never get null on that line, but perhaps if we do not releasing would be a bug? Not sure |
I think 'job' can be null if two threads race - both get |
@pettermahlen Yeah, I think this would be hard to test. The logic here is correct however - we need to return the ticket if we didn't actually get a job. I wonder if this could be refactored to rely on Job<T> job = null;
while (!(job = queue.poll()) == null) {
if (!limit.tryAcquire()) {
queue.enqueue(job);
return null;
}
return job;
}
return null; |
I think that algorithm would reorder jobs? Perhaps flipping it around would be better: // speculatively try to acquire a permit
if (!limit.tryAcquire()) {
return null;
}
Job<T> job = queue.poll();
if (job == null) {
// nothing to do; return the permit
limit.release();
}
return job; |
Ah yes, ordering matters. However flipping will still end-up hard to test I think |
Well, I guess a good thing about my suggested algorithm (if it works), is it's not check-then-act on the queue, so there's no race between two threads. The case when 'queue is not empty' followed by 'poll returns null' doesn't exist. So the scenario that isn't tested doesn't exist with that version, I think. |
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 mean... it's a fork of code I already wrote, so how can I reject it? :)
We should probably also add documentation to the README but it doesnt have to be in the same PR
Not sure how to fix the untestable line - we can't reorder it as you mention, and we dont want to risk having jobs stuck on queue forever if they dont get pumped for some reason |
@spkrka what about my alternative algorithm? It looks safe to me, as well as a little more straightforward to understand? |
@pettermahlen I think you are right. I've done the refactoring as a PR here spotify/futures-extra#28 which could be useful to review before we finish this review, as that one is shorter and easier to compare |
@pettermahlen @spkrka Have rebased and moved the new grabJob over |
This has been renamed to ConcurrencyReducer to avoid class conflicts
with FuturesExtra, as they use the same package as CompletableFutures