fix(registry): idempotent Unregister/Release when file missing

The coreio.Local.Delete error wraps the underlying os.ErrNotExist
through core.E, so the prior os.IsNotExist check on the registry
Unregister path never matched. Same wrapping broke the daemon
Stop path that relied on pidfile.Release being a no-op for absent
files.

Switch both to coreio.Local.Exists before Delete, which is the
idempotent pattern the callers already assume. Adds coverage for
TestPIDFile_Release_MissingIsNoop and fixes TestRegistry_Unregister
MissingIsNoop.

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Snider 2026-04-14 19:44:06 +01:00
parent 3f91bca3a3
commit 6db0ad26e3
3 changed files with 15 additions and 4 deletions

View file

@ -67,6 +67,7 @@ func (p *PIDFile) Acquire() error {
}
// Release removes the PID file.
// Returns nil if the PID file does not exist.
//
// Example:
//
@ -74,6 +75,9 @@ func (p *PIDFile) Acquire() error {
func (p *PIDFile) Release() error {
p.mu.Lock()
defer p.mu.Unlock()
if !coreio.Local.Exists(p.path) {
return nil
}
if err := coreio.Local.Delete(p.path); err != nil {
return core.E("pidfile.release", "failed to remove PID file", err)
}

View file

@ -47,6 +47,12 @@ func TestPIDFile_Path_Good(t *testing.T) {
assert.Equal(t, "/tmp/test.pid", pid.Path())
}
func TestPIDFile_Release_MissingIsNoop(t *testing.T) {
pidPath := core.JoinPath(t.TempDir(), "absent.pid")
pid := NewPIDFile(pidPath)
require.NoError(t, pid.Release())
}
func TestReadPID_Missing_Bad(t *testing.T) {
pid, running := ReadPID("/nonexistent/path.pid")
assert.Equal(t, 0, pid)

View file

@ -88,10 +88,11 @@ func (r *Registry) Register(entry DaemonEntry) error {
//
// _ = reg.Unregister("app", "serve")
func (r *Registry) Unregister(code, daemon string) error {
if err := coreio.Local.Delete(r.entryPath(code, daemon)); err != nil {
if os.IsNotExist(err) {
return nil
}
path := r.entryPath(code, daemon)
if !coreio.Local.Exists(path) {
return nil
}
if err := coreio.Local.Delete(path); err != nil {
return coreerr.E("Registry.Unregister", "failed to delete entry file", err)
}
return nil