@mastra/oracledb 0.5.2-alpha.0 → 0.5.2-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +334 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +335 -61
- package/dist/index.js.map +1 -1
- package/dist/storage/db/run-fencing.d.ts +32 -0
- package/dist/storage/db/run-fencing.d.ts.map +1 -0
- package/dist/storage/domains/memory/index.d.ts +18 -8
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/memory/messages.d.ts +6 -4
- package/dist/storage/domains/memory/messages.d.ts.map +1 -1
- package/dist/storage/domains/memory/observational-buffering.d.ts +5 -5
- package/dist/storage/domains/memory/observational-buffering.d.ts.map +1 -1
- package/dist/storage/domains/memory/observational.d.ts +3 -3
- package/dist/storage/domains/memory/observational.d.ts.map +1 -1
- package/dist/storage/domains/memory/resources.d.ts +3 -2
- package/dist/storage/domains/memory/resources.d.ts.map +1 -1
- package/dist/storage/domains/memory/threads.d.ts +5 -3
- package/dist/storage/domains/memory/threads.d.ts.map +1 -1
- package/dist/storage/domains/memory/utils.d.ts +7 -1
- package/dist/storage/domains/memory/utils.d.ts.map +1 -1
- package/dist/storage/domains/workflows/index.d.ts +19 -6
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -3434,6 +3434,59 @@ function isAppendOnlySince(storedObservations, snapshotObservations) {
|
|
|
3434
3434
|
return stored === snapshot || stored.startsWith(snapshot);
|
|
3435
3435
|
}
|
|
3436
3436
|
//#endregion
|
|
3437
|
+
//#region src/storage/db/run-fencing.ts
|
|
3438
|
+
const SINCE_EPOCH = `(SYS_EXTRACT_UTC(SYSTIMESTAMP) - TIMESTAMP '1970-01-01 00:00:00')`;
|
|
3439
|
+
/**
|
|
3440
|
+
* Epoch milliseconds on the database clock. Oracle evaluates `SYSTIMESTAMP`
|
|
3441
|
+
* once per statement, so every reference here reads the same instant, and a
|
|
3442
|
+
* statement that waits on a lock compares against the time it started. That
|
|
3443
|
+
* error only makes an existing lease look longer and a new lease shorter.
|
|
3444
|
+
*/
|
|
3445
|
+
const DB_NOW_MS = `(EXTRACT(DAY FROM ${SINCE_EPOCH}) * 86400000 + EXTRACT(HOUR FROM ${SINCE_EPOCH}) * 3600000 + EXTRACT(MINUTE FROM ${SINCE_EPOCH}) * 60000 + FLOOR(EXTRACT(SECOND FROM ${SINCE_EPOCH}) * 1000))`;
|
|
3446
|
+
const ORA_UNIQUE_CONSTRAINT = -1;
|
|
3447
|
+
const ORA_DEADLOCK = -60;
|
|
3448
|
+
const MAX_CLAIM_ATTEMPTS = 5;
|
|
3449
|
+
/**
|
|
3450
|
+
* The check half of a fenced write; call it first inside the write's
|
|
3451
|
+
* transaction. Oracle has no shared row lock, so this takes the claim row
|
|
3452
|
+
* `FOR UPDATE`: a claim that updates the row waits for the write to commit,
|
|
3453
|
+
* and a write queued behind a claim re-reads the row once the claim commits
|
|
3454
|
+
* and sees the new generation. Writes from one run serialize on its row,
|
|
3455
|
+
* which they mostly do anyway.
|
|
3456
|
+
*/
|
|
3457
|
+
async function assertRunFence(client, claimsTable, fence, operation) {
|
|
3458
|
+
const row = await client.oneOrNone(`SELECT generation AS "generation", "ownerId" FROM ${claimsTable} WHERE "runId" = :runId FOR UPDATE`, { runId: fence.runId });
|
|
3459
|
+
if (!(0, _mastra_core_storage.matchesRunFence)(row ? {
|
|
3460
|
+
generation: Number(row.generation),
|
|
3461
|
+
ownerId: String(row.ownerId)
|
|
3462
|
+
} : null, fence)) throw new _mastra_core_storage.RunFenceConflictError(fence, operation);
|
|
3463
|
+
}
|
|
3464
|
+
/**
|
|
3465
|
+
* Runs `write` in a transaction, behind the fence check when it carries a
|
|
3466
|
+
* fence.
|
|
3467
|
+
*/
|
|
3468
|
+
function withRunFence(db, claimsTable, fence, operation, write) {
|
|
3469
|
+
return db.tx(async (client) => {
|
|
3470
|
+
if (fence) await assertRunFence(client, claimsTable, fence, operation);
|
|
3471
|
+
return write(client);
|
|
3472
|
+
});
|
|
3473
|
+
}
|
|
3474
|
+
/**
|
|
3475
|
+
* Runs a transaction that creates or updates a run's claim row, retrying when
|
|
3476
|
+
* two first claims race to insert it. `FOR UPDATE` locks nothing while the row
|
|
3477
|
+
* is missing, so racing first claims both insert; the second waits on the
|
|
3478
|
+
* primary key and fails once the first commits. On retry the row exists and
|
|
3479
|
+
* the claim serializes behind its row lock. A deadlock is retried too.
|
|
3480
|
+
*/
|
|
3481
|
+
async function claimTransaction(db, fn) {
|
|
3482
|
+
for (let attempt = 1;; attempt++) try {
|
|
3483
|
+
return await db.tx((client) => fn(client));
|
|
3484
|
+
} catch (error) {
|
|
3485
|
+
const retryable = isOracleErrorCode(error, [ORA_UNIQUE_CONSTRAINT, ORA_DEADLOCK]);
|
|
3486
|
+
if (attempt >= MAX_CLAIM_ATTEMPTS || !retryable) throw error;
|
|
3487
|
+
}
|
|
3488
|
+
}
|
|
3489
|
+
//#endregion
|
|
3437
3490
|
//#region src/storage/domains/memory/utils.ts
|
|
3438
3491
|
const STORE_NAME$5 = "ORACLEDB";
|
|
3439
3492
|
const EMPTY_STRING_SENTINEL = "__MASTRA_ORACLE_EMPTY_STRING__";
|
|
@@ -3441,6 +3494,14 @@ const STRING_SENTINEL_ESCAPE_PREFIX = "__MASTRA_ORACLE_ESCAPED__";
|
|
|
3441
3494
|
function table(ctx, tableName) {
|
|
3442
3495
|
return qualifyName(tableName, ctx.schemaName);
|
|
3443
3496
|
}
|
|
3497
|
+
/**
|
|
3498
|
+
* The fence check for a memory write; call it first inside the write's
|
|
3499
|
+
* transaction. `fence` is the one `MemoryOracle` already resolved against the
|
|
3500
|
+
* run fence scope, so an unfenced write skips the check.
|
|
3501
|
+
*/
|
|
3502
|
+
async function assertMemoryFence(ctx, client, fence, operation) {
|
|
3503
|
+
if (fence) await assertRunFence(client, table(ctx, _mastra_core_storage.TABLE_MEMORY_RUN_FENCES), fence, operation);
|
|
3504
|
+
}
|
|
3444
3505
|
function storageError$1(operation, reason, details, cause, category = _mastra_core_error.ErrorCategory.THIRD_PARTY) {
|
|
3445
3506
|
return createOracleStorageError({
|
|
3446
3507
|
storeName: STORE_NAME$5,
|
|
@@ -3998,7 +4059,7 @@ async function listMessagesByResourceId(ctx, args) {
|
|
|
3998
4059
|
orderBy
|
|
3999
4060
|
});
|
|
4000
4061
|
}
|
|
4001
|
-
async function saveMessages(ctx, { messages }) {
|
|
4062
|
+
async function saveMessages(ctx, { messages, fence }) {
|
|
4002
4063
|
if (messages.length === 0) return { messages: [] };
|
|
4003
4064
|
const threadIds = /* @__PURE__ */ new Set();
|
|
4004
4065
|
try {
|
|
@@ -4008,6 +4069,7 @@ async function saveMessages(ctx, { messages }) {
|
|
|
4008
4069
|
}
|
|
4009
4070
|
for (const threadId of threadIds) if (!await ctx.getThreadById({ threadId })) throw storageError$1("SAVE_MESSAGES", "FAILED", { threadId }, /* @__PURE__ */ new Error(`Thread ${threadId} not found`), _mastra_core_error.ErrorCategory.USER);
|
|
4010
4071
|
await ctx.db.tx(async (client) => {
|
|
4072
|
+
await assertMemoryFence(ctx, client, fence, "saveMessages");
|
|
4011
4073
|
await insertMessageBatch(ctx, client, messages);
|
|
4012
4074
|
});
|
|
4013
4075
|
return { messages: new _mastra_core_agent.MessageList().add(messages, "memory").get.all.db() };
|
|
@@ -4085,7 +4147,7 @@ async function insertMessageBatch(ctx, client, messages) {
|
|
|
4085
4147
|
threadId: messageThreadId
|
|
4086
4148
|
})));
|
|
4087
4149
|
}
|
|
4088
|
-
async function updateMessages(ctx, { messages }) {
|
|
4150
|
+
async function updateMessages(ctx, { messages, fence }) {
|
|
4089
4151
|
if (messages.length === 0) return [];
|
|
4090
4152
|
const messageIds = messages.map((message) => message.id);
|
|
4091
4153
|
const existingMessages = (await ctx.listMessagesById({ messageIds })).messages;
|
|
@@ -4094,6 +4156,7 @@ async function updateMessages(ctx, { messages }) {
|
|
|
4094
4156
|
const threadIdsToUpdate = /* @__PURE__ */ new Set();
|
|
4095
4157
|
try {
|
|
4096
4158
|
await ctx.db.tx(async (client) => {
|
|
4159
|
+
await assertMemoryFence(ctx, client, fence, "updateMessages");
|
|
4097
4160
|
const semanticRecallMessageIds = [];
|
|
4098
4161
|
for (const updatePayload of messages) {
|
|
4099
4162
|
const existing = existingById.get(updatePayload.id);
|
|
@@ -4140,13 +4203,15 @@ async function updateMessages(ctx, { messages }) {
|
|
|
4140
4203
|
});
|
|
4141
4204
|
return (await ctx.listMessagesById({ messageIds })).messages;
|
|
4142
4205
|
} catch (error) {
|
|
4206
|
+
if (error instanceof _mastra_core_error.MastraError) throw error;
|
|
4143
4207
|
throw storageError$1("UPDATE_MESSAGES", "FAILED", { messageIds: messageIds.join(",") }, error);
|
|
4144
4208
|
}
|
|
4145
4209
|
}
|
|
4146
|
-
async function deleteMessages(ctx, messageIds) {
|
|
4210
|
+
async function deleteMessages(ctx, messageIds, fence) {
|
|
4147
4211
|
if (!messageIds.length) return;
|
|
4148
4212
|
try {
|
|
4149
4213
|
await ctx.db.tx(async (client) => {
|
|
4214
|
+
await assertMemoryFence(ctx, client, fence, "deleteMessages");
|
|
4150
4215
|
const threadIds = /* @__PURE__ */ new Set();
|
|
4151
4216
|
for (const [chunkIndex, chunk] of chunkValues(messageIds).entries()) {
|
|
4152
4217
|
const { sql, binds } = inClause(`messageId${chunkIndex}`, chunk);
|
|
@@ -4162,6 +4227,7 @@ async function deleteMessages(ctx, messageIds) {
|
|
|
4162
4227
|
})));
|
|
4163
4228
|
});
|
|
4164
4229
|
} catch (error) {
|
|
4230
|
+
if (error instanceof _mastra_core_error.MastraError) throw error;
|
|
4165
4231
|
throw storageError$1("DELETE_MESSAGES", "FAILED", { messageIds: messageIds.join(",") }, error);
|
|
4166
4232
|
}
|
|
4167
4233
|
}
|
|
@@ -4543,9 +4609,10 @@ async function insertObservationalMemoryRecord(ctx, record) {
|
|
|
4543
4609
|
}, error);
|
|
4544
4610
|
}
|
|
4545
4611
|
}
|
|
4546
|
-
async function updateActiveObservations(ctx, input) {
|
|
4612
|
+
async function updateActiveObservations(ctx, input, fence) {
|
|
4547
4613
|
try {
|
|
4548
|
-
return await ctx.db.tx(async (
|
|
4614
|
+
return await ctx.db.tx(async (client, connection) => {
|
|
4615
|
+
await assertMemoryFence(ctx, client, fence, "commitActiveObservations");
|
|
4549
4616
|
const row = await lockOMRow(ctx, connection, input.id, "UPDATE_ACTIVE_OBSERVATIONS");
|
|
4550
4617
|
if (row.supersededBy) return {
|
|
4551
4618
|
applied: false,
|
|
@@ -4582,10 +4649,11 @@ async function updateActiveObservations(ctx, input) {
|
|
|
4582
4649
|
throw storageError$1("UPDATE_ACTIVE_OBSERVATIONS", "FAILED", { id: input.id }, error);
|
|
4583
4650
|
}
|
|
4584
4651
|
}
|
|
4585
|
-
async function createReflectionGeneration(ctx, input) {
|
|
4652
|
+
async function createReflectionGeneration(ctx, input, fence) {
|
|
4586
4653
|
const { currentRecord } = input;
|
|
4587
4654
|
try {
|
|
4588
|
-
return await ctx.db.tx(async (
|
|
4655
|
+
return await ctx.db.tx(async (client, connection) => {
|
|
4656
|
+
await assertMemoryFence(ctx, client, fence, "createReflectionGeneration");
|
|
4589
4657
|
const row = await findOMRowForUpdate(ctx, connection, currentRecord.id);
|
|
4590
4658
|
if (!row) return currentRecord;
|
|
4591
4659
|
if (row.supersededBy) return parseOMRow(await resolveLiveOMRow(ctx, connection, row));
|
|
@@ -4993,9 +5061,10 @@ async function resolveLiveOMRow(ctx, connection, row) {
|
|
|
4993
5061
|
}
|
|
4994
5062
|
//#endregion
|
|
4995
5063
|
//#region src/storage/domains/memory/observational-buffering.ts
|
|
4996
|
-
async function updateBufferedObservations(ctx, input) {
|
|
5064
|
+
async function updateBufferedObservations(ctx, input, fence) {
|
|
4997
5065
|
try {
|
|
4998
|
-
return await ctx.db.tx(async (
|
|
5066
|
+
return await ctx.db.tx(async (client, connection) => {
|
|
5067
|
+
await assertMemoryFence(ctx, client, fence, "appendBufferedObservations");
|
|
4999
5068
|
const row = await resolveLiveOMRow(ctx, connection, await lockOMRow(ctx, connection, input.id, "UPDATE_BUFFERED_OBSERVATIONS"));
|
|
5000
5069
|
const existingChunks = parseBufferedChunks(row.bufferedObservationChunks);
|
|
5001
5070
|
if (existingChunks.some((existing) => existing.cycleId === input.chunk.cycleId) || isBufferedChunkCoveredByCursor(input.chunk.lastObservedAt, row.lastObservedAt)) return {
|
|
@@ -5038,9 +5107,10 @@ async function updateBufferedObservations(ctx, input) {
|
|
|
5038
5107
|
throw storageError$1("UPDATE_BUFFERED_OBSERVATIONS", "FAILED", { id: input.id }, error);
|
|
5039
5108
|
}
|
|
5040
5109
|
}
|
|
5041
|
-
async function swapBufferedToActive(ctx, input) {
|
|
5110
|
+
async function swapBufferedToActive(ctx, input, fence) {
|
|
5042
5111
|
try {
|
|
5043
|
-
return await ctx.db.tx(async (
|
|
5112
|
+
return await ctx.db.tx(async (client, connection) => {
|
|
5113
|
+
await assertMemoryFence(ctx, client, fence, "swapBufferedToActive");
|
|
5044
5114
|
const row = await lockOMRow(ctx, connection, input.id, "SWAP_BUFFERED_TO_ACTIVE");
|
|
5045
5115
|
if (row.supersededBy) return {
|
|
5046
5116
|
...emptySwapResult(),
|
|
@@ -5085,9 +5155,10 @@ async function swapBufferedToActive(ctx, input) {
|
|
|
5085
5155
|
throw storageError$1("SWAP_BUFFERED_TO_ACTIVE", "FAILED", { id: input.id }, error);
|
|
5086
5156
|
}
|
|
5087
5157
|
}
|
|
5088
|
-
async function updateBufferedReflection(ctx, input) {
|
|
5158
|
+
async function updateBufferedReflection(ctx, input, fence) {
|
|
5089
5159
|
try {
|
|
5090
|
-
await ctx.db.tx(async (
|
|
5160
|
+
await ctx.db.tx(async (client, connection) => {
|
|
5161
|
+
await assertMemoryFence(ctx, client, fence, "updateBufferedReflection");
|
|
5091
5162
|
assertRowsAffected((await connection.execute(`UPDATE ${table(ctx, _mastra_core_storage.TABLE_OBSERVATIONAL_MEMORY)}
|
|
5092
5163
|
SET ${OM_BUFFERED_REFLECTION} = CASE
|
|
5093
5164
|
WHEN ${OM_BUFFERED_REFLECTION} IS NOT NULL AND DBMS_LOB.GETLENGTH(${OM_BUFFERED_REFLECTION}) > 0
|
|
@@ -5112,10 +5183,11 @@ async function updateBufferedReflection(ctx, input) {
|
|
|
5112
5183
|
throw storageError$1("UPDATE_BUFFERED_REFLECTION", "FAILED", { id: input.id }, error);
|
|
5113
5184
|
}
|
|
5114
5185
|
}
|
|
5115
|
-
async function swapBufferedReflectionToActive(ctx, input) {
|
|
5186
|
+
async function swapBufferedReflectionToActive(ctx, input, fence) {
|
|
5116
5187
|
const { currentRecord } = input;
|
|
5117
5188
|
try {
|
|
5118
|
-
return await ctx.db.tx(async (
|
|
5189
|
+
return await ctx.db.tx(async (client, connection) => {
|
|
5190
|
+
await assertMemoryFence(ctx, client, fence, "swapBufferedReflectionToActive");
|
|
5119
5191
|
const row = await findOMRowForUpdate(ctx, connection, currentRecord.id);
|
|
5120
5192
|
if (!row) return currentRecord;
|
|
5121
5193
|
if (row.supersededBy) return parseOMRow(await resolveLiveOMRow(ctx, connection, row));
|
|
@@ -5268,17 +5340,24 @@ async function saveResource(ctx, { resource }) {
|
|
|
5268
5340
|
throw storageError$1("SAVE_RESOURCE", "FAILED", { resourceId: resource.id }, error);
|
|
5269
5341
|
}
|
|
5270
5342
|
}
|
|
5271
|
-
async function updateResource(ctx, { resourceId, workingMemory, metadata }) {
|
|
5343
|
+
async function updateResource(ctx, { resourceId, workingMemory, metadata, fence }) {
|
|
5272
5344
|
const existing = await ctx.getResourceById({ resourceId });
|
|
5273
|
-
|
|
5345
|
+
const newResource = () => ({
|
|
5274
5346
|
id: resourceId,
|
|
5275
5347
|
workingMemory,
|
|
5276
5348
|
metadata: metadata ?? {},
|
|
5277
5349
|
createdAt: /* @__PURE__ */ new Date(),
|
|
5278
5350
|
updatedAt: /* @__PURE__ */ new Date()
|
|
5279
|
-
}
|
|
5351
|
+
});
|
|
5352
|
+
if (!existing && !fence) return ctx.saveResource({ resource: newResource() });
|
|
5280
5353
|
try {
|
|
5281
|
-
return await ctx.db.tx(async (
|
|
5354
|
+
return await ctx.db.tx(async (client, connection) => {
|
|
5355
|
+
await assertMemoryFence(ctx, client, fence, "updateResource");
|
|
5356
|
+
if (!existing) {
|
|
5357
|
+
const resource = newResource();
|
|
5358
|
+
await mergeResourceRow(ctx, connection, resource);
|
|
5359
|
+
return resource;
|
|
5360
|
+
}
|
|
5282
5361
|
const row = rows(await connection.execute(`${resourceSelect()} FROM ${table(ctx, _mastra_core_storage.TABLE_RESOURCES)} WHERE id = :resourceId FOR UPDATE`, { resourceId }, executeOptions()))[0];
|
|
5283
5362
|
const locked = row ? parseResource(row) : existing;
|
|
5284
5363
|
const updated = {
|
|
@@ -5372,11 +5451,15 @@ async function getThreadById(ctx, { threadId, resourceId }) {
|
|
|
5372
5451
|
throw storageError$1("GET_THREAD_BY_ID", "FAILED", { threadId }, error);
|
|
5373
5452
|
}
|
|
5374
5453
|
}
|
|
5375
|
-
async function saveThread(ctx, { thread }) {
|
|
5454
|
+
async function saveThread(ctx, { thread, fence }) {
|
|
5376
5455
|
try {
|
|
5377
|
-
await
|
|
5456
|
+
await ctx.db.tx(async (client) => {
|
|
5457
|
+
await assertMemoryFence(ctx, client, fence, "saveThread");
|
|
5458
|
+
await mergeThreadRow(ctx, client, thread);
|
|
5459
|
+
});
|
|
5378
5460
|
return thread;
|
|
5379
5461
|
} catch (error) {
|
|
5462
|
+
if (error instanceof _mastra_core_error.MastraError) throw error;
|
|
5380
5463
|
throw storageError$1("SAVE_THREAD", "FAILED", { threadId: thread.id }, error);
|
|
5381
5464
|
}
|
|
5382
5465
|
}
|
|
@@ -5461,7 +5544,7 @@ async function insertThreadRow(ctx, client, thread) {
|
|
|
5461
5544
|
updatedAt: thread.updatedAt ?? /* @__PURE__ */ new Date()
|
|
5462
5545
|
});
|
|
5463
5546
|
}
|
|
5464
|
-
async function updateThread(ctx, { id, title, metadata }) {
|
|
5547
|
+
async function updateThread(ctx, { id, title, metadata, fence }) {
|
|
5465
5548
|
const existingThread = await ctx.getThreadById({ threadId: id });
|
|
5466
5549
|
if (!existingThread) throw storageError$1("UPDATE_THREAD", "FAILED", {
|
|
5467
5550
|
threadId: id,
|
|
@@ -5473,16 +5556,19 @@ async function updateThread(ctx, { id, title, metadata }) {
|
|
|
5473
5556
|
};
|
|
5474
5557
|
const updatedAt = /* @__PURE__ */ new Date();
|
|
5475
5558
|
try {
|
|
5476
|
-
await ctx.db.
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5559
|
+
await ctx.db.tx(async (client) => {
|
|
5560
|
+
await assertMemoryFence(ctx, client, fence, "updateThread");
|
|
5561
|
+
await client.none(`
|
|
5562
|
+
UPDATE ${table(ctx, _mastra_core_storage.TABLE_THREADS)}
|
|
5563
|
+
SET title = COALESCE(:title, title),
|
|
5564
|
+
metadata = :metadata,
|
|
5565
|
+
${THREAD_UPDATED_AT} = :updatedAt
|
|
5566
|
+
WHERE id = :id`, {
|
|
5567
|
+
id,
|
|
5568
|
+
title: optionalStringBind(title),
|
|
5569
|
+
metadata: jsonBind(mergedMetadata),
|
|
5570
|
+
updatedAt
|
|
5571
|
+
});
|
|
5486
5572
|
});
|
|
5487
5573
|
const updatedThread = await ctx.getThreadById({ threadId: id });
|
|
5488
5574
|
if (!updatedThread) throw storageError$1("UPDATE_THREAD", "FAILED", {
|
|
@@ -5634,7 +5720,8 @@ var MemoryOracle = class MemoryOracle extends _mastra_core_storage.MemoryStorage
|
|
|
5634
5720
|
_mastra_core_storage.TABLE_THREADS,
|
|
5635
5721
|
_mastra_core_storage.TABLE_MESSAGES,
|
|
5636
5722
|
_mastra_core_storage.TABLE_RESOURCES,
|
|
5637
|
-
_mastra_core_storage.TABLE_OBSERVATIONAL_MEMORY
|
|
5723
|
+
_mastra_core_storage.TABLE_OBSERVATIONAL_MEMORY,
|
|
5724
|
+
_mastra_core_storage.TABLE_MEMORY_RUN_FENCES
|
|
5638
5725
|
];
|
|
5639
5726
|
db;
|
|
5640
5727
|
schemaName;
|
|
@@ -5672,6 +5759,10 @@ var MemoryOracle = class MemoryOracle extends _mastra_core_storage.MemoryStorage
|
|
|
5672
5759
|
}
|
|
5673
5760
|
async init() {
|
|
5674
5761
|
await initMemorySchema(this.ctx);
|
|
5762
|
+
await this.db.createTable({
|
|
5763
|
+
tableName: _mastra_core_storage.TABLE_MEMORY_RUN_FENCES,
|
|
5764
|
+
schema: _mastra_core_storage.RUN_FENCING_TABLE_SCHEMAS[_mastra_core_storage.TABLE_MEMORY_RUN_FENCES]
|
|
5765
|
+
});
|
|
5675
5766
|
}
|
|
5676
5767
|
/**
|
|
5677
5768
|
* Mark observational memory rows that are not their key's canonical head as superseded.
|
|
@@ -5684,15 +5775,61 @@ var MemoryOracle = class MemoryOracle extends _mastra_core_storage.MemoryStorage
|
|
|
5684
5775
|
}
|
|
5685
5776
|
async dangerouslyClearAll() {
|
|
5686
5777
|
await clearAllMemoryTables(this.ctx);
|
|
5778
|
+
await this.db.clearTable(_mastra_core_storage.TABLE_MEMORY_RUN_FENCES);
|
|
5779
|
+
}
|
|
5780
|
+
supportsRunFencing() {
|
|
5781
|
+
return true;
|
|
5782
|
+
}
|
|
5783
|
+
async raiseRunFence(fence) {
|
|
5784
|
+
const fences = table(this.ctx, _mastra_core_storage.TABLE_MEMORY_RUN_FENCES);
|
|
5785
|
+
try {
|
|
5786
|
+
return await claimTransaction(this.db, async (client) => {
|
|
5787
|
+
const row = await client.oneOrNone(`SELECT generation AS "generation", "ownerId" FROM ${fences} WHERE "runId" = :runId FOR UPDATE`, { runId: fence.runId });
|
|
5788
|
+
const binds = {
|
|
5789
|
+
runId: fence.runId,
|
|
5790
|
+
generation: fence.generation,
|
|
5791
|
+
ownerId: fence.ownerId
|
|
5792
|
+
};
|
|
5793
|
+
if (!row) {
|
|
5794
|
+
await client.none(`INSERT INTO ${fences} ("runId", generation, "ownerId") VALUES (:runId, :generation, :ownerId)`, binds);
|
|
5795
|
+
return true;
|
|
5796
|
+
}
|
|
5797
|
+
const generation = Number(row.generation);
|
|
5798
|
+
if (!(generation < fence.generation) && !(generation === fence.generation && String(row.ownerId) === fence.ownerId)) return false;
|
|
5799
|
+
await client.none(`UPDATE ${fences} SET generation = :generation, "ownerId" = :ownerId, "retiredAt" = NULL WHERE "runId" = :runId`, binds);
|
|
5800
|
+
return true;
|
|
5801
|
+
});
|
|
5802
|
+
} catch (error) {
|
|
5803
|
+
throw storageError$1("RAISE_RUN_FENCE", "FAILED", { runId: fence.runId }, error);
|
|
5804
|
+
}
|
|
5805
|
+
}
|
|
5806
|
+
async retireRunFence(fence) {
|
|
5807
|
+
const fences = table(this.ctx, _mastra_core_storage.TABLE_MEMORY_RUN_FENCES);
|
|
5808
|
+
try {
|
|
5809
|
+
return await this.db.tx(async (client) => {
|
|
5810
|
+
const row = await client.oneOrNone(`SELECT generation AS "generation", "ownerId" FROM ${fences} WHERE "runId" = :runId FOR UPDATE`, { runId: fence.runId });
|
|
5811
|
+
if (!row || Number(row.generation) !== fence.generation || String(row.ownerId) !== fence.ownerId) return false;
|
|
5812
|
+
await client.none(`UPDATE ${fences} SET "retiredAt" = ${DB_NOW_MS} WHERE "runId" = :runId`, { runId: fence.runId });
|
|
5813
|
+
return true;
|
|
5814
|
+
});
|
|
5815
|
+
} catch (error) {
|
|
5816
|
+
throw storageError$1("RETIRE_RUN_FENCE", "FAILED", { runId: fence.runId }, error);
|
|
5817
|
+
}
|
|
5687
5818
|
}
|
|
5688
5819
|
async getThreadById(args) {
|
|
5689
5820
|
return getThreadById(this.ctx, args);
|
|
5690
5821
|
}
|
|
5691
|
-
async saveThread(args) {
|
|
5692
|
-
return saveThread(this.ctx,
|
|
5822
|
+
async saveThread({ fence, ...args }) {
|
|
5823
|
+
return saveThread(this.ctx, {
|
|
5824
|
+
...args,
|
|
5825
|
+
fence: (0, _mastra_core_storage.resolveRunFence)(this, fence)
|
|
5826
|
+
});
|
|
5693
5827
|
}
|
|
5694
|
-
async updateThread(args) {
|
|
5695
|
-
return updateThread(this.ctx,
|
|
5828
|
+
async updateThread({ fence, ...args }) {
|
|
5829
|
+
return updateThread(this.ctx, {
|
|
5830
|
+
...args,
|
|
5831
|
+
fence: (0, _mastra_core_storage.resolveRunFence)(this, fence)
|
|
5832
|
+
});
|
|
5696
5833
|
}
|
|
5697
5834
|
async deleteThread(args) {
|
|
5698
5835
|
return deleteThread(this.ctx, args);
|
|
@@ -5712,14 +5849,20 @@ var MemoryOracle = class MemoryOracle extends _mastra_core_storage.MemoryStorage
|
|
|
5712
5849
|
async listMessagesByResourceId(args) {
|
|
5713
5850
|
return listMessagesByResourceId(this.ctx, args);
|
|
5714
5851
|
}
|
|
5715
|
-
async saveMessages(args) {
|
|
5716
|
-
return saveMessages(this.ctx,
|
|
5852
|
+
async saveMessages({ fence, ...args }) {
|
|
5853
|
+
return saveMessages(this.ctx, {
|
|
5854
|
+
...args,
|
|
5855
|
+
fence: (0, _mastra_core_storage.resolveRunFence)(this, fence)
|
|
5856
|
+
});
|
|
5717
5857
|
}
|
|
5718
|
-
async updateMessages(args) {
|
|
5719
|
-
return updateMessages(this.ctx,
|
|
5858
|
+
async updateMessages({ fence, ...args }) {
|
|
5859
|
+
return updateMessages(this.ctx, {
|
|
5860
|
+
...args,
|
|
5861
|
+
fence: (0, _mastra_core_storage.resolveRunFence)(this, fence)
|
|
5862
|
+
});
|
|
5720
5863
|
}
|
|
5721
|
-
async deleteMessages(messageIds) {
|
|
5722
|
-
return deleteMessages(this.ctx, messageIds);
|
|
5864
|
+
async deleteMessages(messageIds, options) {
|
|
5865
|
+
return deleteMessages(this.ctx, messageIds, (0, _mastra_core_storage.resolveRunFence)(this, options?.fence));
|
|
5723
5866
|
}
|
|
5724
5867
|
async getResourceById(args) {
|
|
5725
5868
|
return getResourceById(this.ctx, args);
|
|
@@ -5727,8 +5870,11 @@ var MemoryOracle = class MemoryOracle extends _mastra_core_storage.MemoryStorage
|
|
|
5727
5870
|
async saveResource(args) {
|
|
5728
5871
|
return saveResource(this.ctx, args);
|
|
5729
5872
|
}
|
|
5730
|
-
async updateResource(args) {
|
|
5731
|
-
return updateResource(this.ctx,
|
|
5873
|
+
async updateResource({ fence, ...args }) {
|
|
5874
|
+
return updateResource(this.ctx, {
|
|
5875
|
+
...args,
|
|
5876
|
+
fence: (0, _mastra_core_storage.resolveRunFence)(this, fence)
|
|
5877
|
+
});
|
|
5732
5878
|
}
|
|
5733
5879
|
async cloneThread(args) {
|
|
5734
5880
|
const sourceThread = await this.getThreadById({ threadId: args.sourceThreadId });
|
|
@@ -5821,10 +5967,10 @@ var MemoryOracle = class MemoryOracle extends _mastra_core_storage.MemoryStorage
|
|
|
5821
5967
|
assertActiveObservationsApplied(await this.commitActiveObservations(input), input.id);
|
|
5822
5968
|
}
|
|
5823
5969
|
async commitActiveObservations(input) {
|
|
5824
|
-
return updateActiveObservations(this.ctx, input);
|
|
5970
|
+
return updateActiveObservations(this.ctx, input, (0, _mastra_core_storage.resolveRunFence)(this, void 0));
|
|
5825
5971
|
}
|
|
5826
5972
|
async createReflectionGeneration(input) {
|
|
5827
|
-
return createReflectionGeneration(this.ctx, input);
|
|
5973
|
+
return createReflectionGeneration(this.ctx, input, (0, _mastra_core_storage.resolveRunFence)(this, void 0));
|
|
5828
5974
|
}
|
|
5829
5975
|
async setReflectingFlag(id, isReflecting) {
|
|
5830
5976
|
return setReflectingFlag(this.ctx, id, isReflecting);
|
|
@@ -5851,16 +5997,16 @@ var MemoryOracle = class MemoryOracle extends _mastra_core_storage.MemoryStorage
|
|
|
5851
5997
|
await this.appendBufferedObservations(input);
|
|
5852
5998
|
}
|
|
5853
5999
|
async appendBufferedObservations(input) {
|
|
5854
|
-
return updateBufferedObservations(this.ctx, input);
|
|
6000
|
+
return updateBufferedObservations(this.ctx, input, (0, _mastra_core_storage.resolveRunFence)(this, void 0));
|
|
5855
6001
|
}
|
|
5856
6002
|
async swapBufferedToActive(input) {
|
|
5857
|
-
return swapBufferedToActive(this.ctx, input);
|
|
6003
|
+
return swapBufferedToActive(this.ctx, input, (0, _mastra_core_storage.resolveRunFence)(this, void 0));
|
|
5858
6004
|
}
|
|
5859
6005
|
async updateBufferedReflection(input) {
|
|
5860
|
-
return updateBufferedReflection(this.ctx, input);
|
|
6006
|
+
return updateBufferedReflection(this.ctx, input, (0, _mastra_core_storage.resolveRunFence)(this, void 0));
|
|
5861
6007
|
}
|
|
5862
6008
|
async swapBufferedReflectionToActive(input) {
|
|
5863
|
-
return swapBufferedReflectionToActive(this.ctx, input);
|
|
6009
|
+
return swapBufferedReflectionToActive(this.ctx, input, (0, _mastra_core_storage.resolveRunFence)(this, void 0));
|
|
5864
6010
|
}
|
|
5865
6011
|
};
|
|
5866
6012
|
//#endregion
|
|
@@ -8205,8 +8351,19 @@ const STORE_NAME$1 = "ORACLEDB";
|
|
|
8205
8351
|
const WORKFLOW_CREATED_AT = "\"createdAt\"";
|
|
8206
8352
|
const WORKFLOW_UPDATED_AT = "\"updatedAt\"";
|
|
8207
8353
|
const WORKFLOW_RESOURCE_ID = "\"resourceId\"";
|
|
8354
|
+
const RUN_OWNER_COLUMNS = `generation AS "generation", "ownerId", "leaseExpiresAt", ${DB_NOW_MS} AS "nowMs"`;
|
|
8355
|
+
function toRunOwnershipRecord(runId, row) {
|
|
8356
|
+
const leaseExpiresAt = row.leaseExpiresAt === null ? null : Number(row.leaseExpiresAt);
|
|
8357
|
+
return {
|
|
8358
|
+
runId,
|
|
8359
|
+
generation: Number(row.generation),
|
|
8360
|
+
ownerId: String(row.ownerId),
|
|
8361
|
+
leaseExpiresAt: leaseExpiresAt === null ? null : new Date(leaseExpiresAt),
|
|
8362
|
+
live: leaseExpiresAt !== null && leaseExpiresAt > Number(row.nowMs)
|
|
8363
|
+
};
|
|
8364
|
+
}
|
|
8208
8365
|
var WorkflowsOracle = class WorkflowsOracle extends _mastra_core_storage.WorkflowsStorage {
|
|
8209
|
-
static MANAGED_TABLES = [_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT];
|
|
8366
|
+
static MANAGED_TABLES = [_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT, _mastra_core_storage.TABLE_WORKFLOW_RUN_OWNERS];
|
|
8210
8367
|
db;
|
|
8211
8368
|
schemaName;
|
|
8212
8369
|
skipDefaultIndexes;
|
|
@@ -8227,10 +8384,114 @@ var WorkflowsOracle = class WorkflowsOracle extends _mastra_core_storage.Workflo
|
|
|
8227
8384
|
}
|
|
8228
8385
|
async dangerouslyClearAll() {
|
|
8229
8386
|
await this.db.clearTable(_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT);
|
|
8387
|
+
await this.db.clearTable(_mastra_core_storage.TABLE_WORKFLOW_RUN_OWNERS);
|
|
8388
|
+
}
|
|
8389
|
+
supportsRunFencing() {
|
|
8390
|
+
return true;
|
|
8391
|
+
}
|
|
8392
|
+
async claimRunOwnership({ runId, ownerId, leaseMs, force, expectedGeneration }) {
|
|
8393
|
+
const table = this.runOwnersTable();
|
|
8394
|
+
try {
|
|
8395
|
+
return await claimTransaction(this.db, async (client) => {
|
|
8396
|
+
const existing = await client.oneOrNone(`SELECT generation AS "generation" FROM ${table} WHERE "runId" = :runId FOR UPDATE`, { runId });
|
|
8397
|
+
if (!existing) {
|
|
8398
|
+
if (expectedGeneration !== void 0 && expectedGeneration !== 0) return {
|
|
8399
|
+
acquired: false,
|
|
8400
|
+
record: null
|
|
8401
|
+
};
|
|
8402
|
+
await client.none(`INSERT INTO ${table} ("runId", generation, "ownerId", "leaseExpiresAt", "updatedAt")
|
|
8403
|
+
VALUES (:runId, ${DB_NOW_MS}, :ownerId, ${DB_NOW_MS} + :leaseMs, ${DB_NOW_MS})`, {
|
|
8404
|
+
runId,
|
|
8405
|
+
ownerId,
|
|
8406
|
+
leaseMs
|
|
8407
|
+
});
|
|
8408
|
+
return {
|
|
8409
|
+
acquired: true,
|
|
8410
|
+
record: await this.readRunOwner(client, runId)
|
|
8411
|
+
};
|
|
8412
|
+
}
|
|
8413
|
+
await client.none(`UPDATE ${table}
|
|
8414
|
+
SET generation = generation + 1, "ownerId" = :ownerId, "leaseExpiresAt" = ${DB_NOW_MS} + :leaseMs,
|
|
8415
|
+
"updatedAt" = ${DB_NOW_MS}
|
|
8416
|
+
WHERE "runId" = :runId
|
|
8417
|
+
AND (:expectedGeneration IS NULL OR generation = :expectedGeneration)
|
|
8418
|
+
AND (:force = 1 OR "leaseExpiresAt" IS NULL OR "leaseExpiresAt" <= ${DB_NOW_MS})`, {
|
|
8419
|
+
runId,
|
|
8420
|
+
ownerId,
|
|
8421
|
+
leaseMs,
|
|
8422
|
+
expectedGeneration: expectedGeneration ?? null,
|
|
8423
|
+
force: force === true ? 1 : 0
|
|
8424
|
+
});
|
|
8425
|
+
const record = await this.readRunOwner(client, runId);
|
|
8426
|
+
return record && record.generation === Number(existing.generation) + 1 ? {
|
|
8427
|
+
acquired: true,
|
|
8428
|
+
record
|
|
8429
|
+
} : {
|
|
8430
|
+
acquired: false,
|
|
8431
|
+
record
|
|
8432
|
+
};
|
|
8433
|
+
});
|
|
8434
|
+
} catch (error) {
|
|
8435
|
+
throw this.storageError("CLAIM_RUN_OWNERSHIP", "FAILED", { runId }, error);
|
|
8436
|
+
}
|
|
8437
|
+
}
|
|
8438
|
+
async renewRunOwnership({ leaseMs, ...fence }) {
|
|
8439
|
+
try {
|
|
8440
|
+
return await this.db.tx(async (client) => {
|
|
8441
|
+
await client.none(`UPDATE ${this.runOwnersTable()}
|
|
8442
|
+
SET "leaseExpiresAt" = ${DB_NOW_MS} + :leaseMs, "updatedAt" = ${DB_NOW_MS}
|
|
8443
|
+
WHERE "runId" = :runId AND generation = :generation AND "ownerId" = :ownerId
|
|
8444
|
+
AND "leaseExpiresAt" IS NOT NULL`, {
|
|
8445
|
+
runId: fence.runId,
|
|
8446
|
+
generation: fence.generation,
|
|
8447
|
+
ownerId: fence.ownerId,
|
|
8448
|
+
leaseMs
|
|
8449
|
+
});
|
|
8450
|
+
const record = await this.readRunOwner(client, fence.runId);
|
|
8451
|
+
return record !== null && record.generation === fence.generation && record.ownerId === fence.ownerId && record.leaseExpiresAt !== null ? {
|
|
8452
|
+
renewed: true,
|
|
8453
|
+
record
|
|
8454
|
+
} : {
|
|
8455
|
+
renewed: false,
|
|
8456
|
+
record
|
|
8457
|
+
};
|
|
8458
|
+
});
|
|
8459
|
+
} catch (error) {
|
|
8460
|
+
throw this.storageError("RENEW_RUN_OWNERSHIP", "FAILED", { runId: fence.runId }, error);
|
|
8461
|
+
}
|
|
8230
8462
|
}
|
|
8231
|
-
async
|
|
8463
|
+
async releaseRunOwnership(fence) {
|
|
8232
8464
|
try {
|
|
8233
8465
|
return await this.db.tx(async (client) => {
|
|
8466
|
+
await client.none(`UPDATE ${this.runOwnersTable()} SET "leaseExpiresAt" = NULL, "updatedAt" = ${DB_NOW_MS}
|
|
8467
|
+
WHERE "runId" = :runId AND generation = :generation AND "ownerId" = :ownerId`, {
|
|
8468
|
+
runId: fence.runId,
|
|
8469
|
+
generation: fence.generation,
|
|
8470
|
+
ownerId: fence.ownerId
|
|
8471
|
+
});
|
|
8472
|
+
const record = await this.readRunOwner(client, fence.runId);
|
|
8473
|
+
return record !== null && record.generation === fence.generation && record.ownerId === fence.ownerId;
|
|
8474
|
+
});
|
|
8475
|
+
} catch (error) {
|
|
8476
|
+
throw this.storageError("RELEASE_RUN_OWNERSHIP", "FAILED", { runId: fence.runId }, error);
|
|
8477
|
+
}
|
|
8478
|
+
}
|
|
8479
|
+
async getRunOwnership({ runId }) {
|
|
8480
|
+
try {
|
|
8481
|
+
return await this.readRunOwner(this.db, runId);
|
|
8482
|
+
} catch (error) {
|
|
8483
|
+
throw this.storageError("GET_RUN_OWNERSHIP", "FAILED", { runId }, error);
|
|
8484
|
+
}
|
|
8485
|
+
}
|
|
8486
|
+
async readRunOwner(client, runId) {
|
|
8487
|
+
const row = await client.oneOrNone(`SELECT ${RUN_OWNER_COLUMNS} FROM ${this.runOwnersTable()} WHERE "runId" = :runId`, { runId });
|
|
8488
|
+
return row ? toRunOwnershipRecord(runId, row) : null;
|
|
8489
|
+
}
|
|
8490
|
+
async updateWorkflowResults({ workflowName, runId, stepId, result, requestContext, state, fence: explicitFence }) {
|
|
8491
|
+
const fence = (0, _mastra_core_storage.resolveRunFence)(this, explicitFence, runId);
|
|
8492
|
+
try {
|
|
8493
|
+
return await this.db.tx(async (client) => {
|
|
8494
|
+
if (fence) await assertRunFence(client, this.runOwnersTable(), fence, "updateWorkflowResults");
|
|
8234
8495
|
await this.ensureWorkflowRunRow(client, workflowName, runId);
|
|
8235
8496
|
const existing = await client.one(`SELECT snapshot AS "snapshot", ${WORKFLOW_RESOURCE_ID} AS "resourceId" FROM ${this.table()} WHERE workflow_name = :workflowName AND run_id = :runId FOR UPDATE`, {
|
|
8236
8497
|
workflowName,
|
|
@@ -8254,6 +8515,7 @@ var WorkflowsOracle = class WorkflowsOracle extends _mastra_core_storage.Workflo
|
|
|
8254
8515
|
return snapshot.context;
|
|
8255
8516
|
});
|
|
8256
8517
|
} catch (error) {
|
|
8518
|
+
if ((0, _mastra_core_storage.isRunFenceConflictError)(error)) throw error;
|
|
8257
8519
|
throw this.storageError("UPDATE_WORKFLOW_RESULTS", "FAILED", {
|
|
8258
8520
|
workflowName,
|
|
8259
8521
|
runId,
|
|
@@ -8261,9 +8523,11 @@ var WorkflowsOracle = class WorkflowsOracle extends _mastra_core_storage.Workflo
|
|
|
8261
8523
|
}, error);
|
|
8262
8524
|
}
|
|
8263
8525
|
}
|
|
8264
|
-
async updateWorkflowState({ workflowName, runId, opts }) {
|
|
8526
|
+
async updateWorkflowState({ workflowName, runId, opts, fence: explicitFence }) {
|
|
8527
|
+
const fence = (0, _mastra_core_storage.resolveRunFence)(this, explicitFence, runId);
|
|
8265
8528
|
try {
|
|
8266
8529
|
return await this.db.tx(async (client) => {
|
|
8530
|
+
if (fence) await assertRunFence(client, this.runOwnersTable(), fence, "updateWorkflowState");
|
|
8267
8531
|
const existing = await client.oneOrNone(`SELECT snapshot AS "snapshot" FROM ${this.table()} WHERE workflow_name = :workflowName AND run_id = :runId FOR UPDATE`, {
|
|
8268
8532
|
workflowName,
|
|
8269
8533
|
runId
|
|
@@ -8286,24 +8550,26 @@ var WorkflowsOracle = class WorkflowsOracle extends _mastra_core_storage.Workflo
|
|
|
8286
8550
|
return updatedSnapshot;
|
|
8287
8551
|
});
|
|
8288
8552
|
} catch (error) {
|
|
8553
|
+
if ((0, _mastra_core_storage.isRunFenceConflictError)(error)) throw error;
|
|
8289
8554
|
throw this.storageError("UPDATE_WORKFLOW_STATE", "FAILED", {
|
|
8290
8555
|
workflowName,
|
|
8291
8556
|
runId
|
|
8292
8557
|
}, error);
|
|
8293
8558
|
}
|
|
8294
8559
|
}
|
|
8295
|
-
async persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot, createdAt, updatedAt }) {
|
|
8560
|
+
async persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot, createdAt, updatedAt, fence }) {
|
|
8296
8561
|
try {
|
|
8297
8562
|
const now = /* @__PURE__ */ new Date();
|
|
8298
|
-
await this.db.none(this.workflowMergeSql(), {
|
|
8563
|
+
await withRunFence(this.db, this.runOwnersTable(), (0, _mastra_core_storage.resolveRunFence)(this, fence, runId), "persistWorkflowSnapshot", (client) => client.none(this.workflowMergeSql(), {
|
|
8299
8564
|
workflowName,
|
|
8300
8565
|
runId,
|
|
8301
8566
|
resourceId: resourceId ?? null,
|
|
8302
8567
|
snapshot: jsonBind(snapshot),
|
|
8303
8568
|
createdAt: createdAt ?? now,
|
|
8304
8569
|
updatedAt: updatedAt ?? now
|
|
8305
|
-
});
|
|
8570
|
+
}));
|
|
8306
8571
|
} catch (error) {
|
|
8572
|
+
if ((0, _mastra_core_storage.isRunFenceConflictError)(error)) throw error;
|
|
8307
8573
|
throw this.storageError("PERSIST_WORKFLOW_SNAPSHOT", "FAILED", {
|
|
8308
8574
|
workflowName,
|
|
8309
8575
|
runId
|
|
@@ -8367,13 +8633,14 @@ var WorkflowsOracle = class WorkflowsOracle extends _mastra_core_storage.Workflo
|
|
|
8367
8633
|
}, error);
|
|
8368
8634
|
}
|
|
8369
8635
|
}
|
|
8370
|
-
async deleteWorkflowRunById({ runId, workflowName }) {
|
|
8636
|
+
async deleteWorkflowRunById({ runId, workflowName, fence }) {
|
|
8371
8637
|
try {
|
|
8372
|
-
await this.db.none(`DELETE FROM ${this.table()} WHERE workflow_name = :workflowName AND run_id = :runId`, {
|
|
8638
|
+
await withRunFence(this.db, this.runOwnersTable(), (0, _mastra_core_storage.resolveRunFence)(this, fence, runId), "deleteWorkflowRunById", (client) => client.none(`DELETE FROM ${this.table()} WHERE workflow_name = :workflowName AND run_id = :runId`, {
|
|
8373
8639
|
workflowName,
|
|
8374
8640
|
runId
|
|
8375
|
-
});
|
|
8641
|
+
}));
|
|
8376
8642
|
} catch (error) {
|
|
8643
|
+
if ((0, _mastra_core_storage.isRunFenceConflictError)(error)) throw error;
|
|
8377
8644
|
throw this.storageError("DELETE_WORKFLOW_RUN_BY_ID", "FAILED", {
|
|
8378
8645
|
runId,
|
|
8379
8646
|
workflowName
|
|
@@ -8392,6 +8659,10 @@ var WorkflowsOracle = class WorkflowsOracle extends _mastra_core_storage.Workflo
|
|
|
8392
8659
|
CONSTRAINT ${this.constraint("MASTRA_WORKFLOW_SNAPSHOT_PK")} PRIMARY KEY (workflow_name, run_id)
|
|
8393
8660
|
)`, [-955]);
|
|
8394
8661
|
await this.db.executeDdl(`ALTER TABLE ${this.table()} ADD (${WORKFLOW_RESOURCE_ID} VARCHAR2(512))`, [-1430]);
|
|
8662
|
+
await this.db.createTable({
|
|
8663
|
+
tableName: _mastra_core_storage.TABLE_WORKFLOW_RUN_OWNERS,
|
|
8664
|
+
schema: _mastra_core_storage.RUN_FENCING_TABLE_SCHEMAS[_mastra_core_storage.TABLE_WORKFLOW_RUN_OWNERS]
|
|
8665
|
+
});
|
|
8395
8666
|
}
|
|
8396
8667
|
async createIndexes() {
|
|
8397
8668
|
await this.db.withConnection(async (connection) => {
|
|
@@ -8529,6 +8800,9 @@ var WorkflowsOracle = class WorkflowsOracle extends _mastra_core_storage.Workflo
|
|
|
8529
8800
|
table() {
|
|
8530
8801
|
return qualifyName(_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT, this.schemaName);
|
|
8531
8802
|
}
|
|
8803
|
+
runOwnersTable() {
|
|
8804
|
+
return qualifyName(_mastra_core_storage.TABLE_WORKFLOW_RUN_OWNERS, this.schemaName);
|
|
8805
|
+
}
|
|
8532
8806
|
indexName(indexName) {
|
|
8533
8807
|
return indexNameForTable(indexName, "IDX");
|
|
8534
8808
|
}
|