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

5 files changed, 66 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 }
M go.modgo.mod
@@ -13,6 +13,7 @@ github.com/blevesearch/bleve/v2 v2.5.2
github.com/creasty/defaults v1.8.0 github.com/crewjam/csp v0.0.2 github.com/dustin/go-humanize v1.0.1 + github.com/ecnepsnai/sdnotify v1.0.0 github.com/fsnotify/fsnotify v1.9.0 github.com/getsentry/sentry-go v0.33.0 github.com/jessevdk/go-flags v1.6.1
M go.sumgo.sum
@@ -68,6 +68,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/ecnepsnai/sdnotify v1.0.0 h1:3fWha4w2K2fMlbo2ZKFnmVduxinGH0TdlKRyqM+2s90= +github.com/ecnepsnai/sdnotify v1.0.0/go.mod h1:azJ0AoGHF0V1P2/0TC+BDVO2F95KpX9L2O3TyGm/Gi0= github.com/evanw/esbuild v0.14.11/go.mod h1:GG+zjdi59yh3ehDn4ZWfPcATxjPDUH53iU4ZJbp7dkY= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
M gomod2nix.tomlgomod2nix.toml
@@ -91,6 +91,9 @@ hash = "sha256-4vlGmDdQjPiXmueCV51fJH/hRcG8eqhCi9TENCXjzfA="
[mod."github.com/dustin/go-humanize"] version = "v1.0.1" hash = "sha256-yuvxYYngpfVkUg9yAmG99IUVmADTQA0tMbBXe0Fq0Mc=" + [mod."github.com/ecnepsnai/sdnotify"] + version = "v1.0.0" + hash = "sha256-KvbVhR/ubJs0lIZW6jmTMC3PnUiS0X99DSqe0tor+eo=" [mod."github.com/fsnotify/fsnotify"] version = "v1.9.0" hash = "sha256-WtpE1N6dpHwEvIub7Xp/CrWm0fd6PX7MKA4PV44rp2g="
M nix/modules/default.nixnix/modules/default.nix
@@ -23,6 +23,9 @@ Group = cfg.group;
ReadWritePaths = [ cfg.homeDir ]; StateDirectory = mkIf (cfg.homeDir == "/var/lib/searchix") [ "searchix" ]; Restart = "on-failure"; + Type = "notify"; + NotifyAccess = "main"; + WatchdogSec = "60"; CacheDirectory = "searchix"; CapabilityBoundingSet = "";