@convex-dev/workpool 0.2.16 → 0.2.17-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/README.md +1 -0
- package/dist/commonjs/client/index.d.ts +1 -1
- package/dist/commonjs/component/danger.d.ts +11 -0
- package/dist/commonjs/component/danger.d.ts.map +1 -0
- package/dist/commonjs/component/danger.js +92 -0
- package/dist/commonjs/component/danger.js.map +1 -0
- package/dist/commonjs/component/stats.d.ts +1 -1
- package/dist/esm/client/index.d.ts +1 -1
- package/dist/esm/component/danger.d.ts +11 -0
- package/dist/esm/component/danger.d.ts.map +1 -0
- package/dist/esm/component/danger.js +92 -0
- package/dist/esm/component/danger.js.map +1 -0
- package/dist/esm/component/stats.d.ts +1 -1
- package/package.json +14 -14
- package/src/client/index.ts +1 -1
- package/src/component/_generated/api.d.ts +2 -0
- package/src/component/danger.ts +110 -0
package/README.md
CHANGED
|
@@ -280,6 +280,7 @@ See more example usage in [example.ts](./example/convex/example.ts).
|
|
|
280
280
|
Check out the [docstrings](./src/client/index.ts), but notable options include:
|
|
281
281
|
|
|
282
282
|
- `maxParallelism`: How many actions/mutations can run at once within this pool.
|
|
283
|
+
Avoid exceeding 100 on Pro, 20 on the free plan, across all workpools and workflows.
|
|
283
284
|
- `retryActionsByDefault`: Whether to retry actions that fail by default.
|
|
284
285
|
- `defaultRetryBehavior`: The default retry behavior for enqueued actions.
|
|
285
286
|
|
|
@@ -229,7 +229,7 @@ export type RetryOption = {
|
|
|
229
229
|
};
|
|
230
230
|
export type WorkpoolOptions = {
|
|
231
231
|
/** How many actions/mutations can be running at once within this pool.
|
|
232
|
-
* Min 1,
|
|
232
|
+
* Min 1, Suggested max: 100 on Pro, 20 on the free plan.
|
|
233
233
|
*/
|
|
234
234
|
maxParallelism?: number;
|
|
235
235
|
/** How much to log. This is updated on each call to `enqueue*`,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const clearPending: import("convex/server").RegisteredMutation<"internal", {
|
|
2
|
+
olderThan?: number | undefined;
|
|
3
|
+
before?: number | undefined;
|
|
4
|
+
cursor?: string | undefined;
|
|
5
|
+
}, Promise<void>>;
|
|
6
|
+
export declare const clearOldWork: import("convex/server").RegisteredMutation<"internal", {
|
|
7
|
+
olderThan?: number | undefined;
|
|
8
|
+
before?: number | undefined;
|
|
9
|
+
cursor?: string | undefined;
|
|
10
|
+
}, Promise<void>>;
|
|
11
|
+
//# sourceMappingURL=danger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"danger.d.ts","sourceRoot":"","sources":["../../../src/component/danger.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,YAAY;;;;iBAgCvB,CAAC;AAEH,eAAO,MAAM,YAAY;;;;iBA2DvB,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { v } from "convex/values";
|
|
2
|
+
import { internal } from "./_generated/api.js";
|
|
3
|
+
import { internalMutation, } from "./_generated/server.js";
|
|
4
|
+
import { paginator } from "convex-helpers/server/pagination";
|
|
5
|
+
import schema from "./schema.js";
|
|
6
|
+
const DEFAULT_OLDER_THAN = 1000 * 60 * 60 * 24;
|
|
7
|
+
export const clearPending = internalMutation({
|
|
8
|
+
args: {
|
|
9
|
+
olderThan: v.optional(v.number()),
|
|
10
|
+
before: v.optional(v.number()),
|
|
11
|
+
cursor: v.optional(v.string()),
|
|
12
|
+
},
|
|
13
|
+
handler: async (ctx, args) => {
|
|
14
|
+
const time = args.before ?? Date.now() - (args.olderThan ?? DEFAULT_OLDER_THAN);
|
|
15
|
+
const entries = await paginator(ctx.db, schema)
|
|
16
|
+
.query("pendingStart")
|
|
17
|
+
.withIndex("by_creation_time", (q) => q.lt("_creationTime", time))
|
|
18
|
+
.paginate({
|
|
19
|
+
cursor: args.cursor ?? null,
|
|
20
|
+
numItems: 100,
|
|
21
|
+
});
|
|
22
|
+
await Promise.all(entries.page.map(async (entry) => {
|
|
23
|
+
await ctx.db.delete(entry._id);
|
|
24
|
+
const work = await ctx.db.get(entry.workId);
|
|
25
|
+
if (work) {
|
|
26
|
+
await ctx.db.delete(work._id);
|
|
27
|
+
}
|
|
28
|
+
}));
|
|
29
|
+
if (!entries.isDone) {
|
|
30
|
+
await ctx.scheduler.runAfter(0, internal.danger.clearPending, {
|
|
31
|
+
before: time,
|
|
32
|
+
cursor: entries.continueCursor,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
export const clearOldWork = internalMutation({
|
|
38
|
+
args: {
|
|
39
|
+
olderThan: v.optional(v.number()),
|
|
40
|
+
before: v.optional(v.number()),
|
|
41
|
+
cursor: v.optional(v.string()),
|
|
42
|
+
},
|
|
43
|
+
handler: async (ctx, args) => {
|
|
44
|
+
const time = args.before ?? Date.now() - (args.olderThan ?? DEFAULT_OLDER_THAN);
|
|
45
|
+
const entries = await paginator(ctx.db, schema)
|
|
46
|
+
.query("work")
|
|
47
|
+
.withIndex("by_creation_time", (q) => q.lt("_creationTime", time))
|
|
48
|
+
.paginate({
|
|
49
|
+
cursor: args.cursor ?? null,
|
|
50
|
+
numItems: 100,
|
|
51
|
+
});
|
|
52
|
+
await Promise.all(entries.page.map(async (entry) => {
|
|
53
|
+
const pendingStart = await ctx.db
|
|
54
|
+
.query("pendingStart")
|
|
55
|
+
.withIndex("workId", (q) => q.eq("workId", entry._id))
|
|
56
|
+
.unique();
|
|
57
|
+
if (pendingStart) {
|
|
58
|
+
await ctx.db.delete(pendingStart._id);
|
|
59
|
+
}
|
|
60
|
+
const pendingCompletion = await ctx.db
|
|
61
|
+
.query("pendingCompletion")
|
|
62
|
+
.withIndex("workId", (q) => q.eq("workId", entry._id))
|
|
63
|
+
.unique();
|
|
64
|
+
if (pendingCompletion) {
|
|
65
|
+
await ctx.db.delete(pendingCompletion._id);
|
|
66
|
+
}
|
|
67
|
+
const pendingCancelation = await ctx.db
|
|
68
|
+
.query("pendingCancelation")
|
|
69
|
+
.withIndex("workId", (q) => q.eq("workId", entry._id))
|
|
70
|
+
.unique();
|
|
71
|
+
if (pendingCancelation) {
|
|
72
|
+
await ctx.db.delete(pendingCancelation._id);
|
|
73
|
+
}
|
|
74
|
+
console.debug(`cleared ${entry.fnName}: ${entry.fnArgs} (${Object.entries({
|
|
75
|
+
pendingStart,
|
|
76
|
+
pendingCompletion,
|
|
77
|
+
pendingCancelation,
|
|
78
|
+
})
|
|
79
|
+
.filter(([_, v]) => v !== null)
|
|
80
|
+
.map(([name]) => name)
|
|
81
|
+
.join(", ")})`);
|
|
82
|
+
await ctx.db.delete(entry._id);
|
|
83
|
+
}));
|
|
84
|
+
if (!entries.isDone) {
|
|
85
|
+
await ctx.scheduler.runAfter(0, internal.danger.clearOldWork, {
|
|
86
|
+
before: time,
|
|
87
|
+
cursor: entries.continueCursor,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
//# sourceMappingURL=danger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"danger.js","sourceRoot":"","sources":["../../../src/component/danger.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,9 +25,9 @@ export declare const calculateBacklogAndReport: import("convex/server").Register
|
|
|
25
25
|
};
|
|
26
26
|
logLevel: "DEBUG" | "TRACE" | "INFO" | "REPORT" | "WARN" | "ERROR";
|
|
27
27
|
running: number;
|
|
28
|
+
cursor: string;
|
|
28
29
|
startSegment: bigint;
|
|
29
30
|
endSegment: bigint;
|
|
30
|
-
cursor: string;
|
|
31
31
|
}, Promise<void>>;
|
|
32
32
|
/**
|
|
33
33
|
* Warning: this should not be used from a mutation, as it will cause conflicts.
|
|
@@ -229,7 +229,7 @@ export type RetryOption = {
|
|
|
229
229
|
};
|
|
230
230
|
export type WorkpoolOptions = {
|
|
231
231
|
/** How many actions/mutations can be running at once within this pool.
|
|
232
|
-
* Min 1,
|
|
232
|
+
* Min 1, Suggested max: 100 on Pro, 20 on the free plan.
|
|
233
233
|
*/
|
|
234
234
|
maxParallelism?: number;
|
|
235
235
|
/** How much to log. This is updated on each call to `enqueue*`,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const clearPending: import("convex/server").RegisteredMutation<"internal", {
|
|
2
|
+
olderThan?: number | undefined;
|
|
3
|
+
before?: number | undefined;
|
|
4
|
+
cursor?: string | undefined;
|
|
5
|
+
}, Promise<void>>;
|
|
6
|
+
export declare const clearOldWork: import("convex/server").RegisteredMutation<"internal", {
|
|
7
|
+
olderThan?: number | undefined;
|
|
8
|
+
before?: number | undefined;
|
|
9
|
+
cursor?: string | undefined;
|
|
10
|
+
}, Promise<void>>;
|
|
11
|
+
//# sourceMappingURL=danger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"danger.d.ts","sourceRoot":"","sources":["../../../src/component/danger.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,YAAY;;;;iBAgCvB,CAAC;AAEH,eAAO,MAAM,YAAY;;;;iBA2DvB,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { v } from "convex/values";
|
|
2
|
+
import { internal } from "./_generated/api.js";
|
|
3
|
+
import { internalMutation, } from "./_generated/server.js";
|
|
4
|
+
import { paginator } from "convex-helpers/server/pagination";
|
|
5
|
+
import schema from "./schema.js";
|
|
6
|
+
const DEFAULT_OLDER_THAN = 1000 * 60 * 60 * 24;
|
|
7
|
+
export const clearPending = internalMutation({
|
|
8
|
+
args: {
|
|
9
|
+
olderThan: v.optional(v.number()),
|
|
10
|
+
before: v.optional(v.number()),
|
|
11
|
+
cursor: v.optional(v.string()),
|
|
12
|
+
},
|
|
13
|
+
handler: async (ctx, args) => {
|
|
14
|
+
const time = args.before ?? Date.now() - (args.olderThan ?? DEFAULT_OLDER_THAN);
|
|
15
|
+
const entries = await paginator(ctx.db, schema)
|
|
16
|
+
.query("pendingStart")
|
|
17
|
+
.withIndex("by_creation_time", (q) => q.lt("_creationTime", time))
|
|
18
|
+
.paginate({
|
|
19
|
+
cursor: args.cursor ?? null,
|
|
20
|
+
numItems: 100,
|
|
21
|
+
});
|
|
22
|
+
await Promise.all(entries.page.map(async (entry) => {
|
|
23
|
+
await ctx.db.delete(entry._id);
|
|
24
|
+
const work = await ctx.db.get(entry.workId);
|
|
25
|
+
if (work) {
|
|
26
|
+
await ctx.db.delete(work._id);
|
|
27
|
+
}
|
|
28
|
+
}));
|
|
29
|
+
if (!entries.isDone) {
|
|
30
|
+
await ctx.scheduler.runAfter(0, internal.danger.clearPending, {
|
|
31
|
+
before: time,
|
|
32
|
+
cursor: entries.continueCursor,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
export const clearOldWork = internalMutation({
|
|
38
|
+
args: {
|
|
39
|
+
olderThan: v.optional(v.number()),
|
|
40
|
+
before: v.optional(v.number()),
|
|
41
|
+
cursor: v.optional(v.string()),
|
|
42
|
+
},
|
|
43
|
+
handler: async (ctx, args) => {
|
|
44
|
+
const time = args.before ?? Date.now() - (args.olderThan ?? DEFAULT_OLDER_THAN);
|
|
45
|
+
const entries = await paginator(ctx.db, schema)
|
|
46
|
+
.query("work")
|
|
47
|
+
.withIndex("by_creation_time", (q) => q.lt("_creationTime", time))
|
|
48
|
+
.paginate({
|
|
49
|
+
cursor: args.cursor ?? null,
|
|
50
|
+
numItems: 100,
|
|
51
|
+
});
|
|
52
|
+
await Promise.all(entries.page.map(async (entry) => {
|
|
53
|
+
const pendingStart = await ctx.db
|
|
54
|
+
.query("pendingStart")
|
|
55
|
+
.withIndex("workId", (q) => q.eq("workId", entry._id))
|
|
56
|
+
.unique();
|
|
57
|
+
if (pendingStart) {
|
|
58
|
+
await ctx.db.delete(pendingStart._id);
|
|
59
|
+
}
|
|
60
|
+
const pendingCompletion = await ctx.db
|
|
61
|
+
.query("pendingCompletion")
|
|
62
|
+
.withIndex("workId", (q) => q.eq("workId", entry._id))
|
|
63
|
+
.unique();
|
|
64
|
+
if (pendingCompletion) {
|
|
65
|
+
await ctx.db.delete(pendingCompletion._id);
|
|
66
|
+
}
|
|
67
|
+
const pendingCancelation = await ctx.db
|
|
68
|
+
.query("pendingCancelation")
|
|
69
|
+
.withIndex("workId", (q) => q.eq("workId", entry._id))
|
|
70
|
+
.unique();
|
|
71
|
+
if (pendingCancelation) {
|
|
72
|
+
await ctx.db.delete(pendingCancelation._id);
|
|
73
|
+
}
|
|
74
|
+
console.debug(`cleared ${entry.fnName}: ${entry.fnArgs} (${Object.entries({
|
|
75
|
+
pendingStart,
|
|
76
|
+
pendingCompletion,
|
|
77
|
+
pendingCancelation,
|
|
78
|
+
})
|
|
79
|
+
.filter(([_, v]) => v !== null)
|
|
80
|
+
.map(([name]) => name)
|
|
81
|
+
.join(", ")})`);
|
|
82
|
+
await ctx.db.delete(entry._id);
|
|
83
|
+
}));
|
|
84
|
+
if (!entries.isDone) {
|
|
85
|
+
await ctx.scheduler.runAfter(0, internal.danger.clearOldWork, {
|
|
86
|
+
before: time,
|
|
87
|
+
cursor: entries.continueCursor,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
//# sourceMappingURL=danger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"danger.js","sourceRoot":"","sources":["../../../src/component/danger.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,9 +25,9 @@ export declare const calculateBacklogAndReport: import("convex/server").Register
|
|
|
25
25
|
};
|
|
26
26
|
logLevel: "DEBUG" | "TRACE" | "INFO" | "REPORT" | "WARN" | "ERROR";
|
|
27
27
|
running: number;
|
|
28
|
+
cursor: string;
|
|
28
29
|
startSegment: bigint;
|
|
29
30
|
endSegment: bigint;
|
|
30
|
-
cursor: string;
|
|
31
31
|
}, Promise<void>>;
|
|
32
32
|
/**
|
|
33
33
|
* Warning: this should not be used from a mutation, as it will cause conflicts.
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"email": "support@convex.dev",
|
|
8
8
|
"url": "https://github.com/get-convex/workpool/issues"
|
|
9
9
|
},
|
|
10
|
-
"version": "0.2.
|
|
10
|
+
"version": "0.2.17-alpha.1",
|
|
11
11
|
"license": "Apache-2.0",
|
|
12
12
|
"keywords": [
|
|
13
13
|
"convex",
|
|
@@ -64,22 +64,22 @@
|
|
|
64
64
|
}
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
|
-
"convex": ">=1.
|
|
67
|
+
"convex": ">=1.25.0 <1.35.0",
|
|
68
68
|
"convex-helpers": "^0.1.94"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@edge-runtime/vm": "
|
|
72
|
-
"@eslint/js": "
|
|
73
|
-
"@types/node": "
|
|
74
|
-
"@vitest/coverage-v8": "
|
|
75
|
-
"convex-test": "
|
|
76
|
-
"eslint": "
|
|
77
|
-
"globals": "
|
|
78
|
-
"pkg-pr-new": "
|
|
79
|
-
"prettier": "3.2
|
|
80
|
-
"typescript": "
|
|
81
|
-
"typescript-eslint": "
|
|
82
|
-
"vitest": "
|
|
71
|
+
"@edge-runtime/vm": "5.0.0",
|
|
72
|
+
"@eslint/js": "9.31.0",
|
|
73
|
+
"@types/node": "22.16.3",
|
|
74
|
+
"@vitest/coverage-v8": "3.2.4",
|
|
75
|
+
"convex-test": "0.0.38",
|
|
76
|
+
"eslint": "9.31.0",
|
|
77
|
+
"globals": "16.3.0",
|
|
78
|
+
"pkg-pr-new": "0.0.54",
|
|
79
|
+
"prettier": "3.6.2",
|
|
80
|
+
"typescript": "5.8.3",
|
|
81
|
+
"typescript-eslint": "8.36.0",
|
|
82
|
+
"vitest": "3.2.4"
|
|
83
83
|
},
|
|
84
84
|
"main": "./dist/commonjs/client/index.js",
|
|
85
85
|
"types": "./dist/commonjs/client/index.d.ts",
|
package/src/client/index.ts
CHANGED
|
@@ -289,7 +289,7 @@ export type RetryOption = {
|
|
|
289
289
|
|
|
290
290
|
export type WorkpoolOptions = {
|
|
291
291
|
/** How many actions/mutations can be running at once within this pool.
|
|
292
|
-
* Min 1,
|
|
292
|
+
* Min 1, Suggested max: 100 on Pro, 20 on the free plan.
|
|
293
293
|
*/
|
|
294
294
|
maxParallelism?: number;
|
|
295
295
|
/** How much to log. This is updated on each call to `enqueue*`,
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import type * as complete from "../complete.js";
|
|
12
12
|
import type * as crons from "../crons.js";
|
|
13
|
+
import type * as danger from "../danger.js";
|
|
13
14
|
import type * as kick from "../kick.js";
|
|
14
15
|
import type * as lib from "../lib.js";
|
|
15
16
|
import type * as logging from "../logging.js";
|
|
@@ -36,6 +37,7 @@ import type {
|
|
|
36
37
|
declare const fullApi: ApiFromModules<{
|
|
37
38
|
complete: typeof complete;
|
|
38
39
|
crons: typeof crons;
|
|
40
|
+
danger: typeof danger;
|
|
39
41
|
kick: typeof kick;
|
|
40
42
|
lib: typeof lib;
|
|
41
43
|
logging: typeof logging;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { v } from "convex/values";
|
|
2
|
+
import { api, internal } from "./_generated/api.js";
|
|
3
|
+
import type { Doc, Id } from "./_generated/dataModel.js";
|
|
4
|
+
import {
|
|
5
|
+
action,
|
|
6
|
+
internalAction,
|
|
7
|
+
internalMutation,
|
|
8
|
+
internalQuery,
|
|
9
|
+
mutation,
|
|
10
|
+
query,
|
|
11
|
+
} from "./_generated/server.js";
|
|
12
|
+
import { paginator } from "convex-helpers/server/pagination";
|
|
13
|
+
import schema from "./schema.js";
|
|
14
|
+
|
|
15
|
+
const DEFAULT_OLDER_THAN = 1000 * 60 * 60 * 24;
|
|
16
|
+
|
|
17
|
+
export const clearPending = internalMutation({
|
|
18
|
+
args: {
|
|
19
|
+
olderThan: v.optional(v.number()),
|
|
20
|
+
before: v.optional(v.number()),
|
|
21
|
+
cursor: v.optional(v.string()),
|
|
22
|
+
},
|
|
23
|
+
handler: async (ctx, args) => {
|
|
24
|
+
const time =
|
|
25
|
+
args.before ?? Date.now() - (args.olderThan ?? DEFAULT_OLDER_THAN);
|
|
26
|
+
const entries = await paginator(ctx.db, schema)
|
|
27
|
+
.query("pendingStart")
|
|
28
|
+
.withIndex("by_creation_time", (q) => q.lt("_creationTime", time))
|
|
29
|
+
.paginate({
|
|
30
|
+
cursor: args.cursor ?? null,
|
|
31
|
+
numItems: 100,
|
|
32
|
+
});
|
|
33
|
+
await Promise.all(
|
|
34
|
+
entries.page.map(async (entry) => {
|
|
35
|
+
await ctx.db.delete(entry._id);
|
|
36
|
+
const work = await ctx.db.get(entry.workId);
|
|
37
|
+
if (work) {
|
|
38
|
+
await ctx.db.delete(work._id);
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
);
|
|
42
|
+
if (!entries.isDone) {
|
|
43
|
+
await ctx.scheduler.runAfter(0, internal.danger.clearPending, {
|
|
44
|
+
before: time,
|
|
45
|
+
cursor: entries.continueCursor,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
export const clearOldWork = internalMutation({
|
|
52
|
+
args: {
|
|
53
|
+
olderThan: v.optional(v.number()),
|
|
54
|
+
before: v.optional(v.number()),
|
|
55
|
+
cursor: v.optional(v.string()),
|
|
56
|
+
},
|
|
57
|
+
handler: async (ctx, args) => {
|
|
58
|
+
const time =
|
|
59
|
+
args.before ?? Date.now() - (args.olderThan ?? DEFAULT_OLDER_THAN);
|
|
60
|
+
const entries = await paginator(ctx.db, schema)
|
|
61
|
+
.query("work")
|
|
62
|
+
.withIndex("by_creation_time", (q) => q.lt("_creationTime", time))
|
|
63
|
+
.paginate({
|
|
64
|
+
cursor: args.cursor ?? null,
|
|
65
|
+
numItems: 100,
|
|
66
|
+
});
|
|
67
|
+
await Promise.all(
|
|
68
|
+
entries.page.map(async (entry) => {
|
|
69
|
+
const pendingStart = await ctx.db
|
|
70
|
+
.query("pendingStart")
|
|
71
|
+
.withIndex("workId", (q) => q.eq("workId", entry._id))
|
|
72
|
+
.unique();
|
|
73
|
+
if (pendingStart) {
|
|
74
|
+
await ctx.db.delete(pendingStart._id);
|
|
75
|
+
}
|
|
76
|
+
const pendingCompletion = await ctx.db
|
|
77
|
+
.query("pendingCompletion")
|
|
78
|
+
.withIndex("workId", (q) => q.eq("workId", entry._id))
|
|
79
|
+
.unique();
|
|
80
|
+
if (pendingCompletion) {
|
|
81
|
+
await ctx.db.delete(pendingCompletion._id);
|
|
82
|
+
}
|
|
83
|
+
const pendingCancelation = await ctx.db
|
|
84
|
+
.query("pendingCancelation")
|
|
85
|
+
.withIndex("workId", (q) => q.eq("workId", entry._id))
|
|
86
|
+
.unique();
|
|
87
|
+
if (pendingCancelation) {
|
|
88
|
+
await ctx.db.delete(pendingCancelation._id);
|
|
89
|
+
}
|
|
90
|
+
console.debug(
|
|
91
|
+
`cleared ${entry.fnName}: ${entry.fnArgs} (${Object.entries({
|
|
92
|
+
pendingStart,
|
|
93
|
+
pendingCompletion,
|
|
94
|
+
pendingCancelation,
|
|
95
|
+
})
|
|
96
|
+
.filter(([_, v]) => v !== null)
|
|
97
|
+
.map(([name]) => name)
|
|
98
|
+
.join(", ")})`
|
|
99
|
+
);
|
|
100
|
+
await ctx.db.delete(entry._id);
|
|
101
|
+
})
|
|
102
|
+
);
|
|
103
|
+
if (!entries.isDone) {
|
|
104
|
+
await ctx.scheduler.runAfter(0, internal.danger.clearOldWork, {
|
|
105
|
+
before: time,
|
|
106
|
+
cursor: entries.continueCursor,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
});
|