Skip to content

feat: announce stored images on NATS, stop overwriting rewritten objects - #18

Merged
bludot merged 1 commit into
mainfrom
feat/image-stored-events
Oct 5, 2026
Merged

bludot merged 1 commit into
mainfrom
feat/image-stored-events

Conversation

@bludot

@bludot bludot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

What

  • image-stored announcements. After an object is written, a StoredEvent (path, type, id, source_url, size, content_type) is published on NATS_STORED_SUBJECT, default image-stored, over the same NATS connection the consumer already holds. upscaler-service consumes it to upscale what needs it. A failed publish is a warning, never a failed message: the image is stored regardless, and the consumer may not be deployed yet.
  • Real content types. Objects were written as application/octet-stream; they now carry what http.DetectContentType finds (image/jpeg, image/png, image/webp).
  • The skip rule compares the source, not the object. The stored object records the source's byte length as metadata (source-length, plus source-url), and unchanged compares that with the source's Content-Length. The old rule compared the object's own size, which meant any rewrite of the object looked like new artwork: an upscaled poster is bigger than its source and was overwritten with the 225px original on the next event. Objects written before the metadata existed fall back to their own size, so untouched downloads are still skipped.

Storage gains Head (size plus metadata) and PutObject (content type plus metadata); Put/Stat stay. NewImageProcessor takes the publisher; the Kafka handler passes nil.

Checked

New processor tests with an in-memory store and an httptest source: content type and metadata on store; the overwrite regression (object rewritten bigger, same source length, second event does not re-download or re-announce); a genuinely longer source is fetched again; a legacy object with no metadata and the same size is skipped; a failing announcement does not fail the store.

Deploy

Needs a image-stored stream (plus -retry/-dlq) in weeb-argocd's nats-streams, coming in the upscaler-service deploy PR. Until the stream exists each stored image logs one warning.

🤖 Generated with Claude Code

…objects

Every stored object now goes out as a StoredEvent on NATS_STORED_SUBJECT
(default image-stored): path, type, id, source URL, size and content type.
upscaler-service consumes it. A failed announcement is logged, not fatal;
the image is stored either way.

Objects are written with their real content type instead of octet-stream,
and with the source's byte length recorded as metadata. The skip rule now
compares that recorded length with the source's Content-Length. Comparing
the object's own size broke the moment anything rewrote the object: an
upscaled poster is bigger than its source, looked changed, and was
overwritten with the 225px original on the next event. Objects written
before the metadata existed still fall back to their own size.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@bludot
bludot merged commit 4ac28a9 into main Oct 5, 2026
2 checks passed
@bludot
bludot deleted the feat/image-stored-events branch October 5, 2026 12:18
@bludot

bludot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor Author

🎉 This PR is included in version 1.19.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@bludot bludot added the released label Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant