41 lines
947 B
Go
41 lines
947 B
Go
package rate
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestLimiterDoesNotHoldLockWhileWaiting(t *testing.T) {
|
|
limiter := NewLimiter(250 * time.Millisecond)
|
|
if err := limiter.Wait(context.Background()); err != nil {
|
|
t.Fatalf("initial wait: %v", err)
|
|
}
|
|
|
|
firstCtx, cancelFirst := context.WithCancel(context.Background())
|
|
defer cancelFirst()
|
|
|
|
firstDone := make(chan error, 1)
|
|
go func() {
|
|
firstDone <- limiter.Wait(firstCtx)
|
|
}()
|
|
|
|
time.Sleep(20 * time.Millisecond)
|
|
|
|
secondCtx, cancelSecond := context.WithTimeout(context.Background(), 30*time.Millisecond)
|
|
defer cancelSecond()
|
|
|
|
startedAt := time.Now()
|
|
err := limiter.Wait(secondCtx)
|
|
elapsed := time.Since(startedAt)
|
|
if err == nil {
|
|
t.Fatal("second wait succeeded, want context timeout")
|
|
}
|
|
if elapsed > 150*time.Millisecond {
|
|
t.Fatalf("second wait took %s, want it to observe context timeout without waiting behind first caller", elapsed)
|
|
}
|
|
|
|
cancelFirst()
|
|
<-firstDone
|
|
}
|