@convex-dev/workpool 0.1.3-alpha.0 → 0.2.0-beta.0

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.
Files changed (113) hide show
  1. package/README.md +144 -4
  2. package/dist/commonjs/client/index.d.ts +123 -35
  3. package/dist/commonjs/client/index.d.ts.map +1 -1
  4. package/dist/commonjs/client/index.js +122 -15
  5. package/dist/commonjs/client/index.js.map +1 -1
  6. package/dist/commonjs/client/utils.d.ts +16 -0
  7. package/dist/commonjs/client/utils.d.ts.map +1 -0
  8. package/dist/commonjs/client/utils.js +2 -0
  9. package/dist/commonjs/client/utils.js.map +1 -0
  10. package/dist/commonjs/component/convex.config.d.ts.map +1 -1
  11. package/dist/commonjs/component/convex.config.js +0 -2
  12. package/dist/commonjs/component/convex.config.js.map +1 -1
  13. package/dist/commonjs/component/kick.d.ts +9 -0
  14. package/dist/commonjs/component/kick.d.ts.map +1 -0
  15. package/dist/commonjs/component/kick.js +97 -0
  16. package/dist/commonjs/component/kick.js.map +1 -0
  17. package/dist/commonjs/component/lib.d.ts +23 -32
  18. package/dist/commonjs/component/lib.d.ts.map +1 -1
  19. package/dist/commonjs/component/lib.js +70 -564
  20. package/dist/commonjs/component/lib.js.map +1 -1
  21. package/dist/commonjs/component/logging.d.ts +6 -4
  22. package/dist/commonjs/component/logging.d.ts.map +1 -1
  23. package/dist/commonjs/component/logging.js +13 -2
  24. package/dist/commonjs/component/logging.js.map +1 -1
  25. package/dist/commonjs/component/loop.d.ts +26 -0
  26. package/dist/commonjs/component/loop.d.ts.map +1 -0
  27. package/dist/commonjs/component/loop.js +453 -0
  28. package/dist/commonjs/component/loop.js.map +1 -0
  29. package/dist/commonjs/component/recovery.d.ts +8 -0
  30. package/dist/commonjs/component/recovery.d.ts.map +1 -0
  31. package/dist/commonjs/component/recovery.js +74 -0
  32. package/dist/commonjs/component/recovery.js.map +1 -0
  33. package/dist/commonjs/component/schema.d.ts +163 -93
  34. package/dist/commonjs/component/schema.d.ts.map +1 -1
  35. package/dist/commonjs/component/schema.js +54 -65
  36. package/dist/commonjs/component/schema.js.map +1 -1
  37. package/dist/commonjs/component/shared.d.ts +130 -0
  38. package/dist/commonjs/component/shared.d.ts.map +1 -0
  39. package/dist/commonjs/component/shared.js +65 -0
  40. package/dist/commonjs/component/shared.js.map +1 -0
  41. package/dist/commonjs/component/stats.d.ts +3 -2
  42. package/dist/commonjs/component/stats.d.ts.map +1 -1
  43. package/dist/commonjs/component/stats.js +17 -3
  44. package/dist/commonjs/component/stats.js.map +1 -1
  45. package/dist/commonjs/component/worker.d.ts +25 -0
  46. package/dist/commonjs/component/worker.d.ts.map +1 -0
  47. package/dist/commonjs/component/worker.js +86 -0
  48. package/dist/commonjs/component/worker.js.map +1 -0
  49. package/dist/esm/client/index.d.ts +123 -35
  50. package/dist/esm/client/index.d.ts.map +1 -1
  51. package/dist/esm/client/index.js +122 -15
  52. package/dist/esm/client/index.js.map +1 -1
  53. package/dist/esm/client/utils.d.ts +16 -0
  54. package/dist/esm/client/utils.d.ts.map +1 -0
  55. package/dist/esm/client/utils.js +2 -0
  56. package/dist/esm/client/utils.js.map +1 -0
  57. package/dist/esm/component/convex.config.d.ts.map +1 -1
  58. package/dist/esm/component/convex.config.js +0 -2
  59. package/dist/esm/component/convex.config.js.map +1 -1
  60. package/dist/esm/component/kick.d.ts +9 -0
  61. package/dist/esm/component/kick.d.ts.map +1 -0
  62. package/dist/esm/component/kick.js +97 -0
  63. package/dist/esm/component/kick.js.map +1 -0
  64. package/dist/esm/component/lib.d.ts +23 -32
  65. package/dist/esm/component/lib.d.ts.map +1 -1
  66. package/dist/esm/component/lib.js +70 -564
  67. package/dist/esm/component/lib.js.map +1 -1
  68. package/dist/esm/component/logging.d.ts +6 -4
  69. package/dist/esm/component/logging.d.ts.map +1 -1
  70. package/dist/esm/component/logging.js +13 -2
  71. package/dist/esm/component/logging.js.map +1 -1
  72. package/dist/esm/component/loop.d.ts +26 -0
  73. package/dist/esm/component/loop.d.ts.map +1 -0
  74. package/dist/esm/component/loop.js +453 -0
  75. package/dist/esm/component/loop.js.map +1 -0
  76. package/dist/esm/component/recovery.d.ts +8 -0
  77. package/dist/esm/component/recovery.d.ts.map +1 -0
  78. package/dist/esm/component/recovery.js +74 -0
  79. package/dist/esm/component/recovery.js.map +1 -0
  80. package/dist/esm/component/schema.d.ts +163 -93
  81. package/dist/esm/component/schema.d.ts.map +1 -1
  82. package/dist/esm/component/schema.js +54 -65
  83. package/dist/esm/component/schema.js.map +1 -1
  84. package/dist/esm/component/shared.d.ts +130 -0
  85. package/dist/esm/component/shared.d.ts.map +1 -0
  86. package/dist/esm/component/shared.js +65 -0
  87. package/dist/esm/component/shared.js.map +1 -0
  88. package/dist/esm/component/stats.d.ts +3 -2
  89. package/dist/esm/component/stats.d.ts.map +1 -1
  90. package/dist/esm/component/stats.js +17 -3
  91. package/dist/esm/component/stats.js.map +1 -1
  92. package/dist/esm/component/worker.d.ts +25 -0
  93. package/dist/esm/component/worker.d.ts.map +1 -0
  94. package/dist/esm/component/worker.js +86 -0
  95. package/dist/esm/component/worker.js.map +1 -0
  96. package/package.json +6 -5
  97. package/src/client/index.ts +231 -70
  98. package/src/client/utils.ts +45 -0
  99. package/src/component/README.md +73 -0
  100. package/src/component/_generated/api.d.ts +36 -66
  101. package/src/component/convex.config.ts +0 -3
  102. package/src/component/kick.test.ts +286 -0
  103. package/src/component/kick.ts +118 -0
  104. package/src/component/lib.test.ts +203 -0
  105. package/src/component/lib.ts +80 -671
  106. package/src/component/logging.ts +24 -10
  107. package/src/component/loop.ts +579 -0
  108. package/src/component/recovery.ts +79 -0
  109. package/src/component/schema.ts +59 -77
  110. package/src/component/setup.test.ts +5 -0
  111. package/src/component/shared.ts +127 -0
  112. package/src/component/stats.ts +20 -6
  113. package/src/component/worker.ts +94 -0
