diff --git a/actions.go b/actions.go index 5a73f44..8a2526d 100644 --- a/actions.go +++ b/actions.go @@ -39,6 +39,16 @@ type TaskProcessKill struct { PID int } +// TaskProcessList requests a snapshot of managed processes through Core.PERFORM. +// If RunningOnly is true, only active processes are returned. +// +// Example: +// +// c.PERFORM(process.TaskProcessList{RunningOnly: true}) +type TaskProcessList struct { + RunningOnly bool +} + // ActionProcessStarted is broadcast when a process begins execution. // // Example: diff --git a/service.go b/service.go index afe2646..5a1745c 100644 --- a/service.go +++ b/service.go @@ -530,6 +530,18 @@ func (s *Service) handleTask(c *core.Core, task core.Task) core.Result { default: return core.Result{Value: coreerr.E("Service.handleTask", "task process kill requires an id or pid", nil), OK: false} } + case TaskProcessList: + procs := s.List() + if m.RunningOnly { + procs = s.Running() + } + + infos := make([]Info, 0, len(procs)) + for _, proc := range procs { + infos = append(infos, proc.Info()) + } + + return core.Result{Value: infos, OK: true} default: return core.Result{} } diff --git a/service_test.go b/service_test.go index a69749c..4437164 100644 --- a/service_test.go +++ b/service_test.go @@ -549,6 +549,31 @@ func TestService_OnStartup(t *testing.T) { assert.Equal(t, StatusKilled, proc.Status) }) + + t.Run("registers process.list task", 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(TaskProcessList{RunningOnly: true}) + require.True(t, result.OK) + + infos, ok := result.Value.([]Info) + require.True(t, ok) + require.Len(t, infos, 1) + assert.Equal(t, proc.ID, infos[0].ID) + assert.True(t, infos[0].Running) + + cancel() + <-proc.Done() + }) } func TestService_RunWithOptions(t *testing.T) {