executor

package module
v0.0.0-...-d263f4d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 26, 2018 License: Apache-2.0 Imports: 9 Imported by: 17

README

ReportCard Build GoDoc

Executor: flexible, high-level exec.Cmd for golang

Package executor implements a high level execution context with monitoring, control, and logging features. It is made for services which execute lots of small programs and need to carefully control i/o and processes.

Executor can:

  • Terminate on signal or after a timeout via /x/net/context
  • Output a message on an interval if the program is still running. The periodic message can be turned off by setting LogInterval of executor to a value <= 0
  • Capture split-stream stdio, and make it easier to get at io pipes.

Example:

  e := executor.New(exec.Command("/bin/sh", "echo hello"))
  e.Start() // start
  fmt.Println(e.PID()) // get the pid
  fmt.Printf("%v\n", e) // pretty string output
  er, err := e.Wait(context.Background()) // wait for termination
  fmt.Println(er.ExitStatus) // => 0
  
  // lets capture some io, and timeout after a while
  e := executor.NewCapture(exec.Command("/bin/sh", "yes"))
  e.Start()
  ctx, _ := context.WithTimeout(context.Background(), 10 * time.Second)
  er, err := e.Wait(ctx) // wait for only 10 seconds
  fmt.Println(err == context.DeadlineExceeded)
  fmt.Println(er.Stdout) // yes\nyes\nyes\n...

Authors:

  • Erik Hollensbe

Sponsorship

Project Contiv is sponsored by Cisco Systems, Inc.

Documentation

Overview

Package executor implements a high level execution context with monitoring, control, and logging features. It is made for services which execute lots of small programs and need to carefully control i/o and processes.

Executor can:

  • Terminate on signal or after a timeout via /x/net/context
  • Output a message on an interval if the program is still running. The periodic message can be turned off by setting `LogInterval` of executor to a value <= 0
  • Capture split-stream stdio, and make it easier to get at io pipes.

Example:

e := executor.New(exec.Command("/bin/sh", "echo hello"))
e.Start() // start
fmt.Println(e.PID()) // get the pid
fmt.Printf("%v\n", e) // pretty string output
er, err := e.Wait(context.Background()) // wait for termination
fmt.Println(er.ExitStatus) // => 0

// lets capture some io, and timeout after a while
e := executor.NewCapture(exec.Command("/bin/sh", "yes"))
e.Start()
ctx, _ := context.WithTimeout(context.Background(), 10 * time.Second)
er, err := e.Wait(ctx) // wait for only 10 seconds
fmt.Println(err == context.DeadlineExceeded)
fmt.Println(er.Stdout) // yes\nyes\nyes\n...

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ExecResult

type ExecResult struct {
	Stdout     string
	Stderr     string
	ExitStatus int
	Runtime    time.Duration
	// contains filtered or unexported fields
}

ExecResult is the result of a Wait() operation and contains various fields related to the post-mortem state of the process such as output and exit status.

func (*ExecResult) String

func (er *ExecResult) String() string

type Executor

type Executor struct {
	// The interval at which we will log that we are still running.
	LogInterval time.Duration

	// The function used for logging. Expects a format-style string and trailing args.
	LogFunc func(string, ...interface{})

	// The stdin as passed to the process.
	Stdin io.Reader
	// contains filtered or unexported fields
}

Executor is the context used to execute a process. The runtime state is kept here. Please see the struct fields for more information.

New(), NewIO(), or NewCapture() are the appropriate ways to initialize this type.

No attempt is made to manage concurrent requests to this struct after the program has started.

func New

func New(cmd *exec.Cmd) *Executor

New creates a new executor from an *exec.Cmd. You may modify the values before calling Start(). See Executor for more information. Use NewCapture if you want executor to capture output for you.

func NewCapture

func NewCapture(cmd *exec.Cmd) *Executor

NewCapture creates an instance of executor suitable for capturing output. The Wait() call will automatically yield the stdout and stderr of the program. NOTE: this can potentially use unbounded amounts of ram; use carefully.

func NewIO

func NewIO(cmd *exec.Cmd) *Executor

NewIO creates a new executor but allows the Out() and Err() methods to provide a io.ReadCloser as a pipe from the stdout and error respectively. If you wish to read large volumes of output this is the way to go.

func (*Executor) Err

func (e *Executor) Err() io.ReadCloser

Err returns an io.ReadCloser which is the stream of the standard error stream.

func (*Executor) Out

func (e *Executor) Out() io.ReadCloser

Out returns an *os.File which is the stream of the standard output stream.

func (*Executor) PID

func (e *Executor) PID() uint32

PID yields the pid of the process (dead or alive), or 0 if the process has not been run yet.

func (*Executor) Run

func (e *Executor) Run(ctx context.Context) (*ExecResult, error)

Run calls Start(), then Wait(), and returns an ExecResult and error (if any). The error may be of many types including *exec.ExitError and context.Canceled, context.DeadlineExceeded.

func (*Executor) Start

func (e *Executor) Start() error

Start starts the command in the Executor context. It returns any error upon starting the process, but does not wait for it to complete. You may control it in a variety of ways (see Executor for more information).

func (*Executor) String

func (e *Executor) String() string

func (*Executor) TimeRunning

func (e *Executor) TimeRunning() time.Duration

TimeRunning returns the amount of time the program is or was running. Also see ExecResult.Runtime.

func (*Executor) Wait

func (e *Executor) Wait(ctx context.Context) (*ExecResult, error)

Wait waits for the process and return an ExecResult and any error it encountered along the way. While the error may or may not be nil, the ExecResult will always exist with as much information as we could get.

Context is from https://godoc.org/golang.org/x/net/context (see https://blog.golang.org/context for usage). You can use it to set timeouts and cancel executions.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL