From e18bcc93528c63bb35f858478455bf951102baaa Mon Sep 17 00:00:00 2001 From: Jason Lynch Date: Sun, 5 Apr 2026 12:21:39 -0400 Subject: [PATCH] feat: replace host ticker with host monitor This commit completes some previously-started work to replace `host.UpdateTicker` with `monitor.HostMonitor`. The monitor was already implemented, but was not being used yet. PLAT-400 --- server/internal/app/app.go | 6 --- server/internal/host/host.go | 4 +- server/internal/host/provide.go | 16 ------- server/internal/host/ticker.go | 61 ------------------------- server/internal/monitor/host_monitor.go | 6 +-- server/internal/monitor/service.go | 6 ++- 6 files changed, 10 insertions(+), 89 deletions(-) delete mode 100644 server/internal/host/ticker.go diff --git a/server/internal/app/app.go b/server/internal/app/app.go index ea4ad698..797daea4 100644 --- a/server/internal/app/app.go +++ b/server/internal/app/app.go @@ -185,12 +185,6 @@ func (a *App) runInitialized(parentCtx context.Context) error { return handleError(fmt.Errorf("failed to start resource service: %w", err)) } - hostTicker, err := do.Invoke[*host.UpdateTicker](a.i) - if err != nil { - return handleError(fmt.Errorf("failed to initialize host ticker: %w", err)) - } - hostTicker.Start(a.serviceCtx) - monitorSvc, err := do.Invoke[*monitor.Service](a.i) if err != nil { return handleError(fmt.Errorf("failed to initialize monitor service: %w", err)) diff --git a/server/internal/host/host.go b/server/internal/host/host.go index 46e88f51..1b317399 100644 --- a/server/internal/host/host.go +++ b/server/internal/host/host.go @@ -11,6 +11,8 @@ import ( "github.com/pgEdge/control-plane/server/internal/healthcheck" ) +const HostMonitorRefreshInterval = 15 * time.Second + type HostState string const ( @@ -112,7 +114,7 @@ func fromStorage(host *StoredHost, status *StoredHostStatus) (*Host, error) { // Host is considered unreachable if it has failed to check in for 2 // heartbeats. - if time.Since(out.Status.UpdatedAt) > 2*UpdateStatusInterval { + if time.Since(out.Status.UpdatedAt) > 2*HostMonitorRefreshInterval { out.Status.State = HostStateUnreachable out.Status.Components = nil //Clear stale component statuses } diff --git a/server/internal/host/provide.go b/server/internal/host/provide.go index f6aabe7d..7d27f4e3 100644 --- a/server/internal/host/provide.go +++ b/server/internal/host/provide.go @@ -3,7 +3,6 @@ package host import ( "fmt" - "github.com/rs/zerolog" "github.com/samber/do" clientv3 "go.etcd.io/etcd/client/v3" @@ -14,21 +13,6 @@ import ( func Provide(i *do.Injector) { provideStore(i) provideService(i) - provideTicker(i) -} - -func provideTicker(i *do.Injector) { - do.Provide(i, func(i *do.Injector) (*UpdateTicker, error) { - logger, err := do.Invoke[zerolog.Logger](i) - if err != nil { - return nil, fmt.Errorf("failed to get logger: %w", err) - } - svc, err := do.Invoke[*Service](i) - if err != nil { - return nil, fmt.Errorf("failed to get host service: %w", err) - } - return NewUpdateTicker(logger, svc), nil - }) } func provideService(i *do.Injector) { diff --git a/server/internal/host/ticker.go b/server/internal/host/ticker.go deleted file mode 100644 index 38eeb459..00000000 --- a/server/internal/host/ticker.go +++ /dev/null @@ -1,61 +0,0 @@ -package host - -import ( - "context" - "time" - - "github.com/rs/zerolog" - "github.com/samber/do" -) - -var _ do.Shutdownable = (*UpdateTicker)(nil) - -const UpdateStatusInterval = 15 * time.Second - -type UpdateTicker struct { - t *time.Ticker - logger zerolog.Logger - svc *Service - done chan struct{} -} - -func NewUpdateTicker(logger zerolog.Logger, svc *Service) *UpdateTicker { - h := &UpdateTicker{ - logger: logger, - svc: svc, - done: make(chan struct{}, 1), - } - - return h -} - -func (u *UpdateTicker) Start(ctx context.Context) { - u.t = time.NewTicker(UpdateStatusInterval) - - go func() { - for { - select { - case <-ctx.Done(): - return - case <-u.done: - return - case <-u.t.C: - if err := u.svc.UpdateHostStatus(ctx); err != nil { - u.logger.Err(err).Msg("failed to update host") - } - } - } - }() - - // Run the first update immediately - if err := u.svc.UpdateHostStatus(ctx); err != nil { - u.logger.Err(err).Msg("failed to update host") - } -} - -func (u *UpdateTicker) Shutdown() error { - u.t.Stop() - u.done <- struct{}{} - - return nil -} diff --git a/server/internal/monitor/host_monitor.go b/server/internal/monitor/host_monitor.go index 880e6f2b..9575c116 100644 --- a/server/internal/monitor/host_monitor.go +++ b/server/internal/monitor/host_monitor.go @@ -3,9 +3,9 @@ package monitor import ( "context" - "github.com/pgEdge/control-plane/server/internal/database" - "github.com/pgEdge/control-plane/server/internal/host" "github.com/rs/zerolog" + + "github.com/pgEdge/control-plane/server/internal/host" ) type HostMonitor struct { @@ -22,7 +22,7 @@ func NewHostMonitor( } m.monitor = NewMonitor( logger, - database.InstanceMonitorRefreshInterval, + host.HostMonitorRefreshInterval, m.checkStatus, ) return m diff --git a/server/internal/monitor/service.go b/server/internal/monitor/service.go index cb1d47ef..cef1b0d1 100644 --- a/server/internal/monitor/service.go +++ b/server/internal/monitor/service.go @@ -23,7 +23,7 @@ type Service struct { certSvc *certificates.Service dbOrch database.Orchestrator store *Store - hostMoniter *HostMonitor + hostMonitor *HostMonitor instances map[string]*InstanceMonitor serviceInstances map[string]*ServiceInstanceMonitor } @@ -46,7 +46,7 @@ func NewService( store: store, instances: map[string]*InstanceMonitor{}, serviceInstances: map[string]*ServiceInstanceMonitor{}, - hostMoniter: NewHostMonitor(logger, hostSvc), + hostMonitor: NewHostMonitor(logger, hostSvc), } } @@ -56,6 +56,7 @@ func (s *Service) Start(ctx context.Context) error { // The monitors should run for the lifetime of the application rather than // the lifetime of a single operation. s.appCtx = ctx + s.hostMonitor.Start(ctx) stored, err := s.store.InstanceMonitor. GetAllByHostID(s.cfg.HostID). @@ -104,6 +105,7 @@ func (s *Service) Shutdown() error { } s.serviceInstances = map[string]*ServiceInstanceMonitor{} + s.hostMonitor.Stop() return nil }