From 7c6e18f3f035cb344764c023dd96961c47adb3f9 Mon Sep 17 00:00:00 2001 From: blazSmehov Date: Tue, 10 Mar 2026 12:30:28 +0100 Subject: [PATCH] chore: move health to app context to solve the circular dependency, appContext is now used to collect all the statistics --- internal/pkg/common/appcontext/context.go | 67 +++++++++++++++++-- .../{model => common/appcontext}/health.go | 7 +- 2 files changed, 66 insertions(+), 8 deletions(-) rename internal/pkg/{model => common/appcontext}/health.go (86%) diff --git a/internal/pkg/common/appcontext/context.go b/internal/pkg/common/appcontext/context.go index 47a2e8f..3736cf8 100644 --- a/internal/pkg/common/appcontext/context.go +++ b/internal/pkg/common/appcontext/context.go @@ -4,16 +4,23 @@ import ( "fmt" "log/slog" "os" + "sync" + "time" + "github.com/AFASystems/presence/internal/pkg/kafkaclient" "github.com/mitchellh/mapstructure" ) // AppState provides centralized access to application state type AppState struct { - beacons BeaconsList - settings Settings - beaconEvents BeaconEventList - beaconsLookup BeaconsLookup + beacons BeaconsList + settings Settings + beaconEvents BeaconEventList + beaconsLookup BeaconsLookup + locationHealth LocationHealth + decoderHealth DecoderHealth + bridgeHealth BridgeHealth + startTime time.Time } func getEnv(key, def string) string { @@ -26,6 +33,7 @@ func getEnv(key, def string) string { // NewAppState creates a new application context AppState with default values func NewAppState() *AppState { return &AppState{ + startTime: time.Now(), beacons: BeaconsList{ Beacons: make(map[string]Beacon), }, @@ -46,9 +54,60 @@ func NewAppState() *AppState { beaconsLookup: BeaconsLookup{ Lookup: make(map[string]string), }, + locationHealth: LocationHealth{ + BaseHealth: BaseHealth{ + Lock: sync.RWMutex{}, + Uptime: 0, + ActiveReaders: []string{}, + ActiveWriters: []string{}, + ActiveBeacons: []string{}, + }, + }, + decoderHealth: DecoderHealth{ + BaseHealth: BaseHealth{ + Lock: sync.RWMutex{}, + Uptime: 0, + ActiveReaders: []string{}, + ActiveWriters: []string{}, + ActiveBeacons: []string{}, + }, + }, + bridgeHealth: BridgeHealth{ + BaseHealth: BaseHealth{ + Lock: sync.RWMutex{}, + Uptime: 0, + ActiveReaders: []string{}, + ActiveWriters: []string{}, + ActiveBeacons: []string{}, + }, + }, } } +func (m *AppState) GetLocationHealth(k *kafkaclient.KafkaManager) *LocationHealth { + m.locationHealth.GetUptime(m.startTime) + m.locationHealth.GetActiveReaders(k) + m.locationHealth.GetActiveWriters(k) + m.locationHealth.GetActiveBeacons(m) + return &m.locationHealth +} + +func (m *AppState) GetDecoderHealth(k *kafkaclient.KafkaManager) *DecoderHealth { + m.decoderHealth.GetUptime(m.startTime) + m.decoderHealth.GetActiveReaders(k) + m.decoderHealth.GetActiveWriters(k) + m.decoderHealth.GetActiveBeacons(m) + return &m.decoderHealth +} + +func (m *AppState) GetBridgeHealth(k *kafkaclient.KafkaManager) *BridgeHealth { + m.bridgeHealth.GetUptime(m.startTime) + m.bridgeHealth.GetActiveReaders(k) + m.bridgeHealth.GetActiveWriters(k) + m.bridgeHealth.GetActiveBeacons(m) + return &m.bridgeHealth +} + // GetBeacons returns thread-safe access to beacons list func (m *AppState) GetBeacons() *BeaconsList { m.beacons.Lock.RLock() diff --git a/internal/pkg/model/health.go b/internal/pkg/common/appcontext/health.go similarity index 86% rename from internal/pkg/model/health.go rename to internal/pkg/common/appcontext/health.go index 3cf4500..0dec384 100644 --- a/internal/pkg/model/health.go +++ b/internal/pkg/common/appcontext/health.go @@ -1,11 +1,10 @@ -package model +package appcontext import ( "encoding/json" "sync" "time" - "github.com/AFASystems/presence/internal/pkg/common/appcontext" "github.com/AFASystems/presence/internal/pkg/kafkaclient" ) @@ -24,7 +23,7 @@ type DecoderHealth struct { type LocationHealth struct { BaseHealth - ActiveSettings []appcontext.Settings `json:"activeSettings"` + ActiveSettings []Settings `json:"activeSettings"` } type BridgeHealth struct { @@ -49,7 +48,7 @@ func (b *BaseHealth) GetActiveWriters(m *kafkaclient.KafkaManager) { b.Lock.Unlock() } -func (b *BaseHealth) GetActiveBeacons(m *appcontext.AppState) { +func (b *BaseHealth) GetActiveBeacons(m *AppState) { b.Lock.Lock() beacons := m.GetAllBeacons() for beacon := range beacons {