🔧 chore(config): defense-in-depth for WatchAndApply test race (Q-038) (#50)
Some checks failed
CI/CD Pipeline / Build Docker Cache (push) Successful in 14s
CI/CD Pipeline / Trigger Docker Push (push) Has been cancelled
CI/CD Pipeline / CI Pipeline (push) Has been cancelled

Co-authored-by: Gabriel Radureau <arcodange@gmail.com>
Co-committed-by: Gabriel Radureau <arcodange@gmail.com>
This commit was merged in pull request #50.
This commit is contained in:
2026-05-05 09:45:14 +02:00
committed by arcodange
parent 92a8027dd4
commit 46df1f6170
2 changed files with 35 additions and 4 deletions

View File

@@ -730,10 +730,15 @@ func (c *Config) WatchAndApply(ctx context.Context) {
// Stop the watcher on context cancel — we set a flag that the
// OnConfigChange handler checks, avoiding the race with viper's
// internal state that would occur if we called OnConfigChange again.
// We deliberately do NOT log here: viper's internal watcher goroutine
// has no public Stop, so it can outlive ctx, and a zerolog call here
// would race with the next test's LoadConfig → SetupLogging →
// zerolog.SetGlobalLevel under -race (observed 2026-05-05).
//
// We deliberately do NOT log inside this goroutine: this goroutine
// outlives ctx (parent's defer cancel only fires when the test's
// outer scope exits, not when t.Cleanup runs), so a log call here
// races with the next test's LoadConfig → SetupLogging →
// zerolog.SetGlobalLevel under -race (observed 2026-05-05, Q-038).
// The flag-set is the load-bearing operation; the missing log line
// is a small ops cost (operators learn the watcher stops on shutdown
// via the parent shutdown logs, not a dedicated message).
go func() {
<-ctx.Done()
c.reloadMu.Lock()