mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-04-14 20:47:30 +08:00
fix bug
This commit is contained in:
60
pkg/lifecycle/loop_runner.go
Normal file
60
pkg/lifecycle/loop_runner.go
Normal file
@@ -0,0 +1,60 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user