mirror of
https://github.com/tiennm99/rplace.git
synced 2026-10-11 03:13:48 +00:00
feat(canvas): migrate canvas + cooldown storage to DO SQLite
Move pixel state and rate-limit cooldowns out of Upstash Redis and into the existing CanvasRoom Durable Object's SQLite-backed storage. Worker becomes a thin validation/proxy; the DO does atomic cooldown check + pixel write + WS broadcast in one in-memory step. Why: eliminate external dependency, keep $0/month free-tier forever, exploit single-threaded actor for strong consistency without round-trips. Architecture: - canvas_chunks: 256 BLOB rows × 64 KB; CHUNK_COUNT derived from CANVAS_WIDTH × CANVAS_HEIGHT / CHUNK_BYTES so resize is config-only. - cooldowns: user_id → expires_at, 1% sample-rate lazy GC. - Worker forwards /api/canvas, /api/place, /api/ws to DO endpoints. - POST /admin/migrate-from-upstash: token-gated one-shot importer. Phases 1-3 code complete; Upstash dependency stays until prod migration runs and 7-day rollback window passes (Phase 4). Plan: plans/260509-2309-canvas-on-do-storage/
This commit is contained in:
1 parent
e042748b41
commit
c3f7c02f6d
19 files changed
+1688
-119
No files matched your search
@@ -0,0 +1,51 @@
|
||||
# Canvas Resize Procedure
|
||||
|
||||
The canvas dimensions are driven by two constants. Storage chunks auto-derive,
|
||||
so resizing is a config change followed by a redeploy — no migration code
|
||||
needed.
|
||||
|
||||
## Steps
|
||||
|
||||
1. Edit `src/lib/constants.js`:
|
||||
|
||||
```js
|
||||
export const CANVAS_WIDTH = 8192; // was 4096
|
||||
export const CANVAS_HEIGHT = 8192; // was 4096
|
||||
```
|
||||
|
||||
`TOTAL_PIXELS` and `CHUNK_COUNT` recompute automatically. Bumping to
|
||||
`8192×8192` raises `CHUNK_COUNT` from 256 to 1024 (still well under the
|
||||
1 GB single-DO limit, which would allow ~32K×32K).
|
||||
|
||||
2. Build and deploy:
|
||||
|
||||
```bash
|
||||
npm run deploy
|
||||
```
|
||||
|
||||
3. The DO lazy-initializes any missing chunks on the next read. New
|
||||
bytes are zero-filled (palette index 0 — pure black). Existing pixels
|
||||
keep their `(x, y)` coordinates; the canvas just becomes larger around
|
||||
them.
|
||||
|
||||
## Caveats
|
||||
|
||||
- **Shrinking** the canvas leaves orphan chunk rows past the new
|
||||
`CHUNK_COUNT`. Existing reads are unaffected (they only iterate up to
|
||||
the new limit), but storage usage stays high until they're cleaned up.
|
||||
To reclaim: connect to the DO and run
|
||||
`DELETE FROM canvas_chunks WHERE chunk_id >= NEW_CHUNK_COUNT`.
|
||||
- **Aspect ratio change** (non-square) is fine. The 1-D byte-layout
|
||||
(`y * CANVAS_WIDTH + x`) still holds. Just make sure clients pull
|
||||
the new constants too — frontend reads them from the same module.
|
||||
- **Storage cap.** SQLite-backed DO storage is 1 GB on the Free plan.
|
||||
A 1-byte-per-pixel canvas fits up to roughly **32,768 × 32,768**
|
||||
before hitting that ceiling.
|
||||
|
||||
## Free-tier monitoring
|
||||
|
||||
After resize, watch:
|
||||
- Cloudflare Workers requests/day (free cap: 100,000)
|
||||
- Durable Object storage size (free cap: 1 GB per DO)
|
||||
|
||||
Both visible on the Cloudflare dashboard for the rplace project.
|
||||
Reference in new issue
Block a user