-
Estimate
2 developer-days (7–12.5h)
Task Estimate Grep + audit all WebClientcall sites in the Sztabina client layer, categorize by risk1–2h Streaming refactor for blob fetch (highest risk — pipe to ServerHttpResponse)2–3h Streaming refactor for diff / patch fetch 1–2h Streaming refactor for tree listing (verify or clear) 0.5–1h Any pack / clone proxying if present 1–2h Remove maxInMemorySizeoverride, smoke test locally0.5h Regression pass (large blob + large diff) 1–2h Main wildcard: call sites that feed into a non-trivial processing pipeline between receipt and response. Pure pass-through is straightforward; any parsing or transformation in the middle makes the streaming refactor more involved.
| Type |
Bug
|
| Priority |
Normal
|
| Assignee | |
| Version |
1.10.1
|
| Sprints |
n/a
|
| Customer |
n/a
|
Issue Votes (0)
Labels:
enhancementreliabilitybackendsztabina-integrationPriority: High Milestone: MVP (blocker)Background
During testing, Sztab crashed with a non-obvious exception originating in the Netty/WebFlux codec layer (see: https://tigase.dev/sztab/~issues/119). Root cause: the Sztab
WebClient(consumer) was collecting the full Sztabina (producer) HTTP response body into an in-memory buffer before processing it. For large git payloads — blobs, diffs, pack data, or tree listings — this buffer overflowed the WebFlux default codec limit.Sztabina had no visibility into the overflow; it served the response normally. The failure manifested entirely on the Sztab side as a cryptic
DataBufferLimitExceptionor similar Reactor Netty codec error, with no indication in the stack trace that response size was the actual cause. This class of failure is silent until it isn't — it will recur on any sufficiently large repository in production.Tentative Fix (currently in place)
The
WebClientcodec configuration was patched with an approximate max-in-memory size ceiling:This is a stopgap. It is brittle because:
Desired Solution
Replace the collect-to-body pattern with proper reactive streaming wherever Sztab consumes Sztabina responses.
Before (buffered — current stopgap):
After (streaming):
For endpoints that serve content directly to the browser (e.g. blob download), the preferred pattern is to pipe the
Flux<DataBuffer>directly into the SpringServerHttpResponsewithout ever collecting:This keeps memory flat regardless of payload size.
Scope — Full Audit Required
Since the affected scope is not fully characterized, all Sztab service classes that call Sztabina via
WebClientmust be audited. Suspected or confirmed affected interactions:bodyToMono(byte[].class)orbodyToMono(String.class)A grep for
bodyToMonoandbodyToFluxin the Sztabina client layer is the recommended starting point for the audit.Acceptance Criteria
WebClientcalls to Sztabina that carry potentially large payloads usebodyToFlux(DataBuffer.class)or equivalent streaming extraction — nobodyToMono(byte[].class)orbodyToMono(String.class)on unbounded responses.DataBufferUtils.release()is called on every consumedDataBufferto prevent Netty off-heap memory leaks.maxInMemorySizeoverride is removed or reduced back to the WebFlux default once streaming is fully in place.DataBufferLimitExceptionor observable heap spike.DataBufferLimitExceptionappears in logs under normal repo browsing.