@convex-dev/workpool 0.2.20-alpha.0 → 0.3.1-alpha.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.
- package/README.md +77 -68
- package/dist/client/index.d.ts +3 -3
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/utils.d.ts +1 -8
- package/dist/client/utils.d.ts.map +1 -1
- package/dist/client/utils.js.map +1 -1
- package/dist/component/_generated/api.d.ts +27 -124
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/api.js +10 -1
- package/dist/component/_generated/api.js.map +1 -1
- package/dist/component/_generated/component.d.ts +98 -0
- package/dist/component/_generated/component.d.ts.map +1 -0
- package/dist/component/_generated/component.js +11 -0
- package/dist/component/_generated/component.js.map +1 -0
- package/dist/component/_generated/dataModel.d.ts +4 -18
- package/dist/component/_generated/dataModel.d.ts.map +1 -0
- package/dist/component/_generated/dataModel.js +11 -0
- package/dist/component/_generated/dataModel.js.map +1 -0
- package/dist/component/_generated/server.d.ts +10 -38
- package/dist/component/_generated/server.d.ts.map +1 -1
- package/dist/component/_generated/server.js +9 -5
- package/dist/component/_generated/server.js.map +1 -1
- package/dist/component/danger.d.ts +2 -2
- package/dist/component/lib.d.ts +9 -9
- package/dist/component/lib.js +2 -2
- package/dist/component/lib.js.map +1 -1
- package/dist/component/schema.d.ts +15 -15
- package/dist/component/shared.d.ts +3 -3
- package/dist/component/stats.d.ts +2 -2
- package/dist/component/worker.d.ts +3 -3
- package/package.json +30 -29
- package/src/client/index.ts +19 -20
- package/src/client/utils.ts +3 -30
- package/src/component/README.md +6 -6
- package/src/component/_generated/api.ts +70 -0
- package/src/component/_generated/component.ts +117 -0
- package/src/component/_generated/{server.d.ts → server.ts} +33 -21
- package/src/component/complete.test.ts +1 -1
- package/src/component/complete.ts +6 -6
- package/src/component/danger.ts +3 -3
- package/src/component/kick.test.ts +5 -5
- package/src/component/kick.ts +6 -6
- package/src/component/lib.test.ts +5 -5
- package/src/component/lib.ts +10 -10
- package/src/component/logging.ts +2 -2
- package/src/component/loop.test.ts +9 -9
- package/src/component/loop.ts +33 -33
- package/src/component/recovery.test.ts +7 -7
- package/src/component/recovery.ts +2 -2
- package/src/component/schema.ts +2 -2
- package/src/component/shared.ts +5 -5
- package/src/component/stats.test.ts +3 -3
- package/src/component/stats.ts +6 -6
- package/src/test.ts +10 -3
- package/src/component/_generated/api.d.ts +0 -151
- package/src/component/_generated/api.js +0 -23
- package/src/component/_generated/server.js +0 -90
- /package/src/component/_generated/{dataModel.d.ts → dataModel.ts} +0 -0
|
@@ -8,9 +8,8 @@
|
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import type {
|
|
12
12
|
ActionBuilder,
|
|
13
|
-
AnyComponents,
|
|
14
13
|
HttpActionBuilder,
|
|
15
14
|
MutationBuilder,
|
|
16
15
|
QueryBuilder,
|
|
@@ -19,15 +18,18 @@ import {
|
|
|
19
18
|
GenericQueryCtx,
|
|
20
19
|
GenericDatabaseReader,
|
|
21
20
|
GenericDatabaseWriter,
|
|
22
|
-
|
|
21
|
+
} from "convex/server";
|
|
22
|
+
import {
|
|
23
|
+
actionGeneric,
|
|
24
|
+
httpActionGeneric,
|
|
25
|
+
queryGeneric,
|
|
26
|
+
mutationGeneric,
|
|
27
|
+
internalActionGeneric,
|
|
28
|
+
internalMutationGeneric,
|
|
29
|
+
internalQueryGeneric,
|
|
23
30
|
} from "convex/server";
|
|
24
31
|
import type { DataModel } from "./dataModel.js";
|
|
25
32
|
|
|
26
|
-
type GenericCtx =
|
|
27
|
-
| GenericActionCtx<DataModel>
|
|
28
|
-
| GenericMutationCtx<DataModel>
|
|
29
|
-
| GenericQueryCtx<DataModel>;
|
|
30
|
-
|
|
31
33
|
/**
|
|
32
34
|
* Define a query in this Convex app's public API.
|
|
33
35
|
*
|
|
@@ -36,7 +38,7 @@ type GenericCtx =
|
|
|
36
38
|
* @param func - The query function. It receives a {@link QueryCtx} as its first argument.
|
|
37
39
|
* @returns The wrapped query. Include this as an `export` to name it and make it accessible.
|
|
38
40
|
*/
|
|
39
|
-
export
|
|
41
|
+
export const query: QueryBuilder<DataModel, "public"> = queryGeneric;
|
|
40
42
|
|
|
41
43
|
/**
|
|
42
44
|
* Define a query that is only accessible from other Convex functions (but not from the client).
|
|
@@ -46,7 +48,8 @@ export declare const query: QueryBuilder<DataModel, "public">;
|
|
|
46
48
|
* @param func - The query function. It receives a {@link QueryCtx} as its first argument.
|
|
47
49
|
* @returns The wrapped query. Include this as an `export` to name it and make it accessible.
|
|
48
50
|
*/
|
|
49
|
-
export
|
|
51
|
+
export const internalQuery: QueryBuilder<DataModel, "internal"> =
|
|
52
|
+
internalQueryGeneric;
|
|
50
53
|
|
|
51
54
|
/**
|
|
52
55
|
* Define a mutation in this Convex app's public API.
|
|
@@ -56,7 +59,7 @@ export declare const internalQuery: QueryBuilder<DataModel, "internal">;
|
|
|
56
59
|
* @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
|
|
57
60
|
* @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
|
|
58
61
|
*/
|
|
59
|
-
export
|
|
62
|
+
export const mutation: MutationBuilder<DataModel, "public"> = mutationGeneric;
|
|
60
63
|
|
|
61
64
|
/**
|
|
62
65
|
* Define a mutation that is only accessible from other Convex functions (but not from the client).
|
|
@@ -66,7 +69,8 @@ export declare const mutation: MutationBuilder<DataModel, "public">;
|
|
|
66
69
|
* @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
|
|
67
70
|
* @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
|
|
68
71
|
*/
|
|
69
|
-
export
|
|
72
|
+
export const internalMutation: MutationBuilder<DataModel, "internal"> =
|
|
73
|
+
internalMutationGeneric;
|
|
70
74
|
|
|
71
75
|
/**
|
|
72
76
|
* Define an action in this Convex app's public API.
|
|
@@ -79,7 +83,7 @@ export declare const internalMutation: MutationBuilder<DataModel, "internal">;
|
|
|
79
83
|
* @param func - The action. It receives an {@link ActionCtx} as its first argument.
|
|
80
84
|
* @returns The wrapped action. Include this as an `export` to name it and make it accessible.
|
|
81
85
|
*/
|
|
82
|
-
export
|
|
86
|
+
export const action: ActionBuilder<DataModel, "public"> = actionGeneric;
|
|
83
87
|
|
|
84
88
|
/**
|
|
85
89
|
* Define an action that is only accessible from other Convex functions (but not from the client).
|
|
@@ -87,19 +91,26 @@ export declare const action: ActionBuilder<DataModel, "public">;
|
|
|
87
91
|
* @param func - The function. It receives an {@link ActionCtx} as its first argument.
|
|
88
92
|
* @returns The wrapped function. Include this as an `export` to name it and make it accessible.
|
|
89
93
|
*/
|
|
90
|
-
export
|
|
94
|
+
export const internalAction: ActionBuilder<DataModel, "internal"> =
|
|
95
|
+
internalActionGeneric;
|
|
91
96
|
|
|
92
97
|
/**
|
|
93
98
|
* Define an HTTP action.
|
|
94
99
|
*
|
|
95
|
-
*
|
|
96
|
-
* deployment if the requests matches the path and method where
|
|
97
|
-
* is routed. Be sure to route your
|
|
100
|
+
* The wrapped function will be used to respond to HTTP requests received
|
|
101
|
+
* by a Convex deployment if the requests matches the path and method where
|
|
102
|
+
* this action is routed. Be sure to route your httpAction in `convex/http.js`.
|
|
98
103
|
*
|
|
99
|
-
* @param func - The function. It receives an {@link ActionCtx} as its first argument
|
|
104
|
+
* @param func - The function. It receives an {@link ActionCtx} as its first argument
|
|
105
|
+
* and a Fetch API `Request` object as its second.
|
|
100
106
|
* @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up.
|
|
101
107
|
*/
|
|
102
|
-
export
|
|
108
|
+
export const httpAction: HttpActionBuilder = httpActionGeneric;
|
|
109
|
+
|
|
110
|
+
type GenericCtx =
|
|
111
|
+
| GenericActionCtx<DataModel>
|
|
112
|
+
| GenericMutationCtx<DataModel>
|
|
113
|
+
| GenericQueryCtx<DataModel>;
|
|
103
114
|
|
|
104
115
|
/**
|
|
105
116
|
* A set of services for use within Convex query functions.
|
|
@@ -107,8 +118,7 @@ export declare const httpAction: HttpActionBuilder;
|
|
|
107
118
|
* The query context is passed as the first argument to any Convex query
|
|
108
119
|
* function run on the server.
|
|
109
120
|
*
|
|
110
|
-
*
|
|
111
|
-
* read-only.
|
|
121
|
+
* If you're using code generation, use the `QueryCtx` type in `convex/_generated/server.d.ts` instead.
|
|
112
122
|
*/
|
|
113
123
|
export type QueryCtx = GenericQueryCtx<DataModel>;
|
|
114
124
|
|
|
@@ -117,6 +127,8 @@ export type QueryCtx = GenericQueryCtx<DataModel>;
|
|
|
117
127
|
*
|
|
118
128
|
* The mutation context is passed as the first argument to any Convex mutation
|
|
119
129
|
* function run on the server.
|
|
130
|
+
*
|
|
131
|
+
* If you're using code generation, use the `MutationCtx` type in `convex/_generated/server.d.ts` instead.
|
|
120
132
|
*/
|
|
121
133
|
export type MutationCtx = GenericMutationCtx<DataModel>;
|
|
122
134
|
|
|
@@ -19,12 +19,12 @@ export const completeArgs = v.object({
|
|
|
19
19
|
runResult: vResultValidator,
|
|
20
20
|
workId: v.id("work"),
|
|
21
21
|
attempt: v.number(),
|
|
22
|
-
})
|
|
22
|
+
}),
|
|
23
23
|
),
|
|
24
24
|
});
|
|
25
25
|
export async function completeHandler(
|
|
26
26
|
ctx: MutationCtx,
|
|
27
|
-
args: Infer<typeof completeArgs
|
|
27
|
+
args: Infer<typeof completeArgs>,
|
|
28
28
|
) {
|
|
29
29
|
const globals = await ctx.db.query("globals").unique();
|
|
30
30
|
const console = createLogger(globals?.logLevel);
|
|
@@ -76,7 +76,7 @@ export async function completeHandler(
|
|
|
76
76
|
} catch (e) {
|
|
77
77
|
console.error(
|
|
78
78
|
`[complete] error running onComplete for ${job.workId}`,
|
|
79
|
-
e
|
|
79
|
+
e,
|
|
80
80
|
);
|
|
81
81
|
// TODO: store failures in a table for later debugging
|
|
82
82
|
}
|
|
@@ -92,7 +92,7 @@ export async function completeHandler(
|
|
|
92
92
|
retry,
|
|
93
93
|
});
|
|
94
94
|
}
|
|
95
|
-
})
|
|
95
|
+
}),
|
|
96
96
|
);
|
|
97
97
|
if (pendingCompletions.length > 0) {
|
|
98
98
|
const segment = await kickMainLoop(ctx, "complete");
|
|
@@ -101,8 +101,8 @@ export async function completeHandler(
|
|
|
101
101
|
ctx.db.insert("pendingCompletion", {
|
|
102
102
|
...completion,
|
|
103
103
|
segment,
|
|
104
|
-
})
|
|
105
|
-
)
|
|
104
|
+
}),
|
|
105
|
+
),
|
|
106
106
|
);
|
|
107
107
|
}
|
|
108
108
|
}
|
package/src/component/danger.ts
CHANGED
|
@@ -29,7 +29,7 @@ export const clearPending = internalMutation({
|
|
|
29
29
|
if (work) {
|
|
30
30
|
await ctx.db.delete(work._id);
|
|
31
31
|
}
|
|
32
|
-
})
|
|
32
|
+
}),
|
|
33
33
|
);
|
|
34
34
|
if (!entries.isDone) {
|
|
35
35
|
await ctx.scheduler.runAfter(0, internal.danger.clearPending, {
|
|
@@ -87,10 +87,10 @@ export const clearOldWork = internalMutation({
|
|
|
87
87
|
})
|
|
88
88
|
.filter(([_, v]) => v !== null)
|
|
89
89
|
.map(([name]) => name)
|
|
90
|
-
.join(", ")})
|
|
90
|
+
.join(", ")})`,
|
|
91
91
|
);
|
|
92
92
|
await ctx.db.delete(entry._id);
|
|
93
|
-
})
|
|
93
|
+
}),
|
|
94
94
|
);
|
|
95
95
|
if (!entries.isDone) {
|
|
96
96
|
await ctx.scheduler.runAfter(0, internal.danger.clearOldWork, {
|
|
@@ -107,7 +107,7 @@ describe("kickMainLoop", () => {
|
|
|
107
107
|
{
|
|
108
108
|
generation: 0n,
|
|
109
109
|
segment: futureSegment,
|
|
110
|
-
}
|
|
110
|
+
},
|
|
111
111
|
);
|
|
112
112
|
await ctx.db.patch(runStatus._id, {
|
|
113
113
|
state: {
|
|
@@ -149,7 +149,7 @@ describe("kickMainLoop", () => {
|
|
|
149
149
|
{
|
|
150
150
|
generation: 0n,
|
|
151
151
|
segment: nearFutureSegment,
|
|
152
|
-
}
|
|
152
|
+
},
|
|
153
153
|
);
|
|
154
154
|
await ctx.db.patch(runStatus._id, {
|
|
155
155
|
state: {
|
|
@@ -221,8 +221,8 @@ describe("kickMainLoop", () => {
|
|
|
221
221
|
t.run(async (ctx) => {
|
|
222
222
|
const segment = await kickMainLoop(ctx, "enqueue");
|
|
223
223
|
return segment;
|
|
224
|
-
})
|
|
225
|
-
)
|
|
224
|
+
}),
|
|
225
|
+
),
|
|
226
226
|
);
|
|
227
227
|
expect(segments.filter((s) => s === getCurrentSegment())).toHaveLength(1);
|
|
228
228
|
|
|
@@ -278,7 +278,7 @@ describe("kickMainLoop", () => {
|
|
|
278
278
|
const scheduledId = await ctx.scheduler.runAfter(
|
|
279
279
|
10_000,
|
|
280
280
|
internal.loop.main,
|
|
281
|
-
{ generation: 0n, segment }
|
|
281
|
+
{ generation: 0n, segment },
|
|
282
282
|
);
|
|
283
283
|
await ctx.db.patch(runStatus._id, {
|
|
284
284
|
state: {
|
package/src/component/kick.ts
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
export async function kickMainLoop(
|
|
21
21
|
ctx: MutationCtx,
|
|
22
22
|
source: "enqueue" | "cancel" | "complete" | "kick",
|
|
23
|
-
config?: Partial<Config
|
|
23
|
+
config?: Partial<Config>,
|
|
24
24
|
): Promise<bigint> {
|
|
25
25
|
const globals = await getOrUpdateGlobals(ctx, config);
|
|
26
26
|
const console = createLogger(globals.logLevel);
|
|
@@ -30,7 +30,7 @@ export async function kickMainLoop(
|
|
|
30
30
|
// Only kick to run now if we're scheduled or idle.
|
|
31
31
|
if (runStatus.state.kind === "running") {
|
|
32
32
|
console.debug(
|
|
33
|
-
`[${source}] main is actively running, so we don't need to kick it
|
|
33
|
+
`[${source}] main is actively running, so we don't need to kick it`,
|
|
34
34
|
);
|
|
35
35
|
return next;
|
|
36
36
|
}
|
|
@@ -38,25 +38,25 @@ export async function kickMainLoop(
|
|
|
38
38
|
if (runStatus.state.kind === "scheduled") {
|
|
39
39
|
if (source === "enqueue" && runStatus.state.saturated) {
|
|
40
40
|
console.debug(
|
|
41
|
-
`[${source}] main is saturated, so we don't need to kick it
|
|
41
|
+
`[${source}] main is saturated, so we don't need to kick it`,
|
|
42
42
|
);
|
|
43
43
|
return next;
|
|
44
44
|
}
|
|
45
45
|
if (runStatus.state.segment <= toSegment(Date.now() + SECOND)) {
|
|
46
46
|
console.debug(
|
|
47
|
-
`[${source}] main is scheduled to run soon enough, so we don't need to kick it
|
|
47
|
+
`[${source}] main is scheduled to run soon enough, so we don't need to kick it`,
|
|
48
48
|
);
|
|
49
49
|
return next;
|
|
50
50
|
}
|
|
51
51
|
console.debug(
|
|
52
|
-
`[${source}] main is scheduled to run later, so reschedule it to run now
|
|
52
|
+
`[${source}] main is scheduled to run later, so reschedule it to run now`,
|
|
53
53
|
);
|
|
54
54
|
const scheduled = await ctx.db.system.get(runStatus.state.scheduledId);
|
|
55
55
|
if (scheduled && scheduled.state.kind === "pending") {
|
|
56
56
|
await ctx.scheduler.cancel(runStatus.state.scheduledId);
|
|
57
57
|
} else {
|
|
58
58
|
console.warn(
|
|
59
|
-
`[${source}] main is marked as scheduled, but it's status is ${scheduled?.state.kind}
|
|
59
|
+
`[${source}] main is marked as scheduled, but it's status is ${scheduled?.state.kind}`,
|
|
60
60
|
);
|
|
61
61
|
}
|
|
62
62
|
} else if (runStatus.state.kind === "idle") {
|
|
@@ -62,11 +62,11 @@ describe("lib", () => {
|
|
|
62
62
|
fnType: "mutation",
|
|
63
63
|
runAt: Date.now(),
|
|
64
64
|
config: {
|
|
65
|
-
maxParallelism:
|
|
65
|
+
maxParallelism: 500, // More than MAX_POSSIBLE_PARALLELISM
|
|
66
66
|
logLevel: "WARN",
|
|
67
67
|
},
|
|
68
|
-
})
|
|
69
|
-
).rejects.toThrow("maxParallelism must be <=
|
|
68
|
+
}),
|
|
69
|
+
).rejects.toThrow("maxParallelism must be <= 100");
|
|
70
70
|
});
|
|
71
71
|
|
|
72
72
|
it("should throw error if maxParallelism is too low", async () => {
|
|
@@ -81,7 +81,7 @@ describe("lib", () => {
|
|
|
81
81
|
maxParallelism: 0, // Less than minimum
|
|
82
82
|
logLevel: "WARN",
|
|
83
83
|
},
|
|
84
|
-
})
|
|
84
|
+
}),
|
|
85
85
|
).rejects.toThrow("maxParallelism must be >= 1");
|
|
86
86
|
});
|
|
87
87
|
});
|
|
@@ -249,7 +249,7 @@ describe("lib", () => {
|
|
|
249
249
|
expect(scheduledFunctions.length).toBeGreaterThan(0);
|
|
250
250
|
// check that one of the scheduled functions is cancelAll
|
|
251
251
|
const cancelAllScheduledFunction = scheduledFunctions.find(
|
|
252
|
-
(sf) => sf.name === "lib:cancelAll"
|
|
252
|
+
(sf) => sf.name === "lib:cancelAll",
|
|
253
253
|
);
|
|
254
254
|
expect(cancelAllScheduledFunction).toBeDefined();
|
|
255
255
|
assert(cancelAllScheduledFunction);
|
package/src/component/lib.ts
CHANGED
|
@@ -27,8 +27,8 @@ import {
|
|
|
27
27
|
} from "./shared.js";
|
|
28
28
|
import { recordEnqueued } from "./stats.js";
|
|
29
29
|
|
|
30
|
-
const MAX_POSSIBLE_PARALLELISM =
|
|
31
|
-
const MAX_PARALLELISM_SOFT_LIMIT =
|
|
30
|
+
const MAX_POSSIBLE_PARALLELISM = 200;
|
|
31
|
+
const MAX_PARALLELISM_SOFT_LIMIT = 100;
|
|
32
32
|
|
|
33
33
|
const itemArgs = {
|
|
34
34
|
fnHandle: v.string(),
|
|
@@ -58,7 +58,7 @@ async function enqueueHandler(
|
|
|
58
58
|
ctx: MutationCtx,
|
|
59
59
|
console: Logger,
|
|
60
60
|
kickSegment: bigint,
|
|
61
|
-
{ runAt, ...workArgs }: ObjectType<typeof itemArgs
|
|
61
|
+
{ runAt, ...workArgs }: ObjectType<typeof itemArgs>,
|
|
62
62
|
) {
|
|
63
63
|
runAt = boundScheduledTime(runAt, console);
|
|
64
64
|
const workId = await ctx.db.insert("work", {
|
|
@@ -79,7 +79,7 @@ function validateConfig(config: Config) {
|
|
|
79
79
|
throw new Error(`maxParallelism must be <= ${MAX_PARALLELISM_SOFT_LIMIT}`);
|
|
80
80
|
} else if (config.maxParallelism > MAX_PARALLELISM_SOFT_LIMIT) {
|
|
81
81
|
createLogger(config.logLevel).warn(
|
|
82
|
-
`maxParallelism should be <= ${MAX_PARALLELISM_SOFT_LIMIT}, but is set to ${config.maxParallelism}. This will be an error in a future version
|
|
82
|
+
`maxParallelism should be <= ${MAX_PARALLELISM_SOFT_LIMIT}, but is set to ${config.maxParallelism}. This will be an error in a future version.`,
|
|
83
83
|
);
|
|
84
84
|
} else if (config.maxParallelism < 1) {
|
|
85
85
|
throw new Error("maxParallelism must be >= 1");
|
|
@@ -97,7 +97,7 @@ export const enqueueBatch = mutation({
|
|
|
97
97
|
const console = createLogger(config.logLevel);
|
|
98
98
|
const kickSegment = await kickMainLoop(ctx, "enqueue", config);
|
|
99
99
|
return Promise.all(
|
|
100
|
-
items.map((item) => enqueueHandler(ctx, console, kickSegment, item))
|
|
100
|
+
items.map((item) => enqueueHandler(ctx, console, kickSegment, item)),
|
|
101
101
|
);
|
|
102
102
|
},
|
|
103
103
|
});
|
|
@@ -136,8 +136,8 @@ export const cancelAll = mutation({
|
|
|
136
136
|
.take(pageSize);
|
|
137
137
|
const shouldCancel = await Promise.all(
|
|
138
138
|
pageOfWork.map(async ({ _id }) =>
|
|
139
|
-
shouldCancelWorkItem(ctx, _id, logLevel)
|
|
140
|
-
)
|
|
139
|
+
shouldCancelWorkItem(ctx, _id, logLevel),
|
|
140
|
+
),
|
|
141
141
|
);
|
|
142
142
|
let segment = getNextSegment();
|
|
143
143
|
if (shouldCancel.some((c) => c)) {
|
|
@@ -151,7 +151,7 @@ export const cancelAll = mutation({
|
|
|
151
151
|
segment,
|
|
152
152
|
});
|
|
153
153
|
}
|
|
154
|
-
})
|
|
154
|
+
}),
|
|
155
155
|
);
|
|
156
156
|
if (pageOfWork.length === pageSize) {
|
|
157
157
|
await ctx.scheduler.runAfter(0, api.lib.cancelAll, {
|
|
@@ -196,7 +196,7 @@ export const statusBatch = query({
|
|
|
196
196
|
returns: v.array(statusValidator),
|
|
197
197
|
handler: async (ctx, { ids }) => {
|
|
198
198
|
return await Promise.all(
|
|
199
|
-
ids.map(async (id) => await statusHandler(ctx, { id }))
|
|
199
|
+
ids.map(async (id) => await statusHandler(ctx, { id })),
|
|
200
200
|
);
|
|
201
201
|
},
|
|
202
202
|
});
|
|
@@ -204,7 +204,7 @@ export const statusBatch = query({
|
|
|
204
204
|
async function shouldCancelWorkItem(
|
|
205
205
|
ctx: MutationCtx,
|
|
206
206
|
workId: Id<"work">,
|
|
207
|
-
logLevel: LogLevel
|
|
207
|
+
logLevel: LogLevel,
|
|
208
208
|
) {
|
|
209
209
|
const console = createLogger(logLevel);
|
|
210
210
|
// No-op if the work doesn't exist or has completed.
|
package/src/component/logging.ts
CHANGED
|
@@ -10,7 +10,7 @@ export const logLevel = v.union(
|
|
|
10
10
|
v.literal("INFO"),
|
|
11
11
|
v.literal("REPORT"),
|
|
12
12
|
v.literal("WARN"),
|
|
13
|
-
v.literal("ERROR")
|
|
13
|
+
v.literal("ERROR"),
|
|
14
14
|
);
|
|
15
15
|
export type LogLevel = Infer<typeof logLevel>;
|
|
16
16
|
|
|
@@ -30,7 +30,7 @@ const logLevelByName = logLevelOrder.reduce(
|
|
|
30
30
|
acc[l] = i;
|
|
31
31
|
return acc;
|
|
32
32
|
},
|
|
33
|
-
{} as Record<LogLevel, number
|
|
33
|
+
{} as Record<LogLevel, number>,
|
|
34
34
|
);
|
|
35
35
|
export function shouldLog(config: LogLevel, level: LogLevel) {
|
|
36
36
|
return logLevelByName[config] <= logLevelByName[level];
|
|
@@ -49,7 +49,7 @@ describe("loop", () => {
|
|
|
49
49
|
|
|
50
50
|
async function makeDummyWork(
|
|
51
51
|
ctx: MutationCtx,
|
|
52
|
-
overrides: Partial<WithoutSystemFields<Doc<"work">>> = {}
|
|
52
|
+
overrides: Partial<WithoutSystemFields<Doc<"work">>> = {},
|
|
53
53
|
) {
|
|
54
54
|
return ctx.db.insert("work", {
|
|
55
55
|
fnType: "action",
|
|
@@ -63,7 +63,7 @@ describe("loop", () => {
|
|
|
63
63
|
|
|
64
64
|
async function makeDummyScheduledFunction(
|
|
65
65
|
ctx: MutationCtx,
|
|
66
|
-
workId: Id<"work"
|
|
66
|
+
workId: Id<"work">,
|
|
67
67
|
) {
|
|
68
68
|
return ctx.scheduler.runAfter(0, internal.worker.runActionWrapper, {
|
|
69
69
|
workId,
|
|
@@ -76,7 +76,7 @@ describe("loop", () => {
|
|
|
76
76
|
|
|
77
77
|
async function insertInternalState(
|
|
78
78
|
ctx: MutationCtx,
|
|
79
|
-
overrides: Partial<WithoutSystemFields<Doc<"internalState">>> = {}
|
|
79
|
+
overrides: Partial<WithoutSystemFields<Doc<"internalState">>> = {},
|
|
80
80
|
) {
|
|
81
81
|
await ctx.db.insert("internalState", {
|
|
82
82
|
generation: 1n,
|
|
@@ -450,7 +450,7 @@ describe("loop", () => {
|
|
|
450
450
|
const scheduledId = await ctx.scheduler.runAfter(
|
|
451
451
|
1000,
|
|
452
452
|
internal.loop.main,
|
|
453
|
-
{ generation: 1n, segment: getNextSegment() + 10n }
|
|
453
|
+
{ generation: 1n, segment: getNextSegment() + 10n },
|
|
454
454
|
);
|
|
455
455
|
|
|
456
456
|
// Create scheduled runStatus
|
|
@@ -553,7 +553,7 @@ describe("loop", () => {
|
|
|
553
553
|
const scheduledId = await ctx.scheduler.runAfter(
|
|
554
554
|
1000,
|
|
555
555
|
internal.loop.main,
|
|
556
|
-
{ generation: 1n, segment }
|
|
556
|
+
{ generation: 1n, segment },
|
|
557
557
|
);
|
|
558
558
|
|
|
559
559
|
await ctx.db.insert("runStatus", {
|
|
@@ -588,7 +588,7 @@ describe("loop", () => {
|
|
|
588
588
|
|
|
589
589
|
// Call main with mismatched generation
|
|
590
590
|
await expect(
|
|
591
|
-
t.mutation(internal.loop.main, { generation: 1n, segment: 1n })
|
|
591
|
+
t.mutation(internal.loop.main, { generation: 1n, segment: 1n }),
|
|
592
592
|
).rejects.toThrow("generation mismatch");
|
|
593
593
|
});
|
|
594
594
|
|
|
@@ -707,7 +707,7 @@ describe("loop", () => {
|
|
|
707
707
|
// Schedule a function and get its ID
|
|
708
708
|
const scheduledId = await makeDummyScheduledFunction(
|
|
709
709
|
ctx,
|
|
710
|
-
runningWorkId
|
|
710
|
+
runningWorkId,
|
|
711
711
|
);
|
|
712
712
|
|
|
713
713
|
// Create internal state
|
|
@@ -848,7 +848,7 @@ describe("loop", () => {
|
|
|
848
848
|
t.mutation(internal.loop.updateRunStatus, {
|
|
849
849
|
generation: 1n,
|
|
850
850
|
segment: 1n,
|
|
851
|
-
})
|
|
851
|
+
}),
|
|
852
852
|
).rejects.toThrow("generation mismatch");
|
|
853
853
|
});
|
|
854
854
|
|
|
@@ -935,7 +935,7 @@ describe("loop", () => {
|
|
|
935
935
|
const scheduledId = await makeDummyScheduledFunction(ctx, workId);
|
|
936
936
|
|
|
937
937
|
return { workId, scheduledId, started: Date.now() };
|
|
938
|
-
})
|
|
938
|
+
}),
|
|
939
939
|
);
|
|
940
940
|
|
|
941
941
|
// Create internal state with max running jobs
|