-
Notifications
You must be signed in to change notification settings - Fork 252
fix(singleflight): give waiting callers the real error of the run they waited on #1014
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
Merged
+251
−23
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
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
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
Oops, something went wrong.
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.
I wonder if an additional
flightstruct is needed. Can't the error be embedded in thecallstruct directly?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.
Good question — it was tried, and the error cannot live on
call, becausecallis reused by the next flight.do()clears the flight before it closes the channel, so the next flight can start while the previous waiters are still waking up. If the error is a field ofcall, that next flight overwrites it inside this window, and the waiters then read its result instead of their own.All five current tests still pass with the error moved to
call, so the suite does not cover this. A test with 50 waiters, where the next flight starts as soon as the previous one clears its counter, fails at once:That
<nil>is the bug of this PR again: a waiter is told its flight succeeded when it failed.The data race is a second problem. A waiter reads the error without the lock. That is safe for its own flight, because the write happens before
close(ch)and the read happens after<-ch. It is not safe against the next flight's write, which has no such ordering. So an error oncallwould also need the mutex on every wake, whileflight.errneeds no synchronization at all.flightholds only what belongs to one flight. The channel is already per flight and the error has the same lifetime, so they live together, at the cost of one small allocation per refresh.That 50-waiter test can be added here if you want it, since the current tests clearly do not cover this case.
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.
hmm, ok. Maybe we should replace the
chchannel with awgsync.WaitGroup to reduce GC overhead.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.
IDK.. I was unable to have
wgand keep cancellable property. All solutions with the same behavior but fixed issue require 1 extra alloc compared to main branch.flight{err, ch}, this PRflight{err, wg}chan error, bufferedLast one is kinda close perf-wise and only 16 bytes extra alloc. I can push that version if it makes more sense (but it's more complicated than the one here).
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 see. Sorry, I forgot about the cancellation.