openhands
a6cc3cafa9
Gitea Actions Runner Test / test-job (push) Successful in 1s
CI / check (push) Successful in 36s
CI / tests-integration (push) Successful in 1m52s
CI / tests-unit (push) Successful in 1m56s
CI / tests-ui (push) Successful in 2m48s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m27s
fix(catalog): read furnidata from one cache, purge the gamedata edge on write
...
Furniture was not always loading completely because the same file was cached
twice and nobody could reach the client.
The catalog items loader kept its own 30s TTL copy of FurnitureData.json next
to the mtime-validated cache in `furni-data.ts`. An import cleared only the
second one, so the catalog table kept serving pre-import furnidata — empty
descriptions and revisions — until the TTL ran out. The loader now reads
through `readFurniData`, which revalidates on mtime+size and is reset by
every write, so there is exactly one cache and it cannot go stale on its own.
`invalidateFurniDataCache` and its single call site are gone with it.
The client was worse: nginx served all of /gamedata/ with `max-age=604800`,
and the `cms-gamedata` purge that would have fixed it hung off the catalog Git
export, which is disabled in production. A freshly imported item was invisible
in the client for up to seven days no matter how often you imported.
- `writeFurniData` now purges the gamedata edge tag itself. One place covers
import, batch, resync, regen, nitro-editor, translate and dedupe. It is
fire-and-forget and swallowed at every level: a stale edge copy is bounded
by the edge TTL, so a failed purge must never fail an import.
- nginx splits /gamedata/ by how mutable the content is: config/ gets
`max-age=300, must-revalidate`, bundled/ `max-age=3600, must-revalidate`,
and the content-addressed trees (c_images, album*, clothes) keep the long
TTL. `must-revalidate` is the point — the client now revalidates instead of
replaying the old body. All three keep `Cache-Tag: cms-gamedata` so the
purge still reaches them.
- A 30-minute safety-net purge in the jobs worker covers the case where
Cloudflare was unreachable at write time.
2026-10-01 15:16:48 +02:00
..
2026-09-17 21:02:57 +02:00
2026-09-17 21:02:57 +02:00
2026-09-17 21:02:57 +02:00
2026-08-30 21:31:34 +02:00
2026-09-23 14:24:44 +02:00
2026-09-21 18:37:39 +02:00
2026-09-04 13:04:08 +02:00
2026-09-21 18:37:39 +02:00
2026-09-17 21:02:57 +02:00
2026-09-21 18:37:39 +02:00
2026-09-21 18:11:15 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-09-20 12:29:01 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-17 21:02:57 +02:00
2026-09-28 21:55:18 +02:00
2026-09-21 18:37:39 +02:00
2026-09-17 21:02:57 +02:00
2026-09-21 18:37:39 +02:00
2026-09-17 21:02:57 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-17 21:02:57 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-08-30 21:31:34 +02:00
2026-08-30 21:31:34 +02:00
2026-09-17 21:02:57 +02:00
2026-09-28 21:55:18 +02:00
2026-09-21 18:37:39 +02:00
2026-09-21 18:11:15 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-09-28 21:55:18 +02:00
2026-09-21 18:37:39 +02:00
2026-09-20 12:29:01 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-09-28 21:55:18 +02:00
2026-09-21 18:37:39 +02:00
2026-09-17 21:02:57 +02:00
2026-09-17 21:02:57 +02:00
2026-09-17 21:02:57 +02:00
2026-09-17 21:02:57 +02:00
2026-09-28 21:55:18 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-09-17 21:02:57 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-09-17 21:02:57 +02:00
2026-09-21 18:37:39 +02:00
2026-09-17 21:02:57 +02:00
2026-09-17 21:02:57 +02:00
2026-07-31 21:35:05 +02:00
2026-09-13 20:14:32 +02:00
2026-09-21 18:37:39 +02:00
2026-07-31 21:35:05 +02:00
2026-09-21 18:37:39 +02:00
2026-09-09 19:36:15 +02:00
2026-09-17 15:01:23 +02:00
2026-08-27 15:17:54 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-09-17 21:02:57 +02:00
2026-08-30 21:31:34 +02:00
2026-09-17 21:02:57 +02:00
2026-09-30 19:17:20 +02:00
2026-09-30 19:17:20 +02:00
2026-09-30 18:19:36 +02:00
2026-09-06 20:25:19 +02:00
2026-09-21 18:37:39 +02:00
2026-09-09 21:57:56 +02:00
2026-10-01 15:16:48 +02:00
2026-09-21 18:37:39 +02:00
2026-09-09 21:57:56 +02:00
2026-09-21 18:37:39 +02:00
2026-09-09 20:04:10 +02:00
2026-09-29 15:34:36 +02:00
2026-09-21 18:37:39 +02:00
2026-09-17 21:02:57 +02:00
2026-09-21 18:37:39 +02:00
2026-09-20 12:29:01 +02:00
2026-09-21 20:25:58 +02:00
2026-09-03 16:00:32 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-09-11 00:36:55 +02:00
2026-09-10 11:29:28 +02:00
2026-09-21 18:37:39 +02:00
2026-07-31 21:35:05 +02:00
2026-09-21 18:37:39 +02:00
2026-09-03 16:00:32 +02:00
2026-09-21 18:37:39 +02:00
2026-09-09 21:57:56 +02:00
2026-09-21 18:37:39 +02:00
2026-09-30 14:45:26 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-09-17 21:02:57 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-09-03 16:00:32 +02:00
2026-09-21 18:37:39 +02:00
2026-09-17 21:02:57 +02:00
2026-09-21 18:37:39 +02:00
2026-09-03 16:00:32 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-09-11 00:31:29 +02:00
2026-09-21 18:37:39 +02:00
2026-08-01 13:27:59 +02:00
2026-09-21 18:37:39 +02:00
2026-08-01 13:27:59 +02:00
2026-09-21 18:37:39 +02:00
2026-08-01 13:27:59 +02:00
2026-09-21 18:37:39 +02:00
2026-08-01 13:27:59 +02:00
2026-09-21 19:48:31 +02:00
2026-09-21 19:48:31 +02:00
2026-09-21 18:37:39 +02:00
2026-09-03 16:00:32 +02:00
2026-09-13 19:24:43 +02:00
2026-09-13 19:24:43 +02:00
2026-09-21 18:37:39 +02:00
2026-08-29 20:54:06 +02:00
2026-09-21 18:37:39 +02:00
2026-09-13 19:24:43 +02:00
2026-09-21 18:37:39 +02:00
2026-09-21 18:37:39 +02:00
2026-09-03 16:00:32 +02:00
2026-09-21 18:37:39 +02:00
2026-07-31 21:35:05 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-09-13 17:55:01 +02:00
2026-08-31 17:44:29 +02:00
2026-09-18 12:44:39 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00
2026-09-21 18:37:39 +02:00
2026-09-06 17:55:11 +02:00
2026-09-21 18:37:39 +02:00
2026-07-31 21:35:05 +02:00
2026-09-21 18:37:39 +02:00
2026-09-21 18:37:39 +02:00
2026-07-31 21:35:05 +02:00
2026-09-21 18:37:39 +02:00
2026-09-03 16:00:32 +02:00
2026-09-21 18:37:39 +02:00
2026-09-05 23:27:02 +02:00
2026-09-21 18:37:39 +02:00
2026-08-30 21:31:34 +02:00