refactor(store): propagate context.Context through all Store methods
Every Store interface method (except Close) now takes context.Context as first parameter. All 54 db.Query/Exec/QueryRow calls in SQLStore replaced with their *Context variants. DB operations now respect cancellation and deadlines. Context sources by caller: - Engine dbWriter/poll/pruner: engine ctx from Start() - HTTP handlers: r.Context() - config.Apply/Export: caller-provided ctx - TUI/main.go init: context.Background() RunCheck and all sub-checks (HTTP/ping/port/DNS) accept parent ctx. HTTP checks now inherit shutdown cancellation instead of rooting in context.Background(). dbWrite.exec takes ctx so the writer goroutine can cancel stuck DB operations. DeleteSite/ImportData use BeginTx(ctx) instead of Begin().
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package tui
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -13,7 +14,7 @@ import (
|
||||
|
||||
func loadCollapsed(s store.Store) map[int]bool {
|
||||
m := make(map[int]bool)
|
||||
raw, err := s.GetPreference("collapsed_groups")
|
||||
raw, err := s.GetPreference(context.Background(), "collapsed_groups")
|
||||
if err != nil || raw == "" {
|
||||
return m
|
||||
}
|
||||
@@ -130,21 +131,22 @@ func (m *Model) loadTabDataCmd() tea.Cmd {
|
||||
st := m.store
|
||||
isAdmin := m.isAdmin
|
||||
return func() tea.Msg {
|
||||
alerts, err := st.GetAllAlerts()
|
||||
ctx := context.Background()
|
||||
alerts, err := st.GetAllAlerts(ctx)
|
||||
if err != nil {
|
||||
return tabDataMsg{seq: seq, err: err}
|
||||
}
|
||||
var users []models.User
|
||||
if isAdmin {
|
||||
if users, err = st.GetAllUsers(); err != nil {
|
||||
if users, err = st.GetAllUsers(ctx); err != nil {
|
||||
return tabDataMsg{seq: seq, err: err}
|
||||
}
|
||||
}
|
||||
nodes, err := st.GetAllNodes()
|
||||
nodes, err := st.GetAllNodes(ctx)
|
||||
if err != nil {
|
||||
return tabDataMsg{seq: seq, err: err}
|
||||
}
|
||||
maint, err := st.GetAllMaintenanceWindows(100)
|
||||
maint, err := st.GetAllMaintenanceWindows(ctx, 100)
|
||||
if err != nil {
|
||||
return tabDataMsg{seq: seq, err: err}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package tui
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
neturl "net/url"
|
||||
"sort"
|
||||
@@ -528,10 +529,10 @@ func (m *Model) submitAlertForm() tea.Cmd {
|
||||
m.state = stateDashboard
|
||||
if id > 0 {
|
||||
return writeCmd("Update alert", func() error {
|
||||
return st.UpdateAlert(id, name, aType, settings)
|
||||
return st.UpdateAlert(context.Background(), id, name, aType, settings)
|
||||
})
|
||||
}
|
||||
return writeCmd("Add alert", func() error {
|
||||
return st.AddAlert(name, aType, settings)
|
||||
return st.AddAlert(context.Background(), name, aType, settings)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package tui
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
@@ -240,6 +241,6 @@ func (m *Model) submitMaintForm() tea.Cmd {
|
||||
st := m.store
|
||||
m.state = stateDashboard
|
||||
return writeCmd("Add maintenance window", func() error {
|
||||
return st.AddMaintenanceWindow(mw)
|
||||
return st.AddMaintenanceWindow(context.Background(), mw)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package tui
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
@@ -562,7 +563,7 @@ func (m *Model) submitSiteForm() tea.Cmd {
|
||||
// follows in the Cmd. New sites enter the engine via its poll loop
|
||||
// once the insert lands.
|
||||
m.engine.UpdateSiteConfig(site)
|
||||
return writeCmd("Update site", func() error { return st.UpdateSite(site) })
|
||||
return writeCmd("Update site", func() error { return st.UpdateSite(context.Background(), site) })
|
||||
}
|
||||
return writeCmd("Add site", func() error { return st.AddSite(site) })
|
||||
return writeCmd("Add site", func() error { return st.AddSite(context.Background(), site) })
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package tui
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
@@ -118,10 +119,10 @@ func (m *Model) submitUserForm() tea.Cmd {
|
||||
m.state = stateUsers
|
||||
if id > 0 {
|
||||
return writeCmd("Update user", func() error {
|
||||
return st.UpdateUser(id, username, key, role)
|
||||
return st.UpdateUser(context.Background(), id, username, key, role)
|
||||
})
|
||||
}
|
||||
return writeCmd("Add user", func() error {
|
||||
return st.AddUser(username, key, role)
|
||||
return st.AddUser(context.Background(), username, key, role)
|
||||
})
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
package tui
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
@@ -180,7 +181,7 @@ func InitialModel(isAdmin bool, s store.Store, eng *monitor.Engine, version stri
|
||||
spring := harmonica.NewSpring(harmonica.FPS(10), 6.0, 0.4)
|
||||
collapsed := loadCollapsed(s)
|
||||
|
||||
themeName, _ := s.GetPreference("theme")
|
||||
themeName, _ := s.GetPreference(context.Background(), "theme")
|
||||
theme := themeByName(themeName)
|
||||
themeIdx := 0
|
||||
for i, t := range themes {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package tui
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -78,17 +79,17 @@ func (m *Model) handleConfirmDelete(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
var cmd tea.Cmd
|
||||
switch m.deleteTab {
|
||||
case 0:
|
||||
cmd = writeCmd("Delete site", func() error { return st.DeleteSite(id) })
|
||||
cmd = writeCmd("Delete site", func() error { return st.DeleteSite(context.Background(), id) })
|
||||
m.engine.RemoveSite(id)
|
||||
m.adjustCursor(len(m.sites) - 1)
|
||||
case 1:
|
||||
cmd = writeCmd("Delete alert", func() error { return st.DeleteAlert(id) })
|
||||
cmd = writeCmd("Delete alert", func() error { return st.DeleteAlert(context.Background(), id) })
|
||||
m.adjustCursor(len(m.alerts) - 1)
|
||||
case 4:
|
||||
cmd = writeCmd("Delete maintenance window", func() error { return st.DeleteMaintenanceWindow(id) })
|
||||
cmd = writeCmd("Delete maintenance window", func() error { return st.DeleteMaintenanceWindow(context.Background(), id) })
|
||||
m.adjustCursor(len(m.maintenanceWindows) - 1)
|
||||
case 5:
|
||||
cmd = writeCmd("Delete user", func() error { return st.DeleteUser(id) })
|
||||
cmd = writeCmd("Delete user", func() error { return st.DeleteUser(context.Background(), id) })
|
||||
m.adjustCursor(len(m.users) - 1)
|
||||
}
|
||||
m.refreshLive()
|
||||
@@ -566,7 +567,7 @@ func (m *Model) handleDashboardKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||||
st := m.store
|
||||
m.refreshLive()
|
||||
return m, writeCmd("Save collapsed groups", func() error {
|
||||
return st.SetPreference("collapsed_groups", payload)
|
||||
return st.SetPreference(context.Background(), "collapsed_groups", payload)
|
||||
})
|
||||
}
|
||||
case "p":
|
||||
@@ -576,7 +577,7 @@ func (m *Model) handleDashboardKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||||
st := m.store
|
||||
m.refreshLive()
|
||||
return m, writeCmd("Update pause state", func() error {
|
||||
return st.UpdateSitePaused(id, paused)
|
||||
return st.UpdateSitePaused(context.Background(), id, paused)
|
||||
})
|
||||
}
|
||||
case "i":
|
||||
@@ -596,7 +597,7 @@ func (m *Model) handleDashboardKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||||
id := mw.ID
|
||||
m.refreshLive()
|
||||
return m, writeCmd("End maintenance", func() error {
|
||||
return st.EndMaintenanceWindow(id)
|
||||
return st.EndMaintenanceWindow(context.Background(), id)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -607,7 +608,7 @@ func (m *Model) handleDashboardKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||||
st := m.store
|
||||
name := m.theme.Name
|
||||
return m, writeCmd("Save theme", func() error {
|
||||
return st.SetPreference("theme", name)
|
||||
return st.SetPreference(context.Background(), "theme", name)
|
||||
})
|
||||
case "d", "backspace":
|
||||
return m.handleDeleteItem()
|
||||
|
||||
+85
-56
@@ -1,6 +1,7 @@
|
||||
package tui
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -23,80 +24,108 @@ type tuiMockStore struct {
|
||||
deleteSiteCalls int // counts DeleteSite hits (to prove writes run in Cmds)
|
||||
}
|
||||
|
||||
func (m *tuiMockStore) GetAllAlerts() ([]models.AlertConfig, error) { return m.alerts, nil }
|
||||
func (m *tuiMockStore) GetAllUsers() ([]models.User, error) { return m.users, nil }
|
||||
func (m *tuiMockStore) GetAllNodes() ([]models.ProbeNode, error) { return m.nodes, nil }
|
||||
func (m *tuiMockStore) GetStateChanges(int, int) ([]models.StateChange, error) {
|
||||
func (m *tuiMockStore) GetAllAlerts(_ context.Context) ([]models.AlertConfig, error) {
|
||||
return m.alerts, nil
|
||||
}
|
||||
func (m *tuiMockStore) GetAllUsers(_ context.Context) ([]models.User, error) { return m.users, nil }
|
||||
func (m *tuiMockStore) GetAllNodes(_ context.Context) ([]models.ProbeNode, error) {
|
||||
return m.nodes, nil
|
||||
}
|
||||
func (m *tuiMockStore) GetStateChanges(_ context.Context, _ int, _ int) ([]models.StateChange, error) {
|
||||
m.stateChangeCalls++
|
||||
return m.stateChanges, nil
|
||||
}
|
||||
func (m *tuiMockStore) GetAllMaintenanceWindows(int) ([]models.MaintenanceWindow, error) {
|
||||
func (m *tuiMockStore) GetAllMaintenanceWindows(_ context.Context, _ int) ([]models.MaintenanceWindow, error) {
|
||||
return m.maint, nil
|
||||
}
|
||||
|
||||
func (m *tuiMockStore) Init() error { return nil }
|
||||
func (m *tuiMockStore) GetSites() ([]models.Site, error) { return nil, nil }
|
||||
func (m *tuiMockStore) AddSite(models.Site) error { return nil }
|
||||
func (m *tuiMockStore) UpdateSite(models.Site) error { return nil }
|
||||
func (m *tuiMockStore) UpdateSitePaused(int, bool) error { return nil }
|
||||
func (m *tuiMockStore) DeleteSite(int) error {
|
||||
func (m *tuiMockStore) Init(_ context.Context) error { return nil }
|
||||
func (m *tuiMockStore) GetSites(_ context.Context) ([]models.Site, error) { return nil, nil }
|
||||
func (m *tuiMockStore) AddSite(_ context.Context, _ models.Site) error { return nil }
|
||||
func (m *tuiMockStore) UpdateSite(_ context.Context, _ models.Site) error { return nil }
|
||||
func (m *tuiMockStore) UpdateSitePaused(_ context.Context, _ int, _ bool) error { return nil }
|
||||
func (m *tuiMockStore) DeleteSite(_ context.Context, _ int) error {
|
||||
m.deleteSiteCalls++
|
||||
return nil
|
||||
}
|
||||
func (m *tuiMockStore) GetAlert(int) (models.AlertConfig, error) { return models.AlertConfig{}, nil }
|
||||
func (m *tuiMockStore) AddAlert(string, string, map[string]string) error { return nil }
|
||||
func (m *tuiMockStore) UpdateAlert(int, string, string, map[string]string) error { return nil }
|
||||
func (m *tuiMockStore) DeleteAlert(int) error { return nil }
|
||||
func (m *tuiMockStore) GetSiteByName(string) (models.Site, error) { return models.Site{}, nil }
|
||||
func (m *tuiMockStore) GetAlertByName(string) (models.AlertConfig, error) {
|
||||
func (m *tuiMockStore) GetAlert(_ context.Context, _ int) (models.AlertConfig, error) {
|
||||
return models.AlertConfig{}, nil
|
||||
}
|
||||
func (m *tuiMockStore) AddSiteReturningID(models.Site) (int, error) { return 0, nil }
|
||||
func (m *tuiMockStore) AddAlertReturningID(string, string, map[string]string) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
func (m *tuiMockStore) AddUser(string, string, string) error { return nil }
|
||||
func (m *tuiMockStore) UpdateUser(int, string, string, string) error { return nil }
|
||||
func (m *tuiMockStore) DeleteUser(int) error { return nil }
|
||||
func (m *tuiMockStore) SaveCheck(int, int64, bool) error { return nil }
|
||||
func (m *tuiMockStore) SaveCheckFromNode(int, string, int64, bool) error {
|
||||
func (m *tuiMockStore) AddAlert(_ context.Context, _ string, _ string, _ map[string]string) error {
|
||||
return nil
|
||||
}
|
||||
func (m *tuiMockStore) LoadAllHistory(int) (map[int][]models.CheckRecord, error) {
|
||||
return nil, nil
|
||||
func (m *tuiMockStore) UpdateAlert(_ context.Context, _ int, _ string, _ string, _ map[string]string) error {
|
||||
return nil
|
||||
}
|
||||
func (m *tuiMockStore) PruneCheckHistory() error { return nil }
|
||||
func (m *tuiMockStore) SaveStateChange(int, string, string, string) error { return nil }
|
||||
func (m *tuiMockStore) GetStateChangesSince(int, time.Time) ([]models.StateChange, error) {
|
||||
return nil, nil
|
||||
func (m *tuiMockStore) DeleteAlert(_ context.Context, _ int) error { return nil }
|
||||
func (m *tuiMockStore) GetSiteByName(_ context.Context, _ string) (models.Site, error) {
|
||||
return models.Site{}, nil
|
||||
}
|
||||
func (m *tuiMockStore) PruneStateChanges() error { return nil }
|
||||
func (m *tuiMockStore) RegisterNode(models.ProbeNode) error { return nil }
|
||||
func (m *tuiMockStore) GetNode(string) (models.ProbeNode, error) { return models.ProbeNode{}, nil }
|
||||
func (m *tuiMockStore) UpdateNodeLastSeen(string) error { return nil }
|
||||
func (m *tuiMockStore) DeleteNode(string) error { return nil }
|
||||
func (m *tuiMockStore) LoadAlertHealth() (map[int]models.AlertHealthRecord, error) {
|
||||
return nil, nil
|
||||
func (m *tuiMockStore) GetAlertByName(_ context.Context, _ string) (models.AlertConfig, error) {
|
||||
return models.AlertConfig{}, nil
|
||||
}
|
||||
func (m *tuiMockStore) SaveAlertHealth(models.AlertHealthRecord) error { return nil }
|
||||
func (m *tuiMockStore) SaveLog(string) error { return nil }
|
||||
func (m *tuiMockStore) LoadLogs(int) ([]string, error) { return nil, nil }
|
||||
func (m *tuiMockStore) PruneLogs() error { return nil }
|
||||
func (m *tuiMockStore) GetActiveMaintenanceWindows() ([]models.MaintenanceWindow, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *tuiMockStore) AddMaintenanceWindow(models.MaintenanceWindow) error { return nil }
|
||||
func (m *tuiMockStore) EndMaintenanceWindow(int) error { return nil }
|
||||
func (m *tuiMockStore) DeleteMaintenanceWindow(int) error { return nil }
|
||||
func (m *tuiMockStore) PruneExpiredMaintenanceWindows(time.Duration) (int64, error) {
|
||||
func (m *tuiMockStore) AddSiteReturningID(_ context.Context, _ models.Site) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
func (m *tuiMockStore) IsMonitorInMaintenance(int) (bool, error) { return false, nil }
|
||||
func (m *tuiMockStore) GetPreference(string) (string, error) { return "", nil }
|
||||
func (m *tuiMockStore) SetPreference(string, string) error { return nil }
|
||||
func (m *tuiMockStore) ExportData() (models.Backup, error) { return models.Backup{}, nil }
|
||||
func (m *tuiMockStore) ImportData(models.Backup) error { return nil }
|
||||
func (m *tuiMockStore) Close() error { return nil }
|
||||
func (m *tuiMockStore) AddAlertReturningID(_ context.Context, _ string, _ string, _ map[string]string) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
func (m *tuiMockStore) AddUser(_ context.Context, _ string, _ string, _ string) error { return nil }
|
||||
func (m *tuiMockStore) UpdateUser(_ context.Context, _ int, _ string, _ string, _ string) error {
|
||||
return nil
|
||||
}
|
||||
func (m *tuiMockStore) DeleteUser(_ context.Context, _ int) error { return nil }
|
||||
func (m *tuiMockStore) SaveCheck(_ context.Context, _ int, _ int64, _ bool) error { return nil }
|
||||
func (m *tuiMockStore) SaveCheckFromNode(_ context.Context, _ int, _ string, _ int64, _ bool) error {
|
||||
return nil
|
||||
}
|
||||
func (m *tuiMockStore) LoadAllHistory(_ context.Context, _ int) (map[int][]models.CheckRecord, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *tuiMockStore) PruneCheckHistory(_ context.Context) error { return nil }
|
||||
func (m *tuiMockStore) SaveStateChange(_ context.Context, _ int, _ string, _ string, _ string) error {
|
||||
return nil
|
||||
}
|
||||
func (m *tuiMockStore) GetStateChangesSince(_ context.Context, _ int, _ time.Time) ([]models.StateChange, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *tuiMockStore) PruneStateChanges(_ context.Context) error { return nil }
|
||||
func (m *tuiMockStore) RegisterNode(_ context.Context, _ models.ProbeNode) error { return nil }
|
||||
func (m *tuiMockStore) GetNode(_ context.Context, _ string) (models.ProbeNode, error) {
|
||||
return models.ProbeNode{}, nil
|
||||
}
|
||||
func (m *tuiMockStore) UpdateNodeLastSeen(_ context.Context, _ string) error { return nil }
|
||||
func (m *tuiMockStore) DeleteNode(_ context.Context, _ string) error { return nil }
|
||||
func (m *tuiMockStore) LoadAlertHealth(_ context.Context) (map[int]models.AlertHealthRecord, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *tuiMockStore) SaveAlertHealth(_ context.Context, _ models.AlertHealthRecord) error {
|
||||
return nil
|
||||
}
|
||||
func (m *tuiMockStore) SaveLog(_ context.Context, _ string) error { return nil }
|
||||
func (m *tuiMockStore) LoadLogs(_ context.Context, _ int) ([]string, error) { return nil, nil }
|
||||
func (m *tuiMockStore) PruneLogs(_ context.Context) error { return nil }
|
||||
func (m *tuiMockStore) GetActiveMaintenanceWindows(_ context.Context) ([]models.MaintenanceWindow, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *tuiMockStore) AddMaintenanceWindow(_ context.Context, _ models.MaintenanceWindow) error {
|
||||
return nil
|
||||
}
|
||||
func (m *tuiMockStore) EndMaintenanceWindow(_ context.Context, _ int) error { return nil }
|
||||
func (m *tuiMockStore) DeleteMaintenanceWindow(_ context.Context, _ int) error { return nil }
|
||||
func (m *tuiMockStore) PruneExpiredMaintenanceWindows(_ context.Context, _ time.Duration) (int64, error) {
|
||||
return 0, nil
|
||||
}
|
||||
func (m *tuiMockStore) IsMonitorInMaintenance(_ context.Context, _ int) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
func (m *tuiMockStore) GetPreference(_ context.Context, _ string) (string, error) { return "", nil }
|
||||
func (m *tuiMockStore) SetPreference(_ context.Context, _ string, _ string) error { return nil }
|
||||
func (m *tuiMockStore) ExportData(_ context.Context) (models.Backup, error) {
|
||||
return models.Backup{}, nil
|
||||
}
|
||||
func (m *tuiMockStore) ImportData(_ context.Context, _ models.Backup) error { return nil }
|
||||
func (m *tuiMockStore) Close() error { return nil }
|
||||
|
||||
func newTestModel(ms *tuiMockStore) Model {
|
||||
return Model{
|
||||
|
||||
Reference in New Issue
Block a user