周期性 -race 重跑抓到真实 bug:wsClientCore.enqueue close 后 select 随机选择致契约违反;确定性先查 done 修复+测试循环加固+gofmt 存量漂移清理

Result: {"status":"keep","total_issues":8,"eslint_errors":0,"eslint_problems":0,"eslint_warnings":0,"golint_canonicalheader":0,"golint_errname":0,"golint_errorlint":1,"golint_exhaustive":0,"golint_forcetypeassert":0,"golint_gosec":0,"golint_intrange":0,"golint_modernize":3,"golint_nilnil":3,"golint_perfsprint":0,"golint_prealloc":0,"golint_recvcheck":1,"golint_test_testifylint":0,"golint_test_thelper":0,"golint_test_total":0,"golint_test_usetesting":0,"golint_total":8,"golint_usestdlibvars":0,"golint_vetx_total":0,"golint_wastedassign":0,"measure_s":95,"tsc_errors":0,"vitest_failed":0,"vitest_total":126}
This commit is contained in:
ryan
2026-08-26 13:14:59 +08:00
parent 63e3b85294
commit 453f7e5d90
7 changed files with 26 additions and 7 deletions
@@ -12,7 +12,6 @@ import (
"time"
"github.com/gin-gonic/gin"
)
const (
@@ -35,8 +34,6 @@ type agentClient struct {
onStatus AgentStatusHandler
}
type agentHub struct {
mu sync.RWMutex
clients map[string]*agentClient
@@ -36,9 +36,14 @@ func (c *wsClientCore) close() {
// enqueue best-effort delivers message; it never blocks and fails fast when
// the client is closed or its send buffer is full.
func (c *wsClientCore) enqueue(message Message) bool {
// 先确定性检查 closed:若与发送合并在同一个 select,两个 case 同时就绪时
// Go 会随机选择,close 后仍可能投递成功。
select {
case <-c.done:
return false
default:
}
select {
case c.send <- message:
return true
default:
@@ -35,8 +35,12 @@ func TestWSClientCoreEnqueueFailsAfterClose(t *testing.T) {
done: make(chan struct{}),
}
core.close()
if core.enqueue(Message{Type: messageTypePing}) {
t.Fatal("enqueue must fail after close")
// 循环多次:若 close 检查与发送合并在同一个 select,两 case 同时就绪时
// Go 随机选择,单次调用可能碰巧通过。
for range 50 {
if core.enqueue(Message{Type: messageTypePing}) {
t.Fatal("enqueue must fail after close")
}
}
}
@@ -23,7 +23,6 @@ type flaredClient struct {
wsClientCore
}
type flaredHub struct {
mu sync.RWMutex
clients map[string]*flaredClient
@@ -17,7 +17,6 @@ type relayClient struct {
wsClientCore
}
type relayHub struct {
mu sync.RWMutex
clients map[string]*relayClient