Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 

165 righe
4.1 KiB

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