fix: preserve notification surface disables

This commit is contained in:
whoisasx 2026-06-01 03:49:31 +05:30
parent f0c57ac2e2
commit 5c07e818a1
4 changed files with 36 additions and 27 deletions

View File

@ -61,6 +61,8 @@ func Run() error {
return err
}
notifier := startNotifier(ctx, cfg, store, log)
// Terminal streaming: the tmux runtime supplies the PTY-attach command and
// liveness; the CDC broadcaster feeds the session-state channel. The manager
// is handed to httpd, which mounts it at /mux. Raw PTY bytes never flow
@ -71,6 +73,11 @@ func Run() error {
srv, err := httpd.New(cfg, log, termMgr)
if err != nil {
stop()
notifier.Stop()
if cdcErr := cdcPipe.Stop(); cdcErr != nil {
log.Error("cdc pipeline shutdown", "err", cdcErr)
}
return err
}
@ -79,6 +86,11 @@ func Run() error {
// trigger -> change_log -> poller -> broadcaster.
lcStack, err := startLifecycle(ctx, store, log)
if err != nil {
stop()
notifier.Stop()
if cdcErr := cdcPipe.Stop(); cdcErr != nil {
log.Error("cdc pipeline shutdown", "err", cdcErr)
}
return err
}
@ -98,6 +110,7 @@ func Run() error {
// the LIFO trap (see comment after srv.Run), hence explicit.
stop()
lcStack.Stop()
notifier.Stop()
if cdcErr := cdcPipe.Stop(); cdcErr != nil {
log.Error("cdc pipeline shutdown", "err", cdcErr)
}
@ -113,6 +126,7 @@ func Run() error {
// runs before the cancel — which would hang any non-signal exit path.
stop()
lcStack.Stop()
notifier.Stop()
if err := cdcPipe.Stop(); err != nil {
log.Error("cdc pipeline shutdown", "err", err)
}

View File

@ -1,4 +1,4 @@
package main
package daemon
import (
"context"

View File

@ -33,15 +33,9 @@ func NormalizeSettings(in config.NotificationConfig) config.NotificationConfig {
def := config.DefaultNotificationConfig()
out := in
if isZeroDashboardConfig(in.Dashboard) {
out.Dashboard.Enabled = def.Dashboard.Enabled
}
if out.Dashboard.Limit == 0 {
out.Dashboard.Limit = def.Dashboard.Limit
}
if isZeroDesktopConfig(in.Desktop) {
out.Desktop.Enabled = def.Desktop.Enabled
}
if out.Desktop.Priorities == nil {
out.Desktop.Priorities = append([]ports.Priority(nil), def.Desktop.Priorities...)
}
@ -93,23 +87,3 @@ func cloneRoutes(in map[ports.Priority][]string) map[ports.Priority][]string {
}
return out
}
func isZeroNotificationConfig(c config.NotificationConfig) bool {
return !c.Enabled &&
isZeroDashboardConfig(c.Dashboard) &&
isZeroDesktopConfig(c.Desktop) &&
c.Routing.Priorities == nil &&
c.Retry.MaxAttempts == 0 &&
c.Retry.BaseDelay == 0 &&
c.Retry.MaxDelay == 0 &&
c.Retry.LeaseTTL == 0 &&
c.Retry.BatchSize == 0
}
func isZeroDashboardConfig(c config.DashboardNotificationConfig) bool {
return !c.Enabled && c.Limit == 0
}
func isZeroDesktopConfig(c config.DesktopNotificationConfig) bool {
return !c.Enabled && len(c.Priorities) == 0 && len(c.SoundPriorities) == 0
}

View File

@ -28,6 +28,27 @@ func TestSettingsFromConfigPreservesExplicitGlobalDisable(t *testing.T) {
}
}
func TestNormalizeSettingsPreservesExplicitSurfaceDisables(t *testing.T) {
got := StaticSettings(config.NotificationConfig{
Enabled: true,
Dashboard: config.DashboardNotificationConfig{Enabled: false},
Desktop: config.DesktopNotificationConfig{Enabled: false},
}).Settings(context.Background())
if !got.Enabled {
t.Fatalf("global notifications should remain enabled: %+v", got)
}
if got.Dashboard.Enabled {
t.Fatalf("explicit dashboard disable should stay disabled: %+v", got.Dashboard)
}
if got.Desktop.Enabled {
t.Fatalf("explicit desktop disable should stay disabled: %+v", got.Desktop)
}
if got.Dashboard.Limit != 50 || len(got.Desktop.Priorities) == 0 || got.Retry.MaxAttempts != 5 {
t.Fatalf("disabled surfaces should still receive non-bool defaults: %+v", got)
}
}
func TestNormalizeSettingsPreservesExplicitEmptyRoute(t *testing.T) {
cfg := config.DefaultNotificationConfig()
cfg.Routing.Priorities[ports.PriorityUrgent] = []string{}