mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-04-13 05:37:29 +08:00
61 lines
985 B
Go
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
|
|
}
|