-
Notifications
You must be signed in to change notification settings - Fork 60
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
Make ring.DoBatch() result deterministic #430
Conversation
Signed-off-by: Yuri Nikolic <durica.nikolic@grafana.com>
Signed-off-by: Yuri Nikolic <durica.nikolic@grafana.com>
ring/batch.go
Outdated
if it.remaining.Dec() == 0 { | ||
if b.rpcsFailed.Inc() == 1 { | ||
b.err <- it.err.Load() | ||
if it.succeeded.Load() < int32(it.minSuccess) { |
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.
isn't there a race between calling it.suceeded.Inc()
and it.succeeded.Load()
? It's possible that between the time one invocation of succeeded.Inc()
gets to succeeded.Load()
another one has already invoked Inc()
. This was we lose one invocation of remaining.Dec()
of the first one
you can save the return value of succeeded.Inc in a variable and use that instead of calling Load again
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.
That's correct. I will fix this error. Thank you @dimitarvdimitrov
Signed-off-by: Yuri Nikolic <durica.nikolic@grafana.com>
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.
LGTM, thanks for fixing this
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.
Minor thing I noticed post-merge...
go func() { | ||
wg.Wait() | ||
}() |
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.
What's the purpose of waiting for the WaitGroup
on a background goroutine?
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 for pointing this out. This code was copied from batchTracker.DoBatchWithOptions()
, but in the latter the additional go routine also does the cleanup, which is not necessary in this test.
I will now create a PR that removes this go routine.
What this PR does:
This PR fixes a bug present in the
ring.DoBatch()
function. Namely, there might be usecases in which, for the same set of keys, and the same ring instances failing on the same keys, different order of execution ofbatchTracker.record()
on different keys gives different values.For example, let us assume the following scenario:
ring.DoBatch()
is called on 2 keyscallback
function oncallback
function on4xx
error.The expected outcome of this call to$I_1$ , $I_4$ , $I_5$ , $I_2$ , $I_3$ , $I_6$ will actually give rise to a failure, but in the case of this order: $I_1$ , $I_4$ , $I_2$ , $I_3$ , $I_5$ , $I_6$ would actually succeed. The reason for that is that successful execution of $k_1$ on $I_1$ , $I_2$ , $I_3$ is taken into account more than once.
ring.DoBatch()
is that it would fail with the4xx
error.With the current implementation, getting results from ingesters for example in this order:
This PR fixes this problem.
Checklist
CHANGELOG.md
updated - the order of entries should be[CHANGE]
,[FEATURE]
,[ENHANCEMENT]
,[BUGFIX]