From 3930aed49a21e831f493bbc100047e326668089a Mon Sep 17 00:00:00 2001 From: Virgil Date: Sat, 4 Apr 2026 04:19:17 +0000 Subject: [PATCH] feat(process): allow zero-value task signals Co-Authored-By: Virgil --- actions.go | 1 + service.go | 4 ---- service_test.go | 24 ++++++++++++++++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/actions.go b/actions.go index 1ca89c5..c4d4856 100644 --- a/actions.go +++ b/actions.go @@ -66,6 +66,7 @@ type TaskProcessKill struct { } // TaskProcessSignal requests signalling a managed process by ID or PID through Core.PERFORM. +// Signal 0 is allowed for liveness checks. // // Example: // diff --git a/service.go b/service.go index d0c1f14..cbb8769 100644 --- a/service.go +++ b/service.go @@ -668,10 +668,6 @@ func (s *Service) handleTask(c *core.Core, task core.Task) core.Result { return core.Result{Value: coreerr.E("Service.handleTask", "task process kill requires an id or pid", nil), OK: false} } case TaskProcessSignal: - if m.Signal == 0 { - return core.Result{Value: coreerr.E("Service.handleTask", "task process signal requires a signal", nil), OK: false} - } - switch { case m.ID != "": if err := s.Signal(m.ID, m.Signal); err != nil { diff --git a/service_test.go b/service_test.go index 9482a55..ff018c8 100644 --- a/service_test.go +++ b/service_test.go @@ -815,6 +815,30 @@ func TestService_OnStartup(t *testing.T) { assert.Equal(t, StatusKilled, proc.Status) }) + t.Run("allows signal zero liveness checks", func(t *testing.T) { + svc, c := newTestService(t) + + err := svc.OnStartup(context.Background()) + require.NoError(t, err) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + proc, err := svc.Start(ctx, "sleep", "60") + require.NoError(t, err) + + result := c.PERFORM(TaskProcessSignal{ + ID: proc.ID, + Signal: syscall.Signal(0), + }) + require.True(t, result.OK) + + assert.True(t, proc.IsRunning()) + + cancel() + <-proc.Done() + }) + t.Run("registers process.wait task", func(t *testing.T) { svc, c := newTestService(t)