fix: support large output with --enable-live-ouput (#1139)
* fix: support large output with --enable-live-ouput This replaces Scanner with ReadString to handle large amount of data returned by helm ouptut when executing diff action - Changing pkg/helmexec/runner_test.go TestLiveOutput test, adding test with large amount of data, reproducing the issue before applying this fix - Changing pkg/helmexec/runner.go Scanner with Readstring Resolves https://github.com/helmfile/helmfile/issues/893 Signed-off-by: Franck Labatut <franck.labatut@ubisoft.com> * fix: prevent data race Signed-off-by: Franck Labatut <franck.labatut@ubisoft.com> --------- Signed-off-by: Franck Labatut <franck.labatut@ubisoft.com>
This commit is contained in:
parent
e756712e80
commit
b8a729d8c4
|
|
@ -127,13 +127,26 @@ func Output(ctx context.Context, c *exec.Cmd, stripArgsValuesOnExitError bool, l
|
|||
|
||||
func LiveOutput(ctx context.Context, c *exec.Cmd, stripArgsValuesOnExitError bool, stdout io.Writer) ([]byte, error) {
|
||||
reader, writer := io.Pipe()
|
||||
scannerStopped := make(chan struct{})
|
||||
ch := make(chan error)
|
||||
doneCh := make(chan struct{})
|
||||
|
||||
go func() {
|
||||
defer close(scannerStopped)
|
||||
scanner := bufio.NewScanner(reader)
|
||||
for scanner.Scan() {
|
||||
fmt.Fprintln(stdout, scanner.Text())
|
||||
defer close(doneCh)
|
||||
reader := bufio.NewReader(reader)
|
||||
|
||||
for {
|
||||
// prefer readstring over scanner to handle potential large output
|
||||
// https://stackoverflow.com/a/29444042
|
||||
line, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
ch <- err
|
||||
}
|
||||
|
||||
line = strings.TrimSuffix(line, "\n")
|
||||
fmt.Fprintln(stdout, line)
|
||||
}
|
||||
}()
|
||||
|
||||
|
|
@ -142,7 +155,6 @@ func LiveOutput(ctx context.Context, c *exec.Cmd, stripArgsValuesOnExitError boo
|
|||
err := c.Start()
|
||||
|
||||
if err == nil {
|
||||
ch := make(chan error)
|
||||
go func() {
|
||||
ch <- c.Wait()
|
||||
}()
|
||||
|
|
@ -154,7 +166,7 @@ func LiveOutput(ctx context.Context, c *exec.Cmd, stripArgsValuesOnExitError boo
|
|||
err = <-ch
|
||||
}
|
||||
_ = writer.Close()
|
||||
<-scannerStopped
|
||||
<-doneCh
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package helmexec
|
|||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
_ "embed"
|
||||
"os/exec"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
|
@ -48,6 +49,9 @@ func TestShellRunner_Execute(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
//go:embed testdata/live-output-data.txt
|
||||
var liveOutputData string
|
||||
|
||||
func TestLiveOutput(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
@ -55,6 +59,12 @@ func TestLiveOutput(t *testing.T) {
|
|||
wantW string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "live_output_data",
|
||||
cmd: exec.Command("cat", "testdata/live-output-data.txt"),
|
||||
wantW: liveOutputData,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "echo_template",
|
||||
cmd: exec.Command("echo", "template"),
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue