pjfanning opened a new pull request, #3641:
URL: https://github.com/apache/pekko/pull/3641

   ### Motivation
   The Jackson serializers (`serialization-jackson` and 
`serialization-jackson3`) can compress payloads with gzip or lz4. zstd 
compresses nearly as well as gzip while being much faster, so it is a useful 
third option, especially for `jackson-json`, which compresses large payloads by 
default.
   
   ### Modification
   - **New setting:** `compression.algorithm = zstd`, plus 
`compression.zstd-level` (default 3, zstd's default level). The level is 
validated when the serializer is created.
   - **Optional dependency:** zstd-jni is optional, as in #3639: 
`<optional>true</optional>` in the POM and `resolution:=optional` in the OSGi 
`Import-Package`.
     - All zstd-jni calls are in a separate internal `ZstdCompression` object.
     - Configuring `algorithm = zstd` without zstd-jni, or receiving a zstd 
payload without it, fails with an `IllegalArgumentException` naming the missing 
dependency, not a `LinkageError`.
   - **Detection:** zstd payloads are recognised on deserialization by the 
standard zstd frame magic number (`28 B5 2F FD`), whatever `algorithm` is 
configured, like gzip and lz4. No custom header is added.
   - **Decompression bombs:** `compression.max-decompressed-size` applies to 
zstd as well.
     - A frame that declares a decompressed size larger than the limit is 
rejected before anything is allocated.
     - Otherwise the declared size is the capacity of the output, so a frame 
that produces more than it declares fails instead of growing past the checked 
size.
     - Frames that don't declare a size (e.g. written by a streaming 
compressor) are decompressed in chunks and rejected as soon as the output 
passes the limit, like gzip.
   - **Buffer sizing:** the `ByteArrayOutputStream`s used for gzip compression, 
gunzip and the zstd chunked path now start at a size based on the input.
     - Decompression: 4x the compressed size, at least 4 KiB and at most 16 
MiB, and never more than `max-decompressed-size` allows. Before, they started 
at Java's default of 32 bytes.
     - gzip compression: a quarter of the input size, at least 4 KiB. Before, 
it was a fixed 4 KiB.
   - **Docs:** `serialization-jackson.md` covers zstd, adds a dependency 
snippet, and explains how to switch a running cluster to zstd: first roll out 
zstd-jni with the old algorithm, then change `algorithm` in a second rolling 
update.
   
   zstd dictionaries are not supported. They would mainly help small messages, 
but they need every node to share the same dictionaries, which is better 
handled in a follow-up.
   
   ### Result
   Jackson payloads can be compressed with zstd, with the same protection 
against oversized decompression as gzip and lz4.
   
   ### Tests
   - `sbt "serialization-jackson/test" "serialization-jackson3/test"`: passed 
(161 and 159 tests). New tests:
     - compressing large payloads and not compressing small ones;
     - `zstd-level` is used, and an invalid level is rejected;
     - zstd payloads are read whatever the configured algorithm;
     - rejection beyond `max-decompressed-size`, both for declared sizes and 
for frames without one;
     - rejection of a payload that produces more than its declared size;
     - `-1` meaning no limit;
     - buffer sizing bounds;
     - `JacksonWithoutZstdSpec`: gzip works, and zstd use fails clearly, in a 
class loader without zstd-jni.
   - `sbt "serialization-jackson/mimaReportBinaryIssues"`: passed. 
serialization-jackson3 has no MiMa setup, since it hasn't been released yet.
   - `sbt "serialization-jackson/makePom" "serialization-jackson/packageBin"`: 
zstd-jni is optional in the POM and in the OSGi `Import-Package`.
   
   ### References
   Refs #3639 (zstd for Pekko Streams). Both PRs add `zstdJniVersion`/`zstdJni` 
to `project/Dependencies.scala` and `zstd_jni_version` to 
`project/Paradox.scala`, so whichever merges second needs a small rebase.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to