Skip to content

fix(sdk): compression and FrameSignal ordering#313

Merged
sgbalogh merged 3 commits intomainfrom
issue309
Mar 6, 2026
Merged

fix(sdk): compression and FrameSignal ordering#313
sgbalogh merged 3 commits intomainfrom
issue309

Conversation

@sgbalogh
Copy link
Member

@sgbalogh sgbalogh commented Mar 6, 2026

Fixes #309

@sgbalogh sgbalogh changed the title fix for #309 fix(sdk): compression and FrameSignal ordering Mar 6, 2026
@sgbalogh sgbalogh marked this pull request as ready for review March 6, 2026 21:21
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 6, 2026

Greptile Summary

This PR fixes a bug (#309) where enabling compression together with the NoSideEffects append retry policy (which activates a FrameSignal) caused requests to fail. The root cause was an ordering issue: with_monitored_body converted the request body into a streaming type, after which execute_unary_with's call to compress_body correctly rejected it with "streaming request bodies cannot be compressed".

Key changes:

  • sdk/src/api.rs: In the retry loop, compression is now applied before wrapping the body with RequestFrameMonitorBody. This preserves the body as a buffered (non-streaming) type at the time of compression.
  • sdk/src/client.rs: A new compress() method on Request eagerly compresses the body, inserts the Content-Encoding header, and resets compression to Compression::None so that the existing compress_body call inside execute_unary_with is a guaranteed no-op — preventing any risk of double-compression.
  • sdk/tests/stream_ops.rs: Adds compression_with_no_side_effects_unary to directly cover the fixed code path (both Gzip and Zstd with AppendRetryPolicy::NoSideEffects).
  • sdk/tests/common/mod.rs: Defensively installs the aws-lc-rs rustls crypto provider during test setup to avoid a panic when both aws-lc-rs and ring features are active (e.g., via --all-features).

Confidence Score: 5/5

  • This PR is safe to merge — it fixes a clear ordering bug, avoids double-compression via the Compression::None reset, and adds regression tests for the exact failure scenario.
  • The fix is minimal and surgical: the two-line reordering in api.rs directly addresses the root cause, the new compress() method is straightforward with no observable side effects on the non-FrameSignal code path, and a dedicated integration test is included. No existing behaviour is changed for requests that don't use a FrameSignal.
  • No files require special attention.

Important Files Changed

Filename Overview
sdk/src/api.rs Core ordering fix: compression is now applied before wrapping the body with RequestFrameMonitorBody, preventing the "streaming request bodies cannot be compressed" error that occurred when FrameSignal was active.
sdk/src/client.rs New compress method on Request eagerly compresses the body and sets compression: Compression::None, ensuring execute_unary_with's second compress_body call is a no-op and no double-compression occurs.
sdk/tests/stream_ops.rs Adds compression_with_no_side_effects_unary integration test that directly exercises the fixed code path (compression + NoSideEffects retry policy / FrameSignal) for both Gzip and Zstd.
sdk/tests/common/mod.rs Installs the aws-lc-rs rustls crypto provider at test setup time to avoid ambiguity when both aws-lc-rs and ring features are enabled (e.g., --all-features).

Sequence Diagram

sequenceDiagram
    participant C as Caller
    participant RB as RequestBuilder (api.rs)
    participant R as Request (client.rs)
    participant EU as execute_unary_with

    C->>RB: send()
    RB->>R: try_clone()
    alt frame_signal present (NoSideEffects retry)
        Note over RB: NEW: compress BEFORE monitoring
        RB->>R: compress() [sets compression=None, adds Content-Encoding header]
        R-->>RB: Request{body=compressed, compression=None}
        RB->>R: with_monitored_body(signal)
        R-->>RB: Request{body=StreamingMonitored, compression=None}
    end
    RB->>EU: execute_unary(request)
    EU->>EU: compress_body(body, Compression::None) → no-op
    EU->>EU: build_http_request(headers already has Content-Encoding)
    EU-->>RB: UnaryResponse
Loading

Last reviewed commit: 59dd131

@sgbalogh sgbalogh merged commit 76b7476 into main Mar 6, 2026
16 checks passed
@sgbalogh sgbalogh deleted the issue309 branch March 6, 2026 21:36
@s2-release-plz s2-release-plz bot mentioned this pull request Mar 6, 2026
shikhar pushed a commit that referenced this pull request Mar 6, 2026
## 🤖 New release

* `s2-lite`: 0.29.20 -> 0.29.21 (✓ API compatible changes)
* `s2-sdk`: 0.24.7 -> 0.24.8 (✓ API compatible changes)
* `s2-cli`: 0.29.20 -> 0.29.21

<details><summary><i><b>Changelog</b></i></summary><p>

## `s2-lite`

<blockquote>

## [0.29.21] - 2026-03-06

### Bug Fixes

- Allow http endpoints for S3-compatible object stores
([#303](#303))
- Preserve follow wait budget after lagged recovery
([#311](#311))
- Initialize durability notifier from close status
([#312](#312))

<!-- generated by git-cliff -->
</blockquote>

## `s2-sdk`

<blockquote>

## [0.24.8] - 2026-03-06

### Bug Fixes

- Compression and FrameSignal ordering
([#313](#313))

<!-- generated by git-cliff -->
</blockquote>

## `s2-cli`

<blockquote>

## [0.29.21] - 2026-03-06

<!-- generated by git-cliff -->
</blockquote>


</p></details>

---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).

Co-authored-by: s2-release-plz[bot] <262023388+s2-release-plz[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Detail Bug] SDK Append: enabling compression with NoSideEffects retry policy makes all appends fail preflight

1 participant