@@ -0,0 +1,8 @@
1
+ export declare const recover: import("convex/server").RegisteredMutation<"internal", {
2
+ jobs: {
3
+ workId: import("convex/values").GenericId<"work">;
4
+ scheduledId: import("convex/values").GenericId<"_scheduled_functions">;
5
+ started: number;
6
+ }[];
7
+ }, Promise<void>>;
8
+ //# sourceMappingURL=recovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery.d.ts","sourceRoot":"","sources":["../../../src/component/recovery.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,OAAO;;;;;;iBAuElB,CAAC"}
@@ -0,0 +1,74 @@
1
+ import { internalMutation } from "./_generated/server.js";
2
+ import { kickMainLoop } from "./kick.js";
3
+ import { createLogger } from "./logging.js";
4
+ import schema from "./schema.js";
5
+ import { nextSegment } from "./shared.js";
6
+ export const recover = internalMutation({
7
+ args: {
8
+ jobs: schema.tables.internalState.validator.fields.running,
9
+ },
10
+ handler: async (ctx, { jobs }) => {
11
+ const globals = await ctx.db.query("globals").unique();
12
+ const console = createLogger(globals?.logLevel);
13
+ const completed = [];
14
+ let didAnything = false;
15
+ const segment = nextSegment();
16
+ await Promise.all(jobs.map(async (job) => {
17
+ const scheduled = await ctx.db.system.get(job.scheduledId);
18
+ const preamble = `[recovery] Scheduled job ${job.scheduledId} for work ${job.workId}`;
19
+ if (scheduled === null) {
20
+ console.warn(`${preamble} not found`);
21
+ completed.push({
22
+ workId: job.workId,
23
+ runResult: { kind: "failed", error: `Scheduled job not found` },
24
+ });
25
+ return;
26
+ }
27
+ // This will find everything that timed out, failed ungracefully, was
28
+ // canceled, or succeeded without a return value.
29
+ switch (scheduled.state.kind) {
30
+ case "failed": {
31
+ console.debug(`${preamble} failed and detected in recovery`);
32
+ const pendingCompletion = await ctx.db
33
+ .query("pendingCompletion")
34
+ .withIndex("workId", (q) => q.eq("workId", job.workId))
35
+ .first();
36
+ if (pendingCompletion) {
37
+ console.debug(`${preamble} already in pendingCompletion, not reporting`);
38
+ }
39
+ else {
40
+ await ctx.db.insert("pendingCompletion", {
41
+ runResult: scheduled.state,
42
+ workId: job.workId,
43
+ segment,
44
+ });
45
+ didAnything = true;
46
+ }
47
+ break;
48
+ }
49
+ case "canceled": {
50
+ console.debug(`${preamble} was canceled and detected in recovery`);
51
+ const pendingCancelation = await ctx.db
52
+ .query("pendingCancelation")
53
+ .withIndex("workId", (q) => q.eq("workId", job.workId))
54
+ .first();
55
+ if (pendingCancelation) {
56
+ console.debug(`${preamble} already in pendingCancelation, not reporting`);
57
+ }
58
+ else {
59
+ await ctx.db.insert("pendingCancelation", {
60
+ workId: job.workId,
61
+ segment,
62
+ });
63
+ didAnything = true;
64
+ }
65
+ break;
66
+ }
67
+ }
68
+ }));
69
+ if (didAnything) {
70
+ await kickMainLoop(ctx, "recovery");
71
+ }
72
+ },
73
+ });
74
+ //# sourceMappingURL=recovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery.js","sourceRoot":"","sources":["../../../src/component/recovery.ts"],"names":[],"mappings":"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"}
@@ -1,154 +1,224 @@
1
- import { Infer } from "convex/values";
2
- export declare const completionStatus: import("convex/values").VUnion<"success" | "error" | "canceled" | "timeout", [import("convex/values").VLiteral<"success", "required">, import("convex/values").VLiteral<"error", "required">, import("convex/values").VLiteral<"canceled", "required">, import("convex/values").VLiteral<"timeout", "required">], "required", never>;
3
- export type CompletionStatus = Infer<typeof completionStatus>;
4
- /**
5
- Data flow:
6
-
7
- - The mutation `mainLoop` runs periodically and serially.
8
- - Several tables act as queues, with client-driven mutations enqueueing at high
9
- timestamps and `mainLoop` popping at low timestamps:
10
- pendingStart, pendingCompletion, and pendingCancelation.
11
- - The `enqueue` mutation writes to pendingStart.
12
- - The `cancel` mutation writes to pendingCancelation.
13
- - The `saveResult` mutation, run as part of scheduled work, writes to pendingCompletion.
14
- - mainLoop processes the queues:
15
- - pendingStart => inProgressWork.
16
- - pendingCompletion and pendingCancelation => completedWork.
17
- - inProgressWork that finishes uncleanly (timeout or system failure) => completedWork.
18
- - `mainLoop` schedules itself to run.
19
- - `enqueue`, `cancel`, and `saveResult` mutations check when `mainLoop` is scheduled to run,
20
- and if it's too far in the future, they schedule it to run sooner.
21
- - `status` query reads from pendingWork and completedWork.
22
- - `cleanup` mutation deletes old rows from completedWork.
23
-
24
- To avoid OCCs, we restrict which mutations can read and write from each table:
25
- - pools: read by all, written only when static Workpool options change.
26
- - mainLoop (table): read by all, written mostly by `mainLoop`.
27
- If `mainLoop` will not run for a while, mainLoop table is written by `enqueue`, `cancel`, or `saveResult`.
28
- - pendingWork: `enqueue` inserts at high timestamps, `mainLoop` pops at low timestamps. `status` query does point-reads.
29
- - pendingCompletion: `saveResult` inserts at high timestamps, `mainLoop` pops at low timestamps.
30
- - pendingCancelation: `cancel` inserts at high timestamps, `mainLoop` pops at low timestamps.
31
- - inProgressWork: `mainLoop` inserts, reads all, and deletes.
32
- - completedWork: `mainLoop` inserts at hight timestamps, `status` query reads, `cleanup` deletes at low timestamps.
33
-
34
- */
35
1
  declare const _default: import("convex/server").SchemaDefinition<{
36
- pool: import("convex/server").TableDefinition<import("convex/values").VObject<{
2
+ globals: import("convex/server").TableDefinition<import("convex/values").VObject<{
37
3
  maxParallelism: number;
38
- statusTtl: number;
39
4
  logLevel: "DEBUG" | "INFO" | "WARN" | "ERROR";
40
5
  }, {
41
6
  maxParallelism: import("convex/values").VFloat64<number, "required">;
42
- statusTtl: import("convex/values").VFloat64<number, "required">;
43
7
  logLevel: import("convex/values").VUnion<"DEBUG" | "INFO" | "WARN" | "ERROR", [import("convex/values").VLiteral<"DEBUG", "required">, import("convex/values").VLiteral<"INFO", "required">, import("convex/values").VLiteral<"WARN", "required">, import("convex/values").VLiteral<"ERROR", "required">], "required", never>;
44
- }, "required", "maxParallelism" | "statusTtl" | "logLevel">, {}, {}, {}>;
45
- mainLoop: import("convex/server").TableDefinition<import("convex/values").VObject<{
8
+ }, "required", "maxParallelism" | "logLevel">, {}, {}, {}>;
9
+ internalState: import("convex/server").TableDefinition<import("convex/values").VObject<{
10
+ running: {
11
+ workId: import("convex/values").GenericId<"work">;
12
+ scheduledId: import("convex/values").GenericId<"_scheduled_functions">;
13
+ started: number;
14
+ }[];
15
+ lastRecovery: bigint;
16
+ generation: bigint;
17
+ segmentCursors: {
18
+ incoming: bigint;
19
+ completion: bigint;
20
+ cancelation: bigint;
21
+ };
22
+ report: {
23
+ failed: number;
24
+ canceled: number;
25
+ completed: number;
26
+ succeeded: number;
27
+ retries: number;
28
+ lastReportTs: number;
29
+ };
30
+ }, {
31
+ generation: import("convex/values").VInt64<bigint, "required">;
32
+ segmentCursors: import("convex/values").VObject<{
33
+ incoming: bigint;
34
+ completion: bigint;
35
+ cancelation: bigint;
36
+ }, {
37
+ incoming: import("convex/values").VInt64<bigint, "required">;
38
+ completion: import("convex/values").VInt64<bigint, "required">;
39
+ cancelation: import("convex/values").VInt64<bigint, "required">;
40
+ }, "required", "incoming" | "completion" | "cancelation">;
41
+ lastRecovery: import("convex/values").VInt64<bigint, "required">;
42
+ report: import("convex/values").VObject<{
43
+ failed: number;
44
+ canceled: number;
45
+ completed: number;
46
+ succeeded: number;
47
+ retries: number;
48
+ lastReportTs: number;
49
+ }, {
50
+ completed: import("convex/values").VFloat64<number, "required">;
51
+ succeeded: import("convex/values").VFloat64<number, "required">;
52
+ failed: import("convex/values").VFloat64<number, "required">;
53
+ retries: import("convex/values").VFloat64<number, "required">;
54
+ canceled: import("convex/values").VFloat64<number, "required">;
55
+ lastReportTs: import("convex/values").VFloat64<number, "required">;
56
+ }, "required", "failed" | "canceled" | "completed" | "succeeded" | "retries" | "lastReportTs">;
57
+ running: import("convex/values").VArray<{
58
+ workId: import("convex/values").GenericId<"work">;
59
+ scheduledId: import("convex/values").GenericId<"_scheduled_functions">;
60
+ started: number;
61
+ }[], import("convex/values").VObject<{
62
+ workId: import("convex/values").GenericId<"work">;
63
+ scheduledId: import("convex/values").GenericId<"_scheduled_functions">;
64
+ started: number;
65
+ }, {
66
+ workId: import("convex/values").VId<import("convex/values").GenericId<"work">, "required">;
67
+ scheduledId: import("convex/values").VId<import("convex/values").GenericId<"_scheduled_functions">, "required">;
68
+ started: import("convex/values").VFloat64<number, "required">;
69
+ }, "required", "workId" | "scheduledId" | "started">, "required">;
70
+ }, "required", "running" | "lastRecovery" | "generation" | "segmentCursors" | "report" | "segmentCursors.incoming" | "segmentCursors.completion" | "segmentCursors.cancelation" | "report.failed" | "report.canceled" | "report.completed" | "report.succeeded" | "report.retries" | "report.lastReportTs">, {}, {}, {}>;
71
+ runStatus: import("convex/server").TableDefinition<import("convex/values").VObject<{
46
72
  state: {
47
73
  kind: "running";
48
74
  } | {
49
75
  kind: "scheduled";
50
- runAtTime: number;
51
- fn: import("convex/values").GenericId<"_scheduled_functions">;
76
+ generation: bigint;
77
+ scheduledId: import("convex/values").GenericId<"_scheduled_functions">;
78
+ segment: bigint;
79
+ saturated: boolean;
52
80
  } | {
53
81
  kind: "idle";
82
+ generation: bigint;
54
83
  };
55
84
  }, {
56
85
  state: import("convex/values").VUnion<{
57
86
  kind: "running";
58
87
  } | {
59
88
  kind: "scheduled";
60
- runAtTime: number;
61
- fn: import("convex/values").GenericId<"_scheduled_functions">;
89
+ generation: bigint;
90
+ scheduledId: import("convex/values").GenericId<"_scheduled_functions">;
91
+ segment: bigint;
92
+ saturated: boolean;
62
93
  } | {
63
94
  kind: "idle";
95
+ generation: bigint;
64
96
  }, [import("convex/values").VObject<{
65
97
  kind: "running";
66
98
  }, {
67
99
  kind: import("convex/values").VLiteral<"running", "required">;
68
100
  }, "required", "kind">, import("convex/values").VObject<{
69
101
  kind: "scheduled";
70
- runAtTime: number;
71
- fn: import("convex/values").GenericId<"_scheduled_functions">;
102
+ generation: bigint;
103
+ scheduledId: import("convex/values").GenericId<"_scheduled_functions">;
104
+ segment: bigint;
105
+ saturated: boolean;
72
106
  }, {
73
107
  kind: import("convex/values").VLiteral<"scheduled", "required">;
74
- runAtTime: import("convex/values").VFloat64<number, "required">;
75
- fn: import("convex/values").VId<import("convex/values").GenericId<"_scheduled_functions">, "required">;
76
- }, "required", "kind" | "runAtTime" | "fn">, import("convex/values").VObject<{
108
+ segment: import("convex/values").VInt64<bigint, "required">;
109
+ scheduledId: import("convex/values").VId<import("convex/values").GenericId<"_scheduled_functions">, "required">;
110
+ saturated: import("convex/values").VBoolean<boolean, "required">;
111
+ generation: import("convex/values").VInt64<bigint, "required">;
112
+ }, "required", "kind" | "generation" | "scheduledId" | "segment" | "saturated">, import("convex/values").VObject<{
77
113
  kind: "idle";
114
+ generation: bigint;
78
115
  }, {
79
116
  kind: import("convex/values").VLiteral<"idle", "required">;
80
- }, "required", "kind">], "required", "kind" | "runAtTime" | "fn">;
81
- }, "required", "state" | "state.kind" | "state.runAtTime" | "state.fn">, {}, {}, {}>;
117
+ generation: import("convex/values").VInt64<bigint, "required">;
118
+ }, "required", "kind" | "generation">], "required", "kind" | "generation" | "scheduledId" | "segment" | "saturated">;
119
+ }, "required", "state" | "state.kind" | "state.generation" | "state.scheduledId" | "state.segment" | "state.saturated">, {}, {}, {}>;
82
120
  work: import("convex/server").TableDefinition<import("convex/values").VObject<{
83
- fnType: "action" | "mutation";
121
+ onComplete?: {
122
+ context?: any;
123
+ fnHandle: string;
124
+ } | undefined;
125
+ retryBehavior?: {
126
+ maxAttempts: number;
127
+ initialBackoffMs: number;
128
+ base: number;
129
+ } | undefined;
84
130
  fnHandle: string;
131
+ fnType: "action" | "mutation";
85
132
  fnName: string;
86
133
  fnArgs: any;
134
+ attempts: number;
87
135
  }, {
88
136
  fnType: import("convex/values").VUnion<"action" | "mutation", [import("convex/values").VLiteral<"action", "required">, import("convex/values").VLiteral<"mutation", "required">], "required", never>;
89
137
  fnHandle: import("convex/values").VString<string, "required">;
90
138
  fnName: import("convex/values").VString<string, "required">;
91
139
  fnArgs: import("convex/values").VAny<any, "required", string>;
92
- }, "required", "fnType" | "fnHandle" | "fnName" | "fnArgs" | `fnArgs.${string}`>, {}, {}, {}>;
140
+ attempts: import("convex/values").VFloat64<number, "required">;
141
+ onComplete: import("convex/values").VObject<{
142
+ context?: any;
143
+ fnHandle: string;
144
+ } | undefined, {
145
+ fnHandle: import("convex/values").VString<string, "required">;
146
+ context: import("convex/values").VAny<any, "optional", string>;
147
+ }, "optional", "fnHandle" | "context" | `context.${string}`>;
148
+ retryBehavior: import("convex/values").VObject<{
149
+ maxAttempts: number;
150
+ initialBackoffMs: number;
151
+ base: number;
152
+ } | undefined, {
153
+ maxAttempts: import("convex/values").VFloat64<number, "required">;
154
+ initialBackoffMs: import("convex/values").VFloat64<number, "required">;
155
+ base: import("convex/values").VFloat64<number, "required">;
156
+ }, "optional", "maxAttempts" | "initialBackoffMs" | "base">;
157
+ }, "required", "fnHandle" | "fnType" | "fnName" | "fnArgs" | "attempts" | "onComplete" | "retryBehavior" | `fnArgs.${string}` | "onComplete.fnHandle" | "onComplete.context" | `onComplete.context.${string}` | "retryBehavior.maxAttempts" | "retryBehavior.initialBackoffMs" | "retryBehavior.base">, {}, {}, {}>;
93
158
  pendingStart: import("convex/server").TableDefinition<import("convex/values").VObject<{
94
159
  workId: import("convex/values").GenericId<"work">;
160
+ segment: bigint;
95
161
  }, {
96
162
  workId: import("convex/values").VId<import("convex/values").GenericId<"work">, "required">;
97
- }, "required", "workId">, {
163
+ segment: import("convex/values").VInt64<bigint, "required">;
164
+ }, "required", "workId" | "segment">, {
98
165
  workId: ["workId", "_creationTime"];
166
+ segment: ["segment", "_creationTime"];
99
167
  }, {}, {}>;
