status_store.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. package main
  2. import (
  3. "sort"
  4. "sync"
  5. )
  6. // statusStore provides synchronized access to the current set of service statuses.
  7. type statusStore struct {
  8. mu sync.RWMutex
  9. records []serviceStatus
  10. }
  11. // set replaces the store contents with a copy of the provided status records.
  12. func (s *statusStore) set(records []serviceStatus) {
  13. s.mu.Lock()
  14. defer s.mu.Unlock()
  15. s.records = make([]serviceStatus, len(records))
  16. copy(s.records, records)
  17. }
  18. // upsert inserts a new status record or replaces the existing one with the same name.
  19. func (s *statusStore) upsert(record serviceStatus) {
  20. s.mu.Lock()
  21. defer s.mu.Unlock()
  22. for i := range s.records {
  23. if s.records[i].Name == record.Name {
  24. s.records[i] = record
  25. return
  26. }
  27. }
  28. s.records = append(s.records, record)
  29. }
  30. // list returns a copy of the current status records.
  31. func (s *statusStore) list() []serviceStatus {
  32. s.mu.RLock()
  33. defer s.mu.RUnlock()
  34. records := make([]serviceStatus, len(s.records))
  35. copy(records, s.records)
  36. return records
  37. }
  38. // sort orders the stored status records by health and name.
  39. func (s *statusStore) sort() {
  40. s.mu.Lock()
  41. defer s.mu.Unlock()
  42. sortStatuses(s.records)
  43. }
  44. // sortStatuses orders healthy services first and uses the service name as a tiebreaker.
  45. func sortStatuses(records []serviceStatus) {
  46. sort.Slice(records, func(i, j int) bool {
  47. if records[i].Healthy == records[j].Healthy {
  48. return records[i].Name < records[j].Name
  49. }
  50. return records[i].Healthy && !records[j].Healthy
  51. })
  52. }