all repos — searchix @ 49031e3ce0a01afda5079015c442a67720017220

Search engine for NixOS, nix-darwin, home-manager and NUR users

feat: use sd_notify for watchdog and status notification

Alan Pearce
commit

49031e3ce0a01afda5079015c442a67720017220

parent

eeac61c274b3ee615aedf3318c97715d70915a72

1 file changed, 57 insertions(+), 4 deletions(-)

changed files
M cmd/searchix-web/serve.gocmd/searchix-web/serve.go
@@ -3,13 +3,16 @@
import ( "context" "errors" + "math" "os" "os/signal" "sync" "syscall" + "time" "github.com/Southclaws/fault" "github.com/Southclaws/fault/fmsg" + "github.com/ecnepsnai/sdnotify" "golang.org/x/term" "alin.ovh/searchix/internal/file"
@@ -28,9 +31,6 @@ signals := []os.Signal{os.Interrupt, syscall.SIGTERM}
if term.IsTerminal(int(os.Stdout.Fd())) { signals = append(signals, syscall.SIGHUP) } - - ctx, cancel := signal.NotifyContext(context.Background(), signals...) - defer cancel() root, err := file.CreateAndOpenRoot(cfg.DataPath) if err != nil {
@@ -88,7 +88,15 @@ if err != nil {
return fault.Wrap(err, fmsg.With("Failed to create importer")) } + ctx, stop := signal.NotifyContext(context.Background(), signals...) + defer stop() + if store.IsNew() { + err = sdnotify.Status("fetching") + if err != nil { + logger.Warn("failed to update systemd status", "error", err) + } + err = imp.Fetch(ctx, true, false, nil) if err != nil { return fault.Wrap(err, fmsg.With("Failed to start importer"))
@@ -120,9 +128,19 @@ logger.Fatal("error", "error", err)
} }() + err = sdnotify.Ready() + if err != nil { + logger.Fatal("failed to notify systemd of readiness", "error", err) + } + reimport := make(chan os.Signal, 1) go func() { for sig := range reimport { + err := sdnotify.Status("re-indexing") + if err != nil { + logger.Warn("failed to update systemd status", "error", err) + } + if sig == syscall.SIGUSR1 { logger.Info("manual fetch on SIGUSR1") err := imp.Fetch(ctx, true, false, nil)
@@ -133,7 +151,7 @@ logger.Info("manual fetch succeeded")
} logger.Info("manual re-index", "signal", sig.String()) - err := imp.Index(ctx) + err = imp.Index(ctx) if err != nil { logger.Error("manual index error", "error", err) }
@@ -146,6 +164,11 @@ if err != nil {
logger.Error("manual prune error", "error", err) } logger.Info("manual prune completed") + } + + err = sdnotify.Status("completed manual re-index") + if err != nil { + logger.Warn("failed to update systemd status", "error", err) } } }()
@@ -157,9 +180,39 @@ defer wg.Done()
imp.StartUpdateTimer(ctx) }() + if wdu, defined := os.LookupEnv("WATCHDOG_USEC"); defined { + wd, err := time.ParseDuration(wdu + "us") + if err != nil { + logger.Fatal("could not parse WATCHDOG_USEC", "value", wdu) + } + tickRate := time.Duration(math.Ceil(wd.Seconds()*0.75)) * time.Second + + wg.Add(1) + go func() { + defer wg.Done() + for range time.Tick(tickRate) { + err := sdnotify.Watchdog() + if err != nil { + logger.Warn("") + } + } + }() + } + <-ctx.Done() + stop() + + logger.Debug("stopping server") + err = sdnotify.Stopping() + if err != nil { + logger.Warn("failed to notify systemd of shutdown", "error", err) + } s.Stop() + + logger.Debug("waiting for tasks") wg.Wait() + + logger.Info("done") return }