refactor: propagate context.Context through call chains
Thread context.Context from callers instead of creating context.Background() at every call site. Engine stores its lifecycle ctx for use by triggerAlert goroutines. TUI Model carries ctx for store operations in Cmd closures. CLI commands create a root ctx and thread it through openStore, seed functions, and init methods. Only two intentional context.Background() remain in non-root positions: engine constructor default (overridden by Start) and drainWrites (parent already cancelled at shutdown).
This commit was merged in pull request #155.
This commit is contained in:
@@ -19,8 +19,8 @@ type AlertHealth struct {
|
||||
|
||||
// InitAlertHealth restores persisted alert send health so the dashboard shows real
|
||||
// "last sent" / health state on startup instead of resetting every channel to "never".
|
||||
func (e *Engine) InitAlertHealth() {
|
||||
records, err := e.db.LoadAlertHealth(context.Background())
|
||||
func (e *Engine) InitAlertHealth(ctx context.Context) {
|
||||
records, err := e.db.LoadAlertHealth(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -198,7 +198,7 @@ func (e *Engine) triggerAlert(alertID int, title, message string) {
|
||||
if alertID <= 0 {
|
||||
return
|
||||
}
|
||||
cfg, err := e.db.GetAlert(context.Background(), alertID)
|
||||
cfg, err := e.db.GetAlert(e.ctx, alertID)
|
||||
if err != nil {
|
||||
e.AddLog(fmt.Sprintf("Failed to load alert config %d: %v", alertID, err))
|
||||
return
|
||||
@@ -206,7 +206,7 @@ func (e *Engine) triggerAlert(alertID int, title, message string) {
|
||||
provider := alert.GetProvider(cfg)
|
||||
if provider != nil {
|
||||
go func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), alertSendTimeout)
|
||||
ctx, cancel := context.WithTimeout(e.ctx, alertSendTimeout)
|
||||
defer cancel()
|
||||
if err := provider.Send(ctx, title, message); err != nil {
|
||||
e.AddLog(fmt.Sprintf("Alert send failed (%s): %v", cfg.Name, err))
|
||||
@@ -250,8 +250,8 @@ func (e *Engine) GetAlertHealth(alertID int) AlertHealth {
|
||||
return e.alertHealth[alertID]
|
||||
}
|
||||
|
||||
func (e *Engine) TestAlert(alertID int) error {
|
||||
cfg, err := e.db.GetAlert(context.Background(), alertID)
|
||||
func (e *Engine) TestAlert(ctx context.Context, alertID int) error {
|
||||
cfg, err := e.db.GetAlert(ctx, alertID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load alert: %w", err)
|
||||
}
|
||||
@@ -259,7 +259,7 @@ func (e *Engine) TestAlert(alertID int) error {
|
||||
if provider == nil {
|
||||
return fmt.Errorf("no provider for type %q", cfg.Type)
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), alertSendTimeout)
|
||||
ctx, cancel := context.WithTimeout(ctx, alertSendTimeout)
|
||||
defer cancel()
|
||||
err = provider.Send(ctx, "🧪 Test Alert", fmt.Sprintf("Test notification from uptop for channel '%s'.", cfg.Name))
|
||||
if err != nil {
|
||||
|
||||
@@ -14,8 +14,8 @@ type SiteHistory struct {
|
||||
UpChecks int
|
||||
}
|
||||
|
||||
func (e *Engine) InitHistory() {
|
||||
all, err := e.db.LoadAllHistory(context.Background(), maxHistoryLen)
|
||||
func (e *Engine) InitHistory(ctx context.Context) {
|
||||
all, err := e.db.LoadAllHistory(ctx, maxHistoryLen)
|
||||
if err != nil {
|
||||
e.AddLog("Failed to load check history: " + err.Error())
|
||||
return
|
||||
|
||||
@@ -64,6 +64,7 @@ type Engine struct {
|
||||
dbWrites chan dbWrite
|
||||
writerWG sync.WaitGroup
|
||||
checkerWG sync.WaitGroup
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
stopOnce sync.Once
|
||||
}
|
||||
@@ -90,6 +91,7 @@ func newEngine(s store.Store, allowPrivateTargets bool) *Engine {
|
||||
allowPrivateTargets: allowPrivateTargets,
|
||||
maintRetention: defaultMaintRetention,
|
||||
dbWrites: make(chan dbWrite, dbWriteBuffer),
|
||||
ctx: context.Background(),
|
||||
db: s,
|
||||
strictClient: &http.Client{
|
||||
Transport: &http.Transport{
|
||||
@@ -200,6 +202,8 @@ func (e *Engine) dbWriter(ctx context.Context) {
|
||||
}
|
||||
|
||||
// drainWrites flushes everything still buffered, best-effort, at shutdown.
|
||||
// Uses context.Background because the engine ctx is already cancelled when
|
||||
// this runs — writes still need to reach the DB.
|
||||
func (e *Engine) drainWrites() {
|
||||
for {
|
||||
select {
|
||||
@@ -238,8 +242,8 @@ func (e *Engine) Stop() {
|
||||
})
|
||||
}
|
||||
|
||||
func (e *Engine) InitLogs() {
|
||||
entries, err := e.db.LoadLogs(context.Background(), maxLogEntries)
|
||||
func (e *Engine) InitLogs(ctx context.Context) {
|
||||
entries, err := e.db.LoadLogs(ctx, maxLogEntries)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -264,6 +268,7 @@ func (e *Engine) Start(ctx context.Context) {
|
||||
// trace the cross-method call, and cancelling the parent reaps this child
|
||||
// regardless, so the leak it warns about can't occur.
|
||||
ctx, e.cancel = context.WithCancel(ctx) //nolint:gosec // cancel is called in Stop()
|
||||
e.ctx = ctx
|
||||
|
||||
e.writerWG.Add(1)
|
||||
go e.dbWriter(ctx)
|
||||
|
||||
@@ -208,7 +208,7 @@ func TestInitHistory_LoadsFromDB(t *testing.T) {
|
||||
{SiteID: 1, LatencyNs: 3000000, IsUp: false},
|
||||
}
|
||||
e := newTestEngine(ms)
|
||||
e.InitHistory()
|
||||
e.InitHistory(context.Background())
|
||||
|
||||
h, ok := e.GetHistory(1)
|
||||
if !ok {
|
||||
@@ -248,7 +248,7 @@ func TestInitLogs_LoadsFromDB(t *testing.T) {
|
||||
{Message: "old-log-2"},
|
||||
}
|
||||
e := newTestEngine(ms)
|
||||
e.InitLogs()
|
||||
e.InitLogs(context.Background())
|
||||
|
||||
logs := e.GetLogs()
|
||||
if len(logs) != 2 {
|
||||
|
||||
@@ -141,16 +141,16 @@ func (e *Engine) GetDisplayStatus(site models.Site) string {
|
||||
return string(site.Status)
|
||||
}
|
||||
|
||||
func (e *Engine) GetStateChanges(siteID int, limit int) []models.StateChange {
|
||||
changes, err := e.db.GetStateChanges(context.Background(), siteID, limit)
|
||||
func (e *Engine) GetStateChanges(ctx context.Context, siteID int, limit int) []models.StateChange {
|
||||
changes, err := e.db.GetStateChanges(ctx, siteID, limit)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
func (e *Engine) GetStateChangesSince(siteID int, since time.Time) []models.StateChange {
|
||||
changes, err := e.db.GetStateChangesSince(context.Background(), siteID, since)
|
||||
func (e *Engine) GetStateChangesSince(ctx context.Context, siteID int, since time.Time) []models.StateChange {
|
||||
changes, err := e.db.GetStateChangesSince(ctx, siteID, since)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user