@convex-dev/workpool 0.2.0-beta.0 → 0.2.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 (106) hide show
  1. package/README.md +7 -16
  2. package/dist/commonjs/client/index.d.ts +3 -3
  3. package/dist/commonjs/client/index.d.ts.map +1 -1
  4. package/dist/commonjs/client/index.js +10 -5
  5. package/dist/commonjs/client/index.js.map +1 -1
  6. package/dist/commonjs/component/complete.d.ts +89 -0
  7. package/dist/commonjs/component/complete.d.ts.map +1 -0
  8. package/dist/commonjs/component/complete.js +80 -0
  9. package/dist/commonjs/component/complete.js.map +1 -0
  10. package/dist/commonjs/component/kick.d.ts +1 -2
  11. package/dist/commonjs/component/kick.d.ts.map +1 -1
  12. package/dist/commonjs/component/kick.js +7 -5
  13. package/dist/commonjs/component/kick.js.map +1 -1
  14. package/dist/commonjs/component/lib.d.ts +3 -3
  15. package/dist/commonjs/component/lib.d.ts.map +1 -1
  16. package/dist/commonjs/component/lib.js +43 -20
  17. package/dist/commonjs/component/lib.js.map +1 -1
  18. package/dist/commonjs/component/logging.d.ts.map +1 -1
  19. package/dist/commonjs/component/logging.js +1 -2
  20. package/dist/commonjs/component/logging.js.map +1 -1
  21. package/dist/commonjs/component/loop.d.ts +1 -14
  22. package/dist/commonjs/component/loop.d.ts.map +1 -1
  23. package/dist/commonjs/component/loop.js +215 -178
  24. package/dist/commonjs/component/loop.js.map +1 -1
  25. package/dist/commonjs/component/recovery.d.ts +16 -0
  26. package/dist/commonjs/component/recovery.d.ts.map +1 -1
  27. package/dist/commonjs/component/recovery.js +64 -44
  28. package/dist/commonjs/component/recovery.js.map +1 -1
  29. package/dist/commonjs/component/schema.d.ts +6 -2
  30. package/dist/commonjs/component/schema.d.ts.map +1 -1
  31. package/dist/commonjs/component/schema.js +5 -3
  32. package/dist/commonjs/component/schema.js.map +1 -1
  33. package/dist/commonjs/component/shared.d.ts +20 -11
  34. package/dist/commonjs/component/shared.d.ts.map +1 -1
  35. package/dist/commonjs/component/shared.js +18 -5
  36. package/dist/commonjs/component/shared.js.map +1 -1
  37. package/dist/commonjs/component/stats.d.ts +21 -13
  38. package/dist/commonjs/component/stats.d.ts.map +1 -1
  39. package/dist/commonjs/component/stats.js +32 -22
  40. package/dist/commonjs/component/stats.js.map +1 -1
  41. package/dist/commonjs/component/worker.d.ts +2 -12
  42. package/dist/commonjs/component/worker.d.ts.map +1 -1
  43. package/dist/commonjs/component/worker.js +23 -36
  44. package/dist/commonjs/component/worker.js.map +1 -1
  45. package/dist/esm/client/index.d.ts +3 -3
  46. package/dist/esm/client/index.d.ts.map +1 -1
  47. package/dist/esm/client/index.js +10 -5
  48. package/dist/esm/client/index.js.map +1 -1
  49. package/dist/esm/component/complete.d.ts +89 -0
  50. package/dist/esm/component/complete.d.ts.map +1 -0
  51. package/dist/esm/component/complete.js +80 -0
  52. package/dist/esm/component/complete.js.map +1 -0
  53. package/dist/esm/component/kick.d.ts +1 -2
  54. package/dist/esm/component/kick.d.ts.map +1 -1
  55. package/dist/esm/component/kick.js +7 -5
  56. package/dist/esm/component/kick.js.map +1 -1
  57. package/dist/esm/component/lib.d.ts +3 -3
  58. package/dist/esm/component/lib.d.ts.map +1 -1
  59. package/dist/esm/component/lib.js +43 -20
  60. package/dist/esm/component/lib.js.map +1 -1
  61. package/dist/esm/component/logging.d.ts.map +1 -1
  62. package/dist/esm/component/logging.js +1 -2
  63. package/dist/esm/component/logging.js.map +1 -1
  64. package/dist/esm/component/loop.d.ts +1 -14
  65. package/dist/esm/component/loop.d.ts.map +1 -1
  66. package/dist/esm/component/loop.js +215 -178
  67. package/dist/esm/component/loop.js.map +1 -1
  68. package/dist/esm/component/recovery.d.ts +16 -0
  69. package/dist/esm/component/recovery.d.ts.map +1 -1
  70. package/dist/esm/component/recovery.js +64 -44
  71. package/dist/esm/component/recovery.js.map +1 -1
  72. package/dist/esm/component/schema.d.ts +6 -2
  73. package/dist/esm/component/schema.d.ts.map +1 -1
  74. package/dist/esm/component/schema.js +5 -3
  75. package/dist/esm/component/schema.js.map +1 -1
  76. package/dist/esm/component/shared.d.ts +20 -11
  77. package/dist/esm/component/shared.d.ts.map +1 -1
  78. package/dist/esm/component/shared.js +18 -5
  79. package/dist/esm/component/shared.js.map +1 -1
  80. package/dist/esm/component/stats.d.ts +21 -13
  81. package/dist/esm/component/stats.d.ts.map +1 -1
  82. package/dist/esm/component/stats.js +32 -22
  83. package/dist/esm/component/stats.js.map +1 -1
  84. package/dist/esm/component/worker.d.ts +2 -12
  85. package/dist/esm/component/worker.d.ts.map +1 -1
  86. package/dist/esm/component/worker.js +23 -36
  87. package/dist/esm/component/worker.js.map +1 -1
  88. package/package.json +7 -6
  89. package/src/client/index.ts +18 -8
  90. package/src/component/README.md +15 -15
  91. package/src/component/_generated/api.d.ts +7 -2
  92. package/src/component/complete.test.ts +508 -0
  93. package/src/component/complete.ts +98 -0
  94. package/src/component/kick.test.ts +13 -13
  95. package/src/component/kick.ts +13 -8
  96. package/src/component/lib.test.ts +262 -17
  97. package/src/component/lib.ts +55 -24
  98. package/src/component/logging.ts +1 -2
  99. package/src/component/loop.test.ts +1158 -0
  100. package/src/component/loop.ts +289 -221
  101. package/src/component/recovery.test.ts +541 -0
  102. package/src/component/recovery.ts +80 -63
  103. package/src/component/schema.ts +6 -4
  104. package/src/component/shared.ts +21 -6
  105. package/src/component/stats.ts +48 -25
  106. package/src/component/worker.ts +25 -38
