Fix shutdown sequence to ensure final snapshot is taken
- Add Shutdown() method to RouteWatch with mutex-protected shutdown flag - Move all cleanup logic from Run() to Shutdown() - Call Shutdown() from fx OnStop hook - This ensures snapshotter gets called during graceful shutdown
This commit is contained in:
parent
52cdcd5785
commit
fa9b086629
@ -8,6 +8,7 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.eeqj.de/sneak/routewatch/internal/database"
|
"git.eeqj.de/sneak/routewatch/internal/database"
|
||||||
@ -58,6 +59,8 @@ type RouteWatch struct {
|
|||||||
snapshotter *snapshotter.Snapshotter
|
snapshotter *snapshotter.Snapshotter
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
maxRuntime time.Duration
|
maxRuntime time.Duration
|
||||||
|
shutdown bool
|
||||||
|
mu sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new RouteWatch instance
|
// New creates a new RouteWatch instance
|
||||||
@ -130,6 +133,20 @@ func (rw *RouteWatch) Run(ctx context.Context) error {
|
|||||||
// Wait for context cancellation
|
// Wait for context cancellation
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shutdown performs graceful shutdown of all services
|
||||||
|
func (rw *RouteWatch) Shutdown() {
|
||||||
|
rw.mu.Lock()
|
||||||
|
if rw.shutdown {
|
||||||
|
rw.mu.Unlock()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rw.shutdown = true
|
||||||
|
rw.mu.Unlock()
|
||||||
|
|
||||||
// Stop services
|
// Stop services
|
||||||
rw.streamer.Stop()
|
rw.streamer.Stop()
|
||||||
|
|
||||||
@ -153,15 +170,15 @@ func (rw *RouteWatch) Run(ctx context.Context) error {
|
|||||||
|
|
||||||
// Take final snapshot before shutdown if snapshotter is available
|
// Take final snapshot before shutdown if snapshotter is available
|
||||||
if rw.snapshotter != nil {
|
if rw.snapshotter != nil {
|
||||||
rw.logger.Info("Shutting down snapshotter")
|
rw.logger.Info("Taking final snapshot before shutdown")
|
||||||
if err := rw.snapshotter.Shutdown(); err != nil {
|
if err := rw.snapshotter.Shutdown(); err != nil {
|
||||||
rw.logger.Error("Failed to shutdown snapshotter", "error", err)
|
rw.logger.Error("Failed to shutdown snapshotter", "error", err)
|
||||||
|
} else {
|
||||||
|
rw.logger.Info("Final snapshot completed")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rw.logger.Info("No snapshotter available")
|
rw.logger.Info("No snapshotter available")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// logRoutingTableStats periodically logs routing table statistics
|
// logRoutingTableStats periodically logs routing table statistics
|
||||||
|
@ -40,6 +40,7 @@ func CLIEntry() {
|
|||||||
},
|
},
|
||||||
OnStop: func(_ context.Context) error {
|
OnStop: func(_ context.Context) error {
|
||||||
logger.Info("Shutting down RouteWatch")
|
logger.Info("Shutting down RouteWatch")
|
||||||
|
rw.Shutdown()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user