senzzzi opened a new pull request, #817:
URL: https://github.com/apache/arrow-rs-object-store/pull/817

   # Which issue does this PR close?
   
   Closes #281.
   
   # Rationale for this change
   
   `PutPayload` currently only supports collections of `Bytes`. As a result, 
uploading a file through `put` or `put_opts` requires loading the entire file 
into memory or using a multipart upload.
   
   This change allows callers to stream a payload with a known content length 
through a single PUT request. File-backed payloads are a primary use case.
   
   # What changes are included in this PR?
   
   - Extends `PutPayload` to support replayable streaming bodies with a known 
content length.
   - Adds `PutPayload::from_stream` for constructing streaming payloads.
   - Adds `PutPayload::from_file`, which reads files in 16 KiB chunks by 
default.
   - Adds `PutPayload::from_file_with_chunk_size` for configuring the file 
chunk size.
   - Updates HTTP request bodies to poll payload streams asynchronously.
   - Recreates the stream for every request attempt so retryable uploads can 
resend the complete payload.
   - Updates S3 signing and checksum calculation to consume streaming payloads.
   - Updates the local filesystem and in-memory backends to accept streaming 
payloads.
   - Adds regression tests covering:
     - the default 16 KiB file chunk size;
     - replaying cloned streaming request bodies; and
     - retrying an upload using a file-backed streaming payload.
   
   Validation performed:
   
   - `cargo test`
   - `cargo test --all-features`
   - `cargo clippy --all-targets --all-features -- -D warnings`
   - compilation with only the `fs` feature
   - compilation without default features
   
   # Are there any user-facing changes?
   
   Yes. Callers can now upload a file without first loading the complete file 
into memory:
   
   ```rust
   let payload = PutPayload::from_file(file_path).await?;
   store.put(&location, payload).await?;
   ```
   
   Custom streaming payloads can be created with PutPayload::from_stream. The 
stream factory must produce a new stream from the beginning for every 
invocation, and the
   supplied content length must exactly match the number of bytes yielded.
   
   Existing byte-backed PutPayload construction and iteration behavior is 
unchanged. Synchronous APIs such as iter, AsRef<[Bytes]>, and conversion into 
Bytes are not supported for streaming payloads; callers should use 
PutPayload::stream or PutPayload::bytes instead.
   
   ## API compatibility consideration
   
   `PutPayload` remains a public struct backed by a private enum so that 
existing byte-backed construction and usage remain source compatible:
   
   ```rust
   enum PutPayloadInner {
       Bytes(Arc<[Bytes]>),
       Streaming {
           factory: StreamFactory,
           content_length: usize,
       },
   }
   ```
   
   There is an API-design limitation around the existing synchronous accessors. 
Methods and trait implementations such as PutPayload::iter, AsRef<[Bytes]>, 
IntoIterator, and conversion into Bytes cannot synchronously represent an 
asynchronous, fallible stream.
   
   In this implementation, their existing behavior is unchanged for byte-backed 
payloads, but calling them with a streaming payload panics. Streaming-aware 
implementations should instead use PutPayload::stream or PutPayload::bytes.
   
   Changing the existing synchronous APIs to return Option or Result would 
avoid the panic but would be a breaking public API change. Returning an empty 
iterator for streaming payloads was rejected because it could silently result 
in incomplete uploads.
   
   Feedback from maintainers on the preferred long-term API shape would be 
appreciated. Possible alternatives include:
   - accepting the documented limitation for synchronous APIs;
   - changing these APIs in a future breaking release; or
   - introducing streaming uploads through a separate payload type or method.


-- 
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]

Reply via email to