The Server.cleanShutdown() method can be called twice during shutdown:
In serve() when the context is cancelled: <-s.ctx.Done() → s.cleanShutdown()
In the fx lifecycle OnStop hook: s.cleanShutdown()
This results in httpServer.Shutdown() being called twice. While http.Server.Shutdown() is likely idempotent, this is fragile and can produce spurious error logs.
Additionally, there's a potential race condition: if fx sends SIGTERM and the internal signal handler fires simultaneously, both goroutines could call cleanShutdown() concurrently without synchronization (no mutex or sync.Once).
Fix
Wrap cleanShutdown() in a sync.Once to ensure it runs exactly once:
typeServerstruct{...shutdownOncesync.Once}func(s*Server)cleanShutdown(){s.shutdownOnce.Do(func(){// actual shutdown logic})}
Category
Should-fix.
## Bug
The `Server.cleanShutdown()` method can be called twice during shutdown:
1. In `serve()` when the context is cancelled: `<-s.ctx.Done()` → `s.cleanShutdown()`
2. In the fx lifecycle `OnStop` hook: `s.cleanShutdown()`
This results in `httpServer.Shutdown()` being called twice. While `http.Server.Shutdown()` is likely idempotent, this is fragile and can produce spurious error logs.
Additionally, there's a potential race condition: if fx sends SIGTERM and the internal signal handler fires simultaneously, both goroutines could call `cleanShutdown()` concurrently without synchronization (no mutex or sync.Once).
## Fix
Wrap `cleanShutdown()` in a `sync.Once` to ensure it runs exactly once:
```go
type Server struct {
...
shutdownOnce sync.Once
}
func (s *Server) cleanShutdown() {
s.shutdownOnce.Do(func() {
// actual shutdown logic
})
}
```
## Category
Should-fix.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Bug
The
Server.cleanShutdown()method can be called twice during shutdown:serve()when the context is cancelled:<-s.ctx.Done()→s.cleanShutdown()OnStophook:s.cleanShutdown()This results in
httpServer.Shutdown()being called twice. Whilehttp.Server.Shutdown()is likely idempotent, this is fragile and can produce spurious error logs.Additionally, there's a potential race condition: if fx sends SIGTERM and the internal signal handler fires simultaneously, both goroutines could call
cleanShutdown()concurrently without synchronization (no mutex or sync.Once).Fix
Wrap
cleanShutdown()in async.Onceto ensure it runs exactly once:Category
Should-fix.