scylla-rust-driver
scylla-rust-driver copied to clipboard
Proxy: compresssion support
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 Compressionimpl 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.
CompressionWriteris used by therequest_processorto set the compression globally for the whole bunch of proxy workers for that connection once a STARTUP message is intercepted.CompressionReaderis 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 useConditions based on uncompressed body contents.
Unit test for compression mechanisms in the proxy
Outline of the test:
- "driver" sends an, uncompressed, e.g., QUERY frame, feedback returns its uncompressed body, and "node" receives the uncompressed frame.
- "node" responds with an uncompressed RESULT frame, feedback returns its uncompressed body, and "driver" receives the uncompressed frame.
- "driver" sends an uncompressed STARTUP frame, feedback returns its uncompressed body, and "node" receives the uncompressed frame.
- "driver" sends a compressed, e.g., QUERY frame, feedback returns its uncompressed body, and "node" receives the compressed frame.
- "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.~~
cargo semver-checks found no API-breaking changes in this PR.
Checked commit: d3380a41989126d4d5a1646e1385e8a13174f53a
Is that useful for @fruch 's compression tests?
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
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).
Rebased on main.
Addressed @muzarski comments. Thanks!