You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit e461d47
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: packages/remote-cache/README.md
+9-9Lines changed: 9 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,19 +8,19 @@ The package contains no `vp run` client adapter. Cache keys, values, and blobs r
8
8
9
9
The endpoint is `https://<host>/projects/<namespace>`. Namespaces use 1–63 lowercase letters, digits, or hyphens, starting with a letter or digit. An operator can register up to 100 namespaces per deployment.
`/store` requires one `metadata` part with content type `application/cbor` and fields `{ key: bytes, secondary_key: bytes, value: bytes }`. An optional `blob` part has content type `application/octet-stream`. Either part order works. An omitted blob returns `null`; an empty blob gets an ID. Duplicate parts, unknown parts, duplicate envelope fields, extra fields, invalid types, and truncated bodies are rejected.
18
18
19
19
Empty and non-UTF-8 keys work. CBOR definite and indefinite maps and byte strings work, including noncanonical lengths. The bounded envelope decoder supports only the protocol's map and string types. It never decodes `value` contents. Chunked strings have a 4,096-chunk bookkeeping limit.
20
20
21
-
Fetch gives exact matches priority. A fallback follows the latest secondary-key association. A store replaces both mappings atomically. Reassigning a secondary key does not delete its former target. Replacing an entry changes the value seen through every association to that entry.
21
+
Fetch gives exact matches priority. A fallback follows the latest secondary-key association and returns only the stored key, without reading R2. A store replaces both mappings atomically. Reassigning a secondary key does not delete its former target. Replacing an entry preserves the other associations to its key.
22
22
23
-
HTTP status codes follow the [local RFC](docs/0001-remote-cache.md#4-http-api-mapping). A fetch returns `404` when neither key resolves to a live entry. An unavailable blob also returns `404`, including when its R2 object is missing. These responses use plain text. A missing or unreadable value for a live entry is a storage failure and returns `503`, as specified in [the read design](docs/0001-remote-cache.md#7-fetch-and-download-implementation).
23
+
HTTP status codes follow the [local RFC](docs/0001-remote-cache.md#4-http-api-mapping). A fetch returns `404` when neither key resolves to a live entry. An unavailable blob also returns `404`, including when its R2 object is missing. These responses use plain text. A missing or unreadable value for a live exact match is a storage failure and returns `503`, as specified in [the read design](docs/0001-remote-cache.md#7-fetch-and-download-implementation).
24
24
25
25
Errors have `Content-Type: text/plain; charset=utf-8`. Codes are `400` for invalid input, `401` for invalid/missing/expired tokens, `403` for a signed token that fails write policy, `404` for absent data or unavailable namespaces/routes, `413` for size limits, `429` for admission limits, `500` for an incomplete operation, and `503` for unavailable authorization/storage, failed publication guards, quotas, or concurrency admission. `429` and `503` include `Retry-After: 60`.
Use the account's actual Workers subdomain. For a custom domain, set `--origin https://cache.example.com`. Setup disables the unused `workers.dev` alias for a custom domain and disables preview URLs. It rejects an R2 bucket with public custom domains and disables its `r2.dev` access.
55
55
56
-
Setup discovers resources by name, creates missing resources, applies migrations, resolves public repository and owner IDs through GitHub, records the default branch and exact audience, installs lifecycle/Cron settings, deploys, and prints the endpoint. Repeated setup does not duplicate resources or re-enable a withdrawn namespace. Reusing an existing namespace for a different repository is rejected. Configuration is written to the ignored `wrangler.operator.json`; keep a secure backup of this non-secret file.
56
+
Setup discovers resources by name, creates missing resources, applies migrations, resolves public repository and owner IDs through GitHub, records the default branch and exact audience, installs lifecycle/Cron settings, deploys, and prints the endpoint. Repeated setup does not duplicate resources or re-enable a withdrawn namespace. An incompatible origin or repository is rejected before setup changes existing policies, bucket settings, or saved configuration. Configuration is written to the ignored `wrangler.operator.json`; keep a secure backup of this non-secret file.
57
57
58
58
The default `free`**resource profile** retains the RFC's 8 GB budget, 20,000 entries, 20,000 associations, and 16 generations per Cron run. It is not proof of compatibility with the Workers Free CPU limit. **Use Workers Paid for the full payload limits until production CPU measurements establish a supported Free profile.** Local measurements already exceed 10 ms in several cases. Setup does not purchase or change a Workers subscription.
Tokens are limited to 16 KiB. JWKS bodies are limited to 64 KiB, requests to five seconds, cached keys to ten minutes, and refresh attempts to one per 30 seconds per isolate, including failures. Unknown key IDs cannot cause unlimited refreshes. Missing usable keys fail closed. A maintainer's policy change increments its version; publication checks that version, current scope/deployment state, token expiry, lease, bytes, and identity quotas inside the D1 transaction.
92
92
93
-
The rate bindings apply before database or object access. Defaults are 600 requests/minute for each namespace's fetch/blob operation and 30 store attempts/minute. Invalid credentials consume store admission too. Unknown routes share catch-all identities. Limits are approximate per Cloudflare location; they are not a global billing cap. Reads do not write D1 counters or refresh retention.
93
+
The rate bindings apply before database or object access. Defaults are 600 requests/minute for each namespace's fetch/blob operation and 30 store attempts/minute. Invalid credentials consume store admission too. Unknown routes share catch-all identities. Setup and upgrade derive stable limiter IDs from the Worker and binding names, so separate deployments have separate counters. Run `pnpm operator upgrade` for an existing deployment to replace the old shared IDs. Limits are approximate per Cloudflare location; they are not a global billing cap. Reads do not write D1 counters or refresh retention.
Check `key` first. If no live entry exists, resolve `secondary_key` to a stored key. Check that entry. Include the stored key only in the fallback variant. If neither resolves, return HTTP `404`. Fetch does not change entries or associations.
90
+
Check `key` first. If no live entry exists, resolve `secondary_key` to a stored key. Check that entry. For a fallback match, return only the stored key so the client can explain what changed. If neither resolves, return HTTP `404`. Fetch does not change entries or associations.
91
91
92
92
### Download a blob
93
93
@@ -120,13 +120,13 @@ If the request omits the blob, return `null`. A present zero-byte blob receives
120
120
121
121
Each successful store replaces `entries[key]` and sets `associations[secondary_key] = key`. For example:
122
122
123
-
| Operation | Entries afterward | Association afterward |
Other secondary keys that already point to `A` also resolve to `VA2`. A change to `S` does not evict entry `A`.
132
132
@@ -359,7 +359,7 @@ First, apply rate limits. Check that the public scope is enabled. Decode CBOR wi
359
359
360
360
Use one indexed D1 query to select the exact live entry, or the secondary fallback if no exact entry exists. Select the response kind, stored key, and generation references from one database snapshot. Separate exact and fallback reads could observe different commits.
361
361
362
-
Read the selected generation's value from R2. Return the corresponding CBOR variant. Return `503` if D1 identifies a live generation but its value object is missing or unreadable. This condition is a storage failure. Expired or deleted entries count as absent. The client still validates the exact value before it downloads outputs.
362
+
For an exact match, read the selected generation's value from R2 and return the exact CBOR variant. Return `503` if its value object is missing or unreadable. This condition is a storage failure. For a fallback match, return the stored key without reading R2. Expired or deleted entries count as absent. The client still validates the exact value before it downloads outputs.
363
363
364
364
For `/blob/{blob_id}`, check that the public scope is enabled, without authentication. Resolve the blob ID in D1. Stream the R2 object to the response. A blob ID from another scope must not expose data.
365
365
@@ -607,7 +607,7 @@ Public reads require no identity subscription. GitHub issues tokens for publishi
607
607
Use these variables for daily traffic:
608
608
609
609
- `L`: Public fetches after local misses.
610
-
- `F`: Fetches that return a value.
610
+
- `F`: Exact fetches that return a value.
611
611
- `H`: Blob downloads after successful client validation.
612
612
- `P`: Entries successfully published through explicit CI pushes from the main branch, including overwrites.
613
613
@@ -621,7 +621,7 @@ Use these variables for stored data:
621
621
- `E`: Live exact keys.
622
622
- `R`: Retention days.
623
623
624
-
Each store takes one Worker request. Each metadata fetch takes one request. The client makes a blob request only when it needs the blob. The Worker also reads the opaque value from R2. Internal R2 multipart upload changes storage operation counts but adds no client requests:
624
+
Each store takes one Worker request. Each metadata fetch takes one request. The client makes a blob request only when it needs the blob. For an exact match, the Worker also reads the opaque value from R2. Internal R2 multipart upload changes storage operation counts but adds no client requests:
625
625
626
626
```text
627
627
A per store = 1 # no blob: value PUT
@@ -678,7 +678,7 @@ For planning, interpret the approximate KB values as decimal. `V = 250,000` byte
678
678
679
679
D1's provisional 4 KiB estimate for each key covers index and generation records only. Validate it with the reported key sizes. Include repeated key bytes in indexes and associations.
680
680
681
-
Every exact or fallback response transfers the value, even if client validation prevents a blob download. Before protocol overhead and retries, daily response payload equals `F * V + H * B` bytes. At the example's sizes, 1,000 fetches with values and 800 blob downloads transfer about 450 MB/day. This includes 250 MB of values. These transfers affect time, CBOR work, and memory. Request and R2 operation counts follow the same equations.
681
+
Every exact response transfers the value, even if client validation prevents a blob download. Before protocol overhead and retries, daily value and blob payload equals `F * V + H * B` bytes. At the example's sizes, 1,000 fetches with values and 800 blob downloads transfer about 450 MB/day. This includes 250 MB of values. These transfers affect time, CBOR work, and memory. Request and R2 operation counts follow the same equations.
0 commit comments