refactor: rework limiter, traffic accounting, and logging (nlog)
This commit is contained in:
@@ -2,6 +2,7 @@ package limiter
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cedar2025/xboard-node/internal/panel"
|
||||
)
|
||||
@@ -121,3 +122,26 @@ func TestSpeedTracker_UpdateBuckets_RemovesUsers(t *testing.T) {
|
||||
t.Error("expected no bucket for removed user 2")
|
||||
}
|
||||
}
|
||||
|
||||
// Regression: log callback must not run while UpdateBuckets holds t.mu.Lock,
|
||||
// otherwise callbacks that call LimitedUserCount() self-deadlock on RWMutex.
|
||||
func TestSpeedTracker_UpdateBuckets_LogCallbackMayCallLimitedUserCount(t *testing.T) {
|
||||
l := New()
|
||||
st := NewSpeedTracker(l)
|
||||
l.UpdateUsers([]panel.User{{ID: 1, UUID: "u1", SpeedLimit: 1}})
|
||||
st.SetLogCallback(func(msg string) {
|
||||
_ = st.LimitedUserCount()
|
||||
})
|
||||
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
st.UpdateBuckets()
|
||||
close(done)
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("deadlock: UpdateBuckets did not finish (log callback vs RWMutex)")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user