feat: runtime config, Matomo analytics, chat accounts, DM history/search, and Prometheus retention

This commit is contained in:
zwitschi committed 2026-08-13 13:12:35 +02:00
1 parent 06ab5b4655
commit 121fdbacdc
27 files changed
+1841 -161

No files matched your search

+32
View File
@@ -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)
}
+44
View File
@@ -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)
}
}