@convex-dev/workpool 0.2.0-alpha.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 (70) hide show
  1. package/README.md +1 -1
  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.js +1 -1
  7. package/dist/commonjs/component/complete.js.map +1 -1
  8. package/dist/commonjs/component/kick.d.ts +0 -1
  9. package/dist/commonjs/component/kick.d.ts.map +1 -1
  10. package/dist/commonjs/component/kick.js +6 -4
  11. package/dist/commonjs/component/kick.js.map +1 -1
  12. package/dist/commonjs/component/lib.d.ts.map +1 -1
  13. package/dist/commonjs/component/lib.js +4 -3
  14. package/dist/commonjs/component/lib.js.map +1 -1
  15. package/dist/commonjs/component/logging.d.ts.map +1 -1
  16. package/dist/commonjs/component/logging.js +1 -2
  17. package/dist/commonjs/component/logging.js.map +1 -1
  18. package/dist/commonjs/component/loop.d.ts.map +1 -1
  19. package/dist/commonjs/component/loop.js +46 -38
  20. package/dist/commonjs/component/loop.js.map +1 -1
  21. package/dist/commonjs/component/shared.d.ts +1 -0
  22. package/dist/commonjs/component/shared.d.ts.map +1 -1
  23. package/dist/commonjs/component/shared.js +1 -0
  24. package/dist/commonjs/component/shared.js.map +1 -1
  25. package/dist/commonjs/component/stats.d.ts +19 -13
  26. package/dist/commonjs/component/stats.d.ts.map +1 -1
  27. package/dist/commonjs/component/stats.js +26 -21
  28. package/dist/commonjs/component/stats.js.map +1 -1
  29. package/dist/esm/client/index.d.ts +3 -3
  30. package/dist/esm/client/index.d.ts.map +1 -1
  31. package/dist/esm/client/index.js +10 -5
  32. package/dist/esm/client/index.js.map +1 -1
  33. package/dist/esm/component/complete.js +1 -1
  34. package/dist/esm/component/complete.js.map +1 -1
  35. package/dist/esm/component/kick.d.ts +0 -1
  36. package/dist/esm/component/kick.d.ts.map +1 -1
  37. package/dist/esm/component/kick.js +6 -4
  38. package/dist/esm/component/kick.js.map +1 -1
  39. package/dist/esm/component/lib.d.ts.map +1 -1
  40. package/dist/esm/component/lib.js +4 -3
  41. package/dist/esm/component/lib.js.map +1 -1
  42. package/dist/esm/component/logging.d.ts.map +1 -1
  43. package/dist/esm/component/logging.js +1 -2
  44. package/dist/esm/component/logging.js.map +1 -1
  45. package/dist/esm/component/loop.d.ts.map +1 -1
  46. package/dist/esm/component/loop.js +46 -38
  47. package/dist/esm/component/loop.js.map +1 -1
  48. package/dist/esm/component/shared.d.ts +1 -0
  49. package/dist/esm/component/shared.d.ts.map +1 -1
  50. package/dist/esm/component/shared.js +1 -0
  51. package/dist/esm/component/shared.js.map +1 -1
  52. package/dist/esm/component/stats.d.ts +19 -13
  53. package/dist/esm/component/stats.d.ts.map +1 -1
  54. package/dist/esm/component/stats.js +26 -21
  55. package/dist/esm/component/stats.js.map +1 -1
  56. package/package.json +7 -6
  57. package/src/client/index.ts +18 -8
  58. package/src/component/_generated/api.d.ts +3 -0
  59. package/src/component/complete.test.ts +10 -10
  60. package/src/component/complete.ts +1 -1
  61. package/src/component/kick.test.ts +10 -9
  62. package/src/component/kick.ts +11 -6
  63. package/src/component/lib.test.ts +20 -20
  64. package/src/component/lib.ts +4 -2
  65. package/src/component/logging.ts +1 -2
  66. package/src/component/loop.test.ts +101 -147
  67. package/src/component/loop.ts +49 -39
  68. package/src/component/recovery.test.ts +7 -7
  69. package/src/component/shared.ts +1 -0
  70. package/src/component/stats.ts +41 -22
@@ -3,6 +3,7 @@ import { Infer } from "convex/values";
3
3
  import { v } from "convex/values";
4
4
  import { Logger, logLevel } from "./logging.js";
5
5
 
6
+ export const DEFAULT_MAX_PARALLELISM = 10;
6
7
  const SEGMENT_MS = 100;
7
8
  export const SECOND = 1000;
8
9
  export const MINUTE = 60 * SECOND;
@@ -1,6 +1,8 @@
1
1
  import { v } from "convex/values";
2
- import { Doc } from "./_generated/dataModel.js";
3
- import { internalQuery } from "./_generated/server.js";
2
+ import { Doc, Id } from "./_generated/dataModel.js";
3
+ import { internalQuery, query } from "./_generated/server.js";
4
+ import { DEFAULT_MAX_PARALLELISM } from "./shared.js";
5
+ import { Logger } from "./logging.js";
4
6
 
