From 60e342228ba8017e1cacc71a64280143832e7719 Mon Sep 17 00:00:00 2001 From: Sebastien Douheret Date: Fri, 26 Jan 2018 17:08:38 +0100 Subject: Added SplitLineTime and SplitTime support in eows - Used SplitTime to split command output by line - Used SplitLineTime to split command output by line or until a timeout has passed. Signed-off-by: Sebastien Douheret --- golib/eows/eows-out.go | 61 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 16 deletions(-) (limited to 'golib/eows/eows-out.go') diff --git a/golib/eows/eows-out.go b/golib/eows/eows-out.go index 6f6706c..b70e70c 100644 --- a/golib/eows/eows-out.go +++ b/golib/eows/eows-out.go @@ -4,16 +4,52 @@ import ( "bufio" "io" "strings" + "time" ) -// scanBlocks - gain character by character (or as soon as one or more characters are available) -func scanBlocks(data []byte, atEOF bool) (advance int, token []byte, err error) { +// scanChars - gain character by character (or as soon as one or more characters are available) +func scanChars(data []byte, atEOF bool) (advance int, token []byte, err error) { if atEOF && len(data) == 0 { return 0, nil, nil } return len(data), data, nil } +// _pumper is in charge to collect +func (e *ExecOverWS) _pumper(sc *bufio.Scanner, fctOut func(s string)) { + + // Select split function (default sc.ScanLines) + if e.OutSplit == SplitChar || e.OutSplit == SplitLineTime || e.OutSplit == SplitTime { + sc.Split(scanChars) + } + + // Scan method according to split type + if e.OutSplit == SplitLineTime || e.OutSplit == SplitTime { + t0 := time.Now() + buf := "" + for sc.Scan() { + buf += sc.Text() + if time.Since(t0).Nanoseconds() > e.LineTimeSpan || + (e.OutSplit == SplitLineTime && strings.Contains(buf, "\n")) { + fctOut(buf) + buf = "" + t0 = time.Now() + } + } + // Send remaining characters + if len(buf) > 0 { + e.OutputCB(e, "", buf) + } + + } else { + + for sc.Scan() { + e.OutputCB(e, sc.Text(), "") + } + } + +} + // cmdPumpStdout is in charge to forward stdout in websocket func (e *ExecOverWS) cmdPumpStdout(r io.Reader, done chan struct{}) { @@ -22,14 +58,10 @@ func (e *ExecOverWS) cmdPumpStdout(r io.Reader, done chan struct{}) { sc := bufio.NewScanner(r) - // else use default sc.ScanLines - if e.OutSplit == SplitChar { - sc.Split(scanBlocks) - } + e._pumper(sc, func(bufOut string) { + e.OutputCB(e, bufOut, "") + }) - for sc.Scan() { - e.OutputCB(e, sc.Text(), "") - } if sc.Err() != nil && !strings.Contains(sc.Err().Error(), "file already closed") { e.logError("stdout scan: %v", sc.Err()) } @@ -42,16 +74,13 @@ func (e *ExecOverWS) cmdPumpStderr(r io.Reader) { defer func() { }() + sc := bufio.NewScanner(r) - // else use default sc.ScanLines - if e.OutSplit == SplitChar { - sc.Split(scanBlocks) - } + e._pumper(sc, func(bufErr string) { + e.OutputCB(e, "", bufErr) + }) - for sc.Scan() { - e.OutputCB(e, "", sc.Text()) - } if sc.Err() != nil && !strings.Contains(sc.Err().Error(), "file already closed") { e.logError("stderr scan: %v", sc.Err()) } -- cgit 1.2.3-korg