fix(common): fix race condition in countdown timer StopTimer method (#2014)

The TestCountdownShouldBeAbleToStop test was failing intermittently due to
a race condition in the StopTimer() implementation. Previously, the goroutine
used defer to set initilised=false, which executed after close(q) signaled
completion to StopTimer(). This allowed StopTimer() to return before the
state was properly cleaned up, causing isInitilised() checks to occasionally
see stale true values.

Fixed by explicitly calling setInitilised(false) before close(q), ensuring
the state is updated atomically before StopTimer() returns. This eliminates
the race condition and makes the test pass consistently.

Verified by running the test 30 times consecutively with no failures.
This commit is contained in:
Daniel Liu 2026-02-10 19:21:42 +08:00 committed by GitHub
parent ec697ddbdb
commit 81d0db2344
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -64,14 +64,15 @@ func (t *CountdownTimer) Reset(i interface{}, currentRound, highestRound types.R
// A long running process that
func (t *CountdownTimer) startTimer(i interface{}, currentRound, highestRound types.Round) {
// Make sure we mark Initilised to false when we quit the countdown
defer t.setInitilised(false)
timer := time.NewTimer(t.durationHelper.GetTimeoutDuration(currentRound, highestRound))
// We start with a inf loop
for {
select {
case q := <-t.quitc:
log.Debug("Quit countdown timer")
// Set initilised to false before signaling completion
// This ensures the state is updated before StopTimer() returns
t.setInitilised(false)
close(q)
return
case <-timer.C: