@convex-dev/workflow
Version:
Convex component for durably executing workflows.
109 lines • 3.17 kB
JavaScript
import { resultValidator, vResultValidator, vWorkIdValidator, workIdValidator, vOnComplete, } from "@convex-dev/workpool";
import { defineSchema, defineTable } from "convex/server";
import { convexToJson, v } from "convex/values";
import { logLevel } from "./logging.js";
import { deprecated, literals } from "convex-helpers/validators";
export function valueSize(value) {
return JSON.stringify(convexToJson(value)).length;
}
export function resultSize(result) {
let size = 0;
size += result.kind.length;
switch (result.kind) {
case "success": {
size += 8 + valueSize(result.returnValue);
break;
}
case "failed": {
size += result.error.length;
break;
}
case "canceled": {
break;
}
}
return size;
}
const workflowObject = {
name: v.optional(v.string()),
workflowHandle: v.string(),
args: v.any(),
onComplete: v.optional(vOnComplete),
logLevel: deprecated,
startedAt: deprecated,
state: deprecated,
// undefined
runResult: v.optional(vResultValidator),
// Internal execution status, used to totally order mutations.
generationNumber: v.number(),
};
export const workflowDocument = v.object({
_id: v.string(),
_creationTime: v.number(),
...workflowObject,
});
export const step = v.object({
name: v.string(),
inProgress: v.boolean(),
workId: v.optional(vWorkIdValidator),
functionType: literals("query", "mutation", "action"),
handle: v.string(),
argsSize: v.number(),
args: v.any(),
runResult: v.optional(vResultValidator),
startedAt: v.number(),
completedAt: v.optional(v.number()),
});
function stepSize(step) {
let size = 0;
size += step.name.length;
size += 1; // inProgress
if (step.workId) {
size += step.workId.length;
}
size += step.functionType.length;
size += step.handle.length;
// TODO: start time, for scheduled steps
size += 8 + step.argsSize;
if (step.runResult) {
size += resultSize(step.runResult);
}
size += 8; // startedAt
size += 8; // completedAt
return size;
}
const journalObject = {
workflowId: v.id("workflows"),
stepNumber: v.number(),
step,
};
export const journalDocument = v.object({
_id: v.string(),
_creationTime: v.number(),
...journalObject,
});
export function journalEntrySize(entry) {
let size = 0;
size += entry._id.length;
size += 8; // _creationTime
size += entry.workflowId.length;
size += 8; // stepNumber
size += stepSize(entry.step);
return size;
}
export default defineSchema({
config: defineTable({
logLevel: v.optional(logLevel),
maxParallelism: v.optional(v.number()),
}),
workflows: defineTable(workflowObject),
steps: defineTable(journalObject)
.index("workflow", ["workflowId", "stepNumber"])
.index("inProgress", ["step.inProgress", "workflowId"]),
onCompleteFailures: defineTable({
workId: workIdValidator,
result: resultValidator,
context: v.any(),
}),
});
//# sourceMappingURL=schema.js.map