fixxxy

4dd3a32 · gmorell · 2026-05-25 16:17

1 files +14 -9

Files changed

modified lib/git_gud_web/controllers/runner_controller.ex
+14 −9
@@ -421,15 +421,20 @@ defmodule GitGudWeb.RunnerController do
421 421
422 422 step = job && Workflows.ensure_log_step(job)
423 423
424 # Connect-Go decodes empty unary bodies as "method not
425 # implemented" and surfaces it as "unimplemented: 404 Not
426 # Found" — which corrupts the HTTP/1.1 keepalive stream when
427 # the actual content-length disagrees with what was written.
428 # `ack_index = 0` would encode to 0 bytes (proto3 omits default
429 # ints), so we always advertise at least 1 acked row when the
430 # request itself was non-zero — matches Forgejo's behavior of
431 # echoing back the high-water mark.
432 ack_index = max(index + length(rows), 1)
424 + # The runner's `ReportLog` slices its local buffer with
425 + #
426 + # r.logRows = r.logRows[ack-r.logOffset:]
427 + #
428 + # If we lie about `ack_index` (claim more rows than the runner
429 + # sent), the slice runs past `len(r.logRows)` and the runner
430 + # PANICS with `goPanicSliceB`. So `ack_index` MUST be exactly
431 + # `index + length(rows)` — never floor or bump.
432 + #
433 + # The original concern that motivated a floor here — empty
434 + # response bodies confusing Connect-Go / breaking HTTP/1.1
435 + # keepalive framing — is handled by the `Connection: close`
436 + # we set in `respond/2`, so this can be honest.
437 + ack_index = index + length(rows)
433 438
434 439 cond do
435 440 is_nil(step) ->

Parents: 5195c69