Skip to content

Commit

Permalink
fn: stress test GoroutineManager.Stop calls
Browse files Browse the repository at this point in the history
Make sure there is no race condition between Done() and Wait() methods in the
GoroutineManager implementation.

See lightningnetwork#9141 (comment)
  • Loading branch information
starius committed Nov 14, 2024
1 parent 0876173 commit 669ebf4
Showing 1 changed file with 36 additions and 0 deletions.
36 changes: 36 additions & 0 deletions fn/goroutine_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package fn

import (
"context"
"sync"
"testing"
"time"

Expand Down Expand Up @@ -119,3 +120,38 @@ func TestGoroutineManagerStress(t *testing.T) {
// Wait for Stop to complete.
<-stopChan
}

// TestGoroutineManagerStopsStress launches many Stop() calls in parallel with a
// task exiting. It attempts to catch a race condition between wg.Done() and
// wg.Wait() calls. According to documentation of wg.Wait() this is acceptable,
// therefore this test passes even with -race.
func TestGoroutineManagerStopsStress(t *testing.T) {
t.Parallel()

m := NewGoroutineManager(context.Background())

// jobChan is used to make the task to finish.
jobChan := make(chan struct{})

// Start a task and wait inside it until we start calling Stop() method.
err := m.Go(func(ctx context.Context) {
<-jobChan
})
require.NoError(t, err)

// Now launch many gorotines calling Stop() method in parallel.
var wg sync.WaitGroup
for i := 0; i < 100; i++ {
wg.Add(1)
go func() {
defer wg.Done()
m.Stop()
}()
}

// Exit the task in parallel with Stop() calls.
close(jobChan)

// Wait until all the Stop() calls complete.
wg.Wait()
}

0 comments on commit 669ebf4

Please sign in to comment.