thejerf/abtime

invalid timer's Reset result value

LopatkinEvgeniy opened this issue · 3 comments

Stress test to reproduce:

func TestFakeTimerResetStress(t *testing.T) {
    c := NewManual()
    d := time.Hour
    timer := c.NewTimer(d, timerID)

    for i := 0; i < 100000; i++ {
        go func() {
            c.Advance(d)
            c.Trigger(timerID)
        }()

        actualTime := <-timer.Channel()
        expectedTime := c.Now()
        if expectedTime != actualTime {
            t.Fatalf("Unexpected time received from the channel, expected=%s, actual=%s", expectedTime, actualTime)
        }

        wasActive := timer.Reset(d)
        if wasActive {
            t.Fatal("Unexpected reset result value")
        }
    }
}

Result:

go test ./ --run=TestFakeTimerResetStress
--- FAIL: TestFakeTimerResetStress (0.00s)
    manual_test.go:36: Unexpected reset result value
FAIL
FAIL    github.com/thejerf/abtime    0.001s

Reset must return false when timer expired.

Thank you for your report. I also found a race condition; the tick is sent down the channel and then the .stopped flag is updated. It needs to be the other way around. I've released a v1.0.1 to address this.

Also, thanks for letting me know somebody else uses this. :) I still use it on almost every project, so I know it's useful to at least some degree.

I've examined using the ability to export types to make a true drop-in to the time library with the exact same API, but I can't work out any way to avoid having to label the various different uses of the time functions one way or another.