|
- package control
-
- import (
- "sync"
- "time"
-
- offpkg "github.com/jan/fm-rds-tx/internal/offline"
- )
-
- type TelemetryMessage struct {
- Type string `json:"type"`
- TS time.Time `json:"ts"`
- Seq uint64 `json:"seq"`
- Data *offpkg.MeasurementSnapshot `json:"data,omitempty"`
- }
-
- type telemetrySubscriber struct {
- ch chan TelemetryMessage
- }
-
- type TelemetryHub struct {
- mu sync.Mutex
- subscribers map[*telemetrySubscriber]struct{}
- }
-
- func NewTelemetryHub() *TelemetryHub {
- return &TelemetryHub{subscribers: make(map[*telemetrySubscriber]struct{})}
- }
-
- func (h *TelemetryHub) Subscribe() (*telemetrySubscriber, func()) {
- sub := &telemetrySubscriber{ch: make(chan TelemetryMessage, 1)}
- h.mu.Lock()
- h.subscribers[sub] = struct{}{}
- h.mu.Unlock()
- return sub, func() {
- h.mu.Lock()
- if _, ok := h.subscribers[sub]; ok {
- delete(h.subscribers, sub)
- close(sub.ch)
- }
- h.mu.Unlock()
- }
- }
-
- func (h *TelemetryHub) PublishMeasurement(snapshot *offpkg.MeasurementSnapshot) {
- if h == nil || snapshot == nil {
- return
- }
- msg := TelemetryMessage{
- Type: "measurement",
- TS: snapshot.Timestamp,
- Seq: snapshot.Sequence,
- Data: snapshot,
- }
-
- h.mu.Lock()
- subs := make([]*telemetrySubscriber, 0, len(h.subscribers))
- for sub := range h.subscribers {
- subs = append(subs, sub)
- }
- h.mu.Unlock()
-
- for _, sub := range subs {
- select {
- case sub.ch <- msg:
- default:
- select {
- case <-sub.ch:
- default:
- }
- select {
- case sub.ch <- msg:
- default:
- }
- }
- }
- }
|