No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 

166 líneas
4.3 KiB

  1. package appcontext
  2. import (
  3. "fmt"
  4. "log/slog"
  5. "os"
  6. "github.com/AFASystems/presence/internal/pkg/model"
  7. "github.com/mitchellh/mapstructure"
  8. )
  9. // AppState provides centralized access to application state
  10. type AppState struct {
  11. beacons model.BeaconsList
  12. settings model.Settings
  13. beaconEvents model.BeaconEventList
  14. beaconsLookup model.BeaconsLookup
  15. }
  16. func getEnv(key, def string) string {
  17. if v := os.Getenv(key); v != "" {
  18. return v
  19. }
  20. return def
  21. }
  22. // NewAppState creates a new application context AppState with default values
  23. func NewAppState() *AppState {
  24. return &AppState{
  25. beacons: model.BeaconsList{
  26. Beacons: make(map[string]model.Beacon),
  27. },
  28. settings: model.Settings{
  29. ID: 1,
  30. CurrentAlgorithm: getEnv("ALGORITHM", "filter"),
  31. LocationConfidence: 4,
  32. LastSeenThreshold: 15,
  33. BeaconMetricSize: 30,
  34. HASendInterval: 5,
  35. HASendChangesOnly: false,
  36. RSSIEnforceThreshold: false,
  37. RSSIMinThreshold: 100,
  38. },
  39. beaconEvents: model.BeaconEventList{
  40. Beacons: make(map[string]model.BeaconEvent),
  41. },
  42. beaconsLookup: model.BeaconsLookup{
  43. Lookup: make(map[string]string),
  44. },
  45. }
  46. }
  47. // GetBeacons returns thread-safe access to beacons list
  48. func (m *AppState) GetBeacons() *model.BeaconsList {
  49. m.beacons.Lock.RLock()
  50. defer m.beacons.Lock.RUnlock()
  51. return &m.beacons
  52. }
  53. // GetSettings returns thread-safe access to settings
  54. func (m *AppState) GetSettings() *model.Settings {
  55. return &m.settings
  56. }
  57. // GetBeaconEvents returns thread-safe access to beacon events
  58. func (m *AppState) GetBeaconEvents() *model.BeaconEventList {
  59. m.beaconEvents.Lock.RLock()
  60. defer m.beaconEvents.Lock.RUnlock()
  61. return &m.beaconEvents
  62. }
  63. // AddBeaconToLookup adds a beacon ID to the lookup map
  64. func (m *AppState) AddBeaconToLookup(id, value string) {
  65. m.beaconsLookup.Lock.Lock()
  66. m.beaconsLookup.Lookup[id] = value
  67. m.beaconsLookup.Lock.Unlock()
  68. }
  69. // RemoveBeaconFromLookup removes a beacon ID from the lookup map
  70. func (m *AppState) RemoveBeaconFromLookup(id string) {
  71. m.beaconsLookup.Lock.Lock()
  72. delete(m.beaconsLookup.Lookup, id)
  73. m.beaconsLookup.Lock.Unlock()
  74. }
  75. func (m *AppState) CleanLookup() {
  76. m.beaconsLookup.Lock.Lock()
  77. clear(m.beaconsLookup.Lookup)
  78. m.beaconsLookup.Lock.Unlock()
  79. }
  80. // BeaconExists checks if a beacon exists in the lookup
  81. func (m *AppState) BeaconExists(id string) (string, bool) {
  82. m.beaconsLookup.Lock.RLock()
  83. defer m.beaconsLookup.Lock.RUnlock()
  84. val, exists := m.beaconsLookup.Lookup[id]
  85. return val, exists
  86. }
  87. // GetBeacon returns a beacon by ID (thread-safe)
  88. func (m *AppState) GetBeacon(id string) (model.Beacon, bool) {
  89. m.beacons.Lock.RLock()
  90. defer m.beacons.Lock.RUnlock()
  91. beacon, exists := m.beacons.Beacons[id]
  92. return beacon, exists
  93. }
  94. // UpdateBeacon updates a beacon in the list (thread-safe)
  95. func (m *AppState) UpdateBeacon(id string, beacon model.Beacon) {
  96. m.beacons.Lock.Lock()
  97. defer m.beacons.Lock.Unlock()
  98. m.beacons.Beacons[id] = beacon
  99. }
  100. // GetBeaconEvent returns a beacon event by ID (thread-safe)
  101. func (m *AppState) GetBeaconEvent(id string) (model.BeaconEvent, bool) {
  102. m.beaconEvents.Lock.RLock()
  103. defer m.beaconEvents.Lock.RUnlock()
  104. event, exists := m.beaconEvents.Beacons[id]
  105. return event, exists
  106. }
  107. // UpdateBeaconEvent updates a beacon event in the list (thread-safe)
  108. func (m *AppState) UpdateBeaconEvent(id string, event model.BeaconEvent) {
  109. m.beaconEvents.Lock.Lock()
  110. defer m.beaconEvents.Lock.Unlock()
  111. m.beaconEvents.Beacons[id] = event
  112. }
  113. // GetAllBeacons returns a copy of all beacons
  114. func (m *AppState) GetAllBeacons() map[string]model.Beacon {
  115. m.beacons.Lock.RLock()
  116. defer m.beacons.Lock.RUnlock()
  117. beacons := make(map[string]model.Beacon)
  118. for id, beacon := range m.beacons.Beacons {
  119. beacons[id] = beacon
  120. }
  121. return beacons
  122. }
  123. // GetBeaconCount returns the number of tracked beacons
  124. func (m *AppState) GetBeaconCount() int {
  125. m.beacons.Lock.RLock()
  126. defer m.beacons.Lock.RUnlock()
  127. return len(m.beacons.Beacons)
  128. }
  129. // GetSettingsValue returns current settings as a value
  130. func (m *AppState) GetSettingsValue() model.Settings {
  131. return m.settings
  132. }
  133. // UpdateSettings updates the system settings (thread-safe)
  134. func (m *AppState) UpdateSettings(settings map[string]any) {
  135. if err := mapstructure.Decode(settings, &m.settings); err != nil {
  136. msg := fmt.Sprintf("Error in persisting settings: %v", err)
  137. slog.Error(msg)
  138. }
  139. }