Check cached sources with upstream after the cache TTL (closes #69)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
Cached images were served until eviction, so upstream changes were missed. After 24 hours a request checks the source with upstream, sending its stored ETag and Last-Modified. A 304 renews it with no download or conversion. New bytes replace it; older variants are converted again. A failed check serves the cached image and puts the URL in the negative cache. Images not checked for 30 days are evicted. Variant rows keep the source's ETag and Last-Modified for checking a variant of an evicted source. A variant file's modification time is its source's check time when it was made or renewed. Hits read it without a database call. The ETag includes it, so new bytes get a new ETag. Model: opus-5-5
This commit is contained in:
1 parent
b3b8408d18
commit
445ff628fd
29 files changed
+1709
-269
No files matched your search
@@ -6,8 +6,9 @@ results.
|
||||
|
||||
A web page asks pixa for an image at a size and in a format. pixa fetches the
|
||||
original image, makes the requested image from it, and serves that. It keeps
|
||||
both on disk. Later requests for the same image are served from disk, without a
|
||||
fetch or a conversion.
|
||||
both on disk. Later requests for the same image are served from disk. After 24
|
||||
hours pixa first asks the server that holds the original whether it changed (see
|
||||
Cache TTL).
|
||||
|
||||
In this document, the upstream host is the server that holds an original image.
|
||||
|
||||
@@ -232,8 +233,8 @@ These terms are the names the code uses:
|
||||
- **Variant**: the image pixa serves for an image request, made from its source
|
||||
with its transform.
|
||||
- **Variant key**: the SHA-256 hash of a variant's source, size, format, quality
|
||||
and fit. It names the variant's file and its row in the database, and gives
|
||||
its `ETag`.
|
||||
and fit. It names the variant's file and its row in the database. The
|
||||
variant's `ETag` is made from it and the file's modification time.
|
||||
- **Signed URL**: a `/v1/image/` URL whose `sig` parameter signs its image
|
||||
request and its expiry `exp` with `signing_key`.
|
||||
- **Encrypted URL**: a `/v1/e/` URL whose token holds its image request and any
|
||||
@@ -244,9 +245,12 @@ These terms are the names the code uses:
|
||||
after a fetch failed in one of these ways:
|
||||
- the upstream answered with an error status;
|
||||
- the body's first bytes were not those of the format its `Content-Type`
|
||||
names.
|
||||
names;
|
||||
- a check of a cached image failed in any way (see Cache TTL).
|
||||
- **Image cache**: the part of pixa that keeps the sources, the variants and the
|
||||
negative cache (see Storage).
|
||||
- **Cache TTL**: how long pixa uses a cached source and serves its variants
|
||||
before it checks the source with upstream again: 24 hours (see Cache TTL).
|
||||
- **Disk cache limit** (`cache_max_bytes`): the size in bytes that the cached
|
||||
sources and variants may reach together.
|
||||
- **Image proxy**: the part of pixa that serves a variant from the image cache
|
||||
@@ -517,8 +521,10 @@ seconds left until then, at most one year. So no browser or proxy cache keeps
|
||||
the image after pixa would refuse the URL. A URL with no expiry gets one year.
|
||||
`immutable` only stops a client revalidating while its copy is fresh. The
|
||||
response also carries `X-Pixa-Cache`: `HIT` for an image served from the cache,
|
||||
and `MISS` for one made for this request. The `ETag` is the first 16 characters
|
||||
of the variant key, in quotes.
|
||||
and `MISS` for one made for this request or older than 24 hours (see Cache TTL).
|
||||
The `ETag` is made from the first 16 characters of the variant key and the
|
||||
variant file's modification time (see Cache TTL). So a variant made again from a
|
||||
changed source gets a new `ETag`.
|
||||
|
||||
### Signed URLs
|
||||
|
||||
@@ -824,10 +830,17 @@ and `state.sqlite3-shm` beside the file while pixa runs.
|
||||
|
||||
The image cache keeps these tables in the database:
|
||||
|
||||
- `source_content`: a row for each source, by source key, with its size and when
|
||||
it was last used
|
||||
- `source_content`: a row for each source, by source key, with:
|
||||
- its size and when it was last used
|
||||
- when it was fetched, and when upstream last sent it or confirmed it
|
||||
unchanged
|
||||
- the `ETag` and `Last-Modified` headers upstream sent with it
|
||||
- `variant_content`: a row for each variant, by variant key (column
|
||||
`cache_key`), with its size and when it was last used
|
||||
`cache_key`), with:
|
||||
- its size and when it was last used
|
||||
- its source's check time when the variant was made or last renewed
|
||||
- the `ETag` and `Last-Modified` headers upstream sent with the source it
|
||||
was made from
|
||||
- `cache_usage`: the total size of the cached sources and variants, which
|
||||
eviction reads
|
||||
- `negative_cache`: a row for each source URL in the negative cache, with when
|
||||
@@ -881,6 +894,48 @@ within `cache_max_bytes`. It runs after each store, and every five minutes. It
|
||||
also removes the expired rows of the negative cache every five minutes, at most
|
||||
1000 per statement, so a request waits behind 1000 deletions at most.
|
||||
|
||||
### Cache TTL
|
||||
|
||||
pixa uses a cached source for 24 hours after upstream last sent it or confirmed
|
||||
it unchanged. During that time it serves the source's variants from the cache.
|
||||
After that, the next request for an image of that source checks the source with
|
||||
upstream first:
|
||||
|
||||
- pixa asks upstream to send the source only if it changed. It sends the
|
||||
source's `ETag` as `If-None-Match` and its `Last-Modified` as
|
||||
`If-Modified-Since`, when upstream gave them. With neither, upstream sends the
|
||||
whole image again.
|
||||
- When upstream answers 304 Not Modified, pixa uses the cached source and serves
|
||||
its variants for another 24 hours. Nothing is downloaded or converted again.
|
||||
- When upstream sends the image, it replaces the cached source. Each variant
|
||||
made from the old image is converted again from the new one when it is next
|
||||
requested.
|
||||
- When the check fails, pixa serves the cached image. A failure can be an error
|
||||
status, a timeout or no connection. The failure puts the source URL in the
|
||||
negative cache, so pixa does not ask upstream again for 5 minutes, however
|
||||
often it serves the image.
|
||||
|
||||
pixa evicts a source and its variants 30 days after upstream last sent the
|
||||
source or confirmed it unchanged. So pixa uses a source whose checks keep
|
||||
failing for at most 30 days. Eviction to stay under the disk cache limit can
|
||||
remove images sooner.
|
||||
|
||||
That eviction can remove a source and keep its variants. Each variant's row
|
||||
keeps the `ETag` and `Last-Modified` of the source it was made from. So pixa
|
||||
checks such a variant with upstream in the same way after 24 hours:
|
||||
|
||||
- When upstream answers 304 Not Modified, pixa serves the cached variant for
|
||||
another 24 hours. Nothing is downloaded or converted again.
|
||||
- When upstream sends the image, pixa caches it as the source and converts the
|
||||
variant again.
|
||||
- When the check fails, pixa serves the cached variant and puts the source URL
|
||||
in the negative cache.
|
||||
|
||||
A variant file's modification time is its source's check time when the variant
|
||||
was made or last renewed. So a cache hit reads no database row to know whether
|
||||
the variant is older than 24 hours. A request that checks its source with
|
||||
upstream counts as a miss.
|
||||
|
||||
### Configuration
|
||||
|
||||
Every setting can be given as an environment variable, in a config file
|
||||
|
||||
Reference in new issue
Block a user