Skip to content

Commit c331766

Browse files
committed
Try to use Peek for peeking progress if available
Signed-off-by: Andrea Waltlova <awaltlov@redhat.com>
1 parent ce4ef02 commit c331766

1 file changed

Lines changed: 26 additions & 25 deletions

File tree

src/runner.go

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,10 @@ func setEnvVariablesForCommand(cmd *exec.Cmd, variables map[string]string) {
102102
}
103103

104104
// Runs given command and sends stdout to given channel. doneCh used to signal that execution ended.
105-
func runCommandWithOutput(cmd *exec.Cmd, outputCh chan string, doneCh chan bool) {
105+
func runCommandWithOutput(cmd *exec.Cmd, outputCh chan []byte, doneCh chan bool) {
106106
cmdOutput, err := cmd.StdoutPipe()
107107
if err != nil {
108-
outputCh <- fmt.Sprintf("Error: %v", err)
108+
log.Errorln("Error: ", err)
109109
doneCh <- true
110110
return
111111
}
@@ -114,29 +114,34 @@ func runCommandWithOutput(cmd *exec.Cmd, outputCh chan string, doneCh chan bool)
114114
defer close(dataReadCh)
115115

116116
go func() {
117-
defer func() {
118-
dataReadCh <- true
119-
}()
120-
121117
reader := bufio.NewReader(cmdOutput)
118+
readBuffer := 1024
122119

123120
for {
124-
line, err := reader.ReadString('\n')
125-
if errors.Is(err, io.EOF) {
121+
data, err := reader.Peek(readBuffer)
122+
switch {
123+
case errors.Is(err, io.EOF):
126124
log.Infoln("Read ended with EOF")
127-
break
128-
} else if err != nil {
129-
log.Infoln("Read ended with error", err)
130-
outputCh <- fmt.Sprintf("Error reading from stdout: %v", err)
125+
outputCh <- data
126+
dataReadCh <- true
131127
return
128+
case err == nil || errors.Is(err, io.ErrShortBuffer):
129+
log.Infoln("Read n bytes", err)
130+
if len(data) != 0 {
131+
outputCh <- data
132+
_, err := reader.Discard(len(data))
133+
if err != nil {
134+
// TODO: what should I do if I want to move the reader
135+
// If I do nothing it can only cause it to be read twice
136+
log.Errorln("Discard failed", err)
137+
}
138+
}
132139
}
133-
log.Infoln("Read line: ", line)
134-
outputCh <- line
135140
}
136141
}()
137142

138143
if err := cmd.Start(); err != nil {
139-
outputCh <- fmt.Sprintf("Error: %v", err)
144+
log.Errorln("Error: ", err)
140145
doneCh <- true
141146
return
142147
}
@@ -147,7 +152,6 @@ func runCommandWithOutput(cmd *exec.Cmd, outputCh chan string, doneCh chan bool)
147152

148153
if err := cmd.Wait(); err != nil {
149154
log.Errorln("Failed to execute script: ", err)
150-
outputCh <- fmt.Sprintf("Error: %v", err)
151155
}
152156

153157
doneCh <- true // Signal that the command has finished
@@ -160,8 +164,8 @@ func executeCommandWithProgress(command string, interpreter string, variables ma
160164
cmd := exec.Command(interpreter, command)
161165
setEnvVariablesForCommand(cmd, variables)
162166

163-
var bufferedOutput string
164-
outputCh := make(chan string)
167+
var bufferedOutput []byte
168+
outputCh := make(chan []byte)
165169
defer close(outputCh)
166170
doneCh := make(chan bool)
167171
defer close(doneCh)
@@ -174,19 +178,16 @@ func executeCommandWithProgress(command string, interpreter string, variables ma
174178
for {
175179
select {
176180
case output := <-outputCh:
177-
// TODO: this has to be sent to dispatcher back to report to UI
178-
// the idea is to send partial output if buffer with given size sent the output to channel
179-
log.Info(output)
180-
181-
// Append partial to all output
182-
bufferedOutput += output
181+
bufferedOutput = append(bufferedOutput, output...)
183182
case <-ticker.C:
184183
// NOTE: If just message without output is also okay we could send just still running
185184
log.Infoln("Still running ...")
185+
log.Infoln(string(bufferedOutput))
186186
case <-doneCh:
187187
// Execution is done
188188
log.Infoln("Execution done ...")
189-
return bufferedOutput
189+
log.Infoln(string(bufferedOutput))
190+
return string(bufferedOutput)
190191
}
191192
}
192193
}

0 commit comments

Comments
 (0)