feat: runtime config, Matomo analytics, chat accounts, DM history/search, and Prometheus retention
This commit is contained in:
1 parent
06ab5b4655
commit
121fdbacdc
27 files changed
+1841
-161
No files matched your search
@@ -612,6 +612,9 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
// Load shared HLS runtime config (written by the chat admin) before starting.
|
||||
loadSharedHLSConfig()
|
||||
|
||||
fmt.Println("=== Linear Void Playout Service Starting ===")
|
||||
fmt.Println("Playlist:", playlistPath)
|
||||
fmt.Println("R2 Bucket:", bucket)
|
||||
@@ -996,4 +999,33 @@ func runValidateOnly(playlistPath string) {
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println("Playlist valid.")
|
||||
}
|
||||
|
||||
// loadSharedHLSConfig reads HLS settings from the shared runtime config file
|
||||
// (written by the chat admin service) and overrides the env-derived defaults.
|
||||
func loadSharedHLSConfig() {
|
||||
path := envWithDefault("PLAYOUT_CONFIG_PATH", "/app/playlist/config.json")
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
fmt.Println("Warning: cannot read shared config:", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
var cfg map[string]string
|
||||
if err := json.Unmarshal(data, &cfg); err != nil {
|
||||
fmt.Println("Warning: cannot parse shared config:", err)
|
||||
return
|
||||
}
|
||||
if v := strings.TrimSpace(cfg["hls_segment_duration"]); v != "" {
|
||||
if n, err := strconv.Atoi(v); err == nil && n > 0 {
|
||||
hlsSegmentDuration = strconv.Itoa(n)
|
||||
}
|
||||
}
|
||||
if v := strings.TrimSpace(cfg["hls_window_size"]); v != "" {
|
||||
if n, err := strconv.Atoi(v); err == nil && n > 0 {
|
||||
hlsWindowSize = strconv.Itoa(n)
|
||||
}
|
||||
}
|
||||
fmt.Printf("Shared HLS config: segment=%ss window=%s\n", hlsSegmentDuration, hlsWindowSize)
|
||||
}
|
||||
@@ -733,4 +733,48 @@ func TestHLSNextStartNumber(t *testing.T) {
|
||||
t.Errorf("seg-%06d should be kept: %v", i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadSharedHLSConfig(t *testing.T) {
|
||||
prevDur := hlsSegmentDuration
|
||||
prevWin := hlsWindowSize
|
||||
defer func() {
|
||||
hlsSegmentDuration = prevDur
|
||||
hlsWindowSize = prevWin
|
||||
}()
|
||||
|
||||
tmpDir := t.TempDir()
|
||||
cfgPath := filepath.Join(tmpDir, "config.json")
|
||||
if err := os.WriteFile(cfgPath, []byte(`{"hls_segment_duration":"4","hls_window_size":"12"}`), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
os.Setenv("PLAYOUT_CONFIG_PATH", cfgPath)
|
||||
defer os.Unsetenv("PLAYOUT_CONFIG_PATH")
|
||||
|
||||
loadSharedHLSConfig()
|
||||
|
||||
if hlsSegmentDuration != "4" {
|
||||
t.Errorf("hlsSegmentDuration = %q, want 4", hlsSegmentDuration)
|
||||
}
|
||||
if hlsWindowSize != "12" {
|
||||
t.Errorf("hlsWindowSize = %q, want 12", hlsWindowSize)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadSharedHLSConfig_MissingFile(t *testing.T) {
|
||||
prevDur := hlsSegmentDuration
|
||||
prevWin := hlsWindowSize
|
||||
defer func() {
|
||||
hlsSegmentDuration = prevDur
|
||||
hlsWindowSize = prevWin
|
||||
}()
|
||||
|
||||
os.Setenv("PLAYOUT_CONFIG_PATH", filepath.Join(t.TempDir(), "nope.json"))
|
||||
defer os.Unsetenv("PLAYOUT_CONFIG_PATH")
|
||||
|
||||
loadSharedHLSConfig() // should be a no-op without erroring
|
||||
|
||||
if hlsSegmentDuration != prevDur {
|
||||
t.Errorf("hlsSegmentDuration changed to %q, want unchanged %q", hlsSegmentDuration, prevDur)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user