Files
gochat/backend/internal/lifecycle/handler_group.go
T
Rogeeandrogee 798ea43c2f HH-442: isolate runtime processes and harden shutdown (#90)
* HH-442: isolate runtime processes and harden shutdown

* HH-442: harden worker shutdown races

* HH-442: gate dependency shutdown on active handlers

---------

Co-authored-by: Rogee <rogee@ipao.vip>
2026-08-22 02:38:15 +08:00

64 lines
1.0 KiB
Go

package lifecycle
import (
"context"
"sync"
)
// HandlerGroup stops new handlers, cancels their shared lifecycle context,
// and waits for handlers already using application dependencies.
type HandlerGroup struct {
ctx context.Context
cancel context.CancelFunc
mu sync.Mutex
done *sync.Cond
active int
stopped bool
}
func NewHandlerGroup() *HandlerGroup {
ctx, cancel := context.WithCancel(context.Background())
g := &HandlerGroup{ctx: ctx, cancel: cancel}
g.done = sync.NewCond(&g.mu)
return g
}
func (g *HandlerGroup) Context() context.Context { return g.ctx }
func (g *HandlerGroup) Begin() bool {
g.mu.Lock()
defer g.mu.Unlock()
if g.stopped {
return false
}
g.active++
return true
}
func (g *HandlerGroup) Done() {
g.mu.Lock()
g.active--
if g.active == 0 {
g.done.Broadcast()
}
g.mu.Unlock()
}
func (g *HandlerGroup) Stop() {
g.mu.Lock()
if !g.stopped {
g.stopped = true
g.cancel()
}
g.mu.Unlock()
}
func (g *HandlerGroup) Wait() {
g.mu.Lock()
for g.active != 0 {
g.done.Wait()
}
g.mu.Unlock()
}