Files
Agent-System/internal/server/background_loop.go
T
weichen a9c9a9182e refactor(server): remove 24 mirrored Runtime fields via nil-safe accessors; fix Shutdown-vs-background-loop DATA RACE and goose 00071 duplicate version
- Server no longer mirrors app.Runtime services (gov/svc/pwSvc/...): 574 call sites now use accessors in runtime_accessors.go
- backgroundLoop (mutex+sync.Once) stops sweeper/publisher/reminder/wsGC goroutines race-free (baseline 44161d2a reproduced DATA RACE; now green under -race)
- goose 00071 duplicate (dialogue merge 1da17a28 brought two 00071): context-conflict-adjudications renumbered to 00072; dev DB applied only through 00070 so zero data migration
- task_finalize tests build minimal app.Runtime; test injection via serverTestOverrides + setOverride* (explicit-nil markers for fail-closed cases)
2026-09-25 13:17:22 +00:00

37 lines
1018 B
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package server
import "sync"
// backgroundLoop 收口 Server 后台循环的停止语义(修 DATA RACE: Shutdown 与
// sweeper/publisher/reminder/GC goroutine 对 stop 通道的并发 close/nil 写)。
// 通道仅在启动 goroutine 内一次创建并被该 goroutine 独占持有;
// Shutdown 经 stopOnce 通知,不触碰通道字段本身。
type backgroundLoop struct {
mu sync.Mutex
stopCh chan struct{}
stopOnce sync.Once
stopped bool
}
// start 登记停止通道;返回值是否实际启动(幂等:已存在/已停止返回 false)。
func (l *backgroundLoop) start() (chan struct{}, bool) {
l.mu.Lock()
defer l.mu.Unlock()
if l.stopCh != nil || l.stopped {
return nil, false
}
l.stopCh = make(chan struct{})
return l.stopCh, true
}
// stop 通知循环退出并防止后续再启动;可安全多次调用。
func (l *backgroundLoop) stop() {
l.mu.Lock()
ch := l.stopCh
l.stopped = true
l.mu.Unlock()
if ch != nil {
l.stopOnce.Do(func() { close(ch) })
}
}