morz-infoboard/server/backend/internal/httpapi/playerstatus_store.go
Jesko Anschütz cc06b5a728 Leite Frische des letzten Player-Status ab
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-22 18:30:49 +01:00

63 lines
1.7 KiB
Go

package httpapi
import (
"sync"
"time"
)
type playerStatusRecord struct {
ScreenID string `json:"screen_id"`
Timestamp string `json:"ts"`
Status string `json:"status"`
ServerConnectivity string `json:"server_connectivity,omitempty"`
ReceivedAt string `json:"received_at,omitempty"`
Stale bool `json:"stale,omitempty"`
ServerURL string `json:"server_url,omitempty"`
MQTTBroker string `json:"mqtt_broker,omitempty"`
HeartbeatEverySeconds int `json:"heartbeat_every_seconds,omitempty"`
StartedAt string `json:"started_at,omitempty"`
LastHeartbeatAt string `json:"last_heartbeat_at,omitempty"`
}
type playerStatusStore interface {
Save(record playerStatusRecord)
Get(screenID string) (playerStatusRecord, bool)
Now() time.Time
}
type inMemoryPlayerStatusStore struct {
mu sync.RWMutex
records map[string]playerStatusRecord
now func() time.Time
}
func newInMemoryPlayerStatusStore() *inMemoryPlayerStatusStore {
return &inMemoryPlayerStatusStore{records: make(map[string]playerStatusRecord), now: time.Now}
}
func NewPlayerStatusStore() playerStatusStore {
return newInMemoryPlayerStatusStore()
}
func (s *inMemoryPlayerStatusStore) Save(record playerStatusRecord) {
s.mu.Lock()
defer s.mu.Unlock()
if s.now != nil && record.ReceivedAt == "" {
record.ReceivedAt = s.now().Format(time.RFC3339)
}
s.records[record.ScreenID] = record
}
func (s *inMemoryPlayerStatusStore) Get(screenID string) (playerStatusRecord, bool) {
s.mu.RLock()
defer s.mu.RUnlock()
record, ok := s.records[screenID]
return record, ok
}
func (s *inMemoryPlayerStatusStore) Now() time.Time {
if s.now == nil {
return time.Now()
}
return s.now()
}