Fix concurrency issues in controlclient, ipn, types/logger (#456)
Signed-Off-By: Dmytro Shynkevych <dmytro@tailscale.com>
This commit is contained in:
committed by
GitHub
parent
c8cf3169ba
commit
c12d87c54b
@@ -127,18 +127,23 @@ func RateLimitedFn(logf Logf, f time.Duration, burst int, maxCache int) Logf {
|
||||
// since the last time this identical line was logged.
|
||||
func LogOnChange(logf Logf, maxInterval time.Duration, timeNow func() time.Time) Logf {
|
||||
var (
|
||||
mu sync.Mutex
|
||||
sLastLogged string
|
||||
tLastLogged = timeNow()
|
||||
)
|
||||
|
||||
return func(format string, args ...interface{}) {
|
||||
s := fmt.Sprintf(format, args...)
|
||||
|
||||
mu.Lock()
|
||||
if s == sLastLogged && timeNow().Sub(tLastLogged) < maxInterval {
|
||||
mu.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
sLastLogged = s
|
||||
tLastLogged = timeNow()
|
||||
mu.Unlock()
|
||||
|
||||
logf(s)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -117,3 +118,31 @@ func TestArgWriter(t *testing.T) {
|
||||
t.Errorf("got %q; want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSynchronization(t *testing.T) {
|
||||
timeNow := testTimer(1 * time.Second)
|
||||
tests := []struct {
|
||||
name string
|
||||
logf Logf
|
||||
}{
|
||||
{"RateLimitedFn", RateLimitedFn(t.Logf, 1*time.Minute, 2, 50)},
|
||||
{"LogOnChange", LogOnChange(t.Logf, 5*time.Second, timeNow)},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
|
||||
f := func() {
|
||||
tt.logf("1 2 3 4 5")
|
||||
wg.Done()
|
||||
}
|
||||
|
||||
go f()
|
||||
go f()
|
||||
|
||||
wg.Wait()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user