ProcessResponseAsRingBufferToEnd reads the body of an HTTP response line by line, storing only the last maxJobLogLines lines using a ring buffer (sliding window). This efficiently retains the most recent lines, overwriting older ones as needed. Parameters: httpResp: The HTTP response whose
(httpResp *http.Response, maxJobLogLines int)
| 32 | // If the response contains more lines than maxJobLogLines, only the most recent lines are kept. |
| 33 | // Lines exceeding maxLineSize are truncated with a marker. |
| 34 | func ProcessResponseAsRingBufferToEnd(httpResp *http.Response, maxJobLogLines int) (string, int, *http.Response, error) { |
| 35 | if maxJobLogLines <= 0 { |
| 36 | maxJobLogLines = 500 |
| 37 | } |
| 38 | if maxJobLogLines > 100000 { |
| 39 | maxJobLogLines = 100000 |
| 40 | } |
| 41 | |
| 42 | lines := make([]string, maxJobLogLines) |
| 43 | validLines := make([]bool, maxJobLogLines) |
| 44 | totalLines := 0 |
| 45 | writeIndex := 0 |
| 46 | |
| 47 | const readBufferSize = 64 * 1024 // 64KB read buffer |
| 48 | const maxDisplayLength = 1000 // Keep first 1000 chars of truncated lines |
| 49 | |
| 50 | readBuf := make([]byte, readBufferSize) |
| 51 | var currentLine strings.Builder |
| 52 | lineTruncated := false |
| 53 | |
| 54 | // storeLine saves the current line to the ring buffer and resets state |
| 55 | storeLine := func() { |
| 56 | line := currentLine.String() |
| 57 | if lineTruncated && len(line) > maxDisplayLength { |
| 58 | line = line[:maxDisplayLength] |
| 59 | } |
| 60 | if lineTruncated { |
| 61 | line += "... [TRUNCATED]" |
| 62 | } |
| 63 | lines[writeIndex] = line |
| 64 | validLines[writeIndex] = true |
| 65 | totalLines++ |
| 66 | writeIndex = (writeIndex + 1) % maxJobLogLines |
| 67 | currentLine.Reset() |
| 68 | lineTruncated = false |
| 69 | } |
| 70 | |
| 71 | // accumulate adds bytes to currentLine up to maxLineSize, sets lineTruncated if exceeded |
| 72 | accumulate := func(data []byte) { |
| 73 | if lineTruncated { |
| 74 | return |
| 75 | } |
| 76 | remaining := maxLineSize - currentLine.Len() |
| 77 | if remaining <= 0 { |
| 78 | lineTruncated = true |
| 79 | return |
| 80 | } |
| 81 | if remaining > len(data) { |
| 82 | remaining = len(data) |
| 83 | } |
| 84 | currentLine.Write(data[:remaining]) |
| 85 | if currentLine.Len() >= maxLineSize { |
| 86 | lineTruncated = true |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | for { |
| 91 | n, err := httpResp.Body.Read(readBuf) |