fix(heartbeat): resolve bug where service could never start

HeartbeatService.Start() always returned early because running()
checked stopChan closure state, which is "open" (= true) for a
newly created service. This caused Start() to interpret a fresh
service as "already running" and skip launching the goroutine.

Introduce a `started` bool field to separate "has been started"
from "has not been stopped", fixing both the start failure and
a potential double-close panic on Stop().
This commit is contained in:
Together
2026-02-12 17:56:04 +08:00
parent 4a7c48112a
commit bab78de6a4

View File

@@ -14,6 +14,7 @@ type HeartbeatService struct {
interval time.Duration interval time.Duration
enabled bool enabled bool
mu sync.RWMutex mu sync.RWMutex
started bool
stopChan chan struct{} stopChan chan struct{}
} }
@@ -31,7 +32,7 @@ func (hs *HeartbeatService) Start() error {
hs.mu.Lock() hs.mu.Lock()
defer hs.mu.Unlock() defer hs.mu.Unlock()
if hs.running() { if hs.started {
return nil return nil
} }
@@ -39,6 +40,7 @@ func (hs *HeartbeatService) Start() error {
return fmt.Errorf("heartbeat service is disabled") return fmt.Errorf("heartbeat service is disabled")
} }
hs.started = true
go hs.runLoop() go hs.runLoop()
return nil return nil
@@ -48,10 +50,11 @@ func (hs *HeartbeatService) Stop() {
hs.mu.Lock() hs.mu.Lock()
defer hs.mu.Unlock() defer hs.mu.Unlock()
if !hs.running() { if !hs.started {
return return
} }
hs.started = false
close(hs.stopChan) close(hs.stopChan)
} }