Skip to content

docs(release): start the 1.5.0 upgrade guide with the storage module - #49

Merged
herbie-bot merged 1 commit into
mainfrom
docs/release-1.5
Sep 25, 2026
Merged

herbie-bot merged 1 commit into
mainfrom
docs/release-1.5

Conversation

@herbie-bot

Copy link
Copy Markdown
Collaborator

Starts docs/releases/upgrade-to-1.5.md in the same shape as the previous guides — a self-contained prompt an agent can run inside a consumer repo. Marked as a draft, since 1.5.0 is unreleased; further sections land with the features they describe.

What it covers

The one consumer-facing change 1.5.0 carries so far: the optional spring-services-storage module. Dependency, the openelements.storage.type choice and its three property blocks, the ObjectStore surface, and the guard rails.

The other three commits on main since v1.4.0 (<url> POM fix, PomChecker CI guard, PomChecker version pin) have no consumer-facing effect and are deliberately not in the guide.

Guard rails worth highlighting

Most came out of reading the implementations rather than the interface:

  • Nothing schedules abortIncompleteUploadsOlderThan. An interrupted upload leaves a multipart upload that list cannot see — because S3 does not list them either — and that S3 still bills for.
  • Keys are not equally portable: opaque strings on S3, validated paths in the file store. A key that works against one can be rejected by the other.
  • The file store ignores contentType by design; the application keeps it.
  • No transaction integration — a written object is not rolled back with the surrounding database transaction.
  • The S3 store allocates one 8 MiB buffer per in-flight put regardless of payload size, so concurrency and not object size sets the memory ceiling.
  • A maturity note: the implementations themselves are not yet covered by tests in this library.

One finding, recorded rather than documented

Writing the guard rails surfaced a contract violation between the two real implementations, added to docs/TODO.md:

ObjectStore#get(String, long, long) documents that a range past the end returns the available bytes rather than failing. FileObjectStore does that. S3ObjectStore catches only NoSuchKeyException, so a first-byte position at or past the object's length surfaces as a raw S3Exception (HTTP 416) — not even wrapped as ObjectStoreException. Next to it: for length == 0 the file store throws ObjectNotFoundException for a missing key while the S3 store returns an empty stream without checking.

Two backends behind one interface must not answer the same call differently. It is marked fix before 1.5.0 ships — the module is new in this release, so correcting it costs nothing — which is why the guide does not document the divergence as behaviour.

(The 416 reading comes from the standard range semantics and the code path, not from a run against a live endpoint.)

🤖 Generated with Claude Code

Adds docs/releases/upgrade-to-1.5.md in the shape of the previous
upgrade guides — a self-contained prompt an agent can run inside a
consumer repo — covering the one consumer-facing change 1.5.0 carries so
far. Marked as a draft, since 1.5.0 is unreleased and further sections
will land with the features they describe.

Writing the guard-rails section surfaced a contract violation between the
two real implementations; recorded in docs/TODO.md as a fix that should
land before 1.5.0 ships rather than being documented as behaviour.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@herbie-bot
herbie-bot merged commit f5fd651 into main Sep 25, 2026
1 check passed
@herbie-bot
herbie-bot deleted the docs/release-1.5 branch September 25, 2026 07:44
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.

2 participants