A small fix to avoid deadlock that can happen as mentioned in issue #3682 (#3715)

Signed-off-by: Anand Rajagopal <anrajag@amazon.com>
This commit is contained in:
Anand Rajagopal 2024-03-01 03:39:01 -06:00 committed by GitHub
parent d85bef20d9
commit 1eb83c21eb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 58 additions and 3 deletions

View File

@ -151,7 +151,6 @@ func max(a, b int) int {
func (a *Alerts) Subscribe() provider.AlertIterator {
a.mtx.Lock()
defer a.mtx.Unlock()
var (
done = make(chan struct{})
alerts = a.alerts.List()

View File

@ -135,6 +135,63 @@ func TestAlertsSubscribePutStarvation(t *testing.T) {
}
}
func TestDeadLock(t *testing.T) {
t0 := time.Now()
t1 := t0.Add(5 * time.Second)
marker := types.NewMarker(prometheus.NewRegistry())
// Run gc every 5 milliseconds to increase the possibility of a deadlock with Subscribe()
alerts, err := NewAlerts(context.Background(), marker, 5*time.Millisecond, noopCallback{}, log.NewNopLogger(), nil)
if err != nil {
t.Fatal(err)
}
alertsToInsert := []*types.Alert{}
for i := 0; i < 200+1; i++ {
alertsToInsert = append(alertsToInsert, &types.Alert{
Alert: model.Alert{
// Make sure the fingerprints differ
Labels: model.LabelSet{"iteration": model.LabelValue(strconv.Itoa(i))},
Annotations: model.LabelSet{"foo": "bar"},
StartsAt: t0,
EndsAt: t1,
GeneratorURL: "http://example.com/prometheus",
},
UpdatedAt: t0,
Timeout: false,
})
}
if err := alerts.Put(alertsToInsert...); err != nil {
t.Fatal("Unable to add alerts")
}
done := make(chan bool)
// call subscribe repeatedly in a goroutine to increase
// the possibility of a deadlock occurring
go func() {
tick := time.NewTicker(10 * time.Millisecond)
defer tick.Stop()
stopAfter := time.After(1 * time.Second)
for {
select {
case <-tick.C:
alerts.Subscribe()
case <-stopAfter:
done <- true
break
}
}
}()
select {
case <-done:
// no deadlock
alerts.Close()
case <-time.After(10 * time.Second):
t.Error("Deadlock detected")
}
}
func TestAlertsPut(t *testing.T) {
marker := types.NewMarker(prometheus.NewRegistry())
alerts, err := NewAlerts(context.Background(), marker, 30*time.Minute, noopCallback{}, log.NewNopLogger(), nil)

View File

@ -71,8 +71,6 @@ func (a *Alerts) Run(ctx context.Context, interval time.Duration) {
func (a *Alerts) gc() {
a.Lock()
defer a.Unlock()
var resolved []*types.Alert
for fp, alert := range a.c {
if alert.Resolved() {
@ -80,6 +78,7 @@ func (a *Alerts) gc() {
resolved = append(resolved, alert)
}
}
a.Unlock()
a.cb(resolved)
}