Return exit status from Wait of stopped process
This changes Wait() from returning an error whenever you call wait on a stopped process/task to returning the exit status from the process. This also adds the exit status to the Status() call on a process/task so that a user can Wait(), check status, then cancel the wait to avoid races in event handling. Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
33
task.go
33
task.go
@@ -28,14 +28,19 @@ import (
|
||||
|
||||
const UnknownExitStatus = 255
|
||||
|
||||
type Status string
|
||||
type Status struct {
|
||||
Status ProcessStatus
|
||||
ExitStatus uint32
|
||||
}
|
||||
|
||||
type ProcessStatus string
|
||||
|
||||
const (
|
||||
Running Status = "running"
|
||||
Created Status = "created"
|
||||
Stopped Status = "stopped"
|
||||
Paused Status = "paused"
|
||||
Pausing Status = "pausing"
|
||||
Running ProcessStatus = "running"
|
||||
Created ProcessStatus = "created"
|
||||
Stopped ProcessStatus = "stopped"
|
||||
Paused ProcessStatus = "paused"
|
||||
Pausing ProcessStatus = "pausing"
|
||||
)
|
||||
|
||||
type IOCloseInfo struct {
|
||||
@@ -146,12 +151,14 @@ func (t *task) Status(ctx context.Context) (Status, error) {
|
||||
ContainerID: t.id,
|
||||
})
|
||||
if err != nil {
|
||||
return "", errdefs.FromGRPC(err)
|
||||
return Status{}, errdefs.FromGRPC(err)
|
||||
}
|
||||
return Status(strings.ToLower(r.Process.Status.String())), nil
|
||||
return Status{
|
||||
Status: ProcessStatus(strings.ToLower(r.Process.Status.String())),
|
||||
ExitStatus: r.Process.ExitStatus,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Wait is a blocking call that will wait for the task to exit and return the exit status
|
||||
func (t *task) Wait(ctx context.Context) (uint32, error) {
|
||||
eventstream, err := t.client.EventService().Subscribe(ctx, &eventsapi.SubscribeRequest{
|
||||
Filters: []string{"topic==" + runtime.TaskExitEventTopic},
|
||||
@@ -160,8 +167,12 @@ func (t *task) Wait(ctx context.Context) (uint32, error) {
|
||||
return UnknownExitStatus, errdefs.FromGRPC(err)
|
||||
}
|
||||
// first check if the task has exited
|
||||
if status, _ := t.Status(ctx); status == Stopped {
|
||||
return UnknownExitStatus, errdefs.ErrUnavailable
|
||||
status, err := t.Status(ctx)
|
||||
if err != nil {
|
||||
return UnknownExitStatus, errdefs.FromGRPC(err)
|
||||
}
|
||||
if status.Status == Stopped {
|
||||
return status.ExitStatus, nil
|
||||
}
|
||||
for {
|
||||
evt, err := eventstream.Recv()
|
||||
|
Reference in New Issue
Block a user