Bound each shutdown stage by the stop deadline (closes #100)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
Shutdown passes its context to every stage: the streamer, the four handlers, the WHOIS fetcher, the database maintainer and the HTTP server each stop waiting when it ends. A handler then skips its last write and logs how many updates it did not write, and the HTTP server closes the connections still open. The database is checkpointed and closed last, and left open once the deadline has passed, since a write may still hold it. The stop hook gives Shutdown 8 seconds and fx 9, inside the 10 seconds upaas and docker stop allow, so a stop signal exits 0. Model: opus-5-5
This commit was merged in pull request #130.
This commit is contained in:
1 parent
237f73fc49
commit
09d3073fa5
20 files changed
+1097
-130
No files matched your search
@@ -46,7 +46,7 @@ type DBMaintainer struct {
|
||||
db database.Store
|
||||
logger *slog.Logger
|
||||
stopCh chan struct{}
|
||||
wg sync.WaitGroup
|
||||
done chan struct{} // closed when the maintenance goroutine returns
|
||||
|
||||
// Stats tracking
|
||||
statsMu sync.Mutex
|
||||
@@ -67,14 +67,13 @@ func NewDBMaintainer(db database.Store, logger *slog.Logger) *DBMaintainer {
|
||||
db: db,
|
||||
logger: logger.With("component", "db_maintainer"),
|
||||
stopCh: make(chan struct{}),
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
// Start begins the background maintenance goroutine. It runs until Stop:
|
||||
// the end of ctx does not stop it.
|
||||
func (m *DBMaintainer) Start(ctx context.Context) {
|
||||
m.wg.Add(1)
|
||||
|
||||
go m.run(context.WithoutCancel(ctx))
|
||||
|
||||
m.logger.Info("Database maintainer started",
|
||||
@@ -84,16 +83,23 @@ func (m *DBMaintainer) Start(ctx context.Context) {
|
||||
)
|
||||
}
|
||||
|
||||
// Stop gracefully shuts down the maintainer.
|
||||
func (m *DBMaintainer) Stop() {
|
||||
// Stop stops the maintainer and waits, until ctx ends, for a maintenance task
|
||||
// in progress to finish.
|
||||
func (m *DBMaintainer) Stop(ctx context.Context) {
|
||||
close(m.stopCh)
|
||||
m.wg.Wait()
|
||||
m.logger.Info("Database maintainer stopped")
|
||||
|
||||
select {
|
||||
case <-m.done:
|
||||
m.logger.Info("Database maintainer stopped")
|
||||
case <-ctx.Done():
|
||||
m.logger.Warn("Stop deadline passed before the database maintainer " +
|
||||
"stopped")
|
||||
}
|
||||
}
|
||||
|
||||
// run is the main background loop.
|
||||
func (m *DBMaintainer) run(ctx context.Context) {
|
||||
defer m.wg.Done()
|
||||
defer close(m.done)
|
||||
|
||||
// Use different timers for each task
|
||||
checkpointTimer := time.NewTimer(checkpointInterval)
|
||||
|
||||
Reference in new issue
Block a user