scylla-rust-driver icon indicating copy to clipboard operation
scylla-rust-driver copied to clipboard

Proxy: compresssion support

Open wprzytula opened this issue 9 months ago • 4 comments

Motivation

During hackathon, there emerged a need to test compressed communication through proxy. However, proxy did not yet support compression.

What's done

scylla-cql compression utilities

Exposed some scylla-cql compression utilities

These are now used by the proxy.

New impls

  • impl FromStr for Compression
  • impl DeserializableRequest for Startup

The impls are used by the proxy to read the negotiated compression from STARTUP frame.

Minor proxy fixes / features

impl (Partial)Eq for {Request,Response}Frame

It's convenient to be able to compare the whole frame at once.

Fixed some debug prints

Before, they printed the shard number next to the driver, not the node, which was confusing.

Stopped abusing COMPRESSED frame flag in tests randomly

Some tests just set random CQL flags and assert that they are simply passed through the proxy. It used to work, but as now we make the proxy clever enough to interpret at least one of them, namely the compression flag, we needed to stop abusing it blindly.

Combat timing-based flakiness

The test proxy_processes_requests_concurrently showed to be flaky on my machine. As its timeout there was arbitrarily tight, I increased it.

Compression abstractions

CompressionReader and CompressionWriter work in tandem to propagate the compression that the driver negociated with the node (in STARTUP frame) across the proxy connection workers.

  • CompressionWriter is used by the request_processor to set the compression globally for the whole bunch of proxy workers for that connection once a STARTUP message is intercepted.
  • CompressionReader is used by all workers that perform ser/de ({sender_to,receiver_from}_{driver,cluster}) to (de)compress frames as they come. Proxy always stores the frames and feeds them into feedback channels in the decompressed form, so that it is for example possible to use Conditions based on uncompressed body contents.

Unit test for compression mechanisms in the proxy

Outline of the test:

  1. "driver" sends an, uncompressed, e.g., QUERY frame, feedback returns its uncompressed body, and "node" receives the uncompressed frame.
  2. "node" responds with an uncompressed RESULT frame, feedback returns its uncompressed body, and "driver" receives the uncompressed frame.
  3. "driver" sends an uncompressed STARTUP frame, feedback returns its uncompressed body, and "node" receives the uncompressed frame.
  4. "driver" sends a compressed, e.g., QUERY frame, feedback returns its uncompressed body, and "node" receives the compressed frame.
  5. "node" responds with a compressed RESULT frame, feedback returns its uncompressed body, and "driver" receives the compressed frame.

Pre-review checklist

  • [x] I have split my patch into logically separate commits.
  • [x] All commit messages clearly explain what they change and why.
  • [x] I added relevant tests for new features and bug fixes.
  • [x] All commits compile, pass static checks and pass test.
  • [x] PR description sums up the changes and reasons why they should be introduced.
  • [x] I have provided docstrings for the public items that I want to introduce.
  • ~~[ ] I have adjusted the documentation in ./docs/source/.~~
  • ~~[ ] I added appropriate Fixes: annotations to PR description.~~

wprzytula avatar Feb 14 '25 08:02 wprzytula

cargo semver-checks found no API-breaking changes in this PR. Checked commit: d3380a41989126d4d5a1646e1385e8a13174f53a

github-actions[bot] avatar Feb 14 '25 09:02 github-actions[bot]

Is that useful for @fruch 's compression tests?

Lorak-mmk avatar Feb 14 '25 11:02 Lorak-mmk

Is that useful for @fruch 's compression tests?

In my tests I wasn't reading the content, just using the total sizes of frames

I can help as extra validation that it's compressed, and which algorithm was used

fruch avatar Feb 14 '25 12:02 fruch

Is that useful for @fruch 's compression tests?

In my tests I wasn't reading the content, just using the total sizes of frames

I can help as extra validation that it's compressed, and which algorithm was used

Yes: once proxy detects COMPRESSION key in STARTUP frame, it starts to interpret further frames having compression flag set as compressed, and decompresses them automatically using the negotiated compression. So it proxy fails to decompress a frame with an error, then we now that the frame was not compressed even though it should, or it was ill-compressed (perhaps with a wrong compression method).

wprzytula avatar Feb 14 '25 15:02 wprzytula

Rebased on main.

wprzytula avatar Apr 16 '25 06:04 wprzytula

Addressed @muzarski comments. Thanks!

wprzytula avatar Apr 16 '25 07:04 wprzytula