Skip to content

Write every request from a template - #52

Merged
tiptenbrink merged 14 commits into
masterfrom
prepared-poc
Oct 13, 2026
Merged

tiptenbrink merged 14 commits into
masterfrom
prepared-poc

Conversation

@tiptenbrink

@tiptenbrink tiptenbrink commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

Rather large PR. It tries to simplify the API, making it at the same time less awkward to use but also less safe in the sense that it holds less state and you could theoretically mix different stages of different operations. The idea is to build requests from stuff that doesn't change, to basically do as much work before hand and fill in the final details, using "templates". It also contains various performance optimizations following benchmarks on an old server processor.

The reason why is a combination of trying to reduce the CPU work as much as possible and to make the API a little less awkward (a client over the proto API does not necessarily have less liens of code after this PR, though).

Note that when you do mix up a template, it could cause an error or just a wrong request (which could be bad), but it won't panic (at least, that's the goal, no guarantees here). You can use Template::check to verify if you wan to be sure.

The speedup (which can be something like 1,800 cycles to 650 cycles for an Azure GET) comes mostly from the fact that the template has already done most of the work and a request only fills in key, time and range. You're simply repeating less work.

There is massive API churn, the old clients are all gone as are the "Physical" prefixes and the "plan" language and the "layered" stuff (the latter's idea was stuff you don't have to use but you probably would use, but it never really worked nicely).

Other notes:

  • C ABI crate is rebuilt, still unfinished and only lightly reviewed
  • Thanks to a better benchmark setup and a better model (Opus 5.5), parsing listings is also faster now (up to 30%)

@tiptenbrink
tiptenbrink marked this pull request as ready for review October 13, 2026 08:30
tiptenbrink and others added 14 commits October 13, 2026 23:27
These are the 19 changes of #50, which lists each. S3 signing hashes its canonical form once and keeps its key's HMAC states for the day. Request heads are written in fewer passes and copies, and response heads are read with fewer comparisons.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A template is the part of a request that is the same for each object, written once into a buffer the caller owns. Read tests that object-tests already grades are removed, and the rules each service repeats are shared.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This covers tiers, metadata, properties, tags, snapshots, blocks, copies, uploads in parts and batches. Holes are read by index, and the changelog lists every operation.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A request's pass copies the template's text and fills its holes as straight-line code, and the feature compact walks the table instead. Encoding trusts a template's bytes and never panics on others, and a key with nothing to escape is copied whole.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
An Azure template is stored as 80 bytes that end in a hash, and commit blocks come from any iterator. The C ABI mirrors Rust's container, token and timestamps.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Templates return the shape each operation's response is read against, and Placement holds a request without borrowing its buffer.
S3's error-body functions take the shape as Azure's do, and an Azure HEAD that fails needs no body.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Azure answers a put, commit or copy conditional on `If-None-Match` onto an object that exists with 409 `BlobAlreadyExists`, so each now returns `PreconditionFailed`, as S3's 412 does.
The object-tests host reports the status that Azure sent for a failed copy condition.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Blobs, s3::Objects, LegacyRequest, the Physical* plans, layered and the checksum and SHA-256 providers are gone; the helpers that remain moved to azure and the crate root.
s3::finish is s3::set_signature and sigv4::seal_body is sigv4::hash_body, and the bench builds again against the C ABI.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Error::InvalidPlan, ErrorCode::InvalidPlan and BORINK_ERROR_CODE_INVALID_PLAN are renamed to match, and the docs, the error messages and the C crate's plan module now speak of requests, reads, options and items.
Docs that still named the removed WriteOptions checksum fields are corrected.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
PropertySet and PropertyValues are one generic type with an alias per service, and base64 text is checked against one table of its 64 digits.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Both readers name an element from its first bytes and check an entry's fields as UTF-8 once. They compare close tags without memcmp and return a plain key without decoding it. The bench reads a page from a file and measures a read that keeps every property.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Moves common.rs into validate.rs, head.rs, outcome.rs, request.rs, error.rs and checksum.rs, and listed.rs into properties.rs and types.rs. Adds CapacityError::required_by, which the ureq and object-tests hosts use in place of their own copies.

Makes provider-only items private, replaces super:: and inline crate:: paths with imports, and rewrites the overview of templates.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Both page readers match a group's tags whole, fill an entry's spans where the loop keeps them, and check an absent value without a call.
Fields are checked as UTF-8 from an aligned address, so a short key is read a word at a time. A page of groups reads in about half the time.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@tiptenbrink
tiptenbrink merged commit 8e8eba9 into master Oct 13, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant