Skip to content

Commit 73f42db

Browse files
committed
Fix cache memory store unbounded memory usage
1 parent ebdb5e9 commit 73f42db

15 files changed

+63
-28
lines changed

apps/webapp/app/services/authorizationRateLimitMiddleware.server.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ type Options = {
6464
limiterCache?: {
6565
fresh: number;
6666
stale: number;
67+
maxItems: number;
6768
};
6869
log?: {
6970
requests?: boolean;
@@ -145,7 +146,10 @@ export function authorizationRateLimitMiddleware({
145146
limiterConfigOverride,
146147
}: Options) {
147148
const ctx = new DefaultStatefulContext();
148-
const memory = new MemoryStore({ persistentMap: new Map() });
149+
const memory = new MemoryStore({
150+
persistentMap: new Map(),
151+
unstableEvictOnSet: { frequency: 0.001, maxItems: limiterCache?.maxItems ?? 1000 },
152+
});
149153
const redisCacheStore = new RedisCacheStore({
150154
connection: {
151155
keyPrefix: `cache:${keyPrefix}:rate-limit-cache:`,

apps/webapp/app/services/platform.v3.server.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,13 @@ const client = singleton("billingClient", initializeClient);
4444

4545
function initializePlatformCache() {
4646
const ctx = new DefaultStatefulContext();
47-
const memory = new MemoryStore({ persistentMap: new Map() });
47+
const memory = new MemoryStore({
48+
persistentMap: new Map(),
49+
unstableEvictOnSet: {
50+
frequency: 0.01,
51+
maxItems: 1000,
52+
},
53+
});
4854
const redisCacheStore = new RedisCacheStore({
4955
connection: {
5056
keyPrefix: "tr:cache:platform:v3",

apps/webapp/app/services/realtimeClient.server.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,10 @@ export class RealtimeClient {
8383
this.#registerCommands();
8484

8585
const ctx = new DefaultStatefulContext();
86-
const memory = new MemoryStore({ persistentMap: new Map() });
86+
const memory = new MemoryStore({
87+
persistentMap: new Map(),
88+
unstableEvictOnSet: { frequency: 0.01, maxItems: 1000 },
89+
});
8790
const redisCacheStore = new RedisCacheStore({
8891
connection: {
8992
keyPrefix: "tr:cache:realtime",

apps/webapp/app/services/requestIdempotency.server.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,13 @@ export class RequestIdempotencyService<TTypes extends string> {
3333
: "request-idempotency:";
3434

3535
const ctx = new DefaultStatefulContext();
36-
const memory = new MemoryStore({ persistentMap: new Map() });
36+
const memory = new MemoryStore({
37+
persistentMap: new Map(),
38+
unstableEvictOnSet: {
39+
frequency: 0.001,
40+
maxItems: 1000,
41+
},
42+
});
3743
const redisCacheStore = new RedisCacheStore({
3844
name: "request-idempotency",
3945
connection: {

apps/webapp/app/v3/eventRepository/originalRunIdCache.server.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
22
createCache,
33
DefaultStatefulContext,
4-
MemoryStore,
54
Namespace,
65
RedisCacheStore,
76
type UnkeyCache,
@@ -25,7 +24,6 @@ export class OriginalRunIdCache {
2524
constructor(options: OriginalRunIdCacheOptions) {
2625
// Initialize cache
2726
const ctx = new DefaultStatefulContext();
28-
const memory = new MemoryStore({ persistentMap: new Map() });
2927
const redisCacheStore = new RedisCacheStore({
3028
name: "original-run-id-cache",
3129
connection: {
@@ -37,7 +35,7 @@ export class OriginalRunIdCache {
3735

3836
this.cache = createCache({
3937
originalRunId: new Namespace<string>(ctx, {
40-
stores: [memory, redisCacheStore],
38+
stores: [redisCacheStore],
4139
fresh: ORIGINAL_RUN_ID_FRESH_TTL,
4240
stale: ORIGINAL_RUN_ID_STALE_TTL,
4341
}),

apps/webapp/app/v3/marqs/fairDequeuingStrategy.server.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,13 @@ export class FairDequeuingStrategy implements MarQSFairDequeueStrategy {
9999

100100
constructor(private options: FairDequeuingStrategyOptions) {
101101
const ctx = new DefaultStatefulContext();
102-
const memory = new MemoryStore({ persistentMap: new Map() });
102+
const memory = new MemoryStore({
103+
persistentMap: new Map(),
104+
unstableEvictOnSet: {
105+
frequency: 0.01,
106+
maxItems: 500,
107+
},
108+
});
103109

104110
this._cache = createCache({
105111
concurrencyLimit: new Namespace<number>(ctx, {

apps/webapp/app/v3/otlpExporter.server.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,8 @@ function convertLogsToCreateableEvents(
220220
SemanticInternalAttributes.METADATA
221221
);
222222

223-
const properties = {
224-
...convertKeyValueItemsToMap(
223+
const properties =
224+
convertKeyValueItemsToMap(
225225
truncateAttributes(log.attributes ?? [], spanAttributeValueLengthLimit),
226226
[],
227227
undefined,
@@ -233,8 +233,7 @@ function convertLogsToCreateableEvents(
233233
SemanticInternalAttributes.METRIC_EVENTS,
234234
SemanticInternalAttributes.TRIGGER,
235235
]
236-
),
237-
};
236+
) ?? {};
238237

239238
return {
240239
traceId: binaryToHex(log.traceId),
@@ -257,7 +256,7 @@ function convertLogsToCreateableEvents(
257256
metadata: logProperties.metadata ?? resourceProperties.metadata ?? {},
258257
environmentId:
259258
logProperties.environmentId ?? resourceProperties.environmentId ?? "unknown",
260-
environmentType: "DEVELOPMENT" as const,
259+
environmentType: "DEVELOPMENT" as const, // We've deprecated this but we need to keep it for backwards compatibility
261260
organizationId:
262261
logProperties.organizationId ?? resourceProperties.organizationId ?? "unknown",
263262
projectId: logProperties.projectId ?? resourceProperties.projectId ?? "unknown",
@@ -304,8 +303,8 @@ function convertSpansToCreateableEvents(
304303
SemanticInternalAttributes.METADATA
305304
);
306305

307-
const properties = {
308-
...convertKeyValueItemsToMap(
306+
const properties =
307+
convertKeyValueItemsToMap(
309308
truncateAttributes(span.attributes ?? [], spanAttributeValueLengthLimit),
310309
[],
311310
undefined,
@@ -317,8 +316,7 @@ function convertSpansToCreateableEvents(
317316
SemanticInternalAttributes.METRIC_EVENTS,
318317
SemanticInternalAttributes.TRIGGER,
319318
]
320-
),
321-
};
319+
) ?? {};
322320

323321
return {
324322
traceId: binaryToHex(span.traceId),

apps/webapp/app/v3/services/tracePubSub.server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { createRedisClient, RedisClient, RedisWithClusterOptions } from "~/redis.server";
2-
import { EventEmitter } from "node:stream";
2+
import { EventEmitter } from "node:events";
33
import { env } from "~/env.server";
44
import { singleton } from "~/utils/singleton";
55

apps/webapp/app/v3/services/worker/workerGroupTokenService.server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createCache, DefaultStatefulContext, MemoryStore, Namespace } from "@internal/cache";
1+
import { createCache, createMemoryStore, DefaultStatefulContext, Namespace } from "@internal/cache";
22
import {
33
CheckpointInput,
44
CompleteRunAttemptResult,
@@ -39,7 +39,7 @@ function createAuthenticatedWorkerInstanceCache() {
3939
authenticatedWorkerInstance: new Namespace<AuthenticatedWorkerInstance>(
4040
new DefaultStatefulContext(),
4141
{
42-
stores: [new MemoryStore({ persistentMap: new Map() })],
42+
stores: [createMemoryStore(1000, 0.001)],
4343
fresh: 60_000 * 10, // 10 minutes
4444
stale: 60_000 * 11, // 11 minutes
4545
}

internal-packages/cache/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
"types": "./src/index.ts",
77
"type": "module",
88
"dependencies": {
9+
"@internal/redis": "workspace:*",
10+
"@trigger.dev/core": "workspace:*",
911
"@unkey/cache": "^1.5.0",
1012
"@unkey/error": "^0.2.0",
11-
"@trigger.dev/core": "workspace:*",
12-
"@internal/redis": "workspace:*",
1313
"superjson": "^2.2.1"
1414
},
1515
"scripts": {

0 commit comments

Comments
 (0)