Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 5c1dfba

Browse files
committed
Add option to disable caching with default/named caches
1 parent f81bb61 commit 5c1dfba

File tree

9 files changed

+95
-4
lines changed

9 files changed

+95
-4
lines changed

src/cli.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ export default function parseArgv(raw: string[]): Options {
122122
// type: "boolean" | "string",
123123
description: "Path to persist cached data to (omit path for default)",
124124
},
125+
"disable-cache": {
126+
type: "boolean",
127+
description: "Disable caching with default/named caches",
128+
},
125129
site: {
126130
type: "string",
127131
description: "Path to serve Workers Site files from",
@@ -212,6 +216,7 @@ export default function parseArgv(raw: string[]): Options {
212216
kvNamespaces: asStringArray(argv.kv),
213217
kvPersist: argv["kv-persist"] as boolean | string | undefined,
214218
cachePersist: argv["cache-persist"] as boolean | string | undefined,
219+
disableCache: argv["disable-cache"],
215220
sitePath: argv.site,
216221
siteInclude: asStringArray(argv["site-include"]),
217222
siteExclude: asStringArray(argv["site-exclude"]),

src/kv/cache.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,16 @@ function getKey(req: Request): string {
3535
return `${req.url}.json`;
3636
}
3737

38-
export class Cache {
38+
export interface CacheInterface {
39+
put(req: string | Request, res: Response): Promise<undefined>;
40+
match(
41+
req: string | Request,
42+
options?: CacheMatchOptions
43+
): Promise<Response | undefined>;
44+
delete(req: string | Request, options?: CacheMatchOptions): Promise<boolean>;
45+
}
46+
47+
export class Cache implements CacheInterface {
3948
readonly #storage: KVStorage;
4049
readonly #clock: KVClock;
4150
readonly #namespace: KVStorageNamespace;
@@ -149,3 +158,23 @@ export class Cache {
149158
return this.#storage.delete(key);
150159
}
151160
}
161+
162+
export class NoOpCache implements CacheInterface {
163+
async put(_req: string | Request, _res: Response): Promise<undefined> {
164+
return;
165+
}
166+
167+
async match(
168+
_req: string | Request,
169+
_options?: CacheMatchOptions
170+
): Promise<Response | undefined> {
171+
return;
172+
}
173+
174+
async delete(
175+
_req: string | Request,
176+
_options?: CacheMatchOptions
177+
): Promise<boolean> {
178+
return false;
179+
}
180+
}

src/modules/cache.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import path from "path";
22
import { MiniflareError } from "../error";
3-
import { Cache } from "../kv";
3+
import { Cache, NoOpCache } from "../kv";
44
import { KVStorageFactory } from "../kv/helpers";
55
import { Log } from "../log";
66
import { ProcessedOptions } from "../options";
@@ -9,6 +9,8 @@ import { Context, Module } from "./module";
99
const defaultPersistRoot = path.resolve(".mf", "cache");
1010
const defaultCacheName = "default";
1111

12+
const noopCache = new NoOpCache();
13+
1214
export class CacheModule extends Module {
1315
constructor(
1416
log: Log,
@@ -22,7 +24,9 @@ export class CacheModule extends Module {
2224
}
2325

2426
buildSandbox(options: ProcessedOptions): Context {
25-
const defaultCache = this.getCache(undefined, options.cachePersist);
27+
const defaultCache = options.disableCache
28+
? noopCache
29+
: this.getCache(undefined, options.cachePersist);
2630
return {
2731
caches: {
2832
default: defaultCache,
@@ -32,7 +36,9 @@ export class CacheModule extends Module {
3236
`\"${defaultCacheName}\" is a reserved cache name`
3337
);
3438
}
35-
return this.getCache(name, options.cachePersist);
39+
return options.disableCache
40+
? noopCache
41+
: this.getCache(name, options.cachePersist);
3642
},
3743
},
3844
};
@@ -42,3 +48,5 @@ export class CacheModule extends Module {
4248
this.storageFactory.dispose();
4349
}
4450
}
51+
52+
export { Cache, NoOpCache };

src/modules/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export { Cache, NoOpCache } from "./cache";
12
export { DurableObject } from "./do";
23
export { FetchEvent, ScheduledEvent, ResponseWaitUntil } from "./events";
34
export {

src/options/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export interface Options {
8383
kvPersist?: boolean | string;
8484

8585
cachePersist?: boolean | string;
86+
disableCache?: boolean;
8687

8788
sitePath?: string;
8889
siteInclude?: string[];
@@ -140,6 +141,7 @@ export function logOptions(log: Log, options: ProcessedOptions): void {
140141
"KV Namespaces": options.kvNamespaces,
141142
"KV Persistence": options.kvPersist,
142143
"Cache Persistence": options.cachePersist,
144+
"Disable Cache": options.disableCache,
143145
"Workers Site Path": options.sitePath,
144146
"Workers Site Include": options.siteIncludeRegexps,
145147
// Only include excludeRegexps if there are no includeRegexps

test/cli.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ test("parseArgv: parses complete argv", (t) => {
4444
"TEST_NAMESPACE2",
4545
"--kv-persist",
4646
"--cache-persist",
47+
"--disable-cache",
4748
"--site",
4849
"public",
4950
"--site-include",
@@ -91,6 +92,7 @@ test("parseArgv: parses complete argv", (t) => {
9192
kvNamespaces: ["TEST_NAMESPACE1", "TEST_NAMESPACE2"],
9293
kvPersist: true,
9394
cachePersist: true,
95+
disableCache: true,
9496
sitePath: "public",
9597
siteInclude: ["upload_dir"],
9698
siteExclude: ["ignore_dir"],

test/kv/cache.spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
CachedResponse,
77
KVStorage,
88
MemoryKVStorage,
9+
NoOpCache,
910
Request,
1011
Response,
1112
} from "../../src";
@@ -205,3 +206,12 @@ test("Cache: hides implementation details", (t) => {
205206
const { cache } = t.context;
206207
t.deepEqual(getObjectProperties(cache), ["delete", "match", "put"]);
207208
});
209+
210+
test("NoOpCache: doesn't cache", async (t) => {
211+
const req = "http://localhost:8787/test";
212+
const cache = new NoOpCache();
213+
t.is(await cache.put(req, testResponse.clone()), undefined);
214+
t.is(await cache.match(req), undefined);
215+
t.is(await cache.put(req, testResponse.clone()), undefined);
216+
t.false(await cache.delete(req));
217+
});

test/modules/cache.spec.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import path from "path";
33
import test from "ava";
44
import {
55
Cache,
6+
CacheInterface,
67
CachedResponse,
78
MiniflareError,
89
NoOpLog,
@@ -263,3 +264,34 @@ test("buildSandbox: trying to open default cache throws", async (t) => {
263264
message: '"default" is a reserved cache name',
264265
});
265266
});
267+
268+
test("buildSandbox: disabling cache disables caches", async (t) => {
269+
const res = await runInWorker({ disableCache: true }, async () => {
270+
const sandbox = self as any;
271+
const cache = sandbox.caches.default as CacheInterface;
272+
const otherCache = (await sandbox.caches.open("other")) as CacheInterface;
273+
274+
const req = "http://localhost:8787/test";
275+
const res = new sandbox.Response("value", {
276+
headers: { "Cache-Control": "max-age=3600" },
277+
});
278+
279+
await cache.put(req, res.clone());
280+
const matched = (await cache.match(req)) !== undefined;
281+
await cache.put(req, res.clone());
282+
const deleted = await cache.delete(req);
283+
284+
await otherCache.put(req, res.clone());
285+
const matchedOther = (await otherCache.match(req)) !== undefined;
286+
await otherCache.put(req, res.clone());
287+
const deletedOther = await otherCache.delete(req);
288+
289+
return { matched, deleted, matchedOther, deletedOther };
290+
});
291+
t.deepEqual(res, {
292+
matched: false,
293+
deleted: false,
294+
matchedOther: false,
295+
deletedOther: false,
296+
});
297+
});

test/options/index.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ test("logOptions: logs all options", (t) => {
5454
kvNamespaces: ["NAMESPACE1", "NAMESPACE2"],
5555
kvPersist: "kv-data",
5656
cachePersist: false,
57+
disableCache: true,
5758
sitePath: "public",
5859
siteIncludeRegexps: [regexp1, regexp2],
5960
processedDurableObjects: [
@@ -77,6 +78,7 @@ test("logOptions: logs all options", (t) => {
7778
"- KV Namespaces: NAMESPACE1, NAMESPACE2",
7879
"- KV Persistence: kv-data",
7980
"- Cache Persistence: false",
81+
"- Disable Cache: true",
8082
"- Workers Site Path: public",
8183
"- Workers Site Include: regexp1, regexp2",
8284
"- Durable Objects: OBJECT1, OBJECT2",

0 commit comments

Comments
 (0)