100
168
  pendingCompletion: import("convex/server").TableDefinition<import("convex/values").VObject<{
101
169
  workId: import("convex/values").GenericId<"work">;
102
- generation: number;
103
- completionStatus: "success" | "error" | "canceled" | "timeout";
170
+ segment: bigint;
171
+ runResult: {
172
+ kind: "success";
173
+ returnValue: any;
174
+ } | {
175
+ kind: "failed";
176
+ error: string;
177
+ } | {
178
+ kind: "canceled";
179
+ };
104
180
  }, {
105
- generation: import("convex/values").VFloat64<number, "required">;
106
- completionStatus: import("convex/values").VUnion<"success" | "error" | "canceled" | "timeout", [import("convex/values").VLiteral<"success", "required">, import("convex/values").VLiteral<"error", "required">, import("convex/values").VLiteral<"canceled", "required">, import("convex/values").VLiteral<"timeout", "required">], "required", never>;
181
+ segment: import("convex/values").VInt64<bigint, "required">;
182
+ runResult: import("convex/values").VUnion<{
183
+ kind: "success";
184
+ returnValue: any;
185
+ } | {
186
+ kind: "failed";
187
+ error: string;
188
+ } | {
189
+ kind: "canceled";
190
+ }, [import("convex/values").VObject<{
191
+ kind: "success";
192
+ returnValue: any;
193
+ }, {
194
+ kind: import("convex/values").VLiteral<"success", "required">;
195
+ returnValue: import("convex/values").VAny<any, "required", string>;
196
+ }, "required", "kind" | "returnValue" | `returnValue.${string}`>, import("convex/values").VObject<{
197
+ kind: "failed";
198
+ error: string;
199
+ }, {
200
+ kind: import("convex/values").VLiteral<"failed", "required">;
201
+ error: import("convex/values").VString<string, "required">;
202
+ }, "required", "kind" | "error">, import("convex/values").VObject<{
203
+ kind: "canceled";
204
+ }, {
205
+ kind: import("convex/values").VLiteral<"canceled", "required">;
206
+ }, "required", "kind">], "required", "kind" | "returnValue" | `returnValue.${string}` | "error">;
107
207
  workId: import("convex/values").VId<import("convex/values").GenericId<"work">, "required">;
108
- }, "required", "workId" | "generation" | "completionStatus">, {
208
+ }, "required", "workId" | "segment" | "runResult" | "runResult.kind" | "runResult.returnValue" | `runResult.returnValue.${string}` | "runResult.error">, {
109
209
  workId: ["workId", "_creationTime"];
110
- generation: ["generation", "_creationTime"];
210
+ segment: ["segment", "_creationTime"];
111
211
  }, {}, {}>;
