erigontech / erigontech/erigon

Caplin req/resp: stream multi-chunk responses instead of materializing the full body in requestPeer

Open
#21,616 1 comment 0 reactions 1 assignee Claimed by @domiwei View on GitHub
Caplin Networking
Dominant language
Go
Stars
3.6k
Forks
1.5k
Avg merge
1d 16h
Merged PRs (30d)
455

Description

Follow-up from #21562 (raised in review by @domiwei).

## Background

#21562 made `cl/sentinel/httpreqresp` stream the peer response through a per-topic size cap instead of buffering it in the handler, so memory is now bounded by the per-request byte budget. That fixes the original unbounded-buffering OOM.

## Remaining improvement

The full response is still materialized once, in `service.requestPeer`:

```go
data, err := io.ReadAll(resp.Body)
...
return &sentinelproto.ResponseData{Data: data, ...}
```

For a large `by_range` request the budget is large (~ requested-count x per-chunk), so this is still a big single allocation; and `ResponseData.Data` is a single gRPC `bytes` field, so the whole response also crosses the sentinel->`cl/rpc` boundary as one blob before `parseResponseData` decodes it.

## Proposal

Decode req/resp chunks incrementally rather than buffering the whole response:
- keep `max_response_bytes` as a wire-budget guard, enforced by the counting reader already in place;
- decode chunks incrementally from the `io.Reader`, rejecting as soon as the byte budget / chunk count / per-chunk size is exceeded;
- avoid the second full copy in `requestPeer` — this likely requires the sentinel `SendRequest`/`SendPeerRequest` gRPC to become server-streaming, since `ResponseData.Data` is one `bytes` field today.

Peak memory would then be ~ one chunk + the decoded object, the right shape for multi-chunk req/resp.

## Note

Not a live OOM — #21562 already bounds the allocation by the per-request budget. This is memory-shape hardening, hence a regular enhancement.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.