From 5142114e8916ec5d9b932cbfd02028674f3f7fa0 Mon Sep 17 00:00:00 2001 From: Virgil Date: Sat, 4 Apr 2026 00:11:21 +0000 Subject: [PATCH] feat(process): rollback daemon startup on registry failure --- daemon.go | 9 +++++++-- daemon_test.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/daemon.go b/daemon.go index af3e044..ae6fb02 100644 --- a/daemon.go +++ b/daemon.go @@ -91,8 +91,6 @@ func (d *Daemon) Start() error { } } - d.running = true - // Auto-register if registry is set if d.opts.Registry != nil { entry := d.opts.RegistryEntry @@ -101,10 +99,17 @@ func (d *Daemon) Start() error { entry.Health = d.health.Addr() } if err := d.opts.Registry.Register(entry); err != nil { + if d.health != nil { + _ = d.health.Stop(context.Background()) + } + if d.pid != nil { + _ = d.pid.Release() + } return coreerr.E("Daemon.Start", "registry", err) } } + d.running = true return nil } diff --git a/daemon_test.go b/daemon_test.go index 4e641d4..a3ba52b 100644 --- a/daemon_test.go +++ b/daemon_test.go @@ -163,3 +163,40 @@ func TestDaemon_AutoRegisters(t *testing.T) { _, ok = reg.Get("test-app", "serve") assert.False(t, ok) } + +func TestDaemon_StartRollsBackOnRegistryFailure(t *testing.T) { + dir := t.TempDir() + + pidPath := filepath.Join(dir, "daemon.pid") + regDir := filepath.Join(dir, "registry") + require.NoError(t, os.MkdirAll(regDir, 0o755)) + require.NoError(t, os.Chmod(regDir, 0o555)) + + d := NewDaemon(DaemonOptions{ + PIDFile: pidPath, + HealthAddr: "127.0.0.1:0", + Registry: NewRegistry(regDir), + RegistryEntry: DaemonEntry{ + Code: "broken", + Daemon: "start", + }, + }) + + err := d.Start() + require.Error(t, err) + + _, statErr := os.Stat(pidPath) + assert.True(t, os.IsNotExist(statErr)) + + addr := d.HealthAddr() + require.NotEmpty(t, addr) + + client := &http.Client{Timeout: 250 * time.Millisecond} + resp, reqErr := client.Get("http://" + addr + "/health") + if resp != nil { + _ = resp.Body.Close() + } + assert.Error(t, reqErr) + + assert.NoError(t, d.Stop()) +}