add read feedback for execute

main
Ben Grewell 3 years ago
parent 1649d0336a
commit 8ad71c4c56

@ -6,6 +6,7 @@
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="fc2840de-29dc-4fca-8e0e-a283562f60ca" name="Default Changelist" comment=""> <list default="true" id="fc2840de-29dc-4fca-8e0e-a283562f60ca" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/client.go" beforeDir="false" afterPath="$PROJECT_DIR$/client.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/execute.go" beforeDir="false" afterPath="$PROJECT_DIR$/execute.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/execute.go" beforeDir="false" afterPath="$PROJECT_DIR$/execute.go" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />

@ -489,12 +489,13 @@ func (c *Client) SetModeLive() <-chan *StreamIntervalReport {
} }
func (c *Client) Start() (err error) { func (c *Client) Start() (err error) {
read := make(chan interface{})
cmd, err := c.commandString() cmd, err := c.commandString()
if err != nil { if err != nil {
return err return err
} }
var exit chan int var exit chan int
c.outputStream, c.errorStream, exit, c.cancel, err = ExecuteAsyncWithCancel(cmd) c.outputStream, c.errorStream, exit, c.cancel, err = ExecuteAsyncWithCancelReadIndicator(cmd, read)
if err != nil { if err != nil {
return err return err
} }
@ -522,6 +523,7 @@ func (c *Client) Start() (err error) {
fmt.Println("reading output") fmt.Println("reading output")
} }
testOutput, err := ioutil.ReadAll(c.outputStream) testOutput, err := ioutil.ReadAll(c.outputStream)
read <- true
if err != nil { if err != nil {
if c.Debug { if c.Debug {
fmt.Println(err.Error()) fmt.Println(err.Error())

@ -6,7 +6,6 @@ import (
"os/exec" "os/exec"
"strings" "strings"
"syscall" "syscall"
"time"
) )
func ExecuteAsync(cmd string) (outPipe io.ReadCloser, errPipe io.ReadCloser, exitCode chan int, err error) { func ExecuteAsync(cmd string) (outPipe io.ReadCloser, errPipe io.ReadCloser, exitCode chan int, err error) {
@ -44,6 +43,10 @@ func ExecuteAsync(cmd string) (outPipe io.ReadCloser, errPipe io.ReadCloser, exi
} }
func ExecuteAsyncWithCancel(cmd string) (stdOut io.ReadCloser, stdErr io.ReadCloser, exitCode chan int, cancelToken context.CancelFunc, err error) { func ExecuteAsyncWithCancel(cmd string) (stdOut io.ReadCloser, stdErr io.ReadCloser, exitCode chan int, cancelToken context.CancelFunc, err error) {
return ExecuteAsyncWithCancelReadIndicator(cmd, nil)
}
func ExecuteAsyncWithCancelReadIndicator(cmd string, readIndicator chan interface{}) (stdOut io.ReadCloser, stdErr io.ReadCloser, exitCode chan int, cancelToken context.CancelFunc, err error) {
exitCode = make(chan int) exitCode = make(chan int)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
cmdParts := strings.Fields(cmd) cmdParts := strings.Fields(cmd)
@ -69,7 +72,11 @@ func ExecuteAsyncWithCancel(cmd string) (stdOut io.ReadCloser, stdErr io.ReadClo
return nil, nil, nil, nil, err return nil, nil, nil, nil, err
} }
go func() { go func() {
time.Sleep(30 * time.Second) // Note: Wait() will close the Stdout/Stderr and in some cases can do it before we read. In order to prevent
// this we need to actually wait until the caller has finished reading.
if readIndicator != nil {
<- readIndicator
}
if err := exe.Wait(); err != nil { if err := exe.Wait(); err != nil {
if exiterr, ok := err.(*exec.ExitError); ok { if exiterr, ok := err.(*exec.ExitError); ok {
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {

Loading…
Cancel
Save