Skip to content
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

silences: avoid deadlock #995

Merged
merged 2 commits into from
Sep 27, 2017
Merged

silences: avoid deadlock #995

merged 2 commits into from
Sep 27, 2017

Conversation

iksaif
Copy link
Contributor

@iksaif iksaif commented Sep 15, 2017

Calling gossip.GossipBroadcast() will cause a deadlock if
there is a currently executing OnBroadcast* function.

See #982

require.Equal(t, want.data, s.st.data, "Unexpected silence state")

// GossipBroadcast is called in a gorountine.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: goroutine

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Calling gossip.GossipBroadcast() will cause a deadlock if
there is a currently executing OnBroadcast* function.

See prometheus#982
@olive42
Copy link

olive42 commented Sep 15, 2017

LGTM

s.gossip.GossipBroadcast(st)
// setSilence() is called with s.mtx locked, which can produce
// a deadlock if we call GossipBroadcast from here.
go s.gossip.GossipBroadcast(st)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests still pass when I remove the go here. The tests should fail without the inclusion of this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Contributor

@stuartnelson3 stuartnelson3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

once those changes are made to the test, good to merge. Thanks for your patience!

require.NoError(t, s.setSilence(sil))
require.True(t, called, "GossipBroadcast was not called")
s.mtx.Unlock()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this test passes because of the go, if someone were to remove the go, this deadlocks and the timeout in the select below is never called. If you re-arrange the code like below, then we have a passing test with your code 🙌 , and if someone removes the go, it will fail instead of locking up:

diff --git a/silence/silence_test.go b/silence/silence_test.go
index 420a78c..eed4060 100644
--- a/silence/silence_test.go
+++ b/silence/silence_test.go
@@ -213,11 +213,11 @@ func TestSilencesSetSilence(t *testing.T) {
 	}
 
 	// setSilence() is always called with s.mtx locked()
-	s.mtx.Lock()
-	require.NoError(t, s.setSilence(sil))
-	s.mtx.Unlock()
-
-	require.Equal(t, want.data, s.st.data, "Unexpected silence state")
+	go func() {
+		s.mtx.Lock()
+		require.NoError(t, s.setSilence(sil))
+		s.mtx.Unlock()
+	}()
 
 	// GossipBroadcast is called in a goroutine.
 	select {
@@ -225,6 +225,8 @@ func TestSilencesSetSilence(t *testing.T) {
 	case <-time.After(1 * time.Second):
 		t.Fatal("GossipBroadcast was not called")
 	}
+
+	require.Equal(t, want.data, s.st.data, "Unexpected silence state")
 }
 
 func TestSilenceSet(t *testing.T) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point !

Copy link
Contributor

@stuartnelson3 stuartnelson3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@stuartnelson3 stuartnelson3 merged commit 34d9524 into prometheus:master Sep 27, 2017
hh pushed a commit to ii/alertmanager that referenced this pull request Jul 22, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants