feat(process): add async process start task
This commit is contained in:
parent
6c1d53a237
commit
ceea10fc7a
3 changed files with 66 additions and 0 deletions
23
actions.go
23
actions.go
|
|
@ -4,6 +4,29 @@ import "time"
|
|||
|
||||
// --- ACTION messages (broadcast via Core.ACTION) ---
|
||||
|
||||
// TaskProcessStart requests asynchronous process execution through Core.PERFORM.
|
||||
// The handler returns a snapshot of the started process immediately.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// c.PERFORM(process.TaskProcessStart{Command: "sleep", Args: []string{"10"}})
|
||||
type TaskProcessStart struct {
|
||||
Command string
|
||||
Args []string
|
||||
Dir string
|
||||
Env []string
|
||||
// DisableCapture skips buffering process output before returning it.
|
||||
DisableCapture bool
|
||||
// Detach runs the command in its own process group.
|
||||
Detach bool
|
||||
// Timeout bounds the execution duration.
|
||||
Timeout time.Duration
|
||||
// GracePeriod controls SIGTERM-to-SIGKILL escalation.
|
||||
GracePeriod time.Duration
|
||||
// KillGroup terminates the entire process group instead of only the leader.
|
||||
KillGroup bool
|
||||
}
|
||||
|
||||
// TaskProcessRun requests synchronous command execution through Core.PERFORM.
|
||||
// The handler returns the combined command output on success.
|
||||
//
|
||||
|
|
|
|||
16
service.go
16
service.go
|
|
@ -555,6 +555,22 @@ func (s *Service) RunWithOptions(ctx context.Context, opts RunOptions) (string,
|
|||
// handleTask dispatches Core.PERFORM messages for the process service.
|
||||
func (s *Service) handleTask(c *core.Core, task core.Task) core.Result {
|
||||
switch m := task.(type) {
|
||||
case TaskProcessStart:
|
||||
proc, err := s.StartWithOptions(c.Context(), RunOptions{
|
||||
Command: m.Command,
|
||||
Args: m.Args,
|
||||
Dir: m.Dir,
|
||||
Env: m.Env,
|
||||
DisableCapture: m.DisableCapture,
|
||||
Detach: m.Detach,
|
||||
Timeout: m.Timeout,
|
||||
GracePeriod: m.GracePeriod,
|
||||
KillGroup: m.KillGroup,
|
||||
})
|
||||
if err != nil {
|
||||
return core.Result{Value: err, OK: false}
|
||||
}
|
||||
return core.Result{Value: proc.Info(), OK: true}
|
||||
case TaskProcessRun:
|
||||
output, err := s.RunWithOptions(c.Context(), RunOptions{
|
||||
Command: m.Command,
|
||||
|
|
|
|||
|
|
@ -596,6 +596,33 @@ func TestService_OnShutdown(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestService_OnStartup(t *testing.T) {
|
||||
t.Run("registers process.start task", func(t *testing.T) {
|
||||
svc, c := newTestService(t)
|
||||
|
||||
err := svc.OnStartup(context.Background())
|
||||
require.NoError(t, err)
|
||||
|
||||
result := c.PERFORM(TaskProcessStart{
|
||||
Command: "sleep",
|
||||
Args: []string{"1"},
|
||||
})
|
||||
|
||||
require.True(t, result.OK)
|
||||
|
||||
info, ok := result.Value.(Info)
|
||||
require.True(t, ok)
|
||||
assert.NotEmpty(t, info.ID)
|
||||
assert.Equal(t, StatusRunning, info.Status)
|
||||
assert.True(t, info.Running)
|
||||
|
||||
proc, err := svc.Get(info.ID)
|
||||
require.NoError(t, err)
|
||||
assert.True(t, proc.IsRunning())
|
||||
|
||||
<-proc.Done()
|
||||
assert.Equal(t, StatusExited, proc.Status)
|
||||
})
|
||||
|
||||
t.Run("registers process.run task", func(t *testing.T) {
|
||||
svc, c := newTestService(t)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue