Releases: kserksi/summeRain
Release list
v2.0.4
v2.0.4 - Supervised Worker Shutdown
Development prerelease. This release is published from
dev, may receive
rapid follow-up changes, and is not selected by the defaultlatestimage.
Summary
v2.0.4 gives every worker owned by the backend worker manager a common
supervisor and a coordinated, bounded shutdown path. A worker that panics or
returns unexpectedly is restarted with exponential backoff, while an intended
drain stops new claims, completes bounded cleanup, and never starts replacement
work.
Shutdown now drains request-producing HTTP traffic before worker consumers.
The process first becomes unready, then allows active HTTP requests to finish,
drains workers, applies a hard cancellation when required, and finally closes
Redis and MySQL resources. Listener failures enter the same lifecycle as
SIGINT and SIGTERM instead of terminating through log.Fatalf.
This release does not add a database schema version, change an HTTP or upload
API, or change an image-processing recipe.
Changes
Unified worker supervision
- Runs heartbeat, outbox, V2 publish, V2 cleanup, view flush, cleanup, and user
deletion workers under one named supervisor. - Recovers worker panics and restarts unexpected returns with bounded
exponential delays of 1, 2, 4, 8, 16, and 30 seconds. Further failures remain
capped at 30 seconds. - Logs the failed worker name and original panic value so repeated failures can
be attributed without terminating the entire process. - Keeps
Manager.Start(ctx)blocking until all supervised workers stop and
exposes an idempotent, concurrency-safeBeginDrain()signal. - Interrupts restart waits immediately when either drain or hard cancellation
begins, and never restarts a worker after either stop signal.
Producer-before-consumer shutdown
- Changes
/readyto return HTTP 503 withstatus: drainingas soon as
shutdown begins./healthbehavior is unchanged. - Drains the HTTP server before asking workers to stop claiming work. This lets
in-flight uploads finish creating their durable publish and outbox records
before the consumers perform their final drain. - Waits for workers during a soft-drain phase, then cancels their root context
and waits through a separate hard-stop phase when needed. - Closes Redis and the SQL pool only after worker completion or expiry of the
worker stop budget. - Routes unexpected listener exit through the same shutdown coordinator and
reports shutdown failures without using a fatal logger in the lifecycle path.
Bounded lifecycle budget
- Enforces a 30-second application shutdown budget: up to 18 seconds for HTTP
drain, 5 seconds for worker soft drain, 5 seconds for worker hard stop, and
2 seconds for runtime resource closure. - Increases the Compose backend
stop_grace_periodto 40 seconds, leaving time
for the 30-second application budget and container runtime scheduling. - Bounds final view flushing and lease cleanup with fresh contexts so cleanup
can still run after the normal worker context has been canceled.
Durable publish and outbox leases
- Stops V2 publish and outbox workers from claiming new rows after drain begins
while allowing the currently claimed operation to finish during soft drain. - Releases interrupted publish and outbox claims with a fresh three-second
cleanup context. - Fences every release by lease owner and lease token. Cleanup from an old
worker cannot clear a completed row or a lease acquired by a replacement. - Refunds the claim attempt for orderly cancellation so shutdown alone does not
consume the retry budget. - Preserves the attempt for a publish panic, then rethrows the panic to the
supervisor so deterministic failures can still reach the attempt limit. - On an outbox delivery panic, marks only the active event failed, refunds
untouched claimed events, and rethrows the original panic to the supervisor.
Final view-count flush
- Performs one final view-count flush with a fresh context bounded at three
seconds on either soft drain or hard cancellation. - When an explicit MySQL update error follows Redis
GETDEL, restores the
removed count with a fresh one-second RedisINCRBYcontext instead of
silently dropping it. - Keeps the restore operation inside the five-second worker hard-stop budget.
Continuous integration
- Adds a dedicated lifecycle schema to the pinned MySQL 8.4.10 CI service.
- Adds required real-MySQL coverage for publish lease owner/token fencing,
publish panic release and propagation, and outbox lease owner/token fencing. - Adds supervisor, restart-backoff, drain ordering, lifecycle deadline,
readiness-gate, view-flush, and Compose grace-period unit tests.
Verification
- Real MySQL 8.4 lifecycle schema bootstrap and three lease-cleanup integration
scenarios: passed. - Backend
go test ./... -count=1: passed. - Backend race tests for server lifecycle, workers, and publish service: passed.
- Backend
go vet ./...: passed. - Backend
go build ./...: passed. - Frontend ESLint, Vitest, TypeScript project, and Vite production build: passed.
- Python requirements lock and release-image policy tests: passed.
- GitBook documentation and translation verification: passed after refreshing
translation source hashes for this release. - The existing wasm-vips direct-eval dependency warning remains unchanged and
does not fail the build.
Installation
Development images must be pulled explicitly:
docker pull jaykserks/summerain:dev-v2.0.4Equivalent exact development tag:
jaykserks/summerain:dev-2.0.4
The moving dev tag also points to the newest successful development build.
latest, main, and stable semantic-version aliases are not changed by this
release.
No database migration or API migration is required when upgrading from
v2.0.3. A rolling upgrade is supported, but production operators should pin an
exact image tag or digest rather than the moving dev tag.
Known Limitations
- View counts still cross Redis and MySQL without a transactional or idempotent
ledger. If MySQL commits an update but returns an uncertain error, restoring
the Redis count can apply that count a second time during a later flush. The
new restore path prevents loss for explicit failures; it does not provide
cross-store exactly-once delivery. - Heartbeat and user-deletion workers stop between batches, but every database
operation inside an already running batch is not yet fully context-aware. An
in-flight database call can therefore remain until its driver operation
returns or the process stop deadline is enforced. - Strict configuration parsing and validation remain planned for v2.0.5.
- The supervisor covers only background workers owned by
Manager. Resource-
intensive paths executed inside requests, including legacy V1 AVIF
conversion, are not managed by this supervisor. Their resource admission and
limiting controls remain planned for v2.0.6. - Complete readiness checks for runtime dependencies and worker health remain
planned for v2.0.7. v2.0.4 only makes readiness fail immediately during
shutdown drain. - Animated image support remains planned for a later release.
v2.0.3
v2.0.3 - Fail-Fast Database Bootstrap
Development prerelease. This release is published from
dev, may receive
rapid follow-up changes, and is not selected by the defaultlatestimage.
Summary
v2.0.3 serializes every startup-time MySQL schema and configuration mutation
under one connection-scoped advisory lock. Migration ledger corruption,
missing recorded schema objects, legacy cleanup failures, baseline migration
failures, versioned migration failures, and default-configuration failures now
stop the server before it accepts traffic.
No new checksummed schema version, image-processing recipe, or upload API is
introduced. This release changes how existing bootstrap work is coordinated,
validated, and reported.
Mandatory First-Upgrade Procedure
Stop every backend instance running v2.0.2 or earlier before starting the first
v2.0.3 instance. Do not use a rolling deployment that overlaps old and new
binaries. Older binaries perform legacy cleanup, baseline AutoMigrate, and
configuration seeding outside the advisory lock now owned by v2.0.3.
After one v2.0.3 instance completes database bootstrap successfully, other
v2.0.3 instances may start normally. They serialize through the same
database-scoped lock.
Changes
Serialized startup bootstrap
- Replaced four independent startup calls with one
BootstrapDatabase(ctx, db)entry point. - Reserves one physical SQL connection, acquires the MySQL advisory lock on
that connection, and keeps both through ledger validation, legacy token
cleanup, baseline migration, versioned migrations, and default seeding. - Uses clean GORM sessions for baseline migration and seeding while retaining
the pinned physical connection. - Propagates caller context while waiting for the lock and executing database
work, and uses a bounded cleanup context when releasing the lock. - Returns every stage error to
main; the HTTP server no longer starts after a
partially failed bootstrap.
Migration integrity and recovery
- Validates known versions, version continuity, migration names, and immutable
SHA-256 checksums before destructive legacy work. - Verifies that columns, indexes, tables, and the capacity-lock seed represented
by applied ledger entries still exist. - Keeps pending operations retry-safe when MySQL has committed some DDL but the
corresponding ledger entry was not written. - Documents that MySQL DDL commits implicitly. Bootstrap recovery is based on
serialization, object probes, idempotent operations, and retry rather than a
transaction rollback promise.
Legacy token and configuration compatibility
- Inspects all four legacy access-token columns in one pass and removes every
residual legacy column with oneALTER TABLEstatement. - Deletes incompatible legacy token rows only when
token_hashis still
present. A partially migrated table without that hash keeps modern token
rows while its remaining old columns are removed. - Seeds required configuration with conflict-safe inserts that never overwrite
administrator values and now reports query or insert failures. - Copies the former admin key
image_token_default_ttlto the canonical
private_token_ttl_default_mskey when needed, without overwriting an
existing canonical value. - Corrected the admin web UI to read and write the canonical private-token TTL
key used by the backend.
Continuous integration
- Added a pinned MySQL 8.4.10 service to the backend CI job.
- Added a required real-MySQL bootstrap suite. CI fails instead of silently
skipping the suite when its DSN is missing. - Covers a one-connection pool, repeated bootstrap, full and partial legacy
token states, invalid and inconsistent ledgers, context cancellation,
concurrent starters, retry after partially committed DDL, configuration-key
compatibility, seed failure propagation, and advisory-lock release. - Normalized direct Go dependency declarations without changing dependency
versions.
Verification
- MySQL 8.4.10 bootstrap integration: 9 scenarios passed.
- Backend
go test ./... -count=1: passed. - Backend
go vet ./...: passed. - Backend
go build ./...: passed. - Frontend ESLint: passed.
- Frontend Vitest: 17 test files, 131 tests passed.
- TypeScript project and Vite production build: passed.
- Python requirements lock and release-image policy tests: passed.
- GitBook documentation and translation source-hash verification: passed.
- The existing wasm-vips direct-eval dependency warning remains unchanged and
does not fail the build.
Installation
Development images must be pulled explicitly:
docker pull jaykserks/summerain:dev-v2.0.3Equivalent exact development tag:
jaykserks/summerain:dev-2.0.3
The moving dev tag also points to the newest successful development build.
latest, main, and stable semantic-version aliases are not changed by this
release.
Known Limitations
- Applied-object validation proves that recorded objects exist; it does not
compare every column type, default, index column order, constraint, or table
option with the migration definition. - MySQL DDL cannot be transactionally rolled back by this bootstrap. Correct a
reported failure and restart so idempotent probes can converge the schema. - The advisory-lock wait is bounded at 60 seconds. Large historical DDL may
require an upgrade maintenance window that accommodates startup time. - The legacy
image_token_default_ttlrow is retained for compatibility after
its value is copied. Runtime reads and new admin writes use only the canonical
key. - Animated image support remains planned for a later release.
v2.0.2
v2.0.2 - Durable Browser Upload Recovery
Development prerelease. This release is published from
dev, may receive
rapid follow-up changes, and is not selected by the defaultlatestimage.
Summary
v2.0.2 makes browser upload work recoverable across refreshes, page navigation,
tab closure, and transient network failures. Sources and V2 processing results
are stored in a per-user IndexedDB queue before network side effects begin, and
the client reconciles durable work with server upload-session state when the
upload page is opened again.
There are no database migrations and no server upload-protocol changes in this
release.
Changes
Durable browser queue
- Added an IndexedDB queue keyed by user and queue ID, with the source file,
SHA-256 source fingerprint, processing recipe, attempt number, visibility,
upload-session identity, and retry state stored together. - Requests persistent browser storage on a best-effort basis and checks the
available quota while reserving at least 32 MiB or 10 percent of the quota. - Falls back to a clearly labelled current-tab-only item when durable storage is
unavailable instead of blocking every upload. - Applies a 24-hour retention boundary and lazy expiry cleanup. Completed or
explicitly removed items are deleted immediately when storage is available. - Removes persisted processed derivatives after the server enters processing;
the source remains bounded by completion, explicit removal, or expiry.
Crash-safe V2 upload flow
- Upload-session ID and expiry are durably recorded before the first part PUT.
- Persisted processed WebP parts can be reused after interruption without
decoding and encoding the source again when the recipe still matches. - Refresh, navigation, tab closure, and authentication boundaries abort local
work without implicitly cancelling a recoverable server session. - Only explicit removal requests server-side cancellation.
- Existing idempotency keys remain derived from the queue ID and authoritative
attempt, preventing an interrupted attempt from publishing twice.
Server reconciliation
- Reconciles active queue entries through the batch upload-status endpoint and
recursively isolates missing IDs when the server reports a mixed 4043 batch. - Completes already-published entries locally, resumes non-expired part uploads,
polls sessions already processing, and starts a new idempotent attempt only
when the previous session is missing or expired. - Pauses the queue without destructive state changes when status reconciliation
is temporarily unavailable. - Treats an interrupted legacy V1 request as an unknown, non-retryable outcome
and asks the user to check My Images before removing or uploading it again.
Multi-tab and account isolation
- Added renewable per-run leases and transaction-level ownership checks so only
one tab can mutate a durable queue item at a time. - Manual retries are prepared atomically from the authoritative stored attempt
and upload ID, fencing stale UI state after a lease handoff. - Authentication generation guards stop stale login or profile requests from
restoring a previous account, and login, logout, password change, and remote
authentication events clear queue data outside the active user boundary. - Added localized saving, paused, recovery-ready, current-tab-only, storage, and
legacy-outcome messages in English, Simplified Chinese, and Japanese.
Dependencies
- Added exact runtime dependency
idb8.0.3. - Added exact test dependency
fake-indexeddb6.2.5.
Compatibility and Resource Behavior
- The queue uses IndexedDB, Web Crypto SHA-256, Blob, and File APIs supported by
the V2 browser matrix, including Chromium 93+ and the deployed iOS WebKit 605
family. - Browser image processing remains serial. Queue orchestration admits two items
concurrently and allows at most four active upload sessions in one tab,
leaving capacity for recovery or another tab under the server's per-user
session limit. - Server-side image processing, storage layout, recipe
2.0.0, and fixed WebP
variants are unchanged.
Verification
- Frontend Vitest: 17 test files, 131 tests passed.
- ESLint: passed.
- TypeScript project and Vite production build: passed.
- Python requirements lock verification: passed.
- GitBook documentation and translation source-hash verification: passed.
- The existing wasm-vips dependency direct-eval warning remains unchanged and
does not fail the build.
Installation
Development images must be pulled explicitly:
docker pull jaykserks/summerain:dev-v2.0.2Equivalent exact development tag:
jaykserks/summerain:dev-2.0.2
The moving dev tag also points to the newest successful development build.
latest, main, and stable semantic-version aliases are not changed by this
release.
Known Limitations
- Browsers may evict durable queue data when persistent-storage permission is
not granted; affected entries are labelled as current-tab-only when the
initial durable write fails. - The 24-hour cleanup is lazy and runs when queue storage is accessed, so expired
browser data can remain until the upload page is opened again. - Legacy V1 uploads do not expose a queryable session identity. An interrupted
V1 request therefore requires manual confirmation in My Images. - Animated image support remains planned for a later release.
- Real-device acceptance for the supported Chrome and iOS browser matrix is a
deployment validation step and is not represented by jsdom unit tests.
v2.0.1
v2.0.1 - Browser Processing Preflight
Development prerelease. This release is published from
dev, may receive
rapid follow-up changes, and is not selected by the defaultlatestimage.
Summary
v2.0.1 makes the V2 browser image pipeline fail closed before expensive image
decoding or upload-session creation. Processor selection now uses an actual
wasm-vips and WebP encoder probe instead of relying only on browser features,
and every upload is checked against the complete server recipe before image
processing begins.
There are no database migrations and no server upload-protocol changes in this
release.
Changes
Browser capability negotiation
- Added a shared, time-bounded wasm-vips worker probe that initializes the WASM
runtime, its HEIF/AVIF dynamic library, and the WebP encoder. - Reuses the successfully probed worker for the first image instead of paying a
second initialization cost. - Uses native pica/Canvas only when the decoded dimensions are within the
device-specific safe Canvas budget. - Rejects large images before upload when wasm-vips is unavailable. The client
never sends the original image to the backend as an implicit fallback. - Keeps low-memory devices out of the WASM path while allowing browsers without
navigator.deviceMemoryto prove support through the real worker probe.
Image preflight
- Added a single preflight plan that validates the real container format,
extension and MIME agreement, animation, dimensions, the 50 MP source cap,
the negotiated server pixel limit, and the WebP 16,383-pixel side limit. - Reuses the inspected metadata during processing so the source container is
not parsed twice. - Continues to support static JPEG, JPG, PNG, BMP, WebP, and AVIF inputs.
- Animated PNG, WebP, AVIF, and other animated inputs remain unsupported in V2.
Recipe contract
- Added strict Zod validation for numeric limits and the four required variants:
master,gallery,admin, andpublish_source. - Rejects changed dimensions, quality, fit mode, pipeline version, or recipe
version with a stable client error before processing. - Uses no-store API requests and invalidates failed recipe lookups instead of
retaining a rejected cache entry.
Upload feedback
- Added stable
ClientImageErrorcodes for invalid files, unsupported formats,
animation, dimension limits, processor availability, decode/encode failures,
timeouts, and unsupported recipes. - Added a visible
checkingstage and localized English, Simplified Chinese,
and Japanese row-level errors. - Invalid files are now retained as explicit rejected queue rows instead of
disappearing silently. - Non-retryable capability and input errors no longer display a misleading
retry action or produce a large toast burst during bulk selection.
Compatibility and Resource Behavior
- Images up to the negotiated 50 MP maximum use wasm-vips only after the worker
and WebP encoder pass a real probe. - Canvas fallback remains limited to the calculated 8-16 MP safety budget,
depending on reported device memory. - Image processing remains serial, and each worker is terminated after the
request so decoded pixels and WASM memory cannot accumulate across the queue. - The server still receives only the fixed WebP derivatives defined by recipe
2.0.0.
Verification
- Frontend Vitest: 15 test files, 110 tests passed.
- ESLint: passed.
- TypeScript project build: passed.
- Vite production build: passed.
- The existing wasm-vips dependency direct-eval warning remains unchanged and
does not fail the build.
Installation
Development images must be pulled explicitly:
docker pull jaykserks/summerain:dev-v2.0.1Equivalent exact development tag:
jaykserks/summerain:dev-2.0.1
The moving dev tag also points to the newest successful development build.
latest, main, and stable semantic-version aliases are not changed by this
release.
Known Limitations
- The browser upload queue is not yet persisted. Refreshing, closing, or
navigating away from the upload page interrupts the current queue. - Devices that cannot initialize wasm-vips cannot upload images above their
safe Canvas budget. - Animated image support remains planned for a later release.
- Real-device acceptance for the supported Chrome and iOS browser matrix is a
deployment validation step and is not represented by jsdom unit tests.
v2.0.0
summeRain v2.0.0
Important
v2.0.0 is an early major release. The upload protocol, browser image
pipeline, schema, compatibility behavior, and operational defaults may still
change frequently. Expect frequent patch releases, review every changelog
before upgrading, and pin an exact version or OCI index digest in production.
Back up MySQL and the complete image volume before the first V2 startup.
This release replaces the V1 upload hot path with a resource-aware V2 pipeline
designed for burst uploads of large images on a 3-core, 4 GB host shared with
other services. It keeps existing V1 images readable while moving new Web
uploads toward deterministic client preprocessing, fixed persisted variants,
durable background publishing, and bounded cleanup.
The V1 comparison baseline for this changelog is tag v0.1.0.
Highlights
- Moves expensive decode, resize, format conversion, and compression work from
the server to the browser for new V2 Web uploads. - Persists deterministic WebP variants instead of generating thumbnails on the
first read, eliminating the V1 double-read/double-write hot path for new
images. - Adds resumable, idempotent upload sessions and durable MySQL-backed publish
jobs, cleanup state, storage lineage, and transactional outbox delivery. - Preserves V1 image serving and provides an explicit server-advertised V1
upload fallback for deployments that disable V2. - Adds a bounded deployment profile, disk-pressure admission, finite database
and Redis pools, and incremental cleanup for constrained shared hosts. - Publishes reproducible multi-platform images to Docker Hub and GHCR with a
recoverable, immutable release-tag workflow.
Full Changelog from V1
Browser-side image processing
- Added V2 preprocessing for static JPEG, PNG, BMP, WebP, and AVIF inputs.
- Added signature-based format inspection before decoding, including extension,
MIME, dimensions, empty-file, and animation validation. - Added explicit rejection for animated PNG, WebP, and AVIF files. GIF is not a
V2 upload format. - Enforced a 15 MiB source-file limit and a 50 megapixel source-image limit.
- Added EXIF-aware orientation handling before crop and resize operations.
- Added a dedicated
wasm-vipsworker fast path with HEIF/AVIF decoding,
single-threaded execution, disabled operation caching, and a bounded tracked
cache. - Added a native fallback based on Pica,
ImageBitmap,OffscreenCanvas, and
Canvas 2D. - Added runtime validation that every generated part is a complete WebP
container before it can be uploaded. - Added an eight-minute client-processing timeout, cancellation, and explicit
worker, bitmap, canvas, blob URL, and object URL cleanup.
V2 generates the following deterministic assets:
| Asset | Geometry | Quality | Lifecycle and use |
|---|---|---|---|
master |
Original oriented dimensions | 80 | Persisted full-resolution WebP; owner/admin access |
gallery |
400x400 cover crop | 60 | Persisted My Images and dashboard preview |
admin |
120x160 cover crop | 60 | Persisted Image Management preview, displayed at 60x80 for 2x density |
publish_source |
Aspect-preserving, longest edge at most 2048 | 80 | Temporary upload part used to create publish |
publish |
Derived from publish_source |
Server output | Persisted public/private publishing asset with optional watermark |
- Added SHA-256, byte size, dimensions, quality, processor version, and recipe
version metadata to upload manifests. - V2 does not preserve the original encoded source bytes.
masteris the
full-resolution, quality-80 WebP replacement. - All persisted V2 variants are WebP. AVIF is supported as an input format only.
Resumable upload protocol and browser recovery
- Added the session-based
/api/v1/uploadsAPI for recipe discovery,
initialization, part upload, completion, single and batch status, and
cancellation. - Added required
Idempotency-Keyhandling. The same key and manifest return
the existing session; a different manifest is rejected. - Added durable session states for initialization, transfer, processing,
completion, failure, cancellation, and cleanup pending. - Added all-or-nothing batch status for up to 100 IDs without leaking whether a
missing ID belongs to another user. - Added four-part resumable manifests with strict client/server manifest
matching. - Added byte-accurate XHR progress, two-minute part timeouts, exponential
backoff with jitter, and up to five part attempts. - Added CSRF refresh and replay only for requests explicitly marked idempotent.
- Added best-effort server-session cancellation after browser cancellation or a
terminal part failure. - Added completion recovery that checks durable server state before retrying an
ambiguous completion response. - Added retry classification that can continue polling, reuse the current
attempt, or create a new attempt after terminal or expired state. - Added adaptive publish polling: 2 seconds for the first 30 seconds, 5 seconds
until 2 minutes, and 10 seconds afterward, with a 10-minute deadline. - Browser processing is limited to one image at a time, upload pipelines to
two, and active upload sessions to four. - Part transfer starts at concurrency two and may increase to three on capable,
fast, non-metered connections. - Upload visibility is fixed for the lifetime of an attempt and cannot be
changed while the batch is active. - The client reads
/api/v1/uploads/recipebefore preprocessing. It uses the V1
multipart path only when the server explicitly advertises
v2_enabled=false. - There is no per-file raw-source fallback while V2 is enabled. Browsers that
cannot use either the WASM or bounded native path receive a clear error.
Backend upload validation and immutable storage
- Streams each part directly to staging while computing SHA-256 and validating
byte length, RIFF/WebP structure, dimensions, and animation in one pass. - Rejects truncated containers, forged RIFF sizes, trailing bytes, unexpected
geometry, hash mismatch, invalid MIME/recipe fields, and animated WebP parts. - Avoids loading complete V2 parts into Go memory and avoids a second staging
read solely for format validation. - Promotes
master,gallery, andadmininto immutable content-addressed
storage and verifies the identity of an already existing target before reuse. - Keeps expensive target prevalidation outside the process-level capacity gate
while retaining serialized transaction and promotion control. - Makes completion idempotent and commits the image, fixed variants, quota
accounting, publish job, and processing event as one durable transition. - Deletes
publish_sourceand the upload staging directory after successful
publish. Upload intermediates are not retained as user-visible assets.
Durable publishing and watermarks
- Added asynchronous MySQL-backed publish jobs with priority, retry limits,
leases, renewal, fencing tokens, and expired-worker recovery. - Prevents a worker that lost its lease from committing or recreating a stale
result. - Adds compensating cleanup for exhausted terminal jobs instead of leaving an
image indefinitely half-published. - Snapshots watermark configuration when completion creates the publish job, so
later configuration changes do not alter an already queued image. - Applies the server-side watermark only to the final
publishasset. Client
generatedmaster,gallery, andadminremain unwatermarked. - Uses atomic watermark replacement, process-local locking, filesystem
flock,
and a recovery journal. - Allows jobs with the same watermark snapshot to run concurrently; historical
snapshots are serialized while the active SVG is safely swapped and restored. - Defaults V2 publishing and imgproxy to two workers each, with a documented
one-worker fallback for more constrained or contended hosts.
Fixed serving routes and V1 compatibility
- Added fixed V2 routes:
/i/<asset_link>.webp/i/<asset_link>/master.webp/i/<asset_link>/gallery.webp/i/<asset_link>/admin.webp/i/<asset_link>/publish.webp
- Query parameters do not generate additional V2 sizes or formats.
masterandadminrequire owner or administrator authorization. Private
galleryandpublishassets retain normal private-image authorization.- Existing V1 images remain readable through their original short links.
- V1 dynamic format, width, height, and quality parameters remain available,
with dimensions capped at 4096. - Existing no-size WebP files and background AVIF outputs may remain persisted.
Arbitrary V1 transformations now use bounded temporary files and are deleted
after the final waiting response finishes. - Concurrent requests for the same V1 transformation share one imgproxy job.
- V1 dynamic generation is limited to two active transformations and four
queued transformation keys; excess work returns a retryable busy response. - Background V1 AVIF generation is limited to one operation, enforces a response
cap, and uses temporary-file plus atomic-rename persistence. - With V2 enabled, legacy
POST /api/v1/images/returns4262. Setting
V2_UPLOAD_ENABLED=falsere-enables the V1 multipart upload endpoint.
Image UI and administration
- Added separate queue states for local processing, transfer, and server-side
publication. - Replaced raw-source previews with previews from the processed
galleryblob. - Added per-file retry, batch retry, cancellation on page exit, and deterministic
object URL cleanup. - Changed the upload completion action to copy fixed Markdown containing V2 WebP
publish links. - Removed the upload-page combinations for arbitrary URL/Markdown/BBCode/HTML
and original/WebP/AVIF output. - My Images and dashboard previews now use
galleryfor V2 images. - Image Management uses
adminat 60x80 CSS pixels andmasterfor zooming. - V2 details e...
v0.1.0
Full Changelog: https://github.com/kserksi/summeRain/commits/v0.1.0