Repository navigation
chore: retire the multipart upload token from the staged ledger - #593
Merged
Merged
Conversation
StagedObject.multipart_token and StagedObjectRecord.multipart_upload_id were reserved for a provider multipart path that never existed: every producer set them to None, the lifecycle cleaner refused any request carrying one as ambiguous because no provider exposes a multipart abort, and the Uploading provider state was never written. Now that the owner writes every block with one create, the token has no possible future either. Remove the wire field and its limit, the durable field and its limit, the Uploading state from the registry and the transition tables, the multipart branch from the lifecycle cleanup request, its proof digest and its refusal, and the row key from the Python inspection result; reword the docs. The staged-object record moves to its own value version 8 while the shared publish value version stays at 7: clients seal manifest rows against the shared encoding, and the manifest row did not change. A version 7 staged-object record is refused instead of read with its bytes shifted. Signed-off-by: wchwawa <wch19961116@gmail.com>
Signed-off-by: wchwawa <wch19961116@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TLDR
The multipart upload token leaves the wire, the durable staged-object record, the lifecycle cleaner, the Python inspection rows, and the docs, together with the
Uploadingprovider state that nothing ever wrote. The staged-object record gets its own value version so a store written before this change is refused instead of misread.Problem
StagedObject.multipart_tokenandStagedObjectRecord.multipart_upload_idwere reserved for a provider multipart path that never existed: every producer set them toNone, the lifecycle cleaner refused any request that carried one as ambiguous because no provider exposes a multipart abort, andStagedProviderState::Uploadingwas never written by any code path. Since the owner-mediated upload path landed (#586, the R5 slice of #566), the owner writes every block with one create and the token has no possible future either. This is the legacy cleanup item of R5 under #566; no separate issue exists.Consequences
Every reader of the staged ledger, in Rust, in the Python SDK, in the acceptance gate, and in the schema docs, carried a field and a state that could only be
Noneand never. Validation code, a proof-digest branch, a codec branch, and a refusal path in the cleaner existed to handle values no producer could create, and each new reader had to learn why they were there.Example
Before this change
Client.operation_inspectreturned entries like{"sequence": 0, "object_identity": ..., "expected_length": 4194304, "expected_digest": "sha256:...", "multipart_token": None}and the acceptance gate asserted the last key wasNone; the lifecycle cleaner's proof digest hashed a presence byte for the absent id. After it the entry has the four fields that carry information, the gate checks those, and the proof digest covers the purpose, the key, and the disposition.Solution
Remove the wire field and its size limit from
StagedObject, the durable field and its limit fromStagedObjectRecord, theUploadingstate from the durable provider-state registry and the transition tables, the multipart branch from the lifecycle cleanup request, its proof digest, and its refusal, and the row key from the Python inspection result; reword the docs. The staged-object record now carriesSTAGED_OBJECT_VALUE_FORMAT_VERSION8 while the sharedPUBLISH_VALUE_FORMAT_VERSIONstays at 7, because clients seal manifest rows against the shared encoding and the manifest row did not change.Gain
One fewer field on every staged ledger surface, three dead codec helpers and one dead refusal path gone, and a proof digest and a transition table that describe only states the system can reach. The protocol's fused v15 golden and the record golden change with the encoding, on purpose.
Tradeoffs
A store holding version 7 staged-object records is refused when one is read, which only affects stores written by unreleased builds since the v15 cut, consistent with the decision that format 15 ships without a migrator. The wire change is breaking within the unreleased v15 protocol: a client built before it cannot stage objects against this owner.
Validation
cargo fmt --all -- --checkand CI's five clippy combinations (--workspace --all-targets,nokv-meta/nokv-benchwithmetadata-read-stats,nokv-meta-holtwithread-stats,nokv-serverandnokv-benchwithrestore-crash-test-support), all with-D warningson Rust 1.99.1: clean.cargo teston the touched crates: nokv-types 189, nokv-protocol 74 + 1 doc, nokv-meta 398, nokv-server 229, nokv-client 153, nokv 19 passed, 0 failed;cargo test --workspace --no-fail-fast: every target passed.operation_inspectrows, and no Python test referenced it.