Skip to content

Commit 6a512b6

Browse files
committed
Do not store the entire context into redis
1 parent 205abc8 commit 6a512b6

3 files changed

Lines changed: 25 additions & 66 deletions

File tree

packages/core/orchestration/src/transaction/datastore/abstract-storage.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ export interface IDistributedTransactionStorage {
2121
key: string,
2222
options?: TransactionOptions & { isCancelling?: boolean }
2323
): Promise<TransactionCheckpoint | undefined>
24-
list(): Promise<TransactionCheckpoint[]>
2524
save(
2625
key: string,
2726
data: TransactionCheckpoint,
@@ -93,10 +92,6 @@ export abstract class DistributedTransactionStorage
9392
throw new Error("Method 'get' not implemented.")
9493
}
9594

96-
async list(): Promise<TransactionCheckpoint[]> {
97-
throw new Error("Method 'list' not implemented.")
98-
}
99-
10095
async save(
10196
key: string,
10297
data: TransactionCheckpoint,

packages/modules/workflow-engine-inmemory/src/utils/workflow-orchestrator-storage.ts

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ export class InMemoryDistributedTransactionStorage
6262
private logger_: Logger
6363
private workflowOrchestratorService_: WorkflowOrchestratorService
6464

65-
private storage: Map<string, TransactionCheckpoint> = new Map()
65+
private storage: Map<string, Omit<TransactionCheckpoint, "context">> =
66+
new Map()
6667
private scheduled: Map<
6768
string,
6869
{
@@ -137,12 +138,6 @@ export class InMemoryDistributedTransactionStorage
137138
isCancelling?: boolean
138139
}
139140
): Promise<TransactionCheckpoint | undefined> {
140-
const data = this.storage.get(key)
141-
142-
if (data) {
143-
return data
144-
}
145-
146141
const { idempotent, store, retentionTime } = options ?? {}
147142
if (!idempotent && !(store && isDefined(retentionTime))) {
148143
return
@@ -202,10 +197,6 @@ export class InMemoryDistributedTransactionStorage
202197
return
203198
}
204199

205-
async list(): Promise<TransactionCheckpoint[]> {
206-
return Array.from(this.storage.values())
207-
}
208-
209200
async save(
210201
key: string,
211202
data: TransactionCheckpoint,
@@ -252,7 +243,11 @@ export class InMemoryDistributedTransactionStorage
252243
}
253244
}
254245

255-
this.storage.set(key, data)
246+
const { flow, errors } = data
247+
this.storage.set(key, {
248+
flow,
249+
errors,
250+
})
256251

257252
// Optimize DB operations - only perform when necessary
258253
if (hasFinished) {

packages/modules/workflow-engine-redis/src/utils/workflow-orchestrator-storage.ts

Lines changed: 18 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import {
2-
DistributedTransaction,
32
DistributedTransactionType,
43
IDistributedSchedulerStorage,
54
IDistributedTransactionStorage,
@@ -274,14 +273,6 @@ export class RedisDistributedTransactionStorage
274273
key: string,
275274
options?: TransactionOptions & { isCancelling?: boolean }
276275
): Promise<TransactionCheckpoint | undefined> {
277-
const data = await this.redisClient.get(key)
278-
279-
if (data) {
280-
const parsedData = JSON.parse(data) as TransactionCheckpoint
281-
return parsedData
282-
}
283-
284-
// Not in Redis either - check database if needed
285276
const { idempotent, store, retentionTime } = options ?? {}
286277
if (!idempotent && !(store && isDefined(retentionTime))) {
287278
return
@@ -340,38 +331,6 @@ export class RedisDistributedTransactionStorage
340331
return
341332
}
342333

343-
async list(): Promise<TransactionCheckpoint[]> {
344-
// Replace Redis KEYS with SCAN to avoid blocking the server
345-
const transactions: TransactionCheckpoint[] = []
346-
let cursor = "0"
347-
348-
do {
349-
// Use SCAN instead of KEYS to avoid blocking Redis
350-
const [nextCursor, keys] = await this.redisClient.scan(
351-
cursor,
352-
"MATCH",
353-
DistributedTransaction.keyPrefix + ":*",
354-
"COUNT",
355-
100 // Fetch in reasonable batches
356-
)
357-
358-
cursor = nextCursor
359-
360-
if (keys.length) {
361-
// Use mget to batch retrieve multiple keys at once
362-
const values = await this.redisClient.mget(keys)
363-
364-
for (const value of values) {
365-
if (value) {
366-
transactions.push(JSON.parse(value))
367-
}
368-
}
369-
}
370-
} while (cursor !== "0")
371-
372-
return transactions
373-
}
374-
375334
async save(
376335
key: string,
377336
data: TransactionCheckpoint,
@@ -408,7 +367,11 @@ export class RedisDistributedTransactionStorage
408367
const shouldSetNX = isNotStarted && isManualTransactionId
409368

410369
// Prepare operations to be executed in batch or pipeline
411-
const stringifiedData = JSON.stringify(data)
370+
const data_ = {
371+
errors: data.errors,
372+
flow: data.flow,
373+
}
374+
const stringifiedData = JSON.stringify(data_)
412375
const pipeline = this.redisClient.pipeline()
413376

414377
// Execute Redis operations
@@ -658,14 +621,20 @@ export class RedisDistributedTransactionStorage
658621
*/
659622
const currentFlow = data.flow
660623

661-
const getOptions = {
662-
...options,
663-
isCancelling: !!data.flow.cancelledAt,
664-
} as Parameters<typeof this.get>[1]
624+
// const getOptions = {
625+
// ...options,
626+
// isCancelling: !!data.flow.cancelledAt,
627+
// } as Parameters<typeof this.get>[1]
628+
629+
const rawData = await this.redisClient.get(key)
630+
let data_ = {} as TransactionCheckpoint
631+
if (rawData) {
632+
data_ = JSON.parse(rawData)
633+
} else {
634+
data_ = { flow: {} } as TransactionCheckpoint
635+
}
665636

666-
const { flow: latestUpdatedFlow } =
667-
(await this.get(key, getOptions)) ??
668-
({ flow: {} } as { flow: TransactionFlow })
637+
const { flow: latestUpdatedFlow } = data_
669638

670639
if (!isInitialCheckpoint && !isPresent(latestUpdatedFlow)) {
671640
/**

0 commit comments

Comments
 (0)