Skip to content

Commit 5e937c1

Browse files
authored
feat: Allow min 30s cache TTL in miniflare KV plugin (#11391)
* feat: Change Miniflare to allow lower than 60 seconds cache TTL in the KV plugin * chore: Refactored KV constants to include unit prefix * chore: Updated change to patch
1 parent 76f0540 commit 5e937c1

File tree

5 files changed

+29
-22
lines changed

5 files changed

+29
-22
lines changed

.changeset/gold-ties-enjoy.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"miniflare": patch
3+
---
4+
5+
Set minimum KV Cache TTL in Miniflare to 30 seconds

packages/miniflare/src/workers/kv/constants.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { MatcherRegExps, testRegExps } from "miniflare:shared";
22

33
export const KVLimits = {
4-
MIN_CACHE_TTL: 60 /* 60s */,
4+
MIN_CACHE_TTL_SECONDS: 30,
5+
MIN_EXPIRATION_TTL_SECONDS: 60,
56
MAX_LIST_KEYS: 1000,
6-
MAX_KEY_SIZE: 512 /* 512B */,
7-
MAX_VALUE_SIZE: 25 * 1024 * 1024 /* 25MiB */,
8-
MAX_VALUE_SIZE_TEST: 1024 /* 1KiB */,
9-
MAX_METADATA_SIZE: 1024 /* 1KiB */,
10-
MAX_BULK_SIZE: 25 * 1024 * 1024 /* 25MiB */,
7+
MAX_KEY_SIZE_BYTES: 512,
8+
MAX_VALUE_SIZE_BYTES: 25 * 1024 * 1024 /* 25MiB */,
9+
MAX_VALUE_SIZE_TEST_BYTES: 1024 /* 1KiB */,
10+
MAX_METADATA_SIZE_BYTES: 1024 /* 1KiB */,
11+
MAX_BULK_SIZE_BYTES: 25 * 1024 * 1024 /* 25MiB */,
1112
} as const;
1213

1314
export const KVParams = {

packages/miniflare/src/workers/kv/namespace.worker.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,8 @@ export class KVNamespaceObject extends MiniflareDurableObject {
161161
obj[key] = value;
162162
}
163163
const maxValueSize = this.beingTested
164-
? KVLimits.MAX_VALUE_SIZE_TEST
165-
: KVLimits.MAX_BULK_SIZE;
164+
? KVLimits.MAX_VALUE_SIZE_TEST_BYTES
165+
: KVLimits.MAX_BULK_SIZE_BYTES;
166166
if (totalBytes > maxValueSize) {
167167
throw new HttpError(
168168
413,
@@ -233,8 +233,8 @@ export class KVNamespaceObject extends MiniflareDurableObject {
233233
});
234234

235235
const maxValueSize = this.beingTested
236-
? KVLimits.MAX_VALUE_SIZE_TEST
237-
: KVLimits.MAX_VALUE_SIZE;
236+
? KVLimits.MAX_VALUE_SIZE_TEST_BYTES
237+
: KVLimits.MAX_VALUE_SIZE_BYTES;
238238
let maxLengthStream: MaxLengthStream | undefined;
239239
if (valueLengthHint !== undefined && valueLengthHint > maxValueSize) {
240240
// If we know the size of the value (i.e. from `Content-Length`) use that

packages/miniflare/src/workers/kv/validator.worker.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ export function validateKey(key: string): void {
3030

3131
export function validateKeyLength(key: string): void {
3232
const keyLength = Buffer.byteLength(key);
33-
if (keyLength > KVLimits.MAX_KEY_SIZE) {
33+
if (keyLength > KVLimits.MAX_KEY_SIZE_BYTES) {
3434
throw new HttpError(
3535
414,
36-
`UTF-8 encoded length of ${keyLength} exceeds key length limit of ${KVLimits.MAX_KEY_SIZE}.`
36+
`UTF-8 encoded length of ${keyLength} exceeds key length limit of ${KVLimits.MAX_KEY_SIZE_BYTES}.`
3737
);
3838
}
3939
}
@@ -48,11 +48,11 @@ export function validateGetOptions(
4848
const cacheTtl = options?.cacheTtl;
4949
if (
5050
cacheTtl !== undefined &&
51-
(isNaN(cacheTtl) || cacheTtl < KVLimits.MIN_CACHE_TTL)
51+
(isNaN(cacheTtl) || cacheTtl < KVLimits.MIN_CACHE_TTL_SECONDS)
5252
) {
5353
throw new HttpError(
5454
400,
55-
`Invalid ${KVParams.CACHE_TTL} of ${cacheTtl}. Cache TTL must be at least ${KVLimits.MIN_CACHE_TTL}.`
55+
`Invalid ${KVParams.CACHE_TTL} of ${cacheTtl}. Cache TTL must be at least ${KVLimits.MIN_CACHE_TTL_SECONDS}.`
5656
);
5757
}
5858
}
@@ -80,10 +80,10 @@ export function validatePutOptions(
8080
`Invalid ${KVParams.EXPIRATION_TTL} of ${rawExpirationTtl}. Please specify integer greater than 0.`
8181
);
8282
}
83-
if (expirationTtl < KVLimits.MIN_CACHE_TTL) {
83+
if (expirationTtl < KVLimits.MIN_EXPIRATION_TTL_SECONDS) {
8484
throw new HttpError(
8585
400,
86-
`Invalid ${KVParams.EXPIRATION_TTL} of ${rawExpirationTtl}. Expiration TTL must be at least ${KVLimits.MIN_CACHE_TTL}.`
86+
`Invalid ${KVParams.EXPIRATION_TTL} of ${rawExpirationTtl}. Expiration TTL must be at least ${KVLimits.MIN_EXPIRATION_TTL_SECONDS}.`
8787
);
8888
}
8989
expiration = now + expirationTtl;
@@ -95,10 +95,10 @@ export function validatePutOptions(
9595
`Invalid ${KVParams.EXPIRATION} of ${rawExpiration}. Please specify integer greater than the current number of seconds since the UNIX epoch.`
9696
);
9797
}
98-
if (expiration < now + KVLimits.MIN_CACHE_TTL) {
98+
if (expiration < now + KVLimits.MIN_EXPIRATION_TTL_SECONDS) {
9999
throw new HttpError(
100100
400,
101-
`Invalid ${KVParams.EXPIRATION} of ${rawExpiration}. Expiration times must be at least ${KVLimits.MIN_CACHE_TTL} seconds in the future.`
101+
`Invalid ${KVParams.EXPIRATION} of ${rawExpiration}. Expiration times must be at least ${KVLimits.MIN_EXPIRATION_TTL_SECONDS} seconds in the future.`
102102
);
103103
}
104104
}
@@ -107,10 +107,10 @@ export function validatePutOptions(
107107
let metadata: unknown | undefined;
108108
if (rawMetadata !== null) {
109109
const metadataLength = Buffer.byteLength(rawMetadata);
110-
if (metadataLength > KVLimits.MAX_METADATA_SIZE) {
110+
if (metadataLength > KVLimits.MAX_METADATA_SIZE_BYTES) {
111111
throw new HttpError(
112112
413,
113-
`Metadata length of ${metadataLength} exceeds limit of ${KVLimits.MAX_METADATA_SIZE}.`
113+
`Metadata length of ${metadataLength} exceeds limit of ${KVLimits.MAX_METADATA_SIZE_BYTES}.`
114114
);
115115
}
116116
metadata = JSON.parse(rawMetadata);

packages/miniflare/test/plugins/kv/index.spec.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,13 +283,14 @@ test("get: validates but ignores cache ttl", async (t) => {
283283
await t.throwsAsync(kv.get("key", { cacheTtl: "not a number" as any }), {
284284
instanceOf: Error,
285285
message:
286-
"KV GET failed: 400 Invalid cache_ttl of 0. Cache TTL must be at least 60.",
286+
"KV GET failed: 400 Invalid cache_ttl of 0. Cache TTL must be at least 30.",
287287
});
288288
await t.throwsAsync(kv.get("key", { cacheTtl: 10 }), {
289289
instanceOf: Error,
290290
message:
291-
"KV GET failed: 400 Invalid cache_ttl of 10. Cache TTL must be at least 60.",
291+
"KV GET failed: 400 Invalid cache_ttl of 10. Cache TTL must be at least 30.",
292292
});
293+
t.not(await kv.get("key", { cacheTtl: 30 }), undefined);
293294
t.not(await kv.get("key", { cacheTtl: 60 }), undefined);
294295
});
295296

0 commit comments

Comments
 (0)