Handle stderr in stream processors

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby
2019-08-06 21:06:18 +00:00
parent 3fded74bc7
commit 552a0b1be5
3 changed files with 86 additions and 18 deletions

View File

@@ -25,14 +25,17 @@ import (
"io"
"os"
"os/exec"
"sync"
"github.com/gogo/protobuf/proto"
"github.com/gogo/protobuf/types"
"github.com/pkg/errors"
)
// NewBinaryProcessor returns a binary processor for use with processing content streams
func NewBinaryProcessor(ctx context.Context, imt, rmt string, stream StreamProcessor, name string, args []string, payload *types.Any) (StreamProcessor, error) {
cmd := exec.CommandContext(ctx, name, args...)
cmd.Env = os.Environ()
var payloadC io.Closer
if payload != nil {
@@ -71,10 +74,19 @@ func NewBinaryProcessor(ctx context.Context, imt, rmt string, stream StreamProce
}
cmd.Stdout = w
stderr := bytes.NewBuffer(nil)
cmd.Stderr = stderr
if err := cmd.Start(); err != nil {
return nil, err
}
go cmd.Wait()
p := &binaryProcessor{
cmd: cmd,
r: r,
mt: rmt,
stderr: stderr,
}
go p.wait()
// close after start and dup
w.Close()
@@ -84,17 +96,33 @@ func NewBinaryProcessor(ctx context.Context, imt, rmt string, stream StreamProce
if payloadC != nil {
payloadC.Close()
}
return &binaryProcessor{
cmd: cmd,
r: r,
mt: rmt,
}, nil
return p, nil
}
type binaryProcessor struct {
cmd *exec.Cmd
r *os.File
mt string
cmd *exec.Cmd
r *os.File
mt string
stderr *bytes.Buffer
mu sync.Mutex
err error
}
func (c *binaryProcessor) Err() error {
c.mu.Lock()
defer c.mu.Unlock()
return c.err
}
func (c *binaryProcessor) wait() {
if err := c.cmd.Wait(); err != nil {
if _, ok := err.(*exec.ExitError); ok {
c.mu.Lock()
c.err = errors.New(c.stderr.String())
c.mu.Unlock()
}
}
}
func (c *binaryProcessor) File() *os.File {