From d1d370ce018e999b66582dec9a91eaeedd876775 Mon Sep 17 00:00:00 2001 From: Roberto Bruggemann Date: Fri, 19 Jan 2018 10:42:57 +0000 Subject: [PATCH 1/2] logReadCloser: ensure reader errors yield EOF This change makes the underlying reader set their corresponding `eof` slot to true on termination. This make the overall logReadCloser converge to EOF in case of errors of the underlying readers, therefore prevent spinning on read. `bufio.Reader.ReadBytes` may not return io.EOF when `Close()` closes the underlying reader. For instance, closing logReadCloser from the Scope App makes `bufio.Reader.ReadBytes` produce the following error: `http2: response body closed`. --- probe/kubernetes/logreadcloser.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/probe/kubernetes/logreadcloser.go b/probe/kubernetes/logreadcloser.go index 740bd1b61b..7eabd8602c 100644 --- a/probe/kubernetes/logreadcloser.go +++ b/probe/kubernetes/logreadcloser.go @@ -130,7 +130,6 @@ func (l *logReadCloser) readInput(idx int) { if len(line) > 0 { l.dataChannel <- l.annotateLine(idx, line) } - l.eofChannel <- idx break } if err != nil { @@ -139,6 +138,8 @@ func (l *logReadCloser) readInput(idx int) { } l.dataChannel <- l.annotateLine(idx, line) } + + l.eofChannel <- idx } func (l *logReadCloser) annotateLine(idx int, line []byte) []byte { From 9198f6b38bde3e9e852a1b373466cbb687edb207 Mon Sep 17 00:00:00 2001 From: Roberto Bruggemann Date: Fri, 19 Jan 2018 14:23:13 +0000 Subject: [PATCH 2/2] logReadCloser: ensure loop terminates if channels are closed Adding the !EOF check to the loop condition ensures not reading from closed channels. --- probe/kubernetes/logreadcloser.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/probe/kubernetes/logreadcloser.go b/probe/kubernetes/logreadcloser.go index 7eabd8602c..1af7e6e3f2 100644 --- a/probe/kubernetes/logreadcloser.go +++ b/probe/kubernetes/logreadcloser.go @@ -84,7 +84,7 @@ func (l *logReadCloser) Read(p []byte) (int, error) { // check if there's more data to read, without blocking empty := false - for !empty && l.buffer.Len() < len(p) { + for !empty && l.buffer.Len() < len(p) && !l.isEOF() { select { case data := <-l.dataChannel: l.buffer.Write(data)