services decoupling
This commit is contained in:
+7
-5
@@ -22,15 +22,17 @@ type DeviceService struct {
|
||||
TelemCh <-chan telemetry.TelemetryData
|
||||
// Output
|
||||
Messages chan string
|
||||
// Callbacks
|
||||
OnTelemetryProviderDiscovered func()
|
||||
}
|
||||
|
||||
func NewDeviceService(logger *slog.Logger) *DeviceService {
|
||||
sharedChannel := make(chan string, 10)
|
||||
|
||||
func NewDeviceService(logger *slog.Logger, msg chan string) *DeviceService {
|
||||
dev := &DeviceService{
|
||||
PSS: NewPeripheralStateStore(logger.With("Service", "PeripheralStateStore"), devices.List),
|
||||
PSS: NewPeripheralStateStore(
|
||||
logger.With("Service", "PeripheralStateStore"), devices.List, msg,
|
||||
),
|
||||
Logger: logger,
|
||||
Messages: sharedChannel,
|
||||
Messages: msg,
|
||||
}
|
||||
|
||||
// Start the routine that looks for devices - should always be running in the background
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
package services
|
||||
@@ -2,6 +2,7 @@ package services
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"maps"
|
||||
"sync"
|
||||
@@ -51,15 +52,19 @@ type PeripheralStateStore struct {
|
||||
Logger *slog.Logger
|
||||
mu sync.RWMutex
|
||||
store map[string]*PeripheralState
|
||||
// Messaging for UI and stuff
|
||||
Messages chan string
|
||||
}
|
||||
|
||||
func NewPeripheralStateStore(
|
||||
nLogger *slog.Logger,
|
||||
devList map[string]*devices.Device,
|
||||
msg chan string,
|
||||
) *PeripheralStateStore {
|
||||
store := PeripheralStateStore{
|
||||
Logger: nLogger,
|
||||
store: make(map[string]*PeripheralState),
|
||||
Logger: nLogger,
|
||||
store: make(map[string]*PeripheralState),
|
||||
Messages: msg,
|
||||
}
|
||||
|
||||
for _, dev := range devList {
|
||||
@@ -154,6 +159,8 @@ func (pss *PeripheralStateStore) setDeviceConnected(pname string, per peripheral
|
||||
defer pss.mu.Unlock()
|
||||
pss.store[pname].Peripheral = per
|
||||
pss.store[pname].State = DeviceIsConnected
|
||||
|
||||
pss.Messages <- fmt.Sprintf("Device successfuly connected: %s\n", pname)
|
||||
}
|
||||
|
||||
func (pss *PeripheralStateStore) setDeviceTimedOut(pname string) {
|
||||
|
||||
@@ -1,2 +1,34 @@
|
||||
// Package services interacts with the other libraries required for this UI
|
||||
package services
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
type Orchestrator struct {
|
||||
DeviceService *DeviceService
|
||||
TelemetryService *TelemetryService
|
||||
Messages chan string
|
||||
}
|
||||
|
||||
func NewOrchestrator(logger *slog.Logger) (*Orchestrator, error) {
|
||||
msg := make(chan string, 10)
|
||||
|
||||
devService := NewDeviceService(logger.With("service", "DeviceService"), msg)
|
||||
|
||||
telemService := NewTelemetryService(logger.With("service", "TelemetryService"), devService, msg)
|
||||
if telemService == nil {
|
||||
return nil, errors.New("failed to create telemetry service")
|
||||
}
|
||||
|
||||
go telemService.FindProvider(telemService.CtxMonitor)
|
||||
|
||||
// Need to setup the callbacks on the services
|
||||
|
||||
return &Orchestrator{
|
||||
DeviceService: devService,
|
||||
TelemetryService: telemService,
|
||||
Messages: msg,
|
||||
}, nil
|
||||
}
|
||||
|
||||
+9
-31
@@ -32,16 +32,21 @@ type TelemetryService struct {
|
||||
cancelMonitor context.CancelFunc
|
||||
CtxHealthcheck context.Context
|
||||
healthCheckCancel context.CancelFunc
|
||||
// Callbacks
|
||||
OnDevicesDiscovered func()
|
||||
}
|
||||
|
||||
func NewTelemetryService(logger *slog.Logger, devServo *DeviceService) *TelemetryService {
|
||||
sharedChannel := make(chan string, 10)
|
||||
func NewTelemetryService(
|
||||
logger *slog.Logger,
|
||||
devServo *DeviceService,
|
||||
msg chan string,
|
||||
) *TelemetryService {
|
||||
newService := &TelemetryService{
|
||||
logger: logger,
|
||||
isConnected: false,
|
||||
devService: devServo,
|
||||
listeners: make(map[string]chan telem.TelemetryData),
|
||||
Messages: sharedChannel,
|
||||
Messages: msg,
|
||||
}
|
||||
newService.CtxMonitor, newService.cancelMonitor = context.WithCancel(context.Background())
|
||||
|
||||
@@ -59,6 +64,7 @@ func (t *TelemetryService) ProviderMonitor(ctx context.Context) {
|
||||
case <-ticker.C:
|
||||
slog.Info("checking if provider is still running")
|
||||
if !t.activeProvider.IsAlive(500 * time.Millisecond) {
|
||||
t.Messages <- "Healthcheck on provider failing. Dropping provider.\n"
|
||||
slog.Warn("provider healthcheck failed")
|
||||
t.dropActiveProvider()
|
||||
t.onProviderHealthCheckFailed()
|
||||
@@ -154,34 +160,6 @@ func (t *TelemetryService) SwitchProvider(newProvider telem.TelemetryProvider) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TelemetryService) onProviderHealthCheckFailed() {
|
||||
// Just restart the whole lookup process
|
||||
go t.FindProvider(t.CtxMonitor)
|
||||
}
|
||||
|
||||
func (t *TelemetryService) onFindProvider(prov telem.TelemetryProvider) {
|
||||
// Attach to the provider
|
||||
t.logger.Info("found provider for " + prov.Name())
|
||||
err := t.SwitchProvider(prov)
|
||||
if err != nil {
|
||||
t.logger.Error("failed to switch to provider onFindProvider", "err", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Create a routine to poll this provider while we wait to start the stream or pause it
|
||||
t.CtxHealthcheck, t.healthCheckCancel = context.WithCancel(context.Background())
|
||||
go t.ProviderMonitor(t.CtxHealthcheck)
|
||||
}
|
||||
|
||||
func (t *TelemetryService) onProviderStopsMidStream() {
|
||||
// clear the current provider
|
||||
// TODO: now we need to also clear the devices to restart everything,
|
||||
// if the stream stopped we have to restart the devices and everything
|
||||
t.logger.Info("cleaning dropped provider and restarting lookup service")
|
||||
t.dropActiveProvider()
|
||||
go t.FindProvider(t.CtxMonitor)
|
||||
}
|
||||
|
||||
// TODO: add some way of retriggering this. Currently it should:
|
||||
// start monitoring on startup -> find provider -> stop monitoring (when game closes for example)
|
||||
func (t *TelemetryService) FindProvider(ctx context.Context) {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
telem "esdi/telemetry"
|
||||
)
|
||||
|
||||
func (t *TelemetryService) onProviderHealthCheckFailed() {
|
||||
// Just restart the whole lookup process
|
||||
go t.FindProvider(t.CtxMonitor)
|
||||
}
|
||||
|
||||
func (t *TelemetryService) onFindProvider(prov telem.TelemetryProvider) {
|
||||
// Attach to the provider
|
||||
t.logger.Info("found provider for " + prov.Name())
|
||||
t.Messages <- fmt.Sprintf("Found provider \"%s\"\n", prov.Name())
|
||||
err := t.SwitchProvider(prov)
|
||||
if err != nil {
|
||||
t.Messages <- fmt.Sprintf("Failed to switch to provider: %+v\n", err.Error())
|
||||
t.logger.Error("failed to switch to provider onFindProvider", "err", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Start the healthcheck on our provider so we can drop it if it stops
|
||||
t.CtxHealthcheck, t.healthCheckCancel = context.WithCancel(context.Background())
|
||||
go t.ProviderMonitor(t.CtxHealthcheck)
|
||||
|
||||
// Tell the devices service we got a provider
|
||||
}
|
||||
|
||||
func (t *TelemetryService) onProviderStopsMidStream() {
|
||||
// clear the current provider
|
||||
// TODO: now we need to also clear the devices to restart everything,
|
||||
// if the stream stopped we have to restart the devices and everything
|
||||
t.Messages <- "Telemetry provider stopped mid stream\n"
|
||||
t.logger.Info("cleaning dropped provider and restarting lookup service")
|
||||
t.dropActiveProvider()
|
||||
go t.FindProvider(t.CtxMonitor)
|
||||
}
|
||||
Reference in New Issue
Block a user