Skip to content

Commit f129602

Browse files
authored
feat: prefix for kv cache keys (#616)
1 parent faca3e1 commit f129602

File tree

6 files changed

+42
-38
lines changed

6 files changed

+42
-38
lines changed

.changeset/two-paws-boil.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@opennextjs/cloudflare": patch
3+
---
4+
5+
feat: prefix for kv cache keys

packages/cloudflare/src/api/cloudflare-context.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ import type { Context, RunningCodeOptions } from "node:vm";
22

33
import type { GetPlatformProxyOptions } from "wrangler";
44

5-
import type { DOQueueHandler } from "./durable-objects/queue";
6-
import { DOShardedTagCache } from "./durable-objects/sharded-tag-cache";
5+
import type { DOQueueHandler } from "./durable-objects/queue.js";
6+
import type { DOShardedTagCache } from "./durable-objects/sharded-tag-cache.js";
7+
import type { PREFIX_ENV_NAME as KV_CACHE_PREFIX_ENV_NAME } from "./overrides/incremental-cache/kv-incremental-cache.js";
8+
import type { PREFIX_ENV_NAME as R2_CACHE_PREFIX_ENV_NAME } from "./overrides/incremental-cache/r2-incremental-cache.js";
79

810
declare global {
911
interface CloudflareEnv {
@@ -19,11 +21,13 @@ declare global {
1921

2022
// KV used for the incremental cache
2123
NEXT_INC_CACHE_KV?: KVNamespace;
24+
// Prefix used for the KV incremental cache key
25+
[KV_CACHE_PREFIX_ENV_NAME]?: string;
2226

2327
// R2 bucket used for the incremental cache
2428
NEXT_INC_CACHE_R2_BUCKET?: R2Bucket;
2529
// Prefix used for the R2 incremental cache bucket
26-
NEXT_INC_CACHE_R2_PREFIX?: string;
30+
[R2_CACHE_PREFIX_ENV_NAME]?: string;
2731

2832
// D1 db used for the tag cache
2933
NEXT_TAG_CACHE_D1?: D1Database;

packages/cloudflare/src/api/overrides/incremental-cache/kv-incremental-cache.ts

+6-13
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,22 @@
1-
import { createHash } from "node:crypto";
2-
31
import { error } from "@opennextjs/aws/adapters/logger.js";
42
import type { CacheValue, IncrementalCache, WithLastModified } from "@opennextjs/aws/types/overrides.js";
53
import { IgnorableError } from "@opennextjs/aws/utils/error.js";
64

75
import { getCloudflareContext } from "../../cloudflare-context.js";
8-
import { debugCache, FALLBACK_BUILD_ID, IncrementalCacheEntry } from "../internal.js";
6+
import { computeCacheKey, debugCache, IncrementalCacheEntry } from "../internal.js";
97

108
export const NAME = "cf-kv-incremental-cache";
119

1210
export const BINDING_NAME = "NEXT_INC_CACHE_KV";
1311

14-
export type KeyOptions = {
15-
isFetch?: boolean;
16-
buildId?: string;
17-
};
18-
19-
export function computeCacheKey(key: string, options: KeyOptions) {
20-
const { isFetch = false, buildId = FALLBACK_BUILD_ID } = options;
21-
const hash = createHash("sha256").update(key).digest("hex");
22-
return `${buildId}/${hash}.${isFetch ? "fetch" : "cache"}`.replace(/\/+/g, "/");
23-
}
12+
export const PREFIX_ENV_NAME = "NEXT_INC_CACHE_KV_PREFIX";
2413

2514
/**
2615
* Open Next cache based on Cloudflare KV.
2716
*
17+
* The prefix that the cache entries are stored under can be configured with the `NEXT_INC_CACHE_KV_PREFIX`
18+
* environment variable, and defaults to `incremental-cache`.
19+
*
2820
* Note: The class is instantiated outside of the request context.
2921
* The cloudflare context and process.env are not initialized yet
3022
* when the constructor is called.
@@ -106,6 +98,7 @@ class KVIncrementalCache implements IncrementalCache {
10698

10799
protected getKVKey(key: string, isFetch?: boolean): string {
108100
return computeCacheKey(key, {
101+
prefix: getCloudflareContext().env[PREFIX_ENV_NAME],
109102
buildId: process.env.NEXT_BUILD_ID,
110103
isFetch,
111104
});

packages/cloudflare/src/api/overrides/incremental-cache/r2-incremental-cache.ts

+2-17
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,15 @@
1-
import { createHash } from "node:crypto";
2-
31
import { error } from "@opennextjs/aws/adapters/logger.js";
42
import type { CacheValue, IncrementalCache, WithLastModified } from "@opennextjs/aws/types/overrides.js";
53
import { IgnorableError } from "@opennextjs/aws/utils/error.js";
64

75
import { getCloudflareContext } from "../../cloudflare-context.js";
8-
import { debugCache, FALLBACK_BUILD_ID } from "../internal.js";
6+
import { computeCacheKey, debugCache } from "../internal.js";
97

108
export const NAME = "cf-r2-incremental-cache";
119

1210
export const BINDING_NAME = "NEXT_INC_CACHE_R2_BUCKET";
1311

1412
export const PREFIX_ENV_NAME = "NEXT_INC_CACHE_R2_PREFIX";
15-
export const DEFAULT_PREFIX = "incremental-cache";
16-
17-
export type KeyOptions = {
18-
isFetch?: boolean;
19-
directory?: string;
20-
buildId?: string;
21-
};
22-
23-
export function computeCacheKey(key: string, options: KeyOptions) {
24-
const { isFetch = false, directory = DEFAULT_PREFIX, buildId = FALLBACK_BUILD_ID } = options;
25-
const hash = createHash("sha256").update(key).digest("hex");
26-
return `${directory}/${buildId}/${hash}.${isFetch ? "fetch" : "cache"}`.replace(/\/+/g, "/");
27-
}
2813

2914
/**
3015
* An instance of the Incremental Cache that uses an R2 bucket (`NEXT_INC_CACHE_R2_BUCKET`) as it's
@@ -91,7 +76,7 @@ class R2IncrementalCache implements IncrementalCache {
9176

9277
protected getR2Key(key: string, isFetch?: boolean): string {
9378
return computeCacheKey(key, {
94-
directory: getCloudflareContext().env[PREFIX_ENV_NAME],
79+
prefix: getCloudflareContext().env[PREFIX_ENV_NAME],
9580
buildId: process.env.NEXT_BUILD_ID,
9681
isFetch,
9782
});

packages/cloudflare/src/api/overrides/internal.ts

+16
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { createHash } from "node:crypto";
2+
13
import { CacheValue } from "@opennextjs/aws/types/overrides.js";
24

35
export type IncrementalCacheEntry<IsFetch extends boolean> = {
@@ -12,3 +14,17 @@ export const debugCache = (name: string, ...args: unknown[]) => {
1214
};
1315

1416
export const FALLBACK_BUILD_ID = "no-build-id";
17+
18+
export const DEFAULT_PREFIX = "incremental-cache";
19+
20+
export type KeyOptions = {
21+
isFetch: boolean | undefined;
22+
prefix: string | undefined;
23+
buildId: string | undefined;
24+
};
25+
26+
export function computeCacheKey(key: string, options: KeyOptions) {
27+
const { isFetch = false, prefix = DEFAULT_PREFIX, buildId = FALLBACK_BUILD_ID } = options;
28+
const hash = createHash("sha256").update(key).digest("hex");
29+
return `${prefix}/${buildId}/${hash}.${isFetch ? "fetch" : "cache"}`.replace(/\/+/g, "/");
30+
}

packages/cloudflare/src/cli/commands/populate-cache.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,19 @@ import { unstable_readConfig } from "wrangler";
1616

1717
import {
1818
BINDING_NAME as KV_CACHE_BINDING_NAME,
19-
computeCacheKey as computeKVCacheKey,
2019
NAME as KV_CACHE_NAME,
20+
PREFIX_ENV_NAME as KV_CACHE_PREFIX_ENV_NAME,
2121
} from "../../api/overrides/incremental-cache/kv-incremental-cache.js";
2222
import {
2323
BINDING_NAME as R2_CACHE_BINDING_NAME,
24-
computeCacheKey as computeR2CacheKey,
2524
NAME as R2_CACHE_NAME,
2625
PREFIX_ENV_NAME as R2_CACHE_PREFIX_ENV_NAME,
2726
} from "../../api/overrides/incremental-cache/r2-incremental-cache.js";
2827
import {
2928
CACHE_DIR as STATIC_ASSETS_CACHE_DIR,
3029
NAME as STATIC_ASSETS_CACHE_NAME,
3130
} from "../../api/overrides/incremental-cache/static-assets-incremental-cache.js";
31+
import { computeCacheKey } from "../../api/overrides/internal.js";
3232
import {
3333
BINDING_NAME as D1_TAG_BINDING_NAME,
3434
NAME as D1_TAG_NAME,
@@ -113,8 +113,8 @@ function populateR2IncrementalCache(
113113
const assets = getCacheAssets(options);
114114

115115
for (const { fullPath, key, buildId, isFetch } of tqdm(assets)) {
116-
const cacheKey = computeR2CacheKey(key, {
117-
directory: process.env[R2_CACHE_PREFIX_ENV_NAME],
116+
const cacheKey = computeCacheKey(key, {
117+
prefix: process.env[R2_CACHE_PREFIX_ENV_NAME],
118118
buildId,
119119
isFetch,
120120
});
@@ -146,7 +146,8 @@ function populateKVIncrementalCache(
146146
const assets = getCacheAssets(options);
147147

148148
for (const { fullPath, key, buildId, isFetch } of tqdm(assets)) {
149-
const cacheKey = computeKVCacheKey(key, {
149+
const cacheKey = computeCacheKey(key, {
150+
prefix: process.env[KV_CACHE_PREFIX_ENV_NAME],
150151
buildId,
151152
isFetch,
152153
});

0 commit comments

Comments
 (0)