summaryrefslogtreecommitdiff
path: root/lib/gitlab/ci/trace/stream.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/ci/trace/stream.rb')
-rw-r--r--lib/gitlab/ci/trace/stream.rb24
1 files changed, 21 insertions, 3 deletions
diff --git a/lib/gitlab/ci/trace/stream.rb b/lib/gitlab/ci/trace/stream.rb
index 5e634bcac71..11dbe4de02c 100644
--- a/lib/gitlab/ci/trace/stream.rb
+++ b/lib/gitlab/ci/trace/stream.rb
@@ -14,6 +14,7 @@ module Gitlab
def initialize
@stream = yield
+ @stream.binmode
end
def valid?
@@ -30,7 +31,7 @@ module Gitlab
last_bytes = stream_size
end
stream.seek(-last_bytes, IO::SEEK_END)
- stream.readline
+ seek_previous_line(stream_size)
end
def append(data, offset)
@@ -53,7 +54,7 @@ module Gitlab
read_last_lines(last_lines)
else
stream.read
- end
+ end.force_encoding(Encoding.default_external)
end
def html_with_state(state = nil)
@@ -115,7 +116,24 @@ module Gitlab
end
chunks.join.lines.last(last_lines).join
- .force_encoding(Encoding.default_external)
+ end
+
+ def seek_previous_line(max = stream_size)
+ return if stream.pos.zero?
+
+ seek_size = [stream.pos, BUFFER_SIZE].min
+
+ stream.seek(-seek_size, IO::SEEK_CUR)
+
+ buf = stream.read(seek_size)
+ idx = buf.rindex("\n")
+
+ if idx
+ stream.seek(-seek_size + idx + 1, IO::SEEK_CUR)
+ else
+ stream.seek(-seek_size, IO::SEEK_CUR)
+ seek_previous_line(max)
+ end
end
end
end