Files
yovision/Sense/server/app/sense/media/runtime.go
T

83 lines
1.9 KiB
Go

package media
import (
"context"
"errors"
"os"
"strings"
"sync"
"time"
"gorm.io/gorm"
)
var runtimeState struct {
sync.RWMutex
service *Service
cancel context.CancelFunc
}
func StartRuntime(parent context.Context, db *gorm.DB) error {
mode := strings.ToLower(strings.TrimSpace(os.Getenv("SENSE_MEDIAMTX_MODE")))
if mode == "disabled" {
return nil
}
if db == nil {
return errors.New("Sense database is unavailable for MediaMTX runtime")
}
config, err := ConfigFromEnvironment()
if err != nil {
return err
}
controller, err := NewHTTPController(config.APIBase)
if err != nil {
return err
}
service := NewService(db, controller, NewSupervisor(config.Binary, config.ConfigPath), config)
ctx, cancel := context.WithCancel(parent)
if mode == "managed" || mode == "external" {
if err = service.ensureControl(ctx); err != nil {
cancel()
return err
}
}
runtimeState.Lock()
if runtimeState.cancel != nil {
runtimeState.cancel()
}
runtimeState.service, runtimeState.cancel = service, cancel
runtimeState.Unlock()
go service.Run(ctx)
return nil
}
func ShutdownRuntime(ctx context.Context) error {
runtimeState.Lock()
service, cancel := runtimeState.service, runtimeState.cancel
runtimeState.service, runtimeState.cancel = nil, nil
runtimeState.Unlock()
if cancel != nil {
cancel()
}
if service != nil && service.process != nil {
return service.process.Stop(ctx)
}
return nil
}
func serviceFor(db *gorm.DB) *Service {
runtimeState.RLock()
service := runtimeState.service
runtimeState.RUnlock()
if service != nil {
return service
}
return NewService(db, nil, nil, RuntimeConfig{PollInterval: 5 * time.Second})
}
// EnsureDeviceRoutes is an internal post-admission port. It persists only
// credential-free route intent and deliberately does not fail device probing.
func EnsureDeviceRoutes(ctx context.Context, db *gorm.DB, deviceID string) error {
return serviceFor(db).EnsureDevice(ctx, deviceID)
}