Skip to content

refactor: replace soketto with yawc for per-message deflate support - #1627

Open
ifdario wants to merge 1 commit into
paritytech:masterfrom
infinitefield:master
Open

refactor: replace soketto with yawc for per-message deflate support#1627
ifdario wants to merge 1 commit into
paritytech:masterfrom
infinitefield:master

Conversation

@ifdario

@ifdario ifdario commented Feb 13, 2026

Copy link
Copy Markdown

Migrate from soketto to yawc across the entire codebase (server, client transport, ws-client, test-utils). yawc provides RFC 7692 permessage-deflate compression with balanced compression enabled by default, near-zero-copy frame processing, and SIMD-optimized masking.

Key changes:

  • Replace soketto handshake/connection with yawc WebSocket::upgrade (server) and WebSocket::handshake_with_request (client)
  • Remove tokio-util compat layer (yawc uses tokio I/O natively)
  • Add configurable WsOptions (compression level, payload limits) to ServerConfigBuilder, WsTransportClientBuilder, and WsClientBuilder
  • Re-export DeflateOptions and WsOptions from server and client crates
  • Update test mocks to use yawc with safe Arc<Mutex> pattern
  • Adapt max request body size test for yawc's connection-terminating behavior on oversized payloads

Migrate from soketto to yawc across the entire codebase (server, client
transport, ws-client, test-utils). yawc provides RFC 7692
permessage-deflate compression with balanced compression enabled by
default, near-zero-copy frame processing, and SIMD-optimized masking.

Key changes:
- Replace soketto handshake/connection with yawc WebSocket::upgrade
  (server) and WebSocket::handshake_with_request (client)
- Remove tokio-util compat layer (yawc uses tokio I/O natively)
- Add configurable WsOptions (compression level, payload limits) to
  ServerConfigBuilder, WsTransportClientBuilder, and WsClientBuilder
- Re-export DeflateOptions and WsOptions from server and client crates
- Update test mocks to use yawc with safe Arc<Mutex<Option>> pattern
- Adapt max request body size test for yawc's connection-terminating
  behavior on oversized payloads
@ifdario
ifdario requested a review from a team February 13, 2026 09:16
@jsdw

jsdw commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

Thankyou for your PR. For full context, I can see that yawc is a library that you authored or at least contribute heavily too, and that you've opened several similar PRs. I appreciate the graft!

That said, while I'm curious to see how far this PR would get on our CI run, we don't have much capacity for reviewing such a change (especially as we don't require it for the current jsonrpsee use cases), and we also own soketto and have the internal knowledge to fix and tweak it as needed. Thus, while I am curious, I would not hold your breath re this being merged and if it is, it may take a while! :)

@ifdario

ifdario commented Feb 18, 2026

Copy link
Copy Markdown
Author

Hello @jsdw

I have been planning this PRs for quite some time, waiting for yawc to be stable enough. I consider that yawc has reached this point.
yawc is quite curated and it has been battle tested. Passes all autobahn tests and many other thorough tests. It is design with easy fixability (is that a word?) in mind. Also the library is pretty much organized in simple components that work independently with sans-io design in mind.
Having said that, the main purpose I performed all of this PRs is the services I use (vector and nanoreth) they both use websocket libraries that generally do not support compression. In your case, I see soketto does. The main difference between our crates being yawc supports compression written fully in Rust. Among other features, yawc also supports streaming, stream-decompression, full-duplex concurrency (through Sink/StreamExt traits) and simd masking. Also, if it is of any interest, wasm too.

Feel free to leave the PR open if you see no use case or you would like to leave it for the future.

@niklasad1

Copy link
Copy Markdown
Contributor

Would be cool if you could run the benchmarks on this branch and compare to master, it seems that you don't have any benches against soketto in yawc.

Nice that all tests passes but it's up to @jsdw to decide as the solo maintainer of jsonrpsee these days 😀

@loyd

loyd commented Apr 29, 2026

Copy link
Copy Markdown

I've tried this yawc-based implementation (without performance comparison yet); it works pretty stably, including compression. Soketto looks abandoned: the last changes were made 2 years ago, and critical compression issues have persisted there for years (paritytech/soketto#49).

However, I don't think maintainers will replace the implementation, since Soketto is developed by the same org. So, this is a conflict of interest.

Comment thread server/src/server.rs
/// let ws_opts = WsOptions::default().with_high_compression();
/// let builder = ServerConfigBuilder::default().set_ws_options(ws_opts);
/// ```
pub fn set_ws_options(mut self, options: yawc::Options) -> Self {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a leaky abstraction:

  1. If yawc is updated (it's still v0.x), it will affect the version of jsonrpsee. For instance, this yawc::Options is not even non_exhaustive, so even adding a new option is a breaking change (raising questions about the current state of yawc API).
  2. It makes it more complicated to switch backend or support a new one.

I can't say that jsonrpsee is a well-designed API, quite the opposite. But it would be great to avoid unfounded breaking changes in the future

Comment thread server/src/tests/ws.rs
let response = client.send_request_text(req).await.unwrap();
let response = client2.send_request_text(req).await.unwrap();
assert_eq!(response, ok_response(JsonValue::String("a".repeat(100)), Id::Num(1)));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread server/src/server.rs

/// Set custom WebSocket options such as compression settings.
///
/// By default, balanced compression is enabled. The `max_payload_read` setting

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By default, balanced compression is enabled

I think custom Options can have this in the Default instance instead of .unwrap_or() handling in the code.

Comment thread server/src/server.rs

/// Set custom WebSocket options such as compression settings.
///
/// By default, balanced compression is enabled. The `max_payload_read` setting

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from these options will be overridden by [ServerConfigBuilder::max_request_body_size].

... which is set by default. One more point that it shouldn't accept yawc::Options directly

@jsdw

jsdw commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Apologies; I am leaving Parity myself tomorrow and so will pass on mention of these PRs internally and hopefully somebody else can pick them up!

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.

4 participants