Repository navigation
Conversation
|
There is more rationale for non streaming APIs here:
TLDR is that streaming writes make a bunch of other operations (like retry , error handling, etc) |
|
I see you have talked about multi-part uploads here: #281 (comment) |
It's not the same because of costs. Uploading a 64Mb file in a single put request is still quite fast (depending on your needs) and you are charged for 1 request. If you upload 64 different 1Mb parts, you are charged by the initial request, 64 parts individually and 1 final requests. So it's 66 times more expensive. You can check the link in this comment: #281 (comment) |
tustvold
left a comment
There was a problem hiding this comment.
I think the idea is a good one, but as Andrew says we need to think about how retries, etc... would work
| fn clone(&self) -> Self { | ||
| Self { | ||
| payload: self.payload.clone(), | ||
| stream: None, |
There was a problem hiding this comment.
This would likely be rather limiting in practice as it would break retries in client implementations
|
There is a bunch more discussion on #281 now too |
* refactor: 開源前清理註解:SQL migration、Cargo 設定檔,並移除本 repo 的 issue 編號 - migration SQL 的註解第一次整理:165 個檔、約 3100 行,AI 句型密度 104 → 19(每千行),破折號 175 → 0 - Cargo.toml、deny.toml、clippy.toml、rustfmt.toml、.cargo/config.toml 的註解一併整理,破折號 0 - 移除註解中所有指向本 repo 的 issue/PR 編號(開源會是新 repo,這些編號會失效或指錯);外部專案引用改成完整寫法 apache/arrow-rs-object-store#817 - apps/server/Cargo.toml 幾段疊在一起的說明拆回各自的依賴(takumi、html5ever、http-body-util) - 過時說法:tests/shares.rs 寫「沒有東西會寫 disabled_at」,現在掃毒會寫 - tests/oauth.rs id_of 的 doc 被擠掉,補回 - #423 之後新增的 Rust 註解比照前幾輪整理 - 重新產生 openapi.json 與 contract 快照 * docs: 重新產生資料表文件(migration 註解變動) --------- Co-authored-by: sao-coding <58339015+sao-coding@users.noreply.github.com>


Which issue does this PR close?
Closes #281.
Rationale for this change
PutPayloadcurrently only supports collections ofBytes. As a result, uploading a file throughputorput_optsrequires 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?
PutPayloadto support replayable streaming bodies with a known content length.PutPayload::from_streamfor constructing streaming payloads.PutPayload::from_file, which reads files in 16 KiB chunks by default.PutPayload::from_file_with_chunk_sizefor configuring the file chunk size.Validation performed:
cargo testcargo test --all-featurescargo clippy --all-targets --all-features -- -D warningsfsfeatureAre there any user-facing changes?
Yes. Callers can now upload a file without first loading the complete file into memory:
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
PutPayloadremains a public struct backed by a private enum so that existing byte-backed construction and usage remain source compatible: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: