Skip to content

Commit 575541a

Browse files
committed
fix(services): populate health state directly in Register
Replace the chRefresh channel mechanism with direct map population in Register(). Instead of signaling the run() goroutine to call update() (which re-checks ALL services), Register() now directly populates c.ready and c.healthy for just the newly registered service. This is simpler and avoids unnecessary re-polling of all services.
1 parent 8115835 commit 575541a

1 file changed

Lines changed: 22 additions & 10 deletions

File tree

pkg/services/health.go

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ func CopyHealth(dest, src map[string]error) {
4747
// HealthChecker is a services.Service which monitors other services and can be probed for system health.
4848
type HealthChecker struct {
4949
StateMachine
50-
chStop chan struct{}
51-
chDone chan struct{}
50+
chStop chan struct{}
51+
chDone chan struct{}
5252

5353
cfg HealthCheckerConfig
5454

@@ -130,12 +130,12 @@ func (cfg HealthCheckerConfig) New() *HealthChecker {
130130
cfg.initVerSha()
131131
cfg.setNoopHooks()
132132
return &HealthChecker{
133-
cfg: cfg,
134-
services: make(map[string]HealthReporter, 10),
135-
healthy: make(map[string]error, 10),
136-
ready: make(map[string]error, 10),
137-
chStop: make(chan struct{}),
138-
chDone: make(chan struct{}),
133+
cfg: cfg,
134+
services: make(map[string]HealthReporter, 10),
135+
healthy: make(map[string]error, 10),
136+
ready: make(map[string]error, 10),
137+
chStop: make(chan struct{}),
138+
chDone: make(chan struct{}),
139139
}
140140
}
141141

@@ -219,13 +219,26 @@ func (c *HealthChecker) Register(service HealthReporter) error {
219219
}
220220

221221
c.servicesMu.Lock()
222-
defer c.servicesMu.Unlock()
223222
if testing.Testing() {
224223
if orig, ok := c.services[name]; ok {
225224
panic(fmt.Errorf("duplicate name %q: service names must be unique: types %T & %T", name, service, orig))
226225
}
227226
}
228227
c.services[name] = service
228+
c.servicesMu.Unlock()
229+
230+
// Populate health state directly for the new service so it is
231+
// visible immediately without waiting for the next polling tick.
232+
ready := service.Ready()
233+
report := service.HealthReport()
234+
235+
c.stateMu.Lock()
236+
c.ready[name] = ready
237+
for n, err := range report {
238+
c.healthy[n] = err
239+
}
240+
c.stateMu.Unlock()
241+
229242
return nil
230243
}
231244

@@ -237,7 +250,6 @@ func (c *HealthChecker) Unregister(name string) error {
237250
ctx := context.Background()
238251

239252
c.servicesMu.Lock()
240-
defer c.servicesMu.Unlock()
241253
delete(c.services, name)
242254
c.cfg.Delete(ctx, name)
243255
return nil

0 commit comments

Comments
 (0)