5
7
  /**
6
8
  * Record stats about work execution. Intended to be queried by Axiom or Datadog.
@@ -15,43 +17,58 @@ workpool
15
17
  parse_json(trim("'", tostring(["data.message"]))),
16
18
  parse_json('{}')
17
19
  )
18
- | extend lagSinceEnqueued = parsed_message["lagSinceEnqueued"]
20
+ | extend startLag = parsed_message["startLag"]
19
21
  | extend fnName = parsed_message["fnName"]
20
- | summarize avg(todouble(lagSinceEnqueued)) by bin_auto(_time), tostring(fnName)
22
+ | summarize avg(todouble(startLag)) by bin_auto(_time), tostring(fnName)
21
23
 
22
24
  */
23
25
 
24
- export function recordStarted(work: Doc<"work">): string {
25
- return JSON.stringify({
26
+ export function recordEnqueued(
27
+ console: Logger,
28
+ data: {
29
+ workId: Id<"work">;
30
+ fnName: string;
31
+ runAt: number;
32
+ }
33
+ ) {
34
+ console.event("enqueued", {
35
+ ...data,
36
+ enqueuedAt: Date.now(),
37
+ });
38
+ }
39
+
40
+ export function recordStarted(
41
+ console: Logger,
42
+ work: Doc<"work">,
43
+ lagMs: number
44
+ ) {
45
+ console.event("started", {
26
46
  workId: work._id,
27
- event: "started",
28
47
  fnName: work.fnName,
29
48
  enqueuedAt: work._creationTime,
30
49
  startedAt: Date.now(),
31
- lagSinceEnqueued: Date.now() - work._creationTime,
50
+ startLag: lagMs,
32
51
  });
33
52
  }
34
53
 
35
54
  export function recordCompleted(
55
+ console: Logger,
36
56
  work: Doc<"work">,
37
57
  status: "success" | "failed" | "canceled" | "retrying"
38
- ): string {
39
- return JSON.stringify({
58
+ ) {
59
+ console.event("completed", {
40
60
  workId: work._id,
41
- event: "completed",
42
61
  fnName: work.fnName,
43
62
  completedAt: Date.now(),
44
63
  attempts: work.attempts,
45
64
  status,
46
- lagSinceEnqueued: Date.now() - work._creationTime,
47
65
  });
48
66
  }
49
67
 
50
- export function recordReport(state: Doc<"internalState">): string {
68
+ export function recordReport(console: Logger, state: Doc<"internalState">) {
51
69
  const { completed, succeeded, failed, retries, canceled } = state.report;
52
70
  const withoutRetries = completed - retries;
53
- return JSON.stringify({
54
- event: "report",
71
+ console.event("report", {
55
72
  completed,
56
73
  succeeded,
57
74
  failed,
@@ -66,7 +83,7 @@ export function recordReport(state: Doc<"internalState">): string {
66
83
  * Warning: this should not be used from a mutation, as it will cause conflicts.
67
84
  * Use this to debug or diagnose your queue length when it's backed up.
68
85
  */
69
- export const queueLength = internalQuery({
86
+ export const queueLength = query({
70
87
  args: {},
71
88
  returns: v.number(),
72
89
  handler: async (ctx) => {
@@ -79,12 +96,14 @@ export const queueLength = internalQuery({
79
96
  * Warning: this should not be used from a mutation, as it will cause conflicts.
80
97
  * Use this while developing to see the state of the queue.
81
98
  */
82
- export const debugCounts = internalQuery({
99
+ export const diagnostic = internalQuery({
83
100
  args: {},
84
101
  returns: v.any(),
85
102
  handler: async (ctx) => {
103
+ const global = await ctx.db.query("globals").unique();
86
104
  const internalState = await ctx.db.query("internalState").unique();
87
105
  const inProgressWork = internalState?.running.length ?? 0;
106
+ const maxParallelism = global?.maxParallelism ?? DEFAULT_MAX_PARALLELISM;
88
107
  /* eslint-disable @typescript-eslint/no-explicit-any */
89
108
  const pendingStart = await (ctx.db.query("pendingStart") as any).count();
90
109
  const pendingCompletion = await (
@@ -96,11 +115,11 @@ export const debugCounts = internalQuery({
96
115
  const runStatus = await ctx.db.query("runStatus").unique();
97
116
  /* eslint-enable @typescript-eslint/no-explicit-any */
98
117
  return {
99
- pendingStart,
100
- inProgressWork,
101
- pendingCompletion,
102
- pendingCancelation,
103
- active: inProgressWork - pendingCompletion,
118
+ canceling: pendingCancelation,
119
+ waiting: pendingStart,
120
+ running: inProgressWork - pendingCompletion,
121
+ completing: pendingCompletion,
122
+ spareCapacity: maxParallelism - inProgressWork,
104
123
  runStatus: runStatus?.state.kind,
105
124
  generation: internalState?.generation,
106
125
  };