Fix rotating image caching and document direct R2 serving
Some checks failed
Checks / checks (push) Has been cancelled

This commit is contained in:
Matt Isenhower
2026-09-15 21:04:06 -07:00
parent ac53b7e674
commit 0e93b3d427
3 changed files with 33 additions and 2 deletions

View File

@@ -87,7 +87,10 @@ export default class SocialPostBase {
if (filename) {
// Keep the established public URLs; removing X does not require breaking image links.
await this.publicStorage.writeBytes(`twitter-images/${filename}`, image);
// These URLs are overwritten, so caches must revalidate before reusing them.
await this.publicStorage.writeBytes(`twitter-images/${filename}`, image, {
cacheControl: 'no-cache',
});
this.info(`Saved public image as ${filename}`);
}
}

View File

@@ -55,8 +55,12 @@ test('posts to every client, saves the public image, and records the time per cl
assert.deepEqual(bluesky.sent, [{ status: 'Post 1', media: [{ file: IMAGE, type: 'image/png' }] }]);
assert.deepEqual(other.sent, bluesky.sent);
assert.equal(post.images, 1);
const publicImage = await s.publicBucket.get('twitter-images/hourly.png');
assert.equal(publicImage.httpMetadata.cacheControl, 'no-cache');
assert.deepEqual(
new Uint8Array(await (await s.publicBucket.get('twitter-images/hourly.png')).arrayBuffer()),
new Uint8Array(await publicImage.arrayBuffer()),
IMAGE,
);
assert.deepEqual(await json(s.privateBucket, 'bluesky-lastPostTimes.json'), { hourly: 3600 });

View File

@@ -41,6 +41,30 @@ ambiguous outcome; storage cannot make those two external operations atomic.
## Social posts and screenshots
### Public routing and caching
Cloudflare Pages serves the frontend. Cloud Connector serves individual
`/data/`, `/assets/splatnet/`, and `/twitter-images/` files directly from R2
at their original site URLs; do not redirect file requests to the asset host.
Production `/data`, slash-terminated `/data/` directories, and slash-terminated
`/assets/splatnet/` directories redirect to the browser at `assets.splatoon2.ink`.
The asset-browser Worker handles directory listings only.
Cloudflare's `Long-lived immutable media` cache rule uses a one-year edge TTL
for production `/assets/` files (excluding directories and HTML), and image
files under `assets.splatoon2.ink/assets/splatnet/`. The zone's Browser Cache TTL
is **Respect Existing Headers**; the old `/assets/*` Page Rule that forced a
one-month browser TTL is disabled. These settings are managed in Cloudflare,
not Wrangler. Do not add a browser TTL override to obtain longer edge caching.
Rotating public images under `/twitter-images/` reuse their filenames. The
updater writes them with `Cache-Control: no-cache` so caches revalidate before
reuse. Keep them outside the long-lived asset rule. On September 15, 2026,
production routing and cache settings were verified, the existing schedule and
gear PNGs received this metadata, and their old edge-cache entries were purged.
### Posting pipeline
`src/app/social` posts to Bluesky. Twitter/X support and its dependency have
been removed. Local commands are `npm run social` and `npm run social:test`.