83 lines
1.9 KiB
Go
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)
|
|
}
|