@@ -1,5 +1,6 @@
1
1
  import { v } from "convex/values";
2
- import { internalQuery } from "./_generated/server.js";
2
+ import { internalQuery, query } from "./_generated/server.js";
3
+ import { DEFAULT_MAX_PARALLELISM } from "./shared.js";
3
4
  /**
4
5
  * Record stats about work execution. Intended to be queried by Axiom or Datadog.
5
6
  */
@@ -12,36 +13,39 @@ workpool
12
13
  parse_json(trim("'", tostring(["data.message"]))),
13
14
  parse_json('{}')
14
15
  )
15
- | extend lagSinceEnqueued = parsed_message["lagSinceEnqueued"]
16
+ | extend startLag = parsed_message["startLag"]
16
17
  | extend fnName = parsed_message["fnName"]
17
- | summarize avg(todouble(lagSinceEnqueued)) by bin_auto(_time), tostring(fnName)
18
+ | summarize avg(todouble(startLag)) by bin_auto(_time), tostring(fnName)
18
19
 
19
20
  */
20
- export function recordStarted(work) {
21
- return JSON.stringify({
21
+ export function recordEnqueued(console, data) {
22
+ console.event("enqueued", {
23
+ ...data,
24
+ enqueuedAt: Date.now(),
25
+ });
26
+ }
27
+ export function recordStarted(console, work, lagMs) {
28
+ console.event("started", {
22
29
  workId: work._id,
23
- event: "started",
24
30
  fnName: work.fnName,
25
31
  enqueuedAt: work._creationTime,
26
32
  startedAt: Date.now(),
27
- lagSinceEnqueued: Date.now() - work._creationTime,
33
+ startLag: lagMs,
28
34
  });
29
35
  }
30
- export function recordCompleted(work, status) {
31
- return JSON.stringify({
36
+ export function recordCompleted(console, work, status) {
37
+ console.event("completed", {
32
38
  workId: work._id,
33
- event: "completed",
34
39
  fnName: work.fnName,
35
40
  completedAt: Date.now(),
41
+ attempts: work.attempts,
36
42
  status,
37
- lagSinceEnqueued: Date.now() - work._creationTime,
38
43
  });
39
44
  }
40
- export function recordReport(state) {
45
+ export function recordReport(console, state) {
41
46
  const { completed, succeeded, failed, retries, canceled } = state.report;
42
47
  const withoutRetries = completed - retries;
43
- return JSON.stringify({
44
- event: "report",
48
+ console.event("report", {
45
49
  completed,
46
50
  succeeded,
47
51
  failed,
@@ -55,7 +59,7 @@ export function recordReport(state) {
55
59
  * Warning: this should not be used from a mutation, as it will cause conflicts.
56
60
  * Use this to debug or diagnose your queue length when it's backed up.
57
61
  */
58
- export const queueLength = internalQuery({
62
+ export const queueLength = query({
59
63
  args: {},
60
64
  returns: v.number(),
61
65
  handler: async (ctx) => {
@@ -67,22 +71,28 @@ export const queueLength = internalQuery({
67
71
  * Warning: this should not be used from a mutation, as it will cause conflicts.
68
72
  * Use this while developing to see the state of the queue.
69
73
  */
70
- export const debugCounts = internalQuery({
74
+ export const diagnostic = internalQuery({
71
75
  args: {},
72
76
  returns: v.any(),
73
77
  handler: async (ctx) => {
74
- const inProgressWork = (await ctx.db.query("internalState").unique())?.running.length ?? 0;
78
+ const global = await ctx.db.query("globals").unique();
79
+ const internalState = await ctx.db.query("internalState").unique();
80
+ const inProgressWork = internalState?.running.length ?? 0;
81
+ const maxParallelism = global?.maxParallelism ?? DEFAULT_MAX_PARALLELISM;
75
82
  /* eslint-disable @typescript-eslint/no-explicit-any */
76
83
  const pendingStart = await ctx.db.query("pendingStart").count();
77
84
  const pendingCompletion = await ctx.db.query("pendingCompletion").count();
78
85
  const pendingCancelation = await ctx.db.query("pendingCancelation").count();
86
+ const runStatus = await ctx.db.query("runStatus").unique();
79
87
  /* eslint-enable @typescript-eslint/no-explicit-any */
80
88
  return {
81
- pendingStart,
82
- inProgressWork,
83
- pendingCompletion,
84
- pendingCancelation,
85
- active: inProgressWork - pendingCompletion,
89
+ canceling: pendingCancelation,
90
+ waiting: pendingStart,
91
+ running: inProgressWork - pendingCompletion,
92
+ completing: pendingCompletion,
93
+ spareCapacity: maxParallelism - inProgressWork,
94
+ runStatus: runStatus?.state.kind,
95
+ generation: internalState?.generation,
86
96
  };
87
97
  },
88
98
  });
@@ -1 +1 @@
1
- {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../src/component/stats.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../src/component/stats.ts"],"names":[],"mappings":"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"}
@@ -3,23 +3,13 @@ export declare const runMutationWrapper: import("convex/server").RegisteredMutat
3
3
  fnHandle: string;
4
4
  workId: import("convex/values").GenericId<"work">;
5
5
  fnArgs: any;
6
+ attempt: number;
6
7
  }, Promise<void>>;
7
8
  export declare const runActionWrapper: import("convex/server").RegisteredAction<"internal", {
8
9
  logLevel: "DEBUG" | "INFO" | "WARN" | "ERROR";
9
10
  fnHandle: string;
10
11
  workId: import("convex/values").GenericId<"work">;
11
12
  fnArgs: any;
12
- }, Promise<void>>;
13
- export declare const saveResult: import("convex/server").RegisteredMutation<"internal", {
14
- workId: import("convex/values").GenericId<"work">;
15
- runResult: {
16
- kind: "success";
17
- returnValue: any;
18
- } | {
19
- kind: "failed";
20
- error: string;
21
- } | {
22
- kind: "canceled";
23
- };
13
+ attempt: number;
24
14
  }, Promise<void>>;
25
15
  //# sourceMappingURL=worker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../../src/component/worker.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,kBAAkB;;;;;iBA0B7B,CAAC;AASH,eAAO,MAAM,gBAAgB;;;;;iBA2B3B,CAAC;AAEH,eAAO,MAAM,UAAU;;;;;;;;;;;iBAarB,CAAC"}
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../../src/component/worker.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,kBAAkB;;;;;;iBA4B7B,CAAC;AASH,eAAO,MAAM,gBAAgB;;;;;;iBA4B3B,CAAC"}
@@ -1,33 +1,33 @@
1
1
  import { v } from "convex/values";
2
2
  import { internal } from "./_generated/api.js";
3
3
  import { internalAction, internalMutation } from "./_generated/server.js";
4
- import { kickMainLoop } from "./kick.js";
5
4
  import { createLogger, logLevel } from "./logging.js";
6
- import { nextSegment, runResult } from "./shared.js";
7
5
  export const runMutationWrapper = internalMutation({
8
6
  args: {
9
7
  workId: v.id("work"),
10
8
  fnHandle: v.string(),
11
9
  fnArgs: v.any(),
12
10
  logLevel,
11
+ attempt: v.number(),
13
12
  },
14
- handler: async (ctx, { workId, fnHandle: handleStr, fnArgs, logLevel }) => {
15
- const console = createLogger(logLevel);
16
- const fnHandle = handleStr;
13
+ handler: async (ctx, { workId, attempt, ...args }) => {
14
+ const console = createLogger(args.logLevel);
15
+ const fnHandle = args.fnHandle;
17
16
  try {
18
- const returnValue = await ctx.runMutation(fnHandle, fnArgs);
17
+ const returnValue = await ctx.runMutation(fnHandle, args.fnArgs);
19
18
  // NOTE: we could run the `saveResult` handler here, or call `ctx.runMutation`,
20
19
  // but we want the mutation to be a separate transaction to reduce the window for OCCs.
21
- await ctx.scheduler.runAfter(0, internal.worker.saveResult, {
22
- workId,
23
- runResult: { kind: "success", returnValue },
20
+ await ctx.scheduler.runAfter(0, internal.complete.complete, {
21
+ jobs: [
22
+ { workId, runResult: { kind: "success", returnValue }, attempt },
23
+ ],
24
24
  });
25
25
  }
26
26
  catch (e) {
27
27
  console.error(e);
28
- await ctx.scheduler.runAfter(0, internal.worker.saveResult, {
29
- workId,
30
- runResult: { kind: "failed", error: formatError(e) },
28
+ const runResult = { kind: "failed", error: formatError(e) };
29
+ await ctx.scheduler.runAfter(0, internal.complete.complete, {
30
+ jobs: [{ workId, runResult, attempt }],
31
31
  });
32
32
  }
33
33
  },
@@ -44,43 +44,30 @@ export const runActionWrapper = internalAction({
44
44
  fnHandle: v.string(),
45
45
  fnArgs: v.any(),
46
46
  logLevel,
47
+ attempt: v.number(),
47
48
  },
48
- handler: async (ctx, { workId, fnHandle: handleStr, fnArgs, logLevel }) => {
49
- const console = createLogger(logLevel);
50
- const fnHandle = handleStr;
49
+ handler: async (ctx, { workId, attempt, ...args }) => {
50
+ const console = createLogger(args.logLevel);
51
+ const fnHandle = args.fnHandle;
51
52
  try {
52
- const returnValue = await ctx.runAction(fnHandle, fnArgs);
53
+ const returnValue = await ctx.runAction(fnHandle, args.fnArgs);
53
54
  // NOTE: we could run `ctx.runMutation`, but we want to guarantee execution,
54
55
  // and `ctx.scheduler.runAfter` won't OCC.
55
- await ctx.scheduler.runAfter(0, internal.worker.saveResult, {
56
- workId,
57
- runResult: { kind: "success", returnValue },
56
+ const runResult = { kind: "success", returnValue };
57
+ await ctx.scheduler.runAfter(0, internal.complete.complete, {
58
+ jobs: [{ workId, runResult, attempt }],
58
59
  });
59
60
  }
60
61
  catch (e) {
61
62
  console.error(e);
62
63
  // We let the main loop handle the retries.
63
- await ctx.scheduler.runAfter(0, internal.worker.saveResult, {
64
- workId,
65
- runResult: { kind: "failed", error: formatError(e) },
64
+ const runResult = { kind: "failed", error: formatError(e) };
65
+ await ctx.scheduler.runAfter(0, internal.complete.complete, {
66
+ jobs: [{ workId, runResult, attempt }],
66
67
  });
67
68
  }
68
69
  },
69
70
  });
70
- export const saveResult = internalMutation({
71
- args: {
72
- workId: v.id("work"),
73
- runResult,
74
- },
75
- handler: async (ctx, { workId, runResult }) => {
76
- await ctx.db.insert("pendingCompletion", {
77
- runResult,
78
- workId,
79
- segment: nextSegment(),
80
- });
81
- await kickMainLoop(ctx, "saveResult");
82
- },
83
- });
84
71
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
85
72
  const console = "THIS IS A REMINDER TO USE createLogger";
86
73
  //# sourceMappingURL=worker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../../src/component/worker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../../src/component/worker.ts"],"names":[],"mappings":"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"}
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.0-beta.0",
10
+ "version": "0.2.0",
11
11
  "license": "Apache-2.0",
12
12
  "keywords": [
13
13
  "convex",
@@ -24,14 +24,15 @@
24
24
  "build:cjs": "tsc --project ./commonjs.json && echo '{\\n \"type\": \"commonjs\"\\n}' > dist/commonjs/package.json",
25
25
  "dev": "cd example; npm run dev",
26
26
  "typecheck": "tsc --noEmit",
27
- "prepare": "npm run build",
28
- "prepack": "node node10stubs.mjs",
29
- "postpack": "node node10stubs.mjs --cleanup",
30
- "test": "vitest",
31
27
  "lint": "tsc --noEmit && eslint . && prettier --check .",
32
28
  "format": "prettier --write .",
29
+ "test": "vitest run",
30
+ "test:watch": "vitest",
33
31
  "test:debug": "vitest --inspect-brk --no-file-parallelism",
34
- "test:coverage": "vitest run --coverage --coverage.reporter=text"
32
+ "test:coverage": "vitest run --coverage --coverage.reporter=text",
33
+ "prepare": "npm run build",
34
+ "prepack": "node node10stubs.mjs",
35
+ "postpack": "node node10stubs.mjs --cleanup"
35
36
  },
36
37
  "files": [
37
38
  "dist",
@@ -8,19 +8,22 @@ import {
8
8
  import { v, VString } from "convex/values";
9
9
  import { Mounts } from "../component/_generated/api.js";
10
10
  import {
11
+ DEFAULT_LOG_LEVEL,
12
+ type LogLevel,
13
+ logLevel,
14
+ } from "../component/logging.js";
15
+ import {
16
+ Config,
17
+ DEFAULT_MAX_PARALLELISM,
11
18
  OnComplete,
12
- runResult as runResultValidator,
13
- RunResult,
19
+ runResult as resultValidator,
14
20
  type RetryBehavior,
21
+ RunResult,
15
22
  OnCompleteArgs as SharedOnCompleteArgs,
16
23
  Status,
17
- Config,
18
24
  } from "../component/shared.js";
19
- import { type LogLevel, logLevel } from "../component/logging.js";
20
25
  import { RunMutationCtx, RunQueryCtx, UseApi } from "./utils.js";
21
- import { DEFAULT_LOG_LEVEL } from "../component/logging.js";
22
- import { DEFAULT_MAX_PARALLELISM } from "../component/kick.js";
23
- export { runResultValidator, type RunResult };
26
+ export { resultValidator, type RunResult };
24
27
 
25
28
  // Attempts will run with delay [0, 250, 500, 1000, 2000] (ms)
26
29
  export const DEFAULT_RETRY_BEHAVIOR: RetryBehavior = {
@@ -133,11 +136,18 @@ export class Workpool {
133
136
  fnArgs: Args,
134
137
  options?: CallbackOptions & SchedulerOptions
135
138
  ): Promise<WorkId> {
139
+ const onComplete: OnComplete | undefined = options?.onComplete
140
+ ? {
141
+ fnHandle: await createFunctionHandle(options.onComplete),
142
+ context: options.context,
143
+ }
144
+ : undefined;
136
145
  const id = await ctx.runMutation(this.component.lib.enqueue, {
137
146
  ...(await defaultEnqueueArgs(fn, this.options)),
138
147
  fnArgs,
139
148
  fnType: "mutation",
140
149
  runAt: getRunAt(options),
150
+ onComplete,
141
151
  });
142
152
  return id as WorkId;
143
153
  }
@@ -215,7 +225,7 @@ export type CallbackOptions = {
215
225
  * args: {
216
226
  * workId: workIdValidator,
217
227
  * context: v.any(),
218
- * result: runResult,
228
+ * result: resultValidator,
219
229
  * },
220
230
  * handler: async (ctx, args) => {
221
231
  * console.log(args.result, "Got Context back -> ", args.context, Date.now() - args.context);
@@ -25,19 +25,19 @@ Concepts:
25
25
  flowchart LR
26
26
  Client -->|enqueue| pendingStart
27
27
  Client -->|cancel| pendingCancelation
28
- Recovery-->|recover| pendingCancelation
29
- Recovery-->|recover| pendingCompletion
30
- Worker-->|"saveResult"| pendingCompletion
31
- pendingStart -->|main| workerRunning["internalState.running"]
32
- workerRunning-->|"main(pendingCompletion)"| Retry{"Needs retry?"}
33
- Retry-->|"no / canceled"| complete
34
- Retry-->|yes| pendingStart
35
- pendingStart-->|"main(pendingCancelation)"| complete
28
+ complete --> |success or failure| pendingCompletion
29
+ pendingCompletion -->|retry| pendingStart
30
+ pendingStart --> workerRunning["worker running"]
31
+ workerRunning -->|worker finished| complete
32
+ workerRunning --> |recovery| complete
33
+ successfulCancel["AND"]@{shape: delay} --> |canceled| complete
34
+ pendingStart --> successfulCancel
35
+ pendingCancelation --> successfulCancel
36
36
  ```
37
37
 
38
38
  Notably:
39
39
 
40
- - The pending\* states are only written by other sources.
40
+ - The pending\* states are written by outside sources.
41
41
  - The main loop federates changes to/from "running"
42
42
  - Canceling only impacts pending and retrying jobs.
43
43
 
@@ -53,12 +53,12 @@ flowchart TD
53
53
  running-->|"all done"| idle
54
54
  ```
55
55
 
56
- - While the loop is running, clients won't see database conflicts with the
57
- state changing.
58
- - The "saturated" state is concretely "running" or "scheduled" with a boolean
59
- set, to avoid clients from kicking the main loop on enqueueing, which is
60
- unlikely to be productive, since the next action needs to be something
61
- terminating.
56
+ - While the loop is running, the runStatus doesn't change, making it safer to
57
+ read from clients without database conflicts.
58
+ - The "saturated" state is concretely "running" or "scheduled" at max
59
+ parallelism. There is a boolean set on "scheduled" to avoid clients from
60
+ kicking the main loop on enqueueing, which is unlikely to be productive, since
61
+ the next action needs to be something terminating.
62
62
 
63
63
  ## Retention optimization strategy
64
64
 
@@ -8,6 +8,7 @@
8
8
  * @module
9
9
  */
10
10
 
11
+ import type * as complete from "../complete.js";
11
12
  import type * as kick from "../kick.js";
12
13
  import type * as lib from "../lib.js";
13
14
  import type * as logging from "../logging.js";
@@ -31,6 +32,7 @@ import type {
31
32
  * ```
32
33
  */
33
34
  declare const fullApi: ApiFromModules<{
35
+ complete: typeof complete;
34
36
  kick: typeof kick;
35
37
  lib: typeof lib;
36
38
  logging: typeof logging;
@@ -80,11 +82,14 @@ export type Mounts = {
80
82
  "query",
81
83
  "public",
82
84
  { id: string },
83
- | { attempt: number; state: "pending" }
84
- | { attempt: number; state: "running" }
85
+ | { previousAttempts: number; state: "pending" }
86
+ | { previousAttempts: number; state: "running" }
85
87
  | { state: "finished" }
86
88
  >;
87
89
  };
90
+ stats: {
91
+ queueLength: FunctionReference<"query", "public", {}, number>;
92
+ };
88
93
  };
89
94
  // For now fullApiWithMounts is only fullApi which provides
90
95
  // jump-to-definition in component client code.