112
212
  pendingCancelation: import("convex/server").TableDefinition<import("convex/values").VObject<{
113
213
  workId: import("convex/values").GenericId<"work">;
214
+ segment: bigint;
114
215
  }, {
216
+ segment: import("convex/values").VInt64<bigint, "required">;
115
217
  workId: import("convex/values").VId<import("convex/values").GenericId<"work">, "required">;
116
- }, "required", "workId">, {}, {}, {}>;
117
- inProgressWork: import("convex/server").TableDefinition<import("convex/values").VObject<{
118
- running: import("convex/values").GenericId<"_scheduled_functions">;
119
- workId: import("convex/values").GenericId<"work">;
120
- timeoutMs: number | null;
121
- }, {
122
- running: import("convex/values").VId<import("convex/values").GenericId<"_scheduled_functions">, "required">;
123
- timeoutMs: import("convex/values").VUnion<number | null, [import("convex/values").VFloat64<number, "required">, import("convex/values").VNull<null, "required">], "required", never>;
124
- workId: import("convex/values").VId<import("convex/values").GenericId<"work">, "required">;
125
- }, "required", "running" | "workId" | "timeoutMs">, {
126
- workId: ["workId", "_creationTime"];
127
- }, {}, {}>;
128
- inProgressCount: import("convex/server").TableDefinition<import("convex/values").VObject<{
129
- count: number;
130
- }, {
131
- count: import("convex/values").VFloat64<number, "required">;
132
- }, "required", "count">, {}, {}, {}>;
133
- completedWork: import("convex/server").TableDefinition<import("convex/values").VObject<{
134
- workId: import("convex/values").GenericId<"work">;
135
- completionStatus: "success" | "error" | "canceled" | "timeout";
136
- }, {
137
- completionStatus: import("convex/values").VUnion<"success" | "error" | "canceled" | "timeout", [import("convex/values").VLiteral<"success", "required">, import("convex/values").VLiteral<"error", "required">, import("convex/values").VLiteral<"canceled", "required">, import("convex/values").VLiteral<"timeout", "required">], "required", never>;
138
- workId: import("convex/values").VId<import("convex/values").GenericId<"work">, "required">;
139
- }, "required", "workId" | "completionStatus">, {
218
+ }, "required", "workId" | "segment">, {
140
219
  workId: ["workId", "_creationTime"];
220
+ segment: ["segment", "_creationTime"];
141
221
  }, {}, {}>;
142
- completionGeneration: import("convex/server").TableDefinition<import("convex/values").VObject<{
143
- generation: number;
144
- }, {
145
- generation: import("convex/values").VFloat64<number, "required">;
146
- }, "required", "generation">, {}, {}, {}>;
147
- pendingStartCursor: import("convex/server").TableDefinition<import("convex/values").VObject<{
148
- cursor: number;
149
- }, {
150
- cursor: import("convex/values").VFloat64<number, "required">;
151
- }, "required", "cursor">, {}, {}, {}>;
152
222
  }, true>;
153
223
  export default _default;
154
224
  //# sourceMappingURL=schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/component/schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAK,MAAM,eAAe,CAAC;AAGzC,eAAO,MAAM,gBAAgB,sUAK5B,CAAC;AACF,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,wBA8DG"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/component/schema.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,wBAiFG"}
@@ -1,88 +1,77 @@
1
1
  import { defineSchema, defineTable } from "convex/server";
2
2
  import { v } from "convex/values";
3
- import { logLevel } from "./logging.js";
4
- export const completionStatus = v.union(v.literal("success"), v.literal("error"), v.literal("canceled"), v.literal("timeout"));
5
- /**
6
- Data flow:
7
-
8
- - The mutation `mainLoop` runs periodically and serially.
9
- - Several tables act as queues, with client-driven mutations enqueueing at high
10
- timestamps and `mainLoop` popping at low timestamps:
11
- pendingStart, pendingCompletion, and pendingCancelation.
12
- - The `enqueue` mutation writes to pendingStart.
13
- - The `cancel` mutation writes to pendingCancelation.
14
- - The `saveResult` mutation, run as part of scheduled work, writes to pendingCompletion.
15
- - mainLoop processes the queues:
16
- - pendingStart => inProgressWork.
17
- - pendingCompletion and pendingCancelation => completedWork.
18
- - inProgressWork that finishes uncleanly (timeout or system failure) => completedWork.
19
- - `mainLoop` schedules itself to run.
20
- - `enqueue`, `cancel`, and `saveResult` mutations check when `mainLoop` is scheduled to run,
21
- and if it's too far in the future, they schedule it to run sooner.
22
- - `status` query reads from pendingWork and completedWork.
23
- - `cleanup` mutation deletes old rows from completedWork.
24
-
25
- To avoid OCCs, we restrict which mutations can read and write from each table:
26
- - pools: read by all, written only when static Workpool options change.
27
- - mainLoop (table): read by all, written mostly by `mainLoop`.
28
- If `mainLoop` will not run for a while, mainLoop table is written by `enqueue`, `cancel`, or `saveResult`.
29
- - pendingWork: `enqueue` inserts at high timestamps, `mainLoop` pops at low timestamps. `status` query does point-reads.
30
- - pendingCompletion: `saveResult` inserts at high timestamps, `mainLoop` pops at low timestamps.
31
- - pendingCancelation: `cancel` inserts at high timestamps, `mainLoop` pops at low timestamps.
32
- - inProgressWork: `mainLoop` inserts, reads all, and deletes.
33
- - completedWork: `mainLoop` inserts at hight timestamps, `status` query reads, `cleanup` deletes at low timestamps.
34
-
35
- */
3
+ import { config, onComplete, retryBehavior, runResult } from "./shared.js";
4
+ // Represents a slice of time to process work.
5
+ const segment = v.int64();
36
6
  export default defineSchema({
37
- // Statically configured, singleton.
38
- pool: defineTable({
39
- maxParallelism: v.number(),
40
- statusTtl: v.number(),
41
- logLevel,
7
+ // Written from kickLoop, read everywhere.
8
+ globals: defineTable(config),
9
+ // Singleton, only read & written by `main`.
10
+ internalState: defineTable({
11
+ // Ensure that only one main is running at a time.
12
+ generation: v.int64(),
13
+ segmentCursors: v.object({
14
+ incoming: segment,
15
+ completion: segment,
16
+ cancelation: segment,
17
+ }),
18
+ lastRecovery: segment,
19
+ report: v.object({
20
+ completed: v.number(),
21
+ succeeded: v.number(),
22
+ failed: v.number(),
23
+ retries: v.number(),
24
+ canceled: v.number(),
25
+ lastReportTs: v.number(),
26
+ }),
27
+ running: v.array(v.object({
28
+ workId: v.id("work"),
29
+ scheduledId: v.id("_scheduled_functions"),
30
+ started: v.number(),
31
+ })),
42
32
  }),
43
- mainLoop: defineTable({
33
+ // Singleton, written by `updateRunStatus` when running, by client or worker otherwise.
34
+ // Safe to read from kickLoop, since it should update infrequently.
35
+ runStatus: defineTable({
44
36
  state: v.union(v.object({ kind: v.literal("running") }), v.object({
45
37
  kind: v.literal("scheduled"),
46
- runAtTime: v.number(),
47
- fn: v.id("_scheduled_functions"),
48
- }), v.object({ kind: v.literal("idle") })),
38
+ segment,
39
+ scheduledId: v.id("_scheduled_functions"),
40
+ saturated: v.boolean(),
41
+ generation: v.int64(),
42
+ }), v.object({ kind: v.literal("idle"), generation: v.int64() })),
49
43
  }),
44
+ // Written on enqueue. Safe to read. Deleted by `complete`.
50
45
  work: defineTable({
51
46
  fnType: v.union(v.literal("action"), v.literal("mutation")),
52
47
  fnHandle: v.string(),
53
48
  fnName: v.string(),
54
49
  fnArgs: v.any(),
50
+ attempts: v.number(),
51
+ onComplete: v.optional(onComplete),
52
+ retryBehavior: v.optional(retryBehavior),
55
53
  }),
54
+ // Written on enqueue, read & deleted by `main`.
56
55
  pendingStart: defineTable({
57
56
  workId: v.id("work"),
58
- }).index("workId", ["workId"]),
57
+ segment,
58
+ })
59
+ .index("workId", ["workId"])
60
+ .index("segment", ["segment"]),
61
+ // Written by job, read & deleted by `main`.
59
62
  pendingCompletion: defineTable({
60
- generation: v.number(),
61
- completionStatus,
63
+ segment,
64
+ runResult,
62
65
  workId: v.id("work"),
63
66
  })
64
67
  .index("workId", ["workId"])
65
- .index("generation", ["generation"]),
68
+ .index("segment", ["segment"]),
69
+ // Written on cancelation, read & deleted by `main`.
66
70
  pendingCancelation: defineTable({
71
+ segment,
67
72
  workId: v.id("work"),
68
- }),
69
- inProgressWork: defineTable({
70
- running: v.id("_scheduled_functions"),
71
- timeoutMs: v.union(v.number(), v.null()),
72
- workId: v.id("work"),
73
- }).index("workId", ["workId"]),
74
- inProgressCount: defineTable({
75
- count: v.number(),
76
- }),
77
- completedWork: defineTable({
78
- completionStatus,
79
- workId: v.id("work"),
80
- }).index("workId", ["workId"]),
81
- completionGeneration: defineTable({
82
- generation: v.number(),
83
- }),
84
- pendingStartCursor: defineTable({
85
- cursor: v.number(),
86
- }),
73
+ })
74
+ .index("workId", ["workId"])
75
+ .index("segment", ["segment"]),
87
76
  });
88
77
  //# sourceMappingURL=schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/component/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/component/schema.ts"],"names":[],"mappings":"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"}