Files
clawgo/pkg/lifecycle/loop_runner.go
2026-02-13 17:09:09 +08:00

61 lines
985 B
Go

package lifecycle
import "sync"
// LoopRunner provides a reusable start/stop lifecycle for background loops.
// It guarantees idempotent start/stop and waits for loop exit on stop.
type LoopRunner struct {
mu sync.RWMutex
wg sync.WaitGroup
running bool
stopCh chan struct{}
}
func NewLoopRunner() *LoopRunner {
return &LoopRunner{}
}
func (r *LoopRunner) Start(loop func(stop <-chan struct{})) bool {
if loop == nil {
return false
}
r.mu.Lock()
defer r.mu.Unlock()
if r.running {
return false
}
stopCh := make(chan struct{})
r.stopCh = stopCh
r.running = true
r.wg.Add(1)
go func() {
defer r.wg.Done()
loop(stopCh)
}()
return true
}
func (r *LoopRunner) Stop() bool {
r.mu.Lock()
if !r.running {
r.mu.Unlock()
return false
}
stopCh := r.stopCh
r.stopCh = nil
r.running = false
close(stopCh)
r.mu.Unlock()
r.wg.Wait()
return true
}
func (r *LoopRunner) Running() bool {
r.mu.RLock()
defer r.mu.RUnlock()
return r.running
}