Skip to content

Commit de9e05a

Browse files
authored
feat: bulk insert cache entries to KV (#626)
* feat: bulk insert cache entries to KV * Update packages/cloudflare/src/cli/commands/populate-cache.ts
1 parent 09aaf35 commit de9e05a

File tree

6 files changed

+43
-18
lines changed

6 files changed

+43
-18
lines changed

.changeset/wet-monkeys-look.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@opennextjs/cloudflare": patch
3+
---
4+
5+
feat: bulk insert cache entries to KV

packages/cloudflare/src/cli/args.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ export type Arguments = (
1515
| {
1616
command: "preview" | "deploy" | "upload";
1717
passthroughArgs: string[];
18+
cacheChunkSize?: number;
1819
}
1920
| {
2021
command: "populateCache";
2122
target: WranglerTarget;
2223
environment?: string;
24+
cacheChunkSize?: number;
2325
}
2426
) & { outputDir?: string };
2527

@@ -30,6 +32,7 @@ export function getArgs(): Arguments {
3032
output: { type: "string", short: "o" },
3133
noMinify: { type: "boolean", default: false },
3234
skipWranglerConfigCheck: { type: "boolean", default: false },
35+
cacheChunkSize: { type: "string" },
3336
},
3437
allowPositionals: true,
3538
});
@@ -58,6 +61,7 @@ export function getArgs(): Arguments {
5861
command: positionals[0],
5962
outputDir,
6063
passthroughArgs,
64+
...(values.cacheChunkSize && { cacheChunkSize: Number(values.cacheChunkSize) }),
6165
};
6266
case "populateCache":
6367
if (!isWranglerTarget(positionals[1])) {
@@ -68,6 +72,7 @@ export function getArgs(): Arguments {
6872
outputDir,
6973
target: positionals[1],
7074
environment: getWranglerEnvironmentFlag(passthroughArgs),
75+
...(values.cacheChunkSize && { cacheChunkSize: Number(values.cacheChunkSize) }),
7176
};
7277
default:
7378
throw new Error(

packages/cloudflare/src/cli/commands/deploy.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ import { populateCache } from "./populate-cache.js";
77
export async function deploy(
88
options: BuildOptions,
99
config: OpenNextConfig,
10-
deployOptions: { passthroughArgs: string[] }
10+
deployOptions: { passthroughArgs: string[]; cacheChunkSize?: number }
1111
) {
1212
await populateCache(options, config, {
1313
target: "remote",
1414
environment: getWranglerEnvironmentFlag(deployOptions.passthroughArgs),
15+
cacheChunkSize: deployOptions.cacheChunkSize,
1516
});
1617

1718
runWrangler(options, ["deploy", ...deployOptions.passthroughArgs], { logging: "all" });

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

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { cpSync, existsSync } from "node:fs";
1+
import { cpSync, existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
22
import path from "node:path";
33

44
import type { BuildOptions } from "@opennextjs/aws/build/helper.js";
@@ -133,7 +133,7 @@ async function populateR2IncrementalCache(
133133

134134
async function populateKVIncrementalCache(
135135
options: BuildOptions,
136-
populateCacheOptions: { target: WranglerTarget; environment?: string }
136+
populateCacheOptions: { target: WranglerTarget; environment?: string; cacheChunkSize?: number }
137137
) {
138138
logger.info("\nPopulating KV incremental cache...");
139139

@@ -147,24 +147,36 @@ async function populateKVIncrementalCache(
147147

148148
const assets = getCacheAssets(options);
149149

150-
for (const { fullPath, key, buildId, isFetch } of tqdm(assets)) {
151-
const cacheKey = computeCacheKey(key, {
152-
prefix: proxy.env[KV_CACHE_PREFIX_ENV_NAME],
153-
buildId,
154-
cacheType: isFetch ? "fetch" : "cache",
155-
});
150+
const chunkSize = Math.max(1, populateCacheOptions.cacheChunkSize ?? 25);
151+
const totalChunks = Math.ceil(assets.length / chunkSize);
152+
153+
logger.info(`Inserting ${assets.length} assets to KV in chunks of ${chunkSize}`);
154+
155+
for (const i of tqdm(Array.from({ length: totalChunks }, (_, i) => i))) {
156+
const chunkPath = path.join(options.outputDir, "cloudflare", `cache-chunk-${i}.json`);
157+
158+
const kvMapping = assets
159+
.slice(i * chunkSize, (i + 1) * chunkSize)
160+
.map(({ fullPath, key, buildId, isFetch }) => ({
161+
key: computeCacheKey(key, {
162+
prefix: proxy.env[KV_CACHE_PREFIX_ENV_NAME],
163+
buildId,
164+
cacheType: isFetch ? "fetch" : "cache",
165+
}),
166+
value: readFileSync(fullPath, "utf8"),
167+
}));
168+
169+
writeFileSync(chunkPath, JSON.stringify(kvMapping));
156170

157171
runWrangler(
158172
options,
159-
[
160-
"kv key put",
161-
JSON.stringify(cacheKey),
162-
`--binding ${JSON.stringify(KV_CACHE_BINDING_NAME)}`,
163-
`--path ${JSON.stringify(fullPath)}`,
164-
],
173+
["kv bulk put", JSON.stringify(chunkPath), `--binding ${JSON.stringify(KV_CACHE_BINDING_NAME)}`],
165174
{ ...populateCacheOptions, logging: "error" }
166175
);
176+
177+
rmSync(chunkPath);
167178
}
179+
168180
logger.info(`Successfully populated cache with ${assets.length} assets`);
169181
}
170182

@@ -209,7 +221,7 @@ function populateStaticAssetsIncrementalCache(options: BuildOptions) {
209221
export async function populateCache(
210222
options: BuildOptions,
211223
config: OpenNextConfig,
212-
populateCacheOptions: { target: WranglerTarget; environment?: string }
224+
populateCacheOptions: { target: WranglerTarget; environment?: string; cacheChunkSize?: number }
213225
) {
214226
const { incrementalCache, tagCache } = config.default.override ?? {};
215227

packages/cloudflare/src/cli/commands/preview.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ import { populateCache } from "./populate-cache.js";
77
export async function preview(
88
options: BuildOptions,
99
config: OpenNextConfig,
10-
previewOptions: { passthroughArgs: string[] }
10+
previewOptions: { passthroughArgs: string[]; cacheChunkSize?: number }
1111
) {
1212
await populateCache(options, config, {
1313
target: "local",
1414
environment: getWranglerEnvironmentFlag(previewOptions.passthroughArgs),
15+
cacheChunkSize: previewOptions.cacheChunkSize,
1516
});
1617

1718
runWrangler(options, ["dev", ...previewOptions.passthroughArgs], { logging: "all" });

packages/cloudflare/src/cli/commands/upload.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ import { populateCache } from "./populate-cache.js";
77
export async function upload(
88
options: BuildOptions,
99
config: OpenNextConfig,
10-
uploadOptions: { passthroughArgs: string[] }
10+
uploadOptions: { passthroughArgs: string[]; cacheChunkSize?: number }
1111
) {
1212
await populateCache(options, config, {
1313
target: "remote",
1414
environment: getWranglerEnvironmentFlag(uploadOptions.passthroughArgs),
15+
cacheChunkSize: uploadOptions.cacheChunkSize,
1516
});
1617

1718
runWrangler(options, ["versions upload", ...uploadOptions.passthroughArgs], { logging: "all" });

0 commit comments

Comments
 (0)