-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
etcd: make commit queue test deterministic #5117
Conversation
makeWriteSet([]string{"key4"}), | ||
) | ||
|
||
// Allow Tx1 to continue with the commit. | ||
block.Unlock() |
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.
nit: might be simpler to use a ready
channel, e.g.:
commit := func(...) {
...
if ready != nil {
<-ready
}
}
...
ready := make(chan struct{})
...
commit(_, _, ready)
...
close(ready)
This approach will also work with more than one "free" transaction
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.
See my other comment. We can use a channel, but in the test example it's not possible to submit overlapping conflicting/non-conflicting txns without introducing a deadlock in the test (even if we resolve it 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 agree that using a channel to signal that the commit can continue is better than a mutex
q.Add( | ||
commit("free", true), |
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.
This test seems a bit weaker now, in that it doesn't actually test for transaction reordering. If the commit queue simply executed the transactions in the order they are added, the test would pass. The new version doesn't test that concurrent non-conflicting transactions are executed immediately.
I think it makes sense to keep the current transactions, possibly even making the test stronger by naming the transactions free1
and free2
to assert their order.
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.
Without the sleeps it's not really possible to do this deterministically without submitting non-conflicting txns first since then the non-conflicting txn that should be executed inside the commit queue's read mutex will be behind the conflicting txn which waits on that mutex as a writer. See a simplified example: https://play.golang.org/p/66zi9waGZj-
return func() { | ||
if commit != nil { |
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.
can names this signalStart
or something other that is more descriptive than commit
@@ -33,8 +34,8 @@ func TestCommitQueue(t *testing.T) { | |||
i := atomic.AddInt32(&idx, 1) | |||
commits[i] = tag | |||
|
|||
if sleep { | |||
time.Sleep(commitDuration) | |||
if block != nil { |
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.
this needs a comment, same for the channel close above
makeWriteSet([]string{"key4"}), | ||
) | ||
|
||
// Allow Tx1 to continue with the commit. | ||
block.Unlock() |
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 agree that using a channel to signal that the commit can continue is better than a mutex
Closing this as another solution has been implemented in: #5513 |
Sometimes commit queue test fails due to timing issue introduced by sleeps. This PR changes the test to make it deterministic.