@shipfox/api-workflows 12.7.0 → 13.0.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 (97) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/CHANGELOG.md +9 -0
  3. package/dist/db/index.d.ts +1 -1
  4. package/dist/db/index.d.ts.map +1 -1
  5. package/dist/db/index.js +1 -1
  6. package/dist/db/index.js.map +1 -1
  7. package/dist/db/job-listeners.d.ts.map +1 -1
  8. package/dist/db/job-listeners.js +17 -1
  9. package/dist/db/job-listeners.js.map +1 -1
  10. package/dist/db/workflow-runs/job-executions.d.ts +2 -3
  11. package/dist/db/workflow-runs/job-executions.d.ts.map +1 -1
  12. package/dist/db/workflow-runs/job-executions.js +48 -20
  13. package/dist/db/workflow-runs/job-executions.js.map +1 -1
  14. package/dist/db/workflow-runs/outbox.d.ts +15 -0
  15. package/dist/db/workflow-runs/outbox.d.ts.map +1 -1
  16. package/dist/db/workflow-runs/outbox.js +35 -1
  17. package/dist/db/workflow-runs/outbox.js.map +1 -1
  18. package/dist/db/workflow-runs/run-graph.d.ts.map +1 -1
  19. package/dist/db/workflow-runs/run-graph.js +12 -0
  20. package/dist/db/workflow-runs/run-graph.js.map +1 -1
  21. package/dist/db/workflow-runs/run-status.d.ts.map +1 -1
  22. package/dist/db/workflow-runs/run-status.js +13 -1
  23. package/dist/db/workflow-runs/run-status.js.map +1 -1
  24. package/dist/db/workflow-runs.d.ts +2 -2
  25. package/dist/db/workflow-runs.d.ts.map +1 -1
  26. package/dist/db/workflow-runs.js +2 -2
  27. package/dist/db/workflow-runs.js.map +1 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +2 -4
  30. package/dist/index.js.map +1 -1
  31. package/dist/presentation/index.d.ts +1 -1
  32. package/dist/presentation/index.d.ts.map +1 -1
  33. package/dist/presentation/index.js +1 -1
  34. package/dist/presentation/index.js.map +1 -1
  35. package/dist/presentation/subscribers/index.d.ts +0 -1
  36. package/dist/presentation/subscribers/index.d.ts.map +1 -1
  37. package/dist/presentation/subscribers/index.js +0 -1
  38. package/dist/presentation/subscribers/index.js.map +1 -1
  39. package/dist/temporal/activities/index.d.ts +2 -18
  40. package/dist/temporal/activities/index.d.ts.map +1 -1
  41. package/dist/temporal/activities/index.js +3 -5
  42. package/dist/temporal/activities/index.js.map +1 -1
  43. package/dist/temporal/activities/orchestration-activities.d.ts +5 -14
  44. package/dist/temporal/activities/orchestration-activities.d.ts.map +1 -1
  45. package/dist/temporal/activities/orchestration-activities.js +13 -34
  46. package/dist/temporal/activities/orchestration-activities.js.map +1 -1
  47. package/dist/temporal/workflows/index.bundle.js +20 -68
  48. package/dist/temporal/workflows/job-execution-orchestration.d.ts +0 -3
  49. package/dist/temporal/workflows/job-execution-orchestration.d.ts.map +1 -1
  50. package/dist/temporal/workflows/job-execution-orchestration.js +17 -41
  51. package/dist/temporal/workflows/job-execution-orchestration.js.map +1 -1
  52. package/dist/temporal/workflows/job-listener-orchestration.d.ts +0 -3
  53. package/dist/temporal/workflows/job-listener-orchestration.d.ts.map +1 -1
  54. package/dist/temporal/workflows/job-listener-orchestration.js +1 -9
  55. package/dist/temporal/workflows/job-listener-orchestration.js.map +1 -1
  56. package/dist/temporal/workflows/run-orchestration.d.ts.map +1 -1
  57. package/dist/temporal/workflows/run-orchestration.js +2 -18
  58. package/dist/temporal/workflows/run-orchestration.js.map +1 -1
  59. package/dist/temporal/workflows/test-env.d.ts +4 -6
  60. package/dist/temporal/workflows/test-env.d.ts.map +1 -1
  61. package/dist/temporal/workflows/test-env.js +13 -24
  62. package/dist/temporal/workflows/test-env.js.map +1 -1
  63. package/dist/tsconfig.test.tsbuildinfo +1 -1
  64. package/package.json +3 -3
  65. package/src/db/index.ts +1 -1
  66. package/src/db/job-listeners.test.ts +21 -0
  67. package/src/db/job-listeners.ts +18 -0
  68. package/src/db/workflow-runs/job-executions.test.ts +110 -12
  69. package/src/db/workflow-runs/job-executions.ts +54 -29
  70. package/src/db/workflow-runs/outbox.ts +63 -0
  71. package/src/db/workflow-runs/run-graph.ts +17 -0
  72. package/src/db/workflow-runs/run-status.test.ts +13 -0
  73. package/src/db/workflow-runs/run-status.ts +15 -1
  74. package/src/db/workflow-runs.ts +3 -1
  75. package/src/index.ts +1 -5
  76. package/src/presentation/index.ts +0 -1
  77. package/src/presentation/subscribers/index.ts +0 -1
  78. package/src/temporal/activities/index.ts +2 -8
  79. package/src/temporal/activities/orchestration-activities.test.ts +17 -1
  80. package/src/temporal/activities/orchestration-activities.ts +13 -46
  81. package/src/temporal/workflows/job-execution-orchestration.test.ts +6 -25
  82. package/src/temporal/workflows/job-execution-orchestration.ts +17 -43
  83. package/src/temporal/workflows/job-listener-orchestration-continuation.test.ts +0 -3
  84. package/src/temporal/workflows/job-listener-orchestration.test.ts +9 -12
  85. package/src/temporal/workflows/job-listener-orchestration.ts +0 -8
  86. package/src/temporal/workflows/run-orchestration.test.ts +22 -33
  87. package/src/temporal/workflows/run-orchestration.ts +4 -28
  88. package/src/temporal/workflows/test-env.ts +14 -34
  89. package/test/fixtures/runners-inter-module.ts +0 -3
  90. package/test/helpers/workflow-runs.ts +25 -0
  91. package/tsconfig.build.tsbuildinfo +1 -1
  92. package/dist/presentation/subscribers/on-runner-job-queued.d.ts +0 -3
  93. package/dist/presentation/subscribers/on-runner-job-queued.d.ts.map +0 -1
  94. package/dist/presentation/subscribers/on-runner-job-queued.js +0 -20
  95. package/dist/presentation/subscribers/on-runner-job-queued.js.map +0 -1
  96. package/src/presentation/subscribers/on-runner-job-queued.test.ts +0 -57
  97. package/src/presentation/subscribers/on-runner-job-queued.ts +0 -23
@@ -12,12 +12,9 @@ export interface JobClaimedSignalPayload {
12
12
  }
13
13
  export declare const jobClaimedSignal: import("@temporalio/common").SignalDefinition<[JobClaimedSignalPayload], string>;
14
14
  export interface JobExecutionOrchestrationInput {
15
- workspaceId: string;
16
- workflowRunId: string;
17
15
  runAttemptId: string;
18
16
  jobId: string;
19
17
  jobExecutionId: string;
20
- projectId: string;
21
18
  jobVersion: number;
22
19
  executionVersion: number;
23
20
  executionTimeoutMs?: number | null | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"job-execution-orchestration.d.ts","sourceRoot":"","sources":["../../../src/temporal/workflows/job-execution-orchestration.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,0CAA0C,CAAC;AAoDtF,eAAO,MAAM,iBAAiB;YACL,uBAAuB;qBAAmB,MAAM,GAAG,SAAS;WAElF,CAAC;AACJ,eAAO,MAAM,qBAAqB;qBACA,MAAM,GAAG,SAAS;WAA6B,CAAC;AAClF,MAAM,WAAW,uBAAuB;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,eAAO,MAAM,gBAAgB,kFAA8D,CAAC;AAE5F,MAAM,WAAW,8BAA8B;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/C,gBAAgB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,uBAAuB,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;CACpB;AAwND,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,8BAA8B,GACpC,OAAO,CAAC,+BAA+B,CAAC,CAuD1C"}
1
+ {"version":3,"file":"job-execution-orchestration.d.ts","sourceRoot":"","sources":["../../../src/temporal/workflows/job-execution-orchestration.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,0CAA0C,CAAC;AA4CtF,eAAO,MAAM,iBAAiB;YACL,uBAAuB;qBAAmB,MAAM,GAAG,SAAS;WAElF,CAAC;AACJ,eAAO,MAAM,qBAAqB;qBACA,MAAM,GAAG,SAAS;WAA6B,CAAC;AAClF,MAAM,WAAW,uBAAuB;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,eAAO,MAAM,gBAAgB,kFAA8D,CAAC;AAE5F,MAAM,WAAW,8BAA8B;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/C,gBAAgB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,uBAAuB,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;CACpB;AAsMD,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,8BAA8B,GACpC,OAAO,CAAC,+BAA+B,CAAC,CA0D1C"}
@@ -17,9 +17,9 @@ import { remainingMs } from './deadline.js';
17
17
  * execution pending while it is queued, then performs the versioned pending → running
18
18
  * transition after the current claim. One deadline spans both waits; claim never resets
19
19
  * it. Signals can arrive in any order, so the precedence is finished > lease expired >
20
- * claimed > timeout. Lease cleanup remains best-effort: a runners DB outage must never
21
- * block the child workflow from returning the job outcome to run-orchestration.
22
- */ const { setJobStatus, setJobExecutionStatus, enqueueJobExecutionForRunner, bulkSetStepStatuses, failJobExecutionAsTimedOutActivity, resolveLeaseExpiredJobExecutionActivity } = proxyActivities({
20
+ * claimed > timeout. Workflows commits queue and terminal facts with its state transitions;
21
+ * runners reconciles its local queue, lease, and reservation projections asynchronously.
22
+ */ const { setJobStatus, setJobExecutionStatus, queueJobExecutionActivity, bulkSetStepStatuses, failJobExecutionAsTimedOutActivity, resolveLeaseExpiredJobExecutionActivity } = proxyActivities({
23
23
  startToCloseTimeout: '30s'
24
24
  });
25
25
  const { resolveJobStatusFromJobExecutionsActivity } = proxyActivities({
@@ -28,31 +28,10 @@ const { resolveJobStatusFromJobExecutionsActivity } = proxyActivities({
28
28
  maximumAttempts: 5
29
29
  }
30
30
  });
31
- // Lease cleanup gets a bounded retry policy of its own: after a few attempts the
32
- // workflow stops waiting on it (see releaseLeaseBestEffort) rather than blocking
33
- // the DAG on runners-side availability.
34
- const { releaseLeaseActivity } = proxyActivities({
35
- startToCloseTimeout: '30s',
36
- retry: {
37
- maximumAttempts: 5
38
- }
39
- });
40
31
  const DEFAULT_EXECUTION_MAX_DURATION_MS = 6 * 60 * 60 * 1000;
41
32
  export const jobFinishedSignal = defineSignal(JOB_FINISHED_SIGNAL);
42
33
  export const jobLeaseExpiredSignal = defineSignal(JOB_LEASE_EXPIRED_SIGNAL);
43
34
  export const jobClaimedSignal = defineSignal(JOB_CLAIMED_SIGNAL);
44
- async function releaseLeaseBestEffort(jobExecutionId) {
45
- try {
46
- await releaseLeaseActivity({
47
- jobExecutionId
48
- });
49
- } catch (err) {
50
- log.warn('lease release failed; stuck detector will reap the row', {
51
- jobExecutionId,
52
- error: String(err)
53
- });
54
- }
55
- }
56
35
  async function resolveJobStatusOrFailClosed(input) {
57
36
  try {
58
37
  return await resolveJobStatusFromJobExecutionsActivity({
@@ -76,19 +55,14 @@ async function resolveJobStatusOrFailClosed(input) {
76
55
  };
77
56
  }
78
57
  }
79
- async function enqueueJobExecution(input) {
58
+ async function queueJobExecution(input) {
80
59
  if (hasNoRequiredRunnerLabels(input.requiredLabels)) {
81
60
  throw ApplicationFailure.nonRetryable(`Job ${input.jobId} has no required runner labels`, 'EmptyRequiredLabelsError');
82
61
  }
83
- await enqueueJobExecutionForRunner({
84
- workspaceId: input.workspaceId,
85
- workflowRunId: input.workflowRunId,
86
- runAttemptId: input.runAttemptId,
62
+ return jobExecutionStartOutcome(await queueJobExecutionActivity({
87
63
  jobId: input.jobId,
88
- jobExecutionId: input.jobExecutionId,
89
- projectId: input.projectId,
90
- requiredLabels: input.requiredLabels
91
- });
64
+ jobExecutionId: input.jobExecutionId
65
+ }));
92
66
  }
93
67
  async function markJobExecutionRunning(input) {
94
68
  const { newVersion: runningVersion, status } = await setJobExecutionStatus({
@@ -137,7 +111,6 @@ async function resolveFinishedJobExecution({ input, runningVersion, status }) {
137
111
  terminationReason: 'finished',
138
112
  status
139
113
  });
140
- await releaseLeaseBestEffort(input.jobExecutionId);
141
114
  return {
142
115
  status,
143
116
  jobVersion: input.jobVersion
@@ -150,7 +123,6 @@ async function resolveFinishedJobExecution({ input, runningVersion, status }) {
150
123
  terminationReason: 'finished',
151
124
  status: resolved.status
152
125
  });
153
- await releaseLeaseBestEffort(input.jobExecutionId);
154
126
  return resolved;
155
127
  }
156
128
  function jobExecutionStatusForRuntimeStatus(status) {
@@ -169,7 +141,6 @@ async function resolveLeaseExpiredJobExecution({ input, runningVersion }) {
169
141
  terminationReason: 'lease_expired',
170
142
  status: leaseExpired.status
171
143
  });
172
- await releaseLeaseBestEffort(input.jobExecutionId);
173
144
  return {
174
145
  status: leaseExpired.status,
175
146
  jobVersion: input.jobVersion
@@ -182,15 +153,14 @@ async function resolveLeaseExpiredJobExecution({ input, runningVersion }) {
182
153
  terminationReason: 'lease_expired',
183
154
  status
184
155
  });
185
- await releaseLeaseBestEffort(input.jobExecutionId);
186
156
  return {
187
157
  status,
188
158
  jobVersion
189
159
  };
190
160
  }
191
- // Timeout backstop. The activity atomically fails the execution, marks
192
- // `timed_out_at`, and enqueues WORKFLOWS_JOB_EXECUTION_TIMED_OUT; the runners subscriber
193
- // then asks the runner to cancel. The lease is intentionally NOT released here.
161
+ // Timeout backstop. The activity atomically fails the execution, marks `timed_out_at`, and
162
+ // enqueues the generic terminal execution fact. The runners subscriber then asks the runner to
163
+ // cancel. The lease is intentionally NOT released here.
194
164
  async function resolveTimedOutJobExecution({ input, runningVersion }) {
195
165
  await failJobExecutionAsTimedOutActivity({
196
166
  jobExecutionId: input.jobExecutionId,
@@ -234,7 +204,13 @@ export async function jobExecutionOrchestration(input) {
234
204
  // Register every signal before enqueue can block or publish a claim/outcome event. The
235
205
  // handlers retain signals that arrive while the enqueue activity is in flight.
236
206
  registerJobExecutionSignalHandlers(input.jobExecutionId, signals);
237
- await enqueueJobExecution(input);
207
+ const queued = await queueJobExecution(input);
208
+ if (queued.kind === 'terminal') {
209
+ return {
210
+ status: queued.result.status,
211
+ jobVersion: input.jobVersion
212
+ };
213
+ }
238
214
  const timeoutMs = input.executionTimeoutMs ?? DEFAULT_EXECUTION_MAX_DURATION_MS;
239
215
  const deadline = Date.now() + timeoutMs;
240
216
  await waitForJobExecutionSignal(signals, deadline, true);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/temporal/workflows/job-execution-orchestration.ts"],"sourcesContent":["import {ApplicationFailure} from '@temporalio/common';\nimport {condition, defineSignal, log, proxyActivities, setHandler} from '@temporalio/workflow';\nimport {\n hasNoRequiredRunnerLabels,\n type JobExecutionOutcomeSignals,\n jobExecutionStartOutcome,\n resolveJobExecutionOutcomeSignal,\n} from '#core/job-execution-outcome.js';\nimport type {RuntimeCompletionStatus} from '#core/workflow-scheduling/runtime-dag.js';\n\nimport type {createOrchestrationActivities} from '../activities/index.js';\nimport {JOB_CLAIMED_SIGNAL, JOB_FINISHED_SIGNAL, JOB_LEASE_EXPIRED_SIGNAL} from '../constants.js';\nimport {remainingMs} from './deadline.js';\n\n/**\n * Enqueue, wait for the runner claim, then wait for one of the terminal facts:\n *\n * enqueue ──> PENDING ── job-claimed ──> RUNNING\n * │ │\n * │ timeout ├─ job-finished\n * │ ├─ job-lease-expired\n * ▼ └─ timeout\n * TERMINAL\n *\n * The claim signal is the runner-owned lifecycle boundary. The workflow keeps the\n * execution pending while it is queued, then performs the versioned pending → running\n * transition after the current claim. One deadline spans both waits; claim never resets\n * it. Signals can arrive in any order, so the precedence is finished > lease expired >\n * claimed > timeout. Lease cleanup remains best-effort: a runners DB outage must never\n * block the child workflow from returning the job outcome to run-orchestration.\n */\n\nconst {\n setJobStatus,\n setJobExecutionStatus,\n enqueueJobExecutionForRunner,\n bulkSetStepStatuses,\n failJobExecutionAsTimedOutActivity,\n resolveLeaseExpiredJobExecutionActivity,\n} = proxyActivities<ReturnType<typeof createOrchestrationActivities>>({\n startToCloseTimeout: '30s',\n});\n\nconst {resolveJobStatusFromJobExecutionsActivity} = proxyActivities<\n ReturnType<typeof createOrchestrationActivities>\n>({\n startToCloseTimeout: '30s',\n retry: {maximumAttempts: 5},\n});\n\n// Lease cleanup gets a bounded retry policy of its own: after a few attempts the\n// workflow stops waiting on it (see releaseLeaseBestEffort) rather than blocking\n// the DAG on runners-side availability.\nconst {releaseLeaseActivity} = proxyActivities<ReturnType<typeof createOrchestrationActivities>>({\n startToCloseTimeout: '30s',\n retry: {maximumAttempts: 5},\n});\n\nconst DEFAULT_EXECUTION_MAX_DURATION_MS = 6 * 60 * 60 * 1000;\n\nexport const jobFinishedSignal =\n defineSignal<[{status: RuntimeCompletionStatus; jobExecutionId?: string | undefined}]>(\n JOB_FINISHED_SIGNAL,\n );\nexport const jobLeaseExpiredSignal =\n defineSignal<[{jobExecutionId?: string | undefined}]>(JOB_LEASE_EXPIRED_SIGNAL);\nexport interface JobClaimedSignalPayload {\n jobExecutionId: string;\n claimedAt: string;\n}\nexport const jobClaimedSignal = defineSignal<[JobClaimedSignalPayload]>(JOB_CLAIMED_SIGNAL);\n\nexport interface JobExecutionOrchestrationInput {\n workspaceId: string;\n workflowRunId: string;\n runAttemptId: string;\n jobId: string;\n jobExecutionId: string;\n projectId: string;\n jobVersion: number;\n executionVersion: number;\n executionTimeoutMs?: number | null | undefined;\n resolveJobStatus?: boolean | undefined;\n requiredLabels: string[];\n}\n\nexport interface JobExecutionOrchestrationResult {\n status: RuntimeCompletionStatus;\n jobVersion: number;\n}\n\nasync function releaseLeaseBestEffort(jobExecutionId: string): Promise<void> {\n try {\n await releaseLeaseActivity({jobExecutionId});\n } catch (err) {\n log.warn('lease release failed; stuck detector will reap the row', {\n jobExecutionId,\n error: String(err),\n });\n }\n}\n\nasync function resolveJobStatusOrFailClosed(\n input: JobExecutionOrchestrationInput,\n): Promise<{status: RuntimeCompletionStatus; jobVersion: number}> {\n try {\n return await resolveJobStatusFromJobExecutionsActivity({jobId: input.jobId});\n } catch (err) {\n log.error('job status resolution failed; failing job closed', {\n jobId: input.jobId,\n jobExecutionId: input.jobExecutionId,\n error: String(err),\n });\n const {newVersion} = await setJobStatus({\n jobId: input.jobId,\n status: 'failed',\n version: input.jobVersion,\n statusReason: 'step_failed',\n });\n return {status: 'failed', jobVersion: newVersion};\n }\n}\n\nasync function enqueueJobExecution(input: JobExecutionOrchestrationInput): Promise<void> {\n if (hasNoRequiredRunnerLabels(input.requiredLabels)) {\n throw ApplicationFailure.nonRetryable(\n `Job ${input.jobId} has no required runner labels`,\n 'EmptyRequiredLabelsError',\n );\n }\n\n await enqueueJobExecutionForRunner({\n workspaceId: input.workspaceId,\n workflowRunId: input.workflowRunId,\n runAttemptId: input.runAttemptId,\n jobId: input.jobId,\n jobExecutionId: input.jobExecutionId,\n projectId: input.projectId,\n requiredLabels: input.requiredLabels,\n });\n}\n\nasync function markJobExecutionRunning(\n input: JobExecutionOrchestrationInput,\n): Promise<\n | {kind: 'running'; runningVersion: number}\n | {kind: 'terminal'; result: JobExecutionOrchestrationResult}\n> {\n const {newVersion: runningVersion, status} = await setJobExecutionStatus({\n jobExecutionId: input.jobExecutionId,\n status: 'running',\n version: input.executionVersion,\n });\n\n const start = jobExecutionStartOutcome({newVersion: runningVersion, status});\n if (start.kind === 'terminal') return start;\n return {kind: 'running', runningVersion};\n}\n\ninterface JobExecutionSignals extends JobExecutionOutcomeSignals {\n claimed: JobClaimedSignalPayload | undefined;\n}\n\nfunction registerJobExecutionSignalHandlers(\n jobExecutionId: string,\n signals: JobExecutionSignals,\n): void {\n setHandler(jobFinishedSignal, (payload) => {\n if (payload.jobExecutionId !== undefined && payload.jobExecutionId !== jobExecutionId) return;\n signals.finished ??= payload;\n });\n setHandler(jobLeaseExpiredSignal, (payload = {}) => {\n if (payload.jobExecutionId !== undefined && payload.jobExecutionId !== jobExecutionId) return;\n signals.leaseExpired = true;\n });\n setHandler(jobClaimedSignal, (payload) => {\n if (payload.jobExecutionId !== jobExecutionId) return;\n signals.claimed ??= payload;\n });\n}\n\nasync function waitForJobExecutionSignal(\n signals: JobExecutionSignals,\n deadline: number,\n includeClaim: boolean,\n): Promise<void> {\n await condition(\n () =>\n signals.finished !== undefined ||\n signals.leaseExpired ||\n (includeClaim && signals.claimed !== undefined),\n remainingMs(deadline) ?? 0,\n );\n}\n\ninterface JobExecutionResolution {\n input: JobExecutionOrchestrationInput;\n runningVersion: number;\n}\n\nasync function resolveFinishedJobExecution({\n input,\n runningVersion,\n status,\n}: JobExecutionResolution & {\n status: RuntimeCompletionStatus;\n}): Promise<JobExecutionOrchestrationResult> {\n await setJobExecutionStatus({\n jobExecutionId: input.jobExecutionId,\n status: jobExecutionStatusForRuntimeStatus(status),\n version: runningVersion,\n statusReason: status === 'failed' ? 'step_failed' : null,\n });\n if (input.resolveJobStatus === false) {\n log.info('job execution terminated', {\n jobId: input.jobId,\n jobExecutionId: input.jobExecutionId,\n terminationReason: 'finished',\n status,\n });\n await releaseLeaseBestEffort(input.jobExecutionId);\n return {status, jobVersion: input.jobVersion};\n }\n const resolved = await resolveJobStatusOrFailClosed(input);\n log.info('job execution terminated', {\n jobId: input.jobId,\n jobExecutionId: input.jobExecutionId,\n terminationReason: 'finished',\n status: resolved.status,\n });\n await releaseLeaseBestEffort(input.jobExecutionId);\n return resolved;\n}\n\nfunction jobExecutionStatusForRuntimeStatus(\n status: RuntimeCompletionStatus,\n): 'succeeded' | 'failed' | 'cancelled' {\n if (status === 'succeeded' || status === 'failed' || status === 'cancelled') return status;\n throw ApplicationFailure.nonRetryable(\n `Job execution cannot be marked ${status}`,\n 'InvalidJobExecutionStatusError',\n );\n}\n\nasync function resolveLeaseExpiredJobExecution({\n input,\n runningVersion,\n}: JobExecutionResolution): Promise<JobExecutionOrchestrationResult> {\n const leaseExpired = await resolveLeaseExpiredJobExecutionActivity({\n jobExecutionId: input.jobExecutionId,\n expectedVersion: runningVersion,\n });\n if (input.resolveJobStatus === false) {\n log.info('job execution terminated', {\n jobId: input.jobId,\n jobExecutionId: input.jobExecutionId,\n terminationReason: 'lease_expired',\n status: leaseExpired.status,\n });\n await releaseLeaseBestEffort(input.jobExecutionId);\n return {status: leaseExpired.status, jobVersion: input.jobVersion};\n }\n const {status, jobVersion} = await resolveJobStatusOrFailClosed(input);\n log.info('job execution terminated', {\n jobId: input.jobId,\n jobExecutionId: input.jobExecutionId,\n terminationReason: 'lease_expired',\n status,\n });\n await releaseLeaseBestEffort(input.jobExecutionId);\n return {status, jobVersion};\n}\n\n// Timeout backstop. The activity atomically fails the execution, marks\n// `timed_out_at`, and enqueues WORKFLOWS_JOB_EXECUTION_TIMED_OUT; the runners subscriber\n// then asks the runner to cancel. The lease is intentionally NOT released here.\nasync function resolveTimedOutJobExecution({\n input,\n runningVersion,\n}: JobExecutionResolution): Promise<JobExecutionOrchestrationResult> {\n await failJobExecutionAsTimedOutActivity({\n jobExecutionId: input.jobExecutionId,\n runAttemptId: input.runAttemptId,\n expectedVersion: runningVersion,\n });\n await bulkSetStepStatuses({jobExecutionId: input.jobExecutionId, status: 'failed'});\n if (input.resolveJobStatus === false) {\n log.info('job execution terminated', {\n jobId: input.jobId,\n jobExecutionId: input.jobExecutionId,\n terminationReason: 'max_duration',\n status: 'failed',\n });\n return {status: 'failed', jobVersion: input.jobVersion};\n }\n const {jobVersion} = await resolveJobStatusOrFailClosed(input);\n log.info('job execution terminated', {\n jobId: input.jobId,\n jobExecutionId: input.jobExecutionId,\n terminationReason: 'max_duration',\n status: 'failed',\n });\n return {status: 'failed', jobVersion};\n}\n\nexport async function jobExecutionOrchestration(\n input: JobExecutionOrchestrationInput,\n): Promise<JobExecutionOrchestrationResult> {\n const signals: JobExecutionSignals = {\n finished: undefined,\n leaseExpired: false,\n claimed: undefined,\n };\n // Register every signal before enqueue can block or publish a claim/outcome event. The\n // handlers retain signals that arrive while the enqueue activity is in flight.\n registerJobExecutionSignalHandlers(input.jobExecutionId, signals);\n await enqueueJobExecution(input);\n\n const timeoutMs = input.executionTimeoutMs ?? DEFAULT_EXECUTION_MAX_DURATION_MS;\n const deadline = Date.now() + timeoutMs;\n await waitForJobExecutionSignal(signals, deadline, true);\n\n // A terminal fact wins over claim even when both signals arrive before the condition\n // resumes. This prevents a late claim from reopening an execution that already finished.\n let resolution = resolveJobExecutionOutcomeSignal(signals);\n if (resolution === 'finished') {\n const {finished} = signals;\n if (finished === undefined) throw new Error('Missing finished signal for finished resolution');\n\n return resolveFinishedJobExecution({\n input,\n runningVersion: input.executionVersion,\n status: finished.status,\n });\n }\n if (resolution === 'lease-expired') {\n return resolveLeaseExpiredJobExecution({input, runningVersion: input.executionVersion});\n }\n if (!signals.claimed) {\n return resolveTimedOutJobExecution({input, runningVersion: input.executionVersion});\n }\n\n const running = await markJobExecutionRunning(input);\n if (running.kind === 'terminal') {\n if (input.resolveJobStatus === false) {\n return {status: running.result.status, jobVersion: input.jobVersion};\n }\n return running.result;\n }\n const {runningVersion} = running;\n\n await waitForJobExecutionSignal(signals, deadline, false);\n resolution = resolveJobExecutionOutcomeSignal(signals);\n if (resolution === 'finished') {\n const {finished} = signals;\n if (finished === undefined) throw new Error('Missing finished signal for finished resolution');\n return resolveFinishedJobExecution({input, runningVersion, status: finished.status});\n }\n if (resolution === 'lease-expired') {\n return resolveLeaseExpiredJobExecution({input, runningVersion});\n }\n return resolveTimedOutJobExecution({input, runningVersion});\n}\n"],"names":["ApplicationFailure","condition","defineSignal","log","proxyActivities","setHandler","hasNoRequiredRunnerLabels","jobExecutionStartOutcome","resolveJobExecutionOutcomeSignal","JOB_CLAIMED_SIGNAL","JOB_FINISHED_SIGNAL","JOB_LEASE_EXPIRED_SIGNAL","remainingMs","setJobStatus","setJobExecutionStatus","enqueueJobExecutionForRunner","bulkSetStepStatuses","failJobExecutionAsTimedOutActivity","resolveLeaseExpiredJobExecutionActivity","startToCloseTimeout","resolveJobStatusFromJobExecutionsActivity","retry","maximumAttempts","releaseLeaseActivity","DEFAULT_EXECUTION_MAX_DURATION_MS","jobFinishedSignal","jobLeaseExpiredSignal","jobClaimedSignal","releaseLeaseBestEffort","jobExecutionId","err","warn","error","String","resolveJobStatusOrFailClosed","input","jobId","newVersion","status","version","jobVersion","statusReason","enqueueJobExecution","requiredLabels","nonRetryable","workspaceId","workflowRunId","runAttemptId","projectId","markJobExecutionRunning","runningVersion","executionVersion","start","kind","registerJobExecutionSignalHandlers","signals","payload","undefined","finished","leaseExpired","claimed","waitForJobExecutionSignal","deadline","includeClaim","resolveFinishedJobExecution","jobExecutionStatusForRuntimeStatus","resolveJobStatus","info","terminationReason","resolved","resolveLeaseExpiredJobExecution","expectedVersion","resolveTimedOutJobExecution","jobExecutionOrchestration","timeoutMs","executionTimeoutMs","Date","now","resolution","Error","running","result"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/temporal/workflows/job-execution-orchestration.ts"],"sourcesContent":["import {ApplicationFailure} from '@temporalio/common';\nimport {condition, defineSignal, log, proxyActivities, setHandler} from '@temporalio/workflow';\nimport {\n hasNoRequiredRunnerLabels,\n type JobExecutionOutcomeSignals,\n jobExecutionStartOutcome,\n resolveJobExecutionOutcomeSignal,\n} from '#core/job-execution-outcome.js';\nimport type {RuntimeCompletionStatus} from '#core/workflow-scheduling/runtime-dag.js';\n\nimport type {createOrchestrationActivities} from '../activities/index.js';\nimport {JOB_CLAIMED_SIGNAL, JOB_FINISHED_SIGNAL, JOB_LEASE_EXPIRED_SIGNAL} from '../constants.js';\nimport {remainingMs} from './deadline.js';\n\n/**\n * Enqueue, wait for the runner claim, then wait for one of the terminal facts:\n *\n * enqueue ──> PENDING ── job-claimed ──> RUNNING\n * │ │\n * │ timeout ├─ job-finished\n * │ ├─ job-lease-expired\n * ▼ └─ timeout\n * TERMINAL\n *\n * The claim signal is the runner-owned lifecycle boundary. The workflow keeps the\n * execution pending while it is queued, then performs the versioned pending → running\n * transition after the current claim. One deadline spans both waits; claim never resets\n * it. Signals can arrive in any order, so the precedence is finished > lease expired >\n * claimed > timeout. Workflows commits queue and terminal facts with its state transitions;\n * runners reconciles its local queue, lease, and reservation projections asynchronously.\n */\n\nconst {\n setJobStatus,\n setJobExecutionStatus,\n queueJobExecutionActivity,\n bulkSetStepStatuses,\n failJobExecutionAsTimedOutActivity,\n resolveLeaseExpiredJobExecutionActivity,\n} = proxyActivities<ReturnType<typeof createOrchestrationActivities>>({\n startToCloseTimeout: '30s',\n});\n\nconst {resolveJobStatusFromJobExecutionsActivity} = proxyActivities<\n ReturnType<typeof createOrchestrationActivities>\n>({\n startToCloseTimeout: '30s',\n retry: {maximumAttempts: 5},\n});\n\nconst DEFAULT_EXECUTION_MAX_DURATION_MS = 6 * 60 * 60 * 1000;\n\nexport const jobFinishedSignal =\n defineSignal<[{status: RuntimeCompletionStatus; jobExecutionId?: string | undefined}]>(\n JOB_FINISHED_SIGNAL,\n );\nexport const jobLeaseExpiredSignal =\n defineSignal<[{jobExecutionId?: string | undefined}]>(JOB_LEASE_EXPIRED_SIGNAL);\nexport interface JobClaimedSignalPayload {\n jobExecutionId: string;\n claimedAt: string;\n}\nexport const jobClaimedSignal = defineSignal<[JobClaimedSignalPayload]>(JOB_CLAIMED_SIGNAL);\n\nexport interface JobExecutionOrchestrationInput {\n runAttemptId: string;\n jobId: string;\n jobExecutionId: string;\n jobVersion: number;\n executionVersion: number;\n executionTimeoutMs?: number | null | undefined;\n resolveJobStatus?: boolean | undefined;\n requiredLabels: string[];\n}\n\nexport interface JobExecutionOrchestrationResult {\n status: RuntimeCompletionStatus;\n jobVersion: number;\n}\n\nasync function resolveJobStatusOrFailClosed(\n input: JobExecutionOrchestrationInput,\n): Promise<{status: RuntimeCompletionStatus; jobVersion: number}> {\n try {\n return await resolveJobStatusFromJobExecutionsActivity({jobId: input.jobId});\n } catch (err) {\n log.error('job status resolution failed; failing job closed', {\n jobId: input.jobId,\n jobExecutionId: input.jobExecutionId,\n error: String(err),\n });\n const {newVersion} = await setJobStatus({\n jobId: input.jobId,\n status: 'failed',\n version: input.jobVersion,\n statusReason: 'step_failed',\n });\n return {status: 'failed', jobVersion: newVersion};\n }\n}\n\nasync function queueJobExecution(input: JobExecutionOrchestrationInput) {\n if (hasNoRequiredRunnerLabels(input.requiredLabels)) {\n throw ApplicationFailure.nonRetryable(\n `Job ${input.jobId} has no required runner labels`,\n 'EmptyRequiredLabelsError',\n );\n }\n\n return jobExecutionStartOutcome(\n await queueJobExecutionActivity({\n jobId: input.jobId,\n jobExecutionId: input.jobExecutionId,\n }),\n );\n}\n\nasync function markJobExecutionRunning(\n input: JobExecutionOrchestrationInput,\n): Promise<\n | {kind: 'running'; runningVersion: number}\n | {kind: 'terminal'; result: JobExecutionOrchestrationResult}\n> {\n const {newVersion: runningVersion, status} = await setJobExecutionStatus({\n jobExecutionId: input.jobExecutionId,\n status: 'running',\n version: input.executionVersion,\n });\n\n const start = jobExecutionStartOutcome({newVersion: runningVersion, status});\n if (start.kind === 'terminal') return start;\n return {kind: 'running', runningVersion};\n}\n\ninterface JobExecutionSignals extends JobExecutionOutcomeSignals {\n claimed: JobClaimedSignalPayload | undefined;\n}\n\nfunction registerJobExecutionSignalHandlers(\n jobExecutionId: string,\n signals: JobExecutionSignals,\n): void {\n setHandler(jobFinishedSignal, (payload) => {\n if (payload.jobExecutionId !== undefined && payload.jobExecutionId !== jobExecutionId) return;\n signals.finished ??= payload;\n });\n setHandler(jobLeaseExpiredSignal, (payload = {}) => {\n if (payload.jobExecutionId !== undefined && payload.jobExecutionId !== jobExecutionId) return;\n signals.leaseExpired = true;\n });\n setHandler(jobClaimedSignal, (payload) => {\n if (payload.jobExecutionId !== jobExecutionId) return;\n signals.claimed ??= payload;\n });\n}\n\nasync function waitForJobExecutionSignal(\n signals: JobExecutionSignals,\n deadline: number,\n includeClaim: boolean,\n): Promise<void> {\n await condition(\n () =>\n signals.finished !== undefined ||\n signals.leaseExpired ||\n (includeClaim && signals.claimed !== undefined),\n remainingMs(deadline) ?? 0,\n );\n}\n\ninterface JobExecutionResolution {\n input: JobExecutionOrchestrationInput;\n runningVersion: number;\n}\n\nasync function resolveFinishedJobExecution({\n input,\n runningVersion,\n status,\n}: JobExecutionResolution & {\n status: RuntimeCompletionStatus;\n}): Promise<JobExecutionOrchestrationResult> {\n await setJobExecutionStatus({\n jobExecutionId: input.jobExecutionId,\n status: jobExecutionStatusForRuntimeStatus(status),\n version: runningVersion,\n statusReason: status === 'failed' ? 'step_failed' : null,\n });\n if (input.resolveJobStatus === false) {\n log.info('job execution terminated', {\n jobId: input.jobId,\n jobExecutionId: input.jobExecutionId,\n terminationReason: 'finished',\n status,\n });\n return {status, jobVersion: input.jobVersion};\n }\n const resolved = await resolveJobStatusOrFailClosed(input);\n log.info('job execution terminated', {\n jobId: input.jobId,\n jobExecutionId: input.jobExecutionId,\n terminationReason: 'finished',\n status: resolved.status,\n });\n return resolved;\n}\n\nfunction jobExecutionStatusForRuntimeStatus(\n status: RuntimeCompletionStatus,\n): 'succeeded' | 'failed' | 'cancelled' {\n if (status === 'succeeded' || status === 'failed' || status === 'cancelled') return status;\n throw ApplicationFailure.nonRetryable(\n `Job execution cannot be marked ${status}`,\n 'InvalidJobExecutionStatusError',\n );\n}\n\nasync function resolveLeaseExpiredJobExecution({\n input,\n runningVersion,\n}: JobExecutionResolution): Promise<JobExecutionOrchestrationResult> {\n const leaseExpired = await resolveLeaseExpiredJobExecutionActivity({\n jobExecutionId: input.jobExecutionId,\n expectedVersion: runningVersion,\n });\n if (input.resolveJobStatus === false) {\n log.info('job execution terminated', {\n jobId: input.jobId,\n jobExecutionId: input.jobExecutionId,\n terminationReason: 'lease_expired',\n status: leaseExpired.status,\n });\n return {status: leaseExpired.status, jobVersion: input.jobVersion};\n }\n const {status, jobVersion} = await resolveJobStatusOrFailClosed(input);\n log.info('job execution terminated', {\n jobId: input.jobId,\n jobExecutionId: input.jobExecutionId,\n terminationReason: 'lease_expired',\n status,\n });\n return {status, jobVersion};\n}\n\n// Timeout backstop. The activity atomically fails the execution, marks `timed_out_at`, and\n// enqueues the generic terminal execution fact. The runners subscriber then asks the runner to\n// cancel. The lease is intentionally NOT released here.\nasync function resolveTimedOutJobExecution({\n input,\n runningVersion,\n}: JobExecutionResolution): Promise<JobExecutionOrchestrationResult> {\n await failJobExecutionAsTimedOutActivity({\n jobExecutionId: input.jobExecutionId,\n runAttemptId: input.runAttemptId,\n expectedVersion: runningVersion,\n });\n await bulkSetStepStatuses({jobExecutionId: input.jobExecutionId, status: 'failed'});\n if (input.resolveJobStatus === false) {\n log.info('job execution terminated', {\n jobId: input.jobId,\n jobExecutionId: input.jobExecutionId,\n terminationReason: 'max_duration',\n status: 'failed',\n });\n return {status: 'failed', jobVersion: input.jobVersion};\n }\n const {jobVersion} = await resolveJobStatusOrFailClosed(input);\n log.info('job execution terminated', {\n jobId: input.jobId,\n jobExecutionId: input.jobExecutionId,\n terminationReason: 'max_duration',\n status: 'failed',\n });\n return {status: 'failed', jobVersion};\n}\n\nexport async function jobExecutionOrchestration(\n input: JobExecutionOrchestrationInput,\n): Promise<JobExecutionOrchestrationResult> {\n const signals: JobExecutionSignals = {\n finished: undefined,\n leaseExpired: false,\n claimed: undefined,\n };\n // Register every signal before enqueue can block or publish a claim/outcome event. The\n // handlers retain signals that arrive while the enqueue activity is in flight.\n registerJobExecutionSignalHandlers(input.jobExecutionId, signals);\n const queued = await queueJobExecution(input);\n if (queued.kind === 'terminal') {\n return {status: queued.result.status, jobVersion: input.jobVersion};\n }\n\n const timeoutMs = input.executionTimeoutMs ?? DEFAULT_EXECUTION_MAX_DURATION_MS;\n const deadline = Date.now() + timeoutMs;\n await waitForJobExecutionSignal(signals, deadline, true);\n\n // A terminal fact wins over claim even when both signals arrive before the condition\n // resumes. This prevents a late claim from reopening an execution that already finished.\n let resolution = resolveJobExecutionOutcomeSignal(signals);\n if (resolution === 'finished') {\n const {finished} = signals;\n if (finished === undefined) throw new Error('Missing finished signal for finished resolution');\n\n return resolveFinishedJobExecution({\n input,\n runningVersion: input.executionVersion,\n status: finished.status,\n });\n }\n if (resolution === 'lease-expired') {\n return resolveLeaseExpiredJobExecution({input, runningVersion: input.executionVersion});\n }\n if (!signals.claimed) {\n return resolveTimedOutJobExecution({input, runningVersion: input.executionVersion});\n }\n\n const running = await markJobExecutionRunning(input);\n if (running.kind === 'terminal') {\n if (input.resolveJobStatus === false) {\n return {status: running.result.status, jobVersion: input.jobVersion};\n }\n return running.result;\n }\n const {runningVersion} = running;\n\n await waitForJobExecutionSignal(signals, deadline, false);\n resolution = resolveJobExecutionOutcomeSignal(signals);\n if (resolution === 'finished') {\n const {finished} = signals;\n if (finished === undefined) throw new Error('Missing finished signal for finished resolution');\n return resolveFinishedJobExecution({input, runningVersion, status: finished.status});\n }\n if (resolution === 'lease-expired') {\n return resolveLeaseExpiredJobExecution({input, runningVersion});\n }\n return resolveTimedOutJobExecution({input, runningVersion});\n}\n"],"names":["ApplicationFailure","condition","defineSignal","log","proxyActivities","setHandler","hasNoRequiredRunnerLabels","jobExecutionStartOutcome","resolveJobExecutionOutcomeSignal","JOB_CLAIMED_SIGNAL","JOB_FINISHED_SIGNAL","JOB_LEASE_EXPIRED_SIGNAL","remainingMs","setJobStatus","setJobExecutionStatus","queueJobExecutionActivity","bulkSetStepStatuses","failJobExecutionAsTimedOutActivity","resolveLeaseExpiredJobExecutionActivity","startToCloseTimeout","resolveJobStatusFromJobExecutionsActivity","retry","maximumAttempts","DEFAULT_EXECUTION_MAX_DURATION_MS","jobFinishedSignal","jobLeaseExpiredSignal","jobClaimedSignal","resolveJobStatusOrFailClosed","input","jobId","err","error","jobExecutionId","String","newVersion","status","version","jobVersion","statusReason","queueJobExecution","requiredLabels","nonRetryable","markJobExecutionRunning","runningVersion","executionVersion","start","kind","registerJobExecutionSignalHandlers","signals","payload","undefined","finished","leaseExpired","claimed","waitForJobExecutionSignal","deadline","includeClaim","resolveFinishedJobExecution","jobExecutionStatusForRuntimeStatus","resolveJobStatus","info","terminationReason","resolved","resolveLeaseExpiredJobExecution","expectedVersion","resolveTimedOutJobExecution","runAttemptId","jobExecutionOrchestration","queued","result","timeoutMs","executionTimeoutMs","Date","now","resolution","Error","running"],"mappings":"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"}
@@ -3,9 +3,6 @@ import type { RuntimeCompletionStatus } from '#core/workflow-scheduling/runtime-
3
3
  export declare const listenerEventsAvailableSignal: import("@temporalio/workflow").SignalDefinition<[], string>;
4
4
  export declare const listenerResolveSignal: import("@temporalio/workflow").SignalDefinition<[], string>;
5
5
  export interface JobListenerOrchestrationInput {
6
- workspaceId: string;
7
- workflowRunId: string;
8
- projectId: string;
9
6
  runAttemptId: string;
10
7
  jobId: string;
11
8
  jobVersion: number;
@@ -1 +1 @@
1
- {"version":3,"file":"job-listener-orchestration.d.ts","sourceRoot":"","sources":["../../../src/temporal/workflows/job-listener-orchestration.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,0CAA0C,CAAC;AAkBtF,eAAO,MAAM,6BAA6B,6DAAqD,CAAC;AAChG,eAAO,MAAM,qBAAqB,6DAA4C,CAAC;AAE/E,MAAM,WAAW,6BAA6B;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/C,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/C,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC1C,SAAS,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,GAAG,SAAS,CAAC;IACnD,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC3C,YAAY,CAAC,EAAE,yBAAyB,GAAG,SAAS,CAAC;CACtD;AAED,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,uBAAuB,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,KAAK,eAAe,GAAG,OAAO,CAAC,gBAAgB,EAAE,WAAW,CAAC,GAAG,SAAS,CAAC;AAG1E,MAAM,WAAW,yBAAyB;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,eAAe,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,eAAO,MAAM,qCAAqC,MAAM,CAAC;AAwBzD,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,6BAA6B,GACnC,OAAO,CAAC,8BAA8B,CAAC,CAuIzC;AAiCD,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAClD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sBAAsB,EAAE,OAAO,CAAC;CACjC,GAAG,OAAO,CAKV;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,6BAA6B,EACpC,YAAY,EAAE,yBAAyB,GACtC,6BAA6B,CAE/B"}
1
+ {"version":3,"file":"job-listener-orchestration.d.ts","sourceRoot":"","sources":["../../../src/temporal/workflows/job-listener-orchestration.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,0CAA0C,CAAC;AAiBtF,eAAO,MAAM,6BAA6B,6DAAqD,CAAC;AAChG,eAAO,MAAM,qBAAqB,6DAA4C,CAAC;AAE/E,MAAM,WAAW,6BAA6B;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/C,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/C,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC1C,SAAS,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,GAAG,SAAS,CAAC;IACnD,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC3C,YAAY,CAAC,EAAE,yBAAyB,GAAG,SAAS,CAAC;CACtD;AAED,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,uBAAuB,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,KAAK,eAAe,GAAG,OAAO,CAAC,gBAAgB,EAAE,WAAW,CAAC,GAAG,SAAS,CAAC;AAG1E,MAAM,WAAW,yBAAyB;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,eAAe,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,eAAO,MAAM,qCAAqC,MAAM,CAAC;AAwBzD,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,6BAA6B,GACnC,OAAO,CAAC,8BAA8B,CAAC,CAuIzC;AAiCD,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAClD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sBAAsB,EAAE,OAAO,CAAC;CACjC,GAAG,OAAO,CAKV;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,6BAA6B,EACpC,YAAY,EAAE,yBAAyB,GACtC,6BAA6B,CAE/B"}
@@ -3,7 +3,7 @@ import { runtimeStatusForTerminalJobExecutionStatus } from '#core/job-execution-
3
3
  import { LISTENER_EVENTS_AVAILABLE_SIGNAL, LISTENER_RESOLVE_SIGNAL } from '../constants.js';
4
4
  import { deadlineReached, remainingMs } from './deadline.js';
5
5
  import { jobExecutionOrchestration } from './job-execution-orchestration.js';
6
- const { activateJobListenerActivity, drainListenerEventsActivity, peekListenerBufferActivity, resolveJobListenerActivity, settleListenerJobExecutionActivity, recordListenerFiringOutcomeActivity, cancelRunnerJobsActivity } = proxyActivities({
6
+ const { activateJobListenerActivity, drainListenerEventsActivity, peekListenerBufferActivity, resolveJobListenerActivity, settleListenerJobExecutionActivity, recordListenerFiringOutcomeActivity } = proxyActivities({
7
7
  startToCloseTimeout: '30s'
8
8
  });
9
9
  export const listenerEventsAvailableSignal = defineSignal(LISTENER_EVENTS_AVAILABLE_SIGNAL);
@@ -256,9 +256,6 @@ async function runListenerExecution(params) {
256
256
  workflowIdReusePolicy: 'ALLOW_DUPLICATE',
257
257
  args: [
258
258
  {
259
- workspaceId: params.input.workspaceId,
260
- workflowRunId: params.input.workflowRunId,
261
- projectId: params.input.projectId,
262
259
  jobId: params.input.jobId,
263
260
  jobExecutionId: params.jobExecutionId,
264
261
  runAttemptId: params.input.runAttemptId,
@@ -287,11 +284,6 @@ async function runListenerExecution(params) {
287
284
  await recordListenerFiringOutcomeActivity({
288
285
  outcome: 'cancelled'
289
286
  });
290
- await cancelRunnerJobsActivity({
291
- jobIds: [
292
- params.input.jobId
293
- ]
294
- });
295
287
  return;
296
288
  }
297
289
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/temporal/workflows/job-listener-orchestration.ts"],"sourcesContent":["import {\n CancellationScope,\n condition,\n continueAsNew,\n defineSignal,\n executeChild,\n log,\n ParentClosePolicy,\n proxyActivities,\n setHandler,\n workflowInfo,\n} from '@temporalio/workflow';\nimport type {ResolutionReason} from '#core/entities/job.js';\nimport {runtimeStatusForTerminalJobExecutionStatus} from '#core/job-execution-outcome.js';\nimport type {RuntimeCompletionStatus} from '#core/workflow-scheduling/runtime-dag.js';\nimport type {createOrchestrationActivities} from '../activities/index.js';\nimport {LISTENER_EVENTS_AVAILABLE_SIGNAL, LISTENER_RESOLVE_SIGNAL} from '../constants.js';\nimport {deadlineReached, remainingMs} from './deadline.js';\nimport {jobExecutionOrchestration} from './job-execution-orchestration.js';\n\nconst {\n activateJobListenerActivity,\n drainListenerEventsActivity,\n peekListenerBufferActivity,\n resolveJobListenerActivity,\n settleListenerJobExecutionActivity,\n recordListenerFiringOutcomeActivity,\n cancelRunnerJobsActivity,\n} = proxyActivities<ReturnType<typeof createOrchestrationActivities>>({\n startToCloseTimeout: '30s',\n});\n\nexport const listenerEventsAvailableSignal = defineSignal<[]>(LISTENER_EVENTS_AVAILABLE_SIGNAL);\nexport const listenerResolveSignal = defineSignal<[]>(LISTENER_RESOLVE_SIGNAL);\n\nexport interface JobListenerOrchestrationInput {\n workspaceId: string;\n workflowRunId: string;\n projectId: string;\n runAttemptId: string;\n jobId: string;\n jobVersion: number;\n requiredLabels: string[];\n executionTimeoutMs?: number | null | undefined;\n listeningTimeoutMs?: number | null | undefined;\n maxExecutions?: number | null | undefined;\n onResolve?: 'finish' | 'cancel' | null | undefined;\n batchDebounceMs?: number | null | undefined;\n batchMaxSize?: number | null | undefined;\n batchMaxWaitMs?: number | null | undefined;\n continuation?: ListenerContinuationState | undefined;\n}\n\nexport interface JobListenerOrchestrationResult {\n status: RuntimeCompletionStatus;\n jobVersion: number;\n}\n\ntype ResolutionLatch = Exclude<ResolutionReason, 'cancelled'> | undefined;\ntype BatchFiringDecision = 'fire' | 'resolve' | 'deadline';\n\nexport interface ListenerContinuationState {\n nextSequence: number;\n latchedReason?: ResolutionLatch;\n listenerDeadline?: number | undefined;\n}\n\nexport const LISTENER_CONTINUE_AS_NEW_FIRING_LIMIT = 500;\n\ninterface ListenerBatchConfig {\n debounceMs?: number | undefined;\n maxSizeEvents?: number | undefined;\n maxWaitMs?: number | undefined;\n}\n\ninterface BatchFiringWindowParams {\n jobId: string;\n batchConfig: ListenerBatchConfig;\n listenerDeadline: number | undefined;\n hasEventsHint: () => boolean;\n clearEventsHint: () => void;\n hasResolutionHint: () => boolean;\n}\n\ninterface ListenerBufferPeek {\n fireCount: number;\n resolvePending: boolean;\n oldestAgeMs: number;\n newestAgeMs: number;\n}\n\nexport async function jobListenerOrchestration(\n input: JobListenerOrchestrationInput,\n): Promise<JobListenerOrchestrationResult> {\n let eventsAvailable = false;\n let latchedReason = input.continuation?.latchedReason;\n\n setHandler(listenerEventsAvailableSignal, () => {\n eventsAvailable = true;\n });\n setHandler(listenerResolveSignal, () => {\n latchedReason = 'until';\n });\n\n const listenerDeadline = input.continuation?.listenerDeadline ?? initialListenerDeadline(input);\n\n let nextSequence: number;\n if (input.continuation) {\n nextSequence = input.continuation.nextSequence;\n } else {\n const activated = await activateJobListenerActivity({\n jobId: input.jobId,\n expectedVersion: input.jobVersion,\n });\n if (activated.status === 'terminal') {\n return {\n status: runtimeStatusForTerminalJobExecutionStatus(activated.jobStatus),\n jobVersion: activated.jobVersion,\n };\n }\n nextSequence = activated.executionCount + 1;\n }\n\n let firingsInCurrentRun = 0;\n const maxExecutions = input.maxExecutions ?? undefined;\n const batchConfig = listenerBatchConfig(input);\n while (true) {\n if (deadlineReached(listenerDeadline)) latchedReason ??= 'timeout';\n await continueListenerAsNewIfNeeded({\n input,\n nextSequence,\n latchedReason,\n listenerDeadline,\n firingsInCurrentRun,\n });\n if (latchedReason !== undefined) break;\n if (maxExecutions !== undefined) {\n if (nextSequence > maxExecutions) {\n latchedReason = 'max_executions';\n await continueListenerAsNewIfNeeded({\n input,\n nextSequence,\n latchedReason,\n listenerDeadline,\n firingsInCurrentRun,\n });\n break;\n }\n }\n\n if (batchConfig !== undefined) {\n const decision = await awaitBatchFiringWindow({\n jobId: input.jobId,\n batchConfig,\n listenerDeadline,\n hasEventsHint: () => eventsAvailable,\n clearEventsHint: () => {\n eventsAvailable = false;\n },\n hasResolutionHint: () => latchedReason !== undefined,\n });\n if (decision === 'resolve') {\n latchedReason ??= 'until';\n break;\n }\n if (decision === 'deadline') {\n latchedReason ??= 'timeout';\n break;\n }\n }\n\n eventsAvailable = false;\n const drained = await drainListenerEventsActivity({\n jobId: input.jobId,\n expectedSequence: nextSequence,\n ...(batchConfig?.maxSizeEvents === undefined ? {} : {maxSize: batchConfig.maxSizeEvents}),\n });\n\n if (drained.kind === 'resolve-requested') {\n latchedReason = 'until';\n break;\n }\n\n if (drained.kind === 'empty') {\n const woke = await waitForListenerWakeup(\n () => eventsAvailable || latchedReason !== undefined,\n {deadline: listenerDeadline},\n );\n if (!woke && deadlineReached(listenerDeadline)) latchedReason = 'timeout';\n continue;\n }\n\n if (drained.status === 'failed') {\n await recordListenerFiringOutcomeActivity({outcome: 'failed'});\n nextSequence = drained.sequence + 1;\n firingsInCurrentRun += 1;\n if (maxExecutions !== undefined && drained.sequence >= maxExecutions) {\n latchedReason = 'max_executions';\n }\n continue;\n }\n\n await runListenerExecution({\n input,\n jobExecutionId: drained.jobExecutionId,\n executionVersion: drained.executionVersion,\n requiredLabels: drained.requiredLabels,\n shouldCancelForResolution: () =>\n input.onResolve === 'cancel' &&\n (latchedReason !== undefined || deadlineReached(listenerDeadline)),\n waitForResolution: () =>\n waitForListenerWakeup(\n () => latchedReason !== undefined || deadlineReached(listenerDeadline),\n {deadline: listenerDeadline},\n ),\n });\n\n if (deadlineReached(listenerDeadline)) latchedReason ??= 'timeout';\n nextSequence = drained.sequence + 1;\n firingsInCurrentRun += 1;\n if (maxExecutions !== undefined && drained.sequence >= maxExecutions) {\n latchedReason = 'max_executions';\n }\n }\n\n const reason = latchedReason ?? 'timeout';\n const resolved = await resolveJobListenerActivity({jobId: input.jobId, reason});\n return {status: resolved.status, jobVersion: resolved.jobVersion};\n}\n\nfunction initialListenerDeadline(input: JobListenerOrchestrationInput): number | undefined {\n return input.listeningTimeoutMs === undefined || input.listeningTimeoutMs === null\n ? undefined\n : Date.now() + input.listeningTimeoutMs;\n}\n\nasync function continueListenerAsNewIfNeeded(params: {\n input: JobListenerOrchestrationInput;\n nextSequence: number;\n latchedReason: ResolutionLatch;\n listenerDeadline: number | undefined;\n firingsInCurrentRun: number;\n}): Promise<void> {\n if (\n !shouldContinueListenerAsNew({\n firingsInCurrentRun: params.firingsInCurrentRun,\n continueAsNewSuggested: workflowInfo().continueAsNewSuggested,\n })\n ) {\n return;\n }\n\n await continueAsNew<typeof jobListenerOrchestration>(\n listenerContinuationInput(params.input, {\n nextSequence: params.nextSequence,\n latchedReason: params.latchedReason,\n listenerDeadline: params.listenerDeadline,\n }),\n );\n}\n\nexport function shouldContinueListenerAsNew(params: {\n firingsInCurrentRun: number;\n continueAsNewSuggested: boolean;\n}): boolean {\n return (\n params.continueAsNewSuggested ||\n params.firingsInCurrentRun >= LISTENER_CONTINUE_AS_NEW_FIRING_LIMIT\n );\n}\n\nexport function listenerContinuationInput(\n input: JobListenerOrchestrationInput,\n continuation: ListenerContinuationState,\n): JobListenerOrchestrationInput {\n return {...input, continuation};\n}\n\nfunction listenerBatchConfig(\n input: JobListenerOrchestrationInput,\n): ListenerBatchConfig | undefined {\n const debounceMs = positiveNumber(input.batchDebounceMs);\n const maxSizeEvents = positiveNumber(input.batchMaxSize);\n const maxWaitMs = positiveNumber(input.batchMaxWaitMs);\n if (debounceMs === undefined && maxSizeEvents === undefined && maxWaitMs === undefined) {\n return undefined;\n }\n return {debounceMs, maxSizeEvents, maxWaitMs};\n}\n\nasync function awaitBatchFiringWindow(\n params: BatchFiringWindowParams,\n): Promise<BatchFiringDecision> {\n while (true) {\n const prePeekDecision = resolutionOrDeadlineDecision(params);\n if (prePeekDecision !== undefined) return prePeekDecision;\n\n const peek = await peekBatchBuffer(params);\n const peekDecision = bufferedResolveOrDeadlineDecision(params, peek);\n if (peekDecision !== undefined) return peekDecision;\n\n if (peek.fireCount === 0) {\n const waitDecision = await waitForAnyBatchWakeup(params);\n if (waitDecision !== undefined) return waitDecision;\n continue;\n }\n\n if (batchIsReadyToFire(params.batchConfig, peek)) return 'fire';\n\n const sleepMs = nextBatchWindowMs(params.batchConfig, peek);\n if (sleepMs === undefined) {\n const waitDecision = await waitForAnyBatchWakeup(params);\n if (waitDecision !== undefined) return waitDecision;\n continue;\n }\n\n const waitDecision = await waitForBatchWindow(params, sleepMs);\n if (waitDecision !== undefined) return waitDecision;\n }\n}\n\nfunction resolutionOrDeadlineDecision(\n params: BatchFiringWindowParams,\n): Exclude<BatchFiringDecision, 'fire'> | undefined {\n if (params.hasResolutionHint()) return 'resolve';\n if (deadlineReached(params.listenerDeadline)) return 'deadline';\n return undefined;\n}\n\nasync function peekBatchBuffer(params: BatchFiringWindowParams): Promise<ListenerBufferPeek> {\n params.clearEventsHint();\n return await peekListenerBufferActivity({jobId: params.jobId});\n}\n\nfunction bufferedResolveOrDeadlineDecision(\n params: BatchFiringWindowParams,\n peek: ListenerBufferPeek,\n): Exclude<BatchFiringDecision, 'fire'> | undefined {\n if (peek.resolvePending || params.hasResolutionHint()) return 'resolve';\n if (deadlineReached(params.listenerDeadline)) return 'deadline';\n return undefined;\n}\n\nfunction batchIsReadyToFire(config: ListenerBatchConfig, peek: ListenerBufferPeek): boolean {\n const sizeReached = config.maxSizeEvents !== undefined && peek.fireCount >= config.maxSizeEvents;\n const debounceQuiet = config.debounceMs !== undefined && peek.newestAgeMs >= config.debounceMs;\n const maxWaitReached = config.maxWaitMs !== undefined && peek.oldestAgeMs >= config.maxWaitMs;\n return sizeReached || debounceQuiet || maxWaitReached;\n}\n\nfunction nextBatchWindowMs(\n config: ListenerBatchConfig,\n peek: ListenerBufferPeek,\n): number | undefined {\n const timeWindows = [\n remainingWindowMs(config.debounceMs, peek.newestAgeMs),\n remainingWindowMs(config.maxWaitMs, peek.oldestAgeMs),\n ].filter((value): value is number => value !== undefined);\n return timeWindows.length === 0 ? undefined : Math.min(...timeWindows);\n}\n\nasync function waitForAnyBatchWakeup(\n params: BatchFiringWindowParams,\n): Promise<Exclude<BatchFiringDecision, 'fire'> | undefined> {\n const woke = await waitForListenerWakeup(\n () => params.hasEventsHint() || params.hasResolutionHint(),\n {deadline: params.listenerDeadline},\n );\n if (!woke && deadlineReached(params.listenerDeadline)) return 'deadline';\n return undefined;\n}\n\nasync function waitForBatchWindow(\n params: BatchFiringWindowParams,\n sleepMs: number,\n): Promise<Exclude<BatchFiringDecision, 'fire'> | undefined> {\n const deadlineRemaining = remainingMs(params.listenerDeadline);\n const boundedSleepMs =\n deadlineRemaining === undefined ? sleepMs : Math.min(sleepMs, deadlineRemaining);\n const wakesOnEvents =\n params.batchConfig.debounceMs !== undefined || params.batchConfig.maxSizeEvents !== undefined;\n const woke = await condition(\n () =>\n params.hasResolutionHint() ||\n (wakesOnEvents && params.hasEventsHint()) ||\n deadlineReached(params.listenerDeadline),\n boundedSleepMs,\n );\n if (!woke && deadlineReached(params.listenerDeadline)) return 'deadline';\n return undefined;\n}\n\nfunction positiveNumber(value: number | null | undefined): number | undefined {\n return value === undefined || value === null || value <= 0 ? undefined : value;\n}\n\nfunction remainingWindowMs(limitMs: number | undefined, ageMs: number): number | undefined {\n return limitMs === undefined ? undefined : Math.max(0, limitMs - ageMs);\n}\n\nasync function runListenerExecution(params: {\n input: JobListenerOrchestrationInput;\n jobExecutionId: string;\n executionVersion: number;\n requiredLabels: string[];\n shouldCancelForResolution: () => boolean;\n waitForResolution: () => Promise<boolean>;\n}): Promise<void> {\n const scope = new CancellationScope();\n const child = scope.run(() =>\n executeChild(jobExecutionOrchestration, {\n workflowId: `job:${params.input.jobId}`,\n workflowIdReusePolicy: 'ALLOW_DUPLICATE',\n args: [\n {\n workspaceId: params.input.workspaceId,\n workflowRunId: params.input.workflowRunId,\n projectId: params.input.projectId,\n jobId: params.input.jobId,\n jobExecutionId: params.jobExecutionId,\n runAttemptId: params.input.runAttemptId,\n jobVersion: params.input.jobVersion,\n executionVersion: params.executionVersion,\n ...(params.input.executionTimeoutMs === undefined\n ? {}\n : {executionTimeoutMs: params.input.executionTimeoutMs}),\n resolveJobStatus: false,\n requiredLabels: params.requiredLabels,\n },\n ],\n parentClosePolicy: ParentClosePolicy.TERMINATE,\n }),\n );\n\n if (params.input.onResolve === 'cancel') {\n const winner = await Promise.race([\n child.then(\n () => 'child' as const,\n () => 'child-failed' as const,\n ),\n params.waitForResolution().then(() => 'resolution' as const),\n ]);\n if (winner === 'resolution' && params.shouldCancelForResolution()) {\n scope.cancel();\n await settleListenerJobExecutionActivity({\n jobExecutionId: params.jobExecutionId,\n status: 'cancelled',\n });\n await recordListenerFiringOutcomeActivity({outcome: 'cancelled'});\n await cancelRunnerJobsActivity({jobIds: [params.input.jobId]});\n return;\n }\n }\n\n try {\n const result = await child;\n await recordListenerFiringOutcomeActivity({outcome: listenerFiringOutcome(result.status)});\n } catch (error) {\n log.warn('listener execution child failed; recording failed firing and continuing', {\n jobId: params.input.jobId,\n jobExecutionId: params.jobExecutionId,\n error: String(error),\n });\n await settleListenerJobExecutionActivity({\n jobExecutionId: params.jobExecutionId,\n status: 'failed',\n });\n await recordListenerFiringOutcomeActivity({outcome: 'failed'});\n }\n}\n\nfunction listenerFiringOutcome(\n status: RuntimeCompletionStatus,\n): 'succeeded' | 'failed' | 'cancelled' {\n if (status === 'succeeded' || status === 'failed' || status === 'cancelled') return status;\n throw new Error(`Listener execution cannot finish with status: ${status}`);\n}\n\nasync function waitForListenerWakeup(\n predicate: () => boolean,\n options: {deadline: number | undefined},\n): Promise<boolean> {\n const remaining = remainingMs(options.deadline);\n if (remaining !== undefined && remaining <= 0) return false;\n if (remaining === undefined) {\n await condition(predicate);\n return true;\n }\n return await condition(predicate, remaining);\n}\n"],"names":["CancellationScope","condition","continueAsNew","defineSignal","executeChild","log","ParentClosePolicy","proxyActivities","setHandler","workflowInfo","runtimeStatusForTerminalJobExecutionStatus","LISTENER_EVENTS_AVAILABLE_SIGNAL","LISTENER_RESOLVE_SIGNAL","deadlineReached","remainingMs","jobExecutionOrchestration","activateJobListenerActivity","drainListenerEventsActivity","peekListenerBufferActivity","resolveJobListenerActivity","settleListenerJobExecutionActivity","recordListenerFiringOutcomeActivity","cancelRunnerJobsActivity","startToCloseTimeout","listenerEventsAvailableSignal","listenerResolveSignal","LISTENER_CONTINUE_AS_NEW_FIRING_LIMIT","jobListenerOrchestration","input","eventsAvailable","latchedReason","continuation","listenerDeadline","initialListenerDeadline","nextSequence","activated","jobId","expectedVersion","jobVersion","status","jobStatus","executionCount","firingsInCurrentRun","maxExecutions","undefined","batchConfig","listenerBatchConfig","continueListenerAsNewIfNeeded","decision","awaitBatchFiringWindow","hasEventsHint","clearEventsHint","hasResolutionHint","drained","expectedSequence","maxSizeEvents","maxSize","kind","woke","waitForListenerWakeup","deadline","outcome","sequence","runListenerExecution","jobExecutionId","executionVersion","requiredLabels","shouldCancelForResolution","onResolve","waitForResolution","reason","resolved","listeningTimeoutMs","Date","now","params","shouldContinueListenerAsNew","continueAsNewSuggested","listenerContinuationInput","debounceMs","positiveNumber","batchDebounceMs","batchMaxSize","maxWaitMs","batchMaxWaitMs","prePeekDecision","resolutionOrDeadlineDecision","peek","peekBatchBuffer","peekDecision","bufferedResolveOrDeadlineDecision","fireCount","waitDecision","waitForAnyBatchWakeup","batchIsReadyToFire","sleepMs","nextBatchWindowMs","waitForBatchWindow","resolvePending","config","sizeReached","debounceQuiet","newestAgeMs","maxWaitReached","oldestAgeMs","timeWindows","remainingWindowMs","filter","value","length","Math","min","deadlineRemaining","boundedSleepMs","wakesOnEvents","limitMs","ageMs","max","scope","child","run","workflowId","workflowIdReusePolicy","args","workspaceId","workflowRunId","projectId","runAttemptId","executionTimeoutMs","resolveJobStatus","parentClosePolicy","TERMINATE","winner","Promise","race","then","cancel","jobIds","result","listenerFiringOutcome","error","warn","String","Error","predicate","options","remaining"],"mappings":"AAAA,SACEA,iBAAiB,EACjBC,SAAS,EACTC,aAAa,EACbC,YAAY,EACZC,YAAY,EACZC,GAAG,EACHC,iBAAiB,EACjBC,eAAe,EACfC,UAAU,EACVC,YAAY,QACP,uBAAuB;AAE9B,SAAQC,0CAA0C,QAAO,iCAAiC;AAG1F,SAAQC,gCAAgC,EAAEC,uBAAuB,QAAO,kBAAkB;AAC1F,SAAQC,eAAe,EAAEC,WAAW,QAAO,gBAAgB;AAC3D,SAAQC,yBAAyB,QAAO,mCAAmC;AAE3E,MAAM,EACJC,2BAA2B,EAC3BC,2BAA2B,EAC3BC,0BAA0B,EAC1BC,0BAA0B,EAC1BC,kCAAkC,EAClCC,mCAAmC,EACnCC,wBAAwB,EACzB,GAAGf,gBAAkE;IACpEgB,qBAAqB;AACvB;AAEA,OAAO,MAAMC,gCAAgCrB,aAAiBQ,kCAAkC;AAChG,OAAO,MAAMc,wBAAwBtB,aAAiBS,yBAAyB;AAkC/E,OAAO,MAAMc,wCAAwC,IAAI;AAwBzD,OAAO,eAAeC,yBACpBC,KAAoC;IAEpC,IAAIC,kBAAkB;IACtB,IAAIC,gBAAgBF,MAAMG,YAAY,EAAED;IAExCtB,WAAWgB,+BAA+B;QACxCK,kBAAkB;IACpB;IACArB,WAAWiB,uBAAuB;QAChCK,gBAAgB;IAClB;IAEA,MAAME,mBAAmBJ,MAAMG,YAAY,EAAEC,oBAAoBC,wBAAwBL;IAEzF,IAAIM;IACJ,IAAIN,MAAMG,YAAY,EAAE;QACtBG,eAAeN,MAAMG,YAAY,CAACG,YAAY;IAChD,OAAO;QACL,MAAMC,YAAY,MAAMnB,4BAA4B;YAClDoB,OAAOR,MAAMQ,KAAK;YAClBC,iBAAiBT,MAAMU,UAAU;QACnC;QACA,IAAIH,UAAUI,MAAM,KAAK,YAAY;YACnC,OAAO;gBACLA,QAAQ7B,2CAA2CyB,UAAUK,SAAS;gBACtEF,YAAYH,UAAUG,UAAU;YAClC;QACF;QACAJ,eAAeC,UAAUM,cAAc,GAAG;IAC5C;IAEA,IAAIC,sBAAsB;IAC1B,MAAMC,gBAAgBf,MAAMe,aAAa,IAAIC;IAC7C,MAAMC,cAAcC,oBAAoBlB;IACxC,MAAO,KAAM;QACX,IAAIf,gBAAgBmB,mBAAmBF,kBAAkB;QACzD,MAAMiB,8BAA8B;YAClCnB;YACAM;YACAJ;YACAE;YACAU;QACF;QACA,IAAIZ,kBAAkBc,WAAW;QACjC,IAAID,kBAAkBC,WAAW;YAC/B,IAAIV,eAAeS,eAAe;gBAChCb,gBAAgB;gBAChB,MAAMiB,8BAA8B;oBAClCnB;oBACAM;oBACAJ;oBACAE;oBACAU;gBACF;gBACA;YACF;QACF;QAEA,IAAIG,gBAAgBD,WAAW;YAC7B,MAAMI,WAAW,MAAMC,uBAAuB;gBAC5Cb,OAAOR,MAAMQ,KAAK;gBAClBS;gBACAb;gBACAkB,eAAe,IAAMrB;gBACrBsB,iBAAiB;oBACftB,kBAAkB;gBACpB;gBACAuB,mBAAmB,IAAMtB,kBAAkBc;YAC7C;YACA,IAAII,aAAa,WAAW;gBAC1BlB,kBAAkB;gBAClB;YACF;YACA,IAAIkB,aAAa,YAAY;gBAC3BlB,kBAAkB;gBAClB;YACF;QACF;QAEAD,kBAAkB;QAClB,MAAMwB,UAAU,MAAMpC,4BAA4B;YAChDmB,OAAOR,MAAMQ,KAAK;YAClBkB,kBAAkBpB;YAClB,GAAIW,aAAaU,kBAAkBX,YAAY,CAAC,IAAI;gBAACY,SAASX,YAAYU,aAAa;YAAA,CAAC;QAC1F;QAEA,IAAIF,QAAQI,IAAI,KAAK,qBAAqB;YACxC3B,gBAAgB;YAChB;QACF;QAEA,IAAIuB,QAAQI,IAAI,KAAK,SAAS;YAC5B,MAAMC,OAAO,MAAMC,sBACjB,IAAM9B,mBAAmBC,kBAAkBc,WAC3C;gBAACgB,UAAU5B;YAAgB;YAE7B,IAAI,CAAC0B,QAAQ7C,gBAAgBmB,mBAAmBF,gBAAgB;YAChE;QACF;QAEA,IAAIuB,QAAQd,MAAM,KAAK,UAAU;YAC/B,MAAMlB,oCAAoC;gBAACwC,SAAS;YAAQ;YAC5D3B,eAAemB,QAAQS,QAAQ,GAAG;YAClCpB,uBAAuB;YACvB,IAAIC,kBAAkBC,aAAaS,QAAQS,QAAQ,IAAInB,eAAe;gBACpEb,gBAAgB;YAClB;YACA;QACF;QAEA,MAAMiC,qBAAqB;YACzBnC;YACAoC,gBAAgBX,QAAQW,cAAc;YACtCC,kBAAkBZ,QAAQY,gBAAgB;YAC1CC,gBAAgBb,QAAQa,cAAc;YACtCC,2BAA2B,IACzBvC,MAAMwC,SAAS,KAAK,YACnBtC,CAAAA,kBAAkBc,aAAa/B,gBAAgBmB,iBAAgB;YAClEqC,mBAAmB,IACjBV,sBACE,IAAM7B,kBAAkBc,aAAa/B,gBAAgBmB,mBACrD;oBAAC4B,UAAU5B;gBAAgB;QAEjC;QAEA,IAAInB,gBAAgBmB,mBAAmBF,kBAAkB;QACzDI,eAAemB,QAAQS,QAAQ,GAAG;QAClCpB,uBAAuB;QACvB,IAAIC,kBAAkBC,aAAaS,QAAQS,QAAQ,IAAInB,eAAe;YACpEb,gBAAgB;QAClB;IACF;IAEA,MAAMwC,SAASxC,iBAAiB;IAChC,MAAMyC,WAAW,MAAMpD,2BAA2B;QAACiB,OAAOR,MAAMQ,KAAK;QAAEkC;IAAM;IAC7E,OAAO;QAAC/B,QAAQgC,SAAShC,MAAM;QAAED,YAAYiC,SAASjC,UAAU;IAAA;AAClE;AAEA,SAASL,wBAAwBL,KAAoC;IACnE,OAAOA,MAAM4C,kBAAkB,KAAK5B,aAAahB,MAAM4C,kBAAkB,KAAK,OAC1E5B,YACA6B,KAAKC,GAAG,KAAK9C,MAAM4C,kBAAkB;AAC3C;AAEA,eAAezB,8BAA8B4B,MAM5C;IACC,IACE,CAACC,4BAA4B;QAC3BlC,qBAAqBiC,OAAOjC,mBAAmB;QAC/CmC,wBAAwBpE,eAAeoE,sBAAsB;IAC/D,IACA;QACA;IACF;IAEA,MAAM3E,cACJ4E,0BAA0BH,OAAO/C,KAAK,EAAE;QACtCM,cAAcyC,OAAOzC,YAAY;QACjCJ,eAAe6C,OAAO7C,aAAa;QACnCE,kBAAkB2C,OAAO3C,gBAAgB;IAC3C;AAEJ;AAEA,OAAO,SAAS4C,4BAA4BD,MAG3C;IACC,OACEA,OAAOE,sBAAsB,IAC7BF,OAAOjC,mBAAmB,IAAIhB;AAElC;AAEA,OAAO,SAASoD,0BACdlD,KAAoC,EACpCG,YAAuC;IAEvC,OAAO;QAAC,GAAGH,KAAK;QAAEG;IAAY;AAChC;AAEA,SAASe,oBACPlB,KAAoC;IAEpC,MAAMmD,aAAaC,eAAepD,MAAMqD,eAAe;IACvD,MAAM1B,gBAAgByB,eAAepD,MAAMsD,YAAY;IACvD,MAAMC,YAAYH,eAAepD,MAAMwD,cAAc;IACrD,IAAIL,eAAenC,aAAaW,kBAAkBX,aAAauC,cAAcvC,WAAW;QACtF,OAAOA;IACT;IACA,OAAO;QAACmC;QAAYxB;QAAe4B;IAAS;AAC9C;AAEA,eAAelC,uBACb0B,MAA+B;IAE/B,MAAO,KAAM;QACX,MAAMU,kBAAkBC,6BAA6BX;QACrD,IAAIU,oBAAoBzC,WAAW,OAAOyC;QAE1C,MAAME,OAAO,MAAMC,gBAAgBb;QACnC,MAAMc,eAAeC,kCAAkCf,QAAQY;QAC/D,IAAIE,iBAAiB7C,WAAW,OAAO6C;QAEvC,IAAIF,KAAKI,SAAS,KAAK,GAAG;YACxB,MAAMC,eAAe,MAAMC,sBAAsBlB;YACjD,IAAIiB,iBAAiBhD,WAAW,OAAOgD;YACvC;QACF;QAEA,IAAIE,mBAAmBnB,OAAO9B,WAAW,EAAE0C,OAAO,OAAO;QAEzD,MAAMQ,UAAUC,kBAAkBrB,OAAO9B,WAAW,EAAE0C;QACtD,IAAIQ,YAAYnD,WAAW;YACzB,MAAMgD,eAAe,MAAMC,sBAAsBlB;YACjD,IAAIiB,iBAAiBhD,WAAW,OAAOgD;YACvC;QACF;QAEA,MAAMA,eAAe,MAAMK,mBAAmBtB,QAAQoB;QACtD,IAAIH,iBAAiBhD,WAAW,OAAOgD;IACzC;AACF;AAEA,SAASN,6BACPX,MAA+B;IAE/B,IAAIA,OAAOvB,iBAAiB,IAAI,OAAO;IACvC,IAAIvC,gBAAgB8D,OAAO3C,gBAAgB,GAAG,OAAO;IACrD,OAAOY;AACT;AAEA,eAAe4C,gBAAgBb,MAA+B;IAC5DA,OAAOxB,eAAe;IACtB,OAAO,MAAMjC,2BAA2B;QAACkB,OAAOuC,OAAOvC,KAAK;IAAA;AAC9D;AAEA,SAASsD,kCACPf,MAA+B,EAC/BY,IAAwB;IAExB,IAAIA,KAAKW,cAAc,IAAIvB,OAAOvB,iBAAiB,IAAI,OAAO;IAC9D,IAAIvC,gBAAgB8D,OAAO3C,gBAAgB,GAAG,OAAO;IACrD,OAAOY;AACT;AAEA,SAASkD,mBAAmBK,MAA2B,EAAEZ,IAAwB;IAC/E,MAAMa,cAAcD,OAAO5C,aAAa,KAAKX,aAAa2C,KAAKI,SAAS,IAAIQ,OAAO5C,aAAa;IAChG,MAAM8C,gBAAgBF,OAAOpB,UAAU,KAAKnC,aAAa2C,KAAKe,WAAW,IAAIH,OAAOpB,UAAU;IAC9F,MAAMwB,iBAAiBJ,OAAOhB,SAAS,KAAKvC,aAAa2C,KAAKiB,WAAW,IAAIL,OAAOhB,SAAS;IAC7F,OAAOiB,eAAeC,iBAAiBE;AACzC;AAEA,SAASP,kBACPG,MAA2B,EAC3BZ,IAAwB;IAExB,MAAMkB,cAAc;QAClBC,kBAAkBP,OAAOpB,UAAU,EAAEQ,KAAKe,WAAW;QACrDI,kBAAkBP,OAAOhB,SAAS,EAAEI,KAAKiB,WAAW;KACrD,CAACG,MAAM,CAAC,CAACC,QAA2BA,UAAUhE;IAC/C,OAAO6D,YAAYI,MAAM,KAAK,IAAIjE,YAAYkE,KAAKC,GAAG,IAAIN;AAC5D;AAEA,eAAeZ,sBACblB,MAA+B;IAE/B,MAAMjB,OAAO,MAAMC,sBACjB,IAAMgB,OAAOzB,aAAa,MAAMyB,OAAOvB,iBAAiB,IACxD;QAACQ,UAAUe,OAAO3C,gBAAgB;IAAA;IAEpC,IAAI,CAAC0B,QAAQ7C,gBAAgB8D,OAAO3C,gBAAgB,GAAG,OAAO;IAC9D,OAAOY;AACT;AAEA,eAAeqD,mBACbtB,MAA+B,EAC/BoB,OAAe;IAEf,MAAMiB,oBAAoBlG,YAAY6D,OAAO3C,gBAAgB;IAC7D,MAAMiF,iBACJD,sBAAsBpE,YAAYmD,UAAUe,KAAKC,GAAG,CAAChB,SAASiB;IAChE,MAAME,gBACJvC,OAAO9B,WAAW,CAACkC,UAAU,KAAKnC,aAAa+B,OAAO9B,WAAW,CAACU,aAAa,KAAKX;IACtF,MAAMc,OAAO,MAAMzD,UACjB,IACE0E,OAAOvB,iBAAiB,MACvB8D,iBAAiBvC,OAAOzB,aAAa,MACtCrC,gBAAgB8D,OAAO3C,gBAAgB,GACzCiF;IAEF,IAAI,CAACvD,QAAQ7C,gBAAgB8D,OAAO3C,gBAAgB,GAAG,OAAO;IAC9D,OAAOY;AACT;AAEA,SAASoC,eAAe4B,KAAgC;IACtD,OAAOA,UAAUhE,aAAagE,UAAU,QAAQA,SAAS,IAAIhE,YAAYgE;AAC3E;AAEA,SAASF,kBAAkBS,OAA2B,EAAEC,KAAa;IACnE,OAAOD,YAAYvE,YAAYA,YAAYkE,KAAKO,GAAG,CAAC,GAAGF,UAAUC;AACnE;AAEA,eAAerD,qBAAqBY,MAOnC;IACC,MAAM2C,QAAQ,IAAItH;IAClB,MAAMuH,QAAQD,MAAME,GAAG,CAAC,IACtBpH,aAAaW,2BAA2B;YACtC0G,YAAY,CAAC,IAAI,EAAE9C,OAAO/C,KAAK,CAACQ,KAAK,EAAE;YACvCsF,uBAAuB;YACvBC,MAAM;gBACJ;oBACEC,aAAajD,OAAO/C,KAAK,CAACgG,WAAW;oBACrCC,eAAelD,OAAO/C,KAAK,CAACiG,aAAa;oBACzCC,WAAWnD,OAAO/C,KAAK,CAACkG,SAAS;oBACjC1F,OAAOuC,OAAO/C,KAAK,CAACQ,KAAK;oBACzB4B,gBAAgBW,OAAOX,cAAc;oBACrC+D,cAAcpD,OAAO/C,KAAK,CAACmG,YAAY;oBACvCzF,YAAYqC,OAAO/C,KAAK,CAACU,UAAU;oBACnC2B,kBAAkBU,OAAOV,gBAAgB;oBACzC,GAAIU,OAAO/C,KAAK,CAACoG,kBAAkB,KAAKpF,YACpC,CAAC,IACD;wBAACoF,oBAAoBrD,OAAO/C,KAAK,CAACoG,kBAAkB;oBAAA,CAAC;oBACzDC,kBAAkB;oBAClB/D,gBAAgBS,OAAOT,cAAc;gBACvC;aACD;YACDgE,mBAAmB5H,kBAAkB6H,SAAS;QAChD;IAGF,IAAIxD,OAAO/C,KAAK,CAACwC,SAAS,KAAK,UAAU;QACvC,MAAMgE,SAAS,MAAMC,QAAQC,IAAI,CAAC;YAChCf,MAAMgB,IAAI,CACR,IAAM,SACN,IAAM;YAER5D,OAAON,iBAAiB,GAAGkE,IAAI,CAAC,IAAM;SACvC;QACD,IAAIH,WAAW,gBAAgBzD,OAAOR,yBAAyB,IAAI;YACjEmD,MAAMkB,MAAM;YACZ,MAAMpH,mCAAmC;gBACvC4C,gBAAgBW,OAAOX,cAAc;gBACrCzB,QAAQ;YACV;YACA,MAAMlB,oCAAoC;gBAACwC,SAAS;YAAW;YAC/D,MAAMvC,yBAAyB;gBAACmH,QAAQ;oBAAC9D,OAAO/C,KAAK,CAACQ,KAAK;iBAAC;YAAA;YAC5D;QACF;IACF;IAEA,IAAI;QACF,MAAMsG,SAAS,MAAMnB;QACrB,MAAMlG,oCAAoC;YAACwC,SAAS8E,sBAAsBD,OAAOnG,MAAM;QAAC;IAC1F,EAAE,OAAOqG,OAAO;QACdvI,IAAIwI,IAAI,CAAC,2EAA2E;YAClFzG,OAAOuC,OAAO/C,KAAK,CAACQ,KAAK;YACzB4B,gBAAgBW,OAAOX,cAAc;YACrC4E,OAAOE,OAAOF;QAChB;QACA,MAAMxH,mCAAmC;YACvC4C,gBAAgBW,OAAOX,cAAc;YACrCzB,QAAQ;QACV;QACA,MAAMlB,oCAAoC;YAACwC,SAAS;QAAQ;IAC9D;AACF;AAEA,SAAS8E,sBACPpG,MAA+B;IAE/B,IAAIA,WAAW,eAAeA,WAAW,YAAYA,WAAW,aAAa,OAAOA;IACpF,MAAM,IAAIwG,MAAM,CAAC,8CAA8C,EAAExG,QAAQ;AAC3E;AAEA,eAAeoB,sBACbqF,SAAwB,EACxBC,OAAuC;IAEvC,MAAMC,YAAYpI,YAAYmI,QAAQrF,QAAQ;IAC9C,IAAIsF,cAActG,aAAasG,aAAa,GAAG,OAAO;IACtD,IAAIA,cAActG,WAAW;QAC3B,MAAM3C,UAAU+I;QAChB,OAAO;IACT;IACA,OAAO,MAAM/I,UAAU+I,WAAWE;AACpC"}
1
+ {"version":3,"sources":["../../../src/temporal/workflows/job-listener-orchestration.ts"],"sourcesContent":["import {\n CancellationScope,\n condition,\n continueAsNew,\n defineSignal,\n executeChild,\n log,\n ParentClosePolicy,\n proxyActivities,\n setHandler,\n workflowInfo,\n} from '@temporalio/workflow';\nimport type {ResolutionReason} from '#core/entities/job.js';\nimport {runtimeStatusForTerminalJobExecutionStatus} from '#core/job-execution-outcome.js';\nimport type {RuntimeCompletionStatus} from '#core/workflow-scheduling/runtime-dag.js';\nimport type {createOrchestrationActivities} from '../activities/index.js';\nimport {LISTENER_EVENTS_AVAILABLE_SIGNAL, LISTENER_RESOLVE_SIGNAL} from '../constants.js';\nimport {deadlineReached, remainingMs} from './deadline.js';\nimport {jobExecutionOrchestration} from './job-execution-orchestration.js';\n\nconst {\n activateJobListenerActivity,\n drainListenerEventsActivity,\n peekListenerBufferActivity,\n resolveJobListenerActivity,\n settleListenerJobExecutionActivity,\n recordListenerFiringOutcomeActivity,\n} = proxyActivities<ReturnType<typeof createOrchestrationActivities>>({\n startToCloseTimeout: '30s',\n});\n\nexport const listenerEventsAvailableSignal = defineSignal<[]>(LISTENER_EVENTS_AVAILABLE_SIGNAL);\nexport const listenerResolveSignal = defineSignal<[]>(LISTENER_RESOLVE_SIGNAL);\n\nexport interface JobListenerOrchestrationInput {\n runAttemptId: string;\n jobId: string;\n jobVersion: number;\n requiredLabels: string[];\n executionTimeoutMs?: number | null | undefined;\n listeningTimeoutMs?: number | null | undefined;\n maxExecutions?: number | null | undefined;\n onResolve?: 'finish' | 'cancel' | null | undefined;\n batchDebounceMs?: number | null | undefined;\n batchMaxSize?: number | null | undefined;\n batchMaxWaitMs?: number | null | undefined;\n continuation?: ListenerContinuationState | undefined;\n}\n\nexport interface JobListenerOrchestrationResult {\n status: RuntimeCompletionStatus;\n jobVersion: number;\n}\n\ntype ResolutionLatch = Exclude<ResolutionReason, 'cancelled'> | undefined;\ntype BatchFiringDecision = 'fire' | 'resolve' | 'deadline';\n\nexport interface ListenerContinuationState {\n nextSequence: number;\n latchedReason?: ResolutionLatch;\n listenerDeadline?: number | undefined;\n}\n\nexport const LISTENER_CONTINUE_AS_NEW_FIRING_LIMIT = 500;\n\ninterface ListenerBatchConfig {\n debounceMs?: number | undefined;\n maxSizeEvents?: number | undefined;\n maxWaitMs?: number | undefined;\n}\n\ninterface BatchFiringWindowParams {\n jobId: string;\n batchConfig: ListenerBatchConfig;\n listenerDeadline: number | undefined;\n hasEventsHint: () => boolean;\n clearEventsHint: () => void;\n hasResolutionHint: () => boolean;\n}\n\ninterface ListenerBufferPeek {\n fireCount: number;\n resolvePending: boolean;\n oldestAgeMs: number;\n newestAgeMs: number;\n}\n\nexport async function jobListenerOrchestration(\n input: JobListenerOrchestrationInput,\n): Promise<JobListenerOrchestrationResult> {\n let eventsAvailable = false;\n let latchedReason = input.continuation?.latchedReason;\n\n setHandler(listenerEventsAvailableSignal, () => {\n eventsAvailable = true;\n });\n setHandler(listenerResolveSignal, () => {\n latchedReason = 'until';\n });\n\n const listenerDeadline = input.continuation?.listenerDeadline ?? initialListenerDeadline(input);\n\n let nextSequence: number;\n if (input.continuation) {\n nextSequence = input.continuation.nextSequence;\n } else {\n const activated = await activateJobListenerActivity({\n jobId: input.jobId,\n expectedVersion: input.jobVersion,\n });\n if (activated.status === 'terminal') {\n return {\n status: runtimeStatusForTerminalJobExecutionStatus(activated.jobStatus),\n jobVersion: activated.jobVersion,\n };\n }\n nextSequence = activated.executionCount + 1;\n }\n\n let firingsInCurrentRun = 0;\n const maxExecutions = input.maxExecutions ?? undefined;\n const batchConfig = listenerBatchConfig(input);\n while (true) {\n if (deadlineReached(listenerDeadline)) latchedReason ??= 'timeout';\n await continueListenerAsNewIfNeeded({\n input,\n nextSequence,\n latchedReason,\n listenerDeadline,\n firingsInCurrentRun,\n });\n if (latchedReason !== undefined) break;\n if (maxExecutions !== undefined) {\n if (nextSequence > maxExecutions) {\n latchedReason = 'max_executions';\n await continueListenerAsNewIfNeeded({\n input,\n nextSequence,\n latchedReason,\n listenerDeadline,\n firingsInCurrentRun,\n });\n break;\n }\n }\n\n if (batchConfig !== undefined) {\n const decision = await awaitBatchFiringWindow({\n jobId: input.jobId,\n batchConfig,\n listenerDeadline,\n hasEventsHint: () => eventsAvailable,\n clearEventsHint: () => {\n eventsAvailable = false;\n },\n hasResolutionHint: () => latchedReason !== undefined,\n });\n if (decision === 'resolve') {\n latchedReason ??= 'until';\n break;\n }\n if (decision === 'deadline') {\n latchedReason ??= 'timeout';\n break;\n }\n }\n\n eventsAvailable = false;\n const drained = await drainListenerEventsActivity({\n jobId: input.jobId,\n expectedSequence: nextSequence,\n ...(batchConfig?.maxSizeEvents === undefined ? {} : {maxSize: batchConfig.maxSizeEvents}),\n });\n\n if (drained.kind === 'resolve-requested') {\n latchedReason = 'until';\n break;\n }\n\n if (drained.kind === 'empty') {\n const woke = await waitForListenerWakeup(\n () => eventsAvailable || latchedReason !== undefined,\n {deadline: listenerDeadline},\n );\n if (!woke && deadlineReached(listenerDeadline)) latchedReason = 'timeout';\n continue;\n }\n\n if (drained.status === 'failed') {\n await recordListenerFiringOutcomeActivity({outcome: 'failed'});\n nextSequence = drained.sequence + 1;\n firingsInCurrentRun += 1;\n if (maxExecutions !== undefined && drained.sequence >= maxExecutions) {\n latchedReason = 'max_executions';\n }\n continue;\n }\n\n await runListenerExecution({\n input,\n jobExecutionId: drained.jobExecutionId,\n executionVersion: drained.executionVersion,\n requiredLabels: drained.requiredLabels,\n shouldCancelForResolution: () =>\n input.onResolve === 'cancel' &&\n (latchedReason !== undefined || deadlineReached(listenerDeadline)),\n waitForResolution: () =>\n waitForListenerWakeup(\n () => latchedReason !== undefined || deadlineReached(listenerDeadline),\n {deadline: listenerDeadline},\n ),\n });\n\n if (deadlineReached(listenerDeadline)) latchedReason ??= 'timeout';\n nextSequence = drained.sequence + 1;\n firingsInCurrentRun += 1;\n if (maxExecutions !== undefined && drained.sequence >= maxExecutions) {\n latchedReason = 'max_executions';\n }\n }\n\n const reason = latchedReason ?? 'timeout';\n const resolved = await resolveJobListenerActivity({jobId: input.jobId, reason});\n return {status: resolved.status, jobVersion: resolved.jobVersion};\n}\n\nfunction initialListenerDeadline(input: JobListenerOrchestrationInput): number | undefined {\n return input.listeningTimeoutMs === undefined || input.listeningTimeoutMs === null\n ? undefined\n : Date.now() + input.listeningTimeoutMs;\n}\n\nasync function continueListenerAsNewIfNeeded(params: {\n input: JobListenerOrchestrationInput;\n nextSequence: number;\n latchedReason: ResolutionLatch;\n listenerDeadline: number | undefined;\n firingsInCurrentRun: number;\n}): Promise<void> {\n if (\n !shouldContinueListenerAsNew({\n firingsInCurrentRun: params.firingsInCurrentRun,\n continueAsNewSuggested: workflowInfo().continueAsNewSuggested,\n })\n ) {\n return;\n }\n\n await continueAsNew<typeof jobListenerOrchestration>(\n listenerContinuationInput(params.input, {\n nextSequence: params.nextSequence,\n latchedReason: params.latchedReason,\n listenerDeadline: params.listenerDeadline,\n }),\n );\n}\n\nexport function shouldContinueListenerAsNew(params: {\n firingsInCurrentRun: number;\n continueAsNewSuggested: boolean;\n}): boolean {\n return (\n params.continueAsNewSuggested ||\n params.firingsInCurrentRun >= LISTENER_CONTINUE_AS_NEW_FIRING_LIMIT\n );\n}\n\nexport function listenerContinuationInput(\n input: JobListenerOrchestrationInput,\n continuation: ListenerContinuationState,\n): JobListenerOrchestrationInput {\n return {...input, continuation};\n}\n\nfunction listenerBatchConfig(\n input: JobListenerOrchestrationInput,\n): ListenerBatchConfig | undefined {\n const debounceMs = positiveNumber(input.batchDebounceMs);\n const maxSizeEvents = positiveNumber(input.batchMaxSize);\n const maxWaitMs = positiveNumber(input.batchMaxWaitMs);\n if (debounceMs === undefined && maxSizeEvents === undefined && maxWaitMs === undefined) {\n return undefined;\n }\n return {debounceMs, maxSizeEvents, maxWaitMs};\n}\n\nasync function awaitBatchFiringWindow(\n params: BatchFiringWindowParams,\n): Promise<BatchFiringDecision> {\n while (true) {\n const prePeekDecision = resolutionOrDeadlineDecision(params);\n if (prePeekDecision !== undefined) return prePeekDecision;\n\n const peek = await peekBatchBuffer(params);\n const peekDecision = bufferedResolveOrDeadlineDecision(params, peek);\n if (peekDecision !== undefined) return peekDecision;\n\n if (peek.fireCount === 0) {\n const waitDecision = await waitForAnyBatchWakeup(params);\n if (waitDecision !== undefined) return waitDecision;\n continue;\n }\n\n if (batchIsReadyToFire(params.batchConfig, peek)) return 'fire';\n\n const sleepMs = nextBatchWindowMs(params.batchConfig, peek);\n if (sleepMs === undefined) {\n const waitDecision = await waitForAnyBatchWakeup(params);\n if (waitDecision !== undefined) return waitDecision;\n continue;\n }\n\n const waitDecision = await waitForBatchWindow(params, sleepMs);\n if (waitDecision !== undefined) return waitDecision;\n }\n}\n\nfunction resolutionOrDeadlineDecision(\n params: BatchFiringWindowParams,\n): Exclude<BatchFiringDecision, 'fire'> | undefined {\n if (params.hasResolutionHint()) return 'resolve';\n if (deadlineReached(params.listenerDeadline)) return 'deadline';\n return undefined;\n}\n\nasync function peekBatchBuffer(params: BatchFiringWindowParams): Promise<ListenerBufferPeek> {\n params.clearEventsHint();\n return await peekListenerBufferActivity({jobId: params.jobId});\n}\n\nfunction bufferedResolveOrDeadlineDecision(\n params: BatchFiringWindowParams,\n peek: ListenerBufferPeek,\n): Exclude<BatchFiringDecision, 'fire'> | undefined {\n if (peek.resolvePending || params.hasResolutionHint()) return 'resolve';\n if (deadlineReached(params.listenerDeadline)) return 'deadline';\n return undefined;\n}\n\nfunction batchIsReadyToFire(config: ListenerBatchConfig, peek: ListenerBufferPeek): boolean {\n const sizeReached = config.maxSizeEvents !== undefined && peek.fireCount >= config.maxSizeEvents;\n const debounceQuiet = config.debounceMs !== undefined && peek.newestAgeMs >= config.debounceMs;\n const maxWaitReached = config.maxWaitMs !== undefined && peek.oldestAgeMs >= config.maxWaitMs;\n return sizeReached || debounceQuiet || maxWaitReached;\n}\n\nfunction nextBatchWindowMs(\n config: ListenerBatchConfig,\n peek: ListenerBufferPeek,\n): number | undefined {\n const timeWindows = [\n remainingWindowMs(config.debounceMs, peek.newestAgeMs),\n remainingWindowMs(config.maxWaitMs, peek.oldestAgeMs),\n ].filter((value): value is number => value !== undefined);\n return timeWindows.length === 0 ? undefined : Math.min(...timeWindows);\n}\n\nasync function waitForAnyBatchWakeup(\n params: BatchFiringWindowParams,\n): Promise<Exclude<BatchFiringDecision, 'fire'> | undefined> {\n const woke = await waitForListenerWakeup(\n () => params.hasEventsHint() || params.hasResolutionHint(),\n {deadline: params.listenerDeadline},\n );\n if (!woke && deadlineReached(params.listenerDeadline)) return 'deadline';\n return undefined;\n}\n\nasync function waitForBatchWindow(\n params: BatchFiringWindowParams,\n sleepMs: number,\n): Promise<Exclude<BatchFiringDecision, 'fire'> | undefined> {\n const deadlineRemaining = remainingMs(params.listenerDeadline);\n const boundedSleepMs =\n deadlineRemaining === undefined ? sleepMs : Math.min(sleepMs, deadlineRemaining);\n const wakesOnEvents =\n params.batchConfig.debounceMs !== undefined || params.batchConfig.maxSizeEvents !== undefined;\n const woke = await condition(\n () =>\n params.hasResolutionHint() ||\n (wakesOnEvents && params.hasEventsHint()) ||\n deadlineReached(params.listenerDeadline),\n boundedSleepMs,\n );\n if (!woke && deadlineReached(params.listenerDeadline)) return 'deadline';\n return undefined;\n}\n\nfunction positiveNumber(value: number | null | undefined): number | undefined {\n return value === undefined || value === null || value <= 0 ? undefined : value;\n}\n\nfunction remainingWindowMs(limitMs: number | undefined, ageMs: number): number | undefined {\n return limitMs === undefined ? undefined : Math.max(0, limitMs - ageMs);\n}\n\nasync function runListenerExecution(params: {\n input: JobListenerOrchestrationInput;\n jobExecutionId: string;\n executionVersion: number;\n requiredLabels: string[];\n shouldCancelForResolution: () => boolean;\n waitForResolution: () => Promise<boolean>;\n}): Promise<void> {\n const scope = new CancellationScope();\n const child = scope.run(() =>\n executeChild(jobExecutionOrchestration, {\n workflowId: `job:${params.input.jobId}`,\n workflowIdReusePolicy: 'ALLOW_DUPLICATE',\n args: [\n {\n jobId: params.input.jobId,\n jobExecutionId: params.jobExecutionId,\n runAttemptId: params.input.runAttemptId,\n jobVersion: params.input.jobVersion,\n executionVersion: params.executionVersion,\n ...(params.input.executionTimeoutMs === undefined\n ? {}\n : {executionTimeoutMs: params.input.executionTimeoutMs}),\n resolveJobStatus: false,\n requiredLabels: params.requiredLabels,\n },\n ],\n parentClosePolicy: ParentClosePolicy.TERMINATE,\n }),\n );\n\n if (params.input.onResolve === 'cancel') {\n const winner = await Promise.race([\n child.then(\n () => 'child' as const,\n () => 'child-failed' as const,\n ),\n params.waitForResolution().then(() => 'resolution' as const),\n ]);\n if (winner === 'resolution' && params.shouldCancelForResolution()) {\n scope.cancel();\n await settleListenerJobExecutionActivity({\n jobExecutionId: params.jobExecutionId,\n status: 'cancelled',\n });\n await recordListenerFiringOutcomeActivity({outcome: 'cancelled'});\n return;\n }\n }\n\n try {\n const result = await child;\n await recordListenerFiringOutcomeActivity({outcome: listenerFiringOutcome(result.status)});\n } catch (error) {\n log.warn('listener execution child failed; recording failed firing and continuing', {\n jobId: params.input.jobId,\n jobExecutionId: params.jobExecutionId,\n error: String(error),\n });\n await settleListenerJobExecutionActivity({\n jobExecutionId: params.jobExecutionId,\n status: 'failed',\n });\n await recordListenerFiringOutcomeActivity({outcome: 'failed'});\n }\n}\n\nfunction listenerFiringOutcome(\n status: RuntimeCompletionStatus,\n): 'succeeded' | 'failed' | 'cancelled' {\n if (status === 'succeeded' || status === 'failed' || status === 'cancelled') return status;\n throw new Error(`Listener execution cannot finish with status: ${status}`);\n}\n\nasync function waitForListenerWakeup(\n predicate: () => boolean,\n options: {deadline: number | undefined},\n): Promise<boolean> {\n const remaining = remainingMs(options.deadline);\n if (remaining !== undefined && remaining <= 0) return false;\n if (remaining === undefined) {\n await condition(predicate);\n return true;\n }\n return await condition(predicate, remaining);\n}\n"],"names":["CancellationScope","condition","continueAsNew","defineSignal","executeChild","log","ParentClosePolicy","proxyActivities","setHandler","workflowInfo","runtimeStatusForTerminalJobExecutionStatus","LISTENER_EVENTS_AVAILABLE_SIGNAL","LISTENER_RESOLVE_SIGNAL","deadlineReached","remainingMs","jobExecutionOrchestration","activateJobListenerActivity","drainListenerEventsActivity","peekListenerBufferActivity","resolveJobListenerActivity","settleListenerJobExecutionActivity","recordListenerFiringOutcomeActivity","startToCloseTimeout","listenerEventsAvailableSignal","listenerResolveSignal","LISTENER_CONTINUE_AS_NEW_FIRING_LIMIT","jobListenerOrchestration","input","eventsAvailable","latchedReason","continuation","listenerDeadline","initialListenerDeadline","nextSequence","activated","jobId","expectedVersion","jobVersion","status","jobStatus","executionCount","firingsInCurrentRun","maxExecutions","undefined","batchConfig","listenerBatchConfig","continueListenerAsNewIfNeeded","decision","awaitBatchFiringWindow","hasEventsHint","clearEventsHint","hasResolutionHint","drained","expectedSequence","maxSizeEvents","maxSize","kind","woke","waitForListenerWakeup","deadline","outcome","sequence","runListenerExecution","jobExecutionId","executionVersion","requiredLabels","shouldCancelForResolution","onResolve","waitForResolution","reason","resolved","listeningTimeoutMs","Date","now","params","shouldContinueListenerAsNew","continueAsNewSuggested","listenerContinuationInput","debounceMs","positiveNumber","batchDebounceMs","batchMaxSize","maxWaitMs","batchMaxWaitMs","prePeekDecision","resolutionOrDeadlineDecision","peek","peekBatchBuffer","peekDecision","bufferedResolveOrDeadlineDecision","fireCount","waitDecision","waitForAnyBatchWakeup","batchIsReadyToFire","sleepMs","nextBatchWindowMs","waitForBatchWindow","resolvePending","config","sizeReached","debounceQuiet","newestAgeMs","maxWaitReached","oldestAgeMs","timeWindows","remainingWindowMs","filter","value","length","Math","min","deadlineRemaining","boundedSleepMs","wakesOnEvents","limitMs","ageMs","max","scope","child","run","workflowId","workflowIdReusePolicy","args","runAttemptId","executionTimeoutMs","resolveJobStatus","parentClosePolicy","TERMINATE","winner","Promise","race","then","cancel","result","listenerFiringOutcome","error","warn","String","Error","predicate","options","remaining"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"run-orchestration.d.ts","sourceRoot":"","sources":["../../../src/temporal/workflows/run-orchestration.ts"],"names":[],"mappings":"AA6CA,eAAO,MAAM,eAAe,6DAAsC,CAAC;AAEnE,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwGlF"}
1
+ {"version":3,"file":"run-orchestration.d.ts","sourceRoot":"","sources":["../../../src/temporal/workflows/run-orchestration.ts"],"names":[],"mappings":"AAuCA,eAAO,MAAM,eAAe,6DAAsC,CAAC;AAEnE,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoGlF"}
@@ -1,11 +1,11 @@
1
1
  import { condition, defineSignal, executeChild, log, ParentClosePolicy, proxyActivities, setHandler } from '@temporalio/workflow';
2
- import { createRuntimeRunProgress, nonCompletedRuntimeJobIds, recordRuntimeJobResult, recordSkippedRuntimeJob, runtimeJobVersion, shouldContinueStartedRun } from '#core/workflow-scheduling/run-progress.js';
2
+ import { createRuntimeRunProgress, recordRuntimeJobResult, recordSkippedRuntimeJob, runtimeJobVersion, shouldContinueStartedRun } from '#core/workflow-scheduling/run-progress.js';
3
3
  import { scheduleRuntimeDag } from '#core/workflow-scheduling/schedule-runtime-dag.js';
4
4
  import { RUN_CANCEL_SIGNAL } from '../constants.js';
5
5
  import { deadlineReached, remainingMs } from './deadline.js';
6
6
  import { jobExecutionOrchestration } from './job-execution-orchestration.js';
7
7
  import { jobListenerOrchestration } from './job-listener-orchestration.js';
8
- const { loadRunAttemptDag, evaluateJobActivationsActivity, setRunAttemptStatus, setJobStatus, cancelRunnerJobsActivity } = proxyActivities({
8
+ const { loadRunAttemptDag, evaluateJobActivationsActivity, setRunAttemptStatus, setJobStatus } = proxyActivities({
9
9
  startToCloseTimeout: '30s'
10
10
  });
11
11
  const { failRunAsTimedOutActivity } = proxyActivities({
@@ -34,14 +34,12 @@ export async function runOrchestration(input) {
34
34
  const inFlight = new Map();
35
35
  while(true){
36
36
  if (cancelRequested) {
37
- await cancelNonCompletedRunnerJobs(dag, progress);
38
37
  return;
39
38
  }
40
39
  if (deadlineReached(runDeadline)) {
41
40
  await failRunAsTimedOutActivity({
42
41
  runAttemptId: input.runAttemptId
43
42
  });
44
- await cancelNonCompletedRunnerJobs(dag, progress);
45
43
  return;
46
44
  }
47
45
  const commands = scheduleRuntimeDag({
@@ -101,14 +99,12 @@ export async function runOrchestration(input) {
101
99
  if (startJobs.size === 0 && inFlight.size === 0) continue;
102
100
  const settled = await waitForNextSettlement(inFlight, ()=>cancelRequested, runDeadline);
103
101
  if (settled.kind === 'cancelled') {
104
- await cancelNonCompletedRunnerJobs(dag, progress);
105
102
  return;
106
103
  }
107
104
  if (settled.kind === 'timed-out') {
108
105
  await failRunAsTimedOutActivity({
109
106
  runAttemptId: input.runAttemptId
110
107
  });
111
- await cancelNonCompletedRunnerJobs(dag, progress);
112
108
  return;
113
109
  }
114
110
  inFlight.delete(settled.job.key);
@@ -131,9 +127,6 @@ function launchJob(job, run, progress) {
131
127
  workflowId: `job-listener:${job.id}`,
132
128
  args: [
133
129
  {
134
- workspaceId: run.workspaceId,
135
- workflowRunId: run.workflowRunId,
136
- projectId: run.projectId,
137
130
  jobId: job.id,
138
131
  runAttemptId: run.runAttemptId,
139
132
  jobVersion: runtimeJobVersion(job, progress),
@@ -192,9 +185,6 @@ function launchJob(job, run, progress) {
192
185
  workflowId: `job:${job.id}`,
193
186
  args: [
194
187
  {
195
- workspaceId: run.workspaceId,
196
- workflowRunId: run.workflowRunId,
197
- projectId: run.projectId,
198
188
  jobId: job.id,
199
189
  jobExecutionId: job.jobExecutionId,
200
190
  runAttemptId: run.runAttemptId,
@@ -233,11 +223,5 @@ async function waitForNextSettlement(inFlight, isCancelRequested, runDeadline) {
233
223
  cancel
234
224
  ]);
235
225
  }
236
- async function cancelNonCompletedRunnerJobs(dag, progress) {
237
- const jobIds = nonCompletedRuntimeJobIds(dag.jobs, progress);
238
- await cancelRunnerJobsActivity({
239
- jobIds
240
- });
241
- }
242
226
 
243
227
  //# sourceMappingURL=run-orchestration.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/temporal/workflows/run-orchestration.ts"],"sourcesContent":["import {\n condition,\n defineSignal,\n executeChild,\n log,\n ParentClosePolicy,\n proxyActivities,\n setHandler,\n} from '@temporalio/workflow';\nimport {\n createRuntimeRunProgress,\n nonCompletedRuntimeJobIds,\n type RuntimeRunProgress,\n recordRuntimeJobResult,\n recordSkippedRuntimeJob,\n runtimeJobVersion,\n shouldContinueStartedRun,\n} from '#core/workflow-scheduling/run-progress.js';\nimport type {RuntimeCompletionStatus} from '#core/workflow-scheduling/runtime-dag.js';\nimport {scheduleRuntimeDag} from '#core/workflow-scheduling/schedule-runtime-dag.js';\n\nimport type {createOrchestrationActivities} from '../activities/index.js';\nimport type {DagJob, RunDag} from '../activities/orchestration-activities.js';\nimport {RUN_CANCEL_SIGNAL} from '../constants.js';\nimport {deadlineReached, remainingMs} from './deadline.js';\nimport {jobExecutionOrchestration} from './job-execution-orchestration.js';\nimport {jobListenerOrchestration} from './job-listener-orchestration.js';\n\nconst {\n loadRunAttemptDag,\n evaluateJobActivationsActivity,\n setRunAttemptStatus,\n setJobStatus,\n cancelRunnerJobsActivity,\n} = proxyActivities<ReturnType<typeof createOrchestrationActivities>>({\n startToCloseTimeout: '30s',\n});\n\nconst {failRunAsTimedOutActivity} = proxyActivities<\n ReturnType<typeof createOrchestrationActivities>\n>({\n startToCloseTimeout: '30s',\n retry: {maximumAttempts: 5},\n});\n\nexport const runCancelSignal = defineSignal<[]>(RUN_CANCEL_SIGNAL);\n\nexport interface RunOrchestrationInput {\n workflowRunId: string;\n runAttemptId: string;\n workspaceId: string;\n}\n\nexport async function runOrchestration(input: RunOrchestrationInput): Promise<void> {\n let cancelRequested = false;\n setHandler(runCancelSignal, () => {\n cancelRequested = true;\n });\n\n const dag = await loadRunAttemptDag(input.runAttemptId);\n const runDeadline = Date.now() + dag.runTimeoutMs;\n\n let runVersion = dag.runVersion;\n const {newVersion, status} = await setRunAttemptStatus({\n runAttemptId: input.runAttemptId,\n status: 'running',\n version: runVersion,\n });\n runVersion = newVersion;\n if (!shouldContinueStartedRun(status)) return;\n\n const progress = createRuntimeRunProgress(dag.jobs);\n const inFlight = new Map<string, Promise<{job: DagJob; result: LaunchResult}>>();\n\n while (true) {\n if (cancelRequested) {\n await cancelNonCompletedRunnerJobs(dag, progress);\n return;\n }\n if (deadlineReached(runDeadline)) {\n await failRunAsTimedOutActivity({runAttemptId: input.runAttemptId});\n await cancelNonCompletedRunnerJobs(dag, progress);\n return;\n }\n\n const commands = scheduleRuntimeDag({\n jobs: dag.jobs,\n completed: progress.completed,\n running: new Set(inFlight.keys()),\n });\n const completeRun = commands.find((command) => command.kind === 'complete-run');\n const startJobs = new Map<string, DagJob>();\n\n for (const command of commands) {\n if (command.kind !== 'skip-job') continue;\n await skipJob(command.job, progress, command.statusReason);\n }\n\n for (const command of commands) {\n if (command.kind !== 'evaluate-job-activation') continue;\n const activationJobsById = new Map(command.jobs.map((job) => [job.id, job]));\n const decisions = await evaluateJobActivationsActivity({\n runAttemptId: input.runAttemptId,\n jobs: command.jobs.map((job) => ({\n jobId: job.id,\n expectedVersion: runtimeJobVersion(job, progress),\n })),\n });\n for (const decision of decisions) {\n const job = activationJobsById.get(decision.jobId);\n if (!job) continue;\n if (decision.kind === 'start-job') {\n startJobs.set(job.key, job);\n continue;\n }\n recordRuntimeJobResult(job, progress, {\n status: decision.status,\n jobVersion: decision.jobVersion,\n });\n }\n }\n\n for (const command of commands) {\n if (command.kind !== 'start-job') continue;\n startJobs.set(command.job.key, command.job);\n }\n\n for (const job of startJobs.values()) {\n if (!inFlight.has(job.key)) {\n inFlight.set(job.key, launchJob(job, dag, progress));\n }\n }\n\n if (completeRun) {\n await setRunAttemptStatus({\n runAttemptId: input.runAttemptId,\n status: completeRun.status,\n version: runVersion,\n });\n return;\n }\n\n if (startJobs.size === 0 && inFlight.size === 0) continue;\n\n const settled = await waitForNextSettlement(inFlight, () => cancelRequested, runDeadline);\n if (settled.kind === 'cancelled') {\n await cancelNonCompletedRunnerJobs(dag, progress);\n return;\n }\n if (settled.kind === 'timed-out') {\n await failRunAsTimedOutActivity({runAttemptId: input.runAttemptId});\n await cancelNonCompletedRunnerJobs(dag, progress);\n return;\n }\n inFlight.delete(settled.job.key);\n recordRuntimeJobResult(settled.job, progress, settled.result);\n }\n}\n\nasync function skipJob(\n job: DagJob,\n progress: RuntimeRunProgress,\n statusReason: 'default_gate_rejected',\n): Promise<void> {\n const version = runtimeJobVersion(job, progress);\n const {newVersion} = await setJobStatus({\n jobId: job.id,\n status: 'skipped',\n version,\n statusReason,\n });\n recordSkippedRuntimeJob(job, progress, newVersion);\n}\n\ninterface LaunchResult {\n status: RuntimeCompletionStatus;\n jobVersion: number;\n}\n\nfunction launchJob(\n job: DagJob,\n run: RunDag,\n progress: RuntimeRunProgress,\n): Promise<{job: DagJob; result: LaunchResult}> {\n if (job.mode === 'listening') {\n return executeChild(jobListenerOrchestration, {\n workflowId: `job-listener:${job.id}`,\n args: [\n {\n workspaceId: run.workspaceId,\n workflowRunId: run.workflowRunId,\n projectId: run.projectId,\n jobId: job.id,\n runAttemptId: run.runAttemptId,\n jobVersion: runtimeJobVersion(job, progress),\n ...(job.executionTimeoutMs === undefined\n ? {}\n : {executionTimeoutMs: job.executionTimeoutMs}),\n ...(job.listeningTimeoutMs === undefined\n ? {}\n : {listeningTimeoutMs: job.listeningTimeoutMs}),\n ...(job.maxExecutions === undefined ? {} : {maxExecutions: job.maxExecutions}),\n ...(job.onResolve === undefined ? {} : {onResolve: job.onResolve}),\n ...(job.batchDebounceMs === undefined ? {} : {batchDebounceMs: job.batchDebounceMs}),\n ...(job.batchMaxSize === undefined ? {} : {batchMaxSize: job.batchMaxSize}),\n ...(job.batchMaxWaitMs === undefined ? {} : {batchMaxWaitMs: job.batchMaxWaitMs}),\n requiredLabels: job.runner,\n },\n ],\n parentClosePolicy: ParentClosePolicy.TERMINATE,\n })\n .then((result) => ({job, result}))\n .catch(async (error) => {\n log.warn('listener child failed; marking runtime job failed', {\n jobId: job.id,\n error: String(error),\n });\n const failed = await setJobStatus({\n jobId: job.id,\n status: 'failed',\n version: runtimeJobVersion(job, progress),\n statusReason: 'unknown',\n });\n return {\n job,\n result: {status: 'failed' as const, jobVersion: failed.newVersion},\n };\n });\n }\n\n if (job.jobExecutionId === undefined) {\n throw new Error(`Cannot start job without an execution: ${job.id}`);\n }\n return executeChild(jobExecutionOrchestration, {\n workflowId: `job:${job.id}`,\n args: [\n {\n workspaceId: run.workspaceId,\n workflowRunId: run.workflowRunId,\n projectId: run.projectId,\n jobId: job.id,\n jobExecutionId: job.jobExecutionId,\n runAttemptId: run.runAttemptId,\n jobVersion: runtimeJobVersion(job, progress),\n executionVersion: job.executionVersion ?? runtimeJobVersion(job, progress),\n ...(job.executionTimeoutMs === undefined\n ? {}\n : {executionTimeoutMs: job.executionTimeoutMs}),\n requiredLabels: job.runner,\n },\n ],\n parentClosePolicy: ParentClosePolicy.TERMINATE,\n }).then((result) => ({\n job,\n result: {status: result.status, jobVersion: result.jobVersion},\n }));\n}\n\nasync function waitForNextSettlement(\n inFlight: ReadonlyMap<string, Promise<{job: DagJob; result: LaunchResult}>>,\n isCancelRequested: () => boolean,\n runDeadline: number,\n): Promise<\n {kind: 'settled'; job: DagJob; result: LaunchResult} | {kind: 'cancelled'} | {kind: 'timed-out'}\n> {\n const remaining = remainingMs(runDeadline) ?? 0;\n const childSettled = Promise.race([...inFlight.values()]).then((settled) => ({\n kind: 'settled' as const,\n ...settled,\n }));\n const cancel = condition(isCancelRequested, remaining).then((woke) =>\n woke ? {kind: 'cancelled' as const} : {kind: 'timed-out' as const},\n );\n return await Promise.race([childSettled, cancel]);\n}\n\nasync function cancelNonCompletedRunnerJobs(\n dag: RunDag,\n progress: RuntimeRunProgress,\n): Promise<void> {\n const jobIds = nonCompletedRuntimeJobIds(dag.jobs, progress);\n await cancelRunnerJobsActivity({jobIds});\n}\n"],"names":["condition","defineSignal","executeChild","log","ParentClosePolicy","proxyActivities","setHandler","createRuntimeRunProgress","nonCompletedRuntimeJobIds","recordRuntimeJobResult","recordSkippedRuntimeJob","runtimeJobVersion","shouldContinueStartedRun","scheduleRuntimeDag","RUN_CANCEL_SIGNAL","deadlineReached","remainingMs","jobExecutionOrchestration","jobListenerOrchestration","loadRunAttemptDag","evaluateJobActivationsActivity","setRunAttemptStatus","setJobStatus","cancelRunnerJobsActivity","startToCloseTimeout","failRunAsTimedOutActivity","retry","maximumAttempts","runCancelSignal","runOrchestration","input","cancelRequested","dag","runAttemptId","runDeadline","Date","now","runTimeoutMs","runVersion","newVersion","status","version","progress","jobs","inFlight","Map","cancelNonCompletedRunnerJobs","commands","completed","running","Set","keys","completeRun","find","command","kind","startJobs","skipJob","job","statusReason","activationJobsById","map","id","decisions","jobId","expectedVersion","decision","get","set","key","jobVersion","values","has","launchJob","size","settled","waitForNextSettlement","delete","result","run","mode","workflowId","args","workspaceId","workflowRunId","projectId","executionTimeoutMs","undefined","listeningTimeoutMs","maxExecutions","onResolve","batchDebounceMs","batchMaxSize","batchMaxWaitMs","requiredLabels","runner","parentClosePolicy","TERMINATE","then","catch","error","warn","String","failed","jobExecutionId","Error","executionVersion","isCancelRequested","remaining","childSettled","Promise","race","cancel","woke","jobIds"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/temporal/workflows/run-orchestration.ts"],"sourcesContent":["import {\n condition,\n defineSignal,\n executeChild,\n log,\n ParentClosePolicy,\n proxyActivities,\n setHandler,\n} from '@temporalio/workflow';\nimport {\n createRuntimeRunProgress,\n type RuntimeRunProgress,\n recordRuntimeJobResult,\n recordSkippedRuntimeJob,\n runtimeJobVersion,\n shouldContinueStartedRun,\n} from '#core/workflow-scheduling/run-progress.js';\nimport type {RuntimeCompletionStatus} from '#core/workflow-scheduling/runtime-dag.js';\nimport {scheduleRuntimeDag} from '#core/workflow-scheduling/schedule-runtime-dag.js';\n\nimport type {createOrchestrationActivities} from '../activities/index.js';\nimport type {DagJob, RunDag} from '../activities/orchestration-activities.js';\nimport {RUN_CANCEL_SIGNAL} from '../constants.js';\nimport {deadlineReached, remainingMs} from './deadline.js';\nimport {jobExecutionOrchestration} from './job-execution-orchestration.js';\nimport {jobListenerOrchestration} from './job-listener-orchestration.js';\n\nconst {loadRunAttemptDag, evaluateJobActivationsActivity, setRunAttemptStatus, setJobStatus} =\n proxyActivities<ReturnType<typeof createOrchestrationActivities>>({\n startToCloseTimeout: '30s',\n });\n\nconst {failRunAsTimedOutActivity} = proxyActivities<\n ReturnType<typeof createOrchestrationActivities>\n>({\n startToCloseTimeout: '30s',\n retry: {maximumAttempts: 5},\n});\n\nexport const runCancelSignal = defineSignal<[]>(RUN_CANCEL_SIGNAL);\n\nexport interface RunOrchestrationInput {\n workflowRunId: string;\n runAttemptId: string;\n workspaceId: string;\n}\n\nexport async function runOrchestration(input: RunOrchestrationInput): Promise<void> {\n let cancelRequested = false;\n setHandler(runCancelSignal, () => {\n cancelRequested = true;\n });\n\n const dag = await loadRunAttemptDag(input.runAttemptId);\n const runDeadline = Date.now() + dag.runTimeoutMs;\n\n let runVersion = dag.runVersion;\n const {newVersion, status} = await setRunAttemptStatus({\n runAttemptId: input.runAttemptId,\n status: 'running',\n version: runVersion,\n });\n runVersion = newVersion;\n if (!shouldContinueStartedRun(status)) return;\n\n const progress = createRuntimeRunProgress(dag.jobs);\n const inFlight = new Map<string, Promise<{job: DagJob; result: LaunchResult}>>();\n\n while (true) {\n if (cancelRequested) {\n return;\n }\n if (deadlineReached(runDeadline)) {\n await failRunAsTimedOutActivity({runAttemptId: input.runAttemptId});\n return;\n }\n\n const commands = scheduleRuntimeDag({\n jobs: dag.jobs,\n completed: progress.completed,\n running: new Set(inFlight.keys()),\n });\n const completeRun = commands.find((command) => command.kind === 'complete-run');\n const startJobs = new Map<string, DagJob>();\n\n for (const command of commands) {\n if (command.kind !== 'skip-job') continue;\n await skipJob(command.job, progress, command.statusReason);\n }\n\n for (const command of commands) {\n if (command.kind !== 'evaluate-job-activation') continue;\n const activationJobsById = new Map(command.jobs.map((job) => [job.id, job]));\n const decisions = await evaluateJobActivationsActivity({\n runAttemptId: input.runAttemptId,\n jobs: command.jobs.map((job) => ({\n jobId: job.id,\n expectedVersion: runtimeJobVersion(job, progress),\n })),\n });\n for (const decision of decisions) {\n const job = activationJobsById.get(decision.jobId);\n if (!job) continue;\n if (decision.kind === 'start-job') {\n startJobs.set(job.key, job);\n continue;\n }\n recordRuntimeJobResult(job, progress, {\n status: decision.status,\n jobVersion: decision.jobVersion,\n });\n }\n }\n\n for (const command of commands) {\n if (command.kind !== 'start-job') continue;\n startJobs.set(command.job.key, command.job);\n }\n\n for (const job of startJobs.values()) {\n if (!inFlight.has(job.key)) {\n inFlight.set(job.key, launchJob(job, dag, progress));\n }\n }\n\n if (completeRun) {\n await setRunAttemptStatus({\n runAttemptId: input.runAttemptId,\n status: completeRun.status,\n version: runVersion,\n });\n return;\n }\n\n if (startJobs.size === 0 && inFlight.size === 0) continue;\n\n const settled = await waitForNextSettlement(inFlight, () => cancelRequested, runDeadline);\n if (settled.kind === 'cancelled') {\n return;\n }\n if (settled.kind === 'timed-out') {\n await failRunAsTimedOutActivity({runAttemptId: input.runAttemptId});\n return;\n }\n inFlight.delete(settled.job.key);\n recordRuntimeJobResult(settled.job, progress, settled.result);\n }\n}\n\nasync function skipJob(\n job: DagJob,\n progress: RuntimeRunProgress,\n statusReason: 'default_gate_rejected',\n): Promise<void> {\n const version = runtimeJobVersion(job, progress);\n const {newVersion} = await setJobStatus({\n jobId: job.id,\n status: 'skipped',\n version,\n statusReason,\n });\n recordSkippedRuntimeJob(job, progress, newVersion);\n}\n\ninterface LaunchResult {\n status: RuntimeCompletionStatus;\n jobVersion: number;\n}\n\nfunction launchJob(\n job: DagJob,\n run: RunDag,\n progress: RuntimeRunProgress,\n): Promise<{job: DagJob; result: LaunchResult}> {\n if (job.mode === 'listening') {\n return executeChild(jobListenerOrchestration, {\n workflowId: `job-listener:${job.id}`,\n args: [\n {\n jobId: job.id,\n runAttemptId: run.runAttemptId,\n jobVersion: runtimeJobVersion(job, progress),\n ...(job.executionTimeoutMs === undefined\n ? {}\n : {executionTimeoutMs: job.executionTimeoutMs}),\n ...(job.listeningTimeoutMs === undefined\n ? {}\n : {listeningTimeoutMs: job.listeningTimeoutMs}),\n ...(job.maxExecutions === undefined ? {} : {maxExecutions: job.maxExecutions}),\n ...(job.onResolve === undefined ? {} : {onResolve: job.onResolve}),\n ...(job.batchDebounceMs === undefined ? {} : {batchDebounceMs: job.batchDebounceMs}),\n ...(job.batchMaxSize === undefined ? {} : {batchMaxSize: job.batchMaxSize}),\n ...(job.batchMaxWaitMs === undefined ? {} : {batchMaxWaitMs: job.batchMaxWaitMs}),\n requiredLabels: job.runner,\n },\n ],\n parentClosePolicy: ParentClosePolicy.TERMINATE,\n })\n .then((result) => ({job, result}))\n .catch(async (error) => {\n log.warn('listener child failed; marking runtime job failed', {\n jobId: job.id,\n error: String(error),\n });\n const failed = await setJobStatus({\n jobId: job.id,\n status: 'failed',\n version: runtimeJobVersion(job, progress),\n statusReason: 'unknown',\n });\n return {\n job,\n result: {status: 'failed' as const, jobVersion: failed.newVersion},\n };\n });\n }\n\n if (job.jobExecutionId === undefined) {\n throw new Error(`Cannot start job without an execution: ${job.id}`);\n }\n return executeChild(jobExecutionOrchestration, {\n workflowId: `job:${job.id}`,\n args: [\n {\n jobId: job.id,\n jobExecutionId: job.jobExecutionId,\n runAttemptId: run.runAttemptId,\n jobVersion: runtimeJobVersion(job, progress),\n executionVersion: job.executionVersion ?? runtimeJobVersion(job, progress),\n ...(job.executionTimeoutMs === undefined\n ? {}\n : {executionTimeoutMs: job.executionTimeoutMs}),\n requiredLabels: job.runner,\n },\n ],\n parentClosePolicy: ParentClosePolicy.TERMINATE,\n }).then((result) => ({\n job,\n result: {status: result.status, jobVersion: result.jobVersion},\n }));\n}\n\nasync function waitForNextSettlement(\n inFlight: ReadonlyMap<string, Promise<{job: DagJob; result: LaunchResult}>>,\n isCancelRequested: () => boolean,\n runDeadline: number,\n): Promise<\n {kind: 'settled'; job: DagJob; result: LaunchResult} | {kind: 'cancelled'} | {kind: 'timed-out'}\n> {\n const remaining = remainingMs(runDeadline) ?? 0;\n const childSettled = Promise.race([...inFlight.values()]).then((settled) => ({\n kind: 'settled' as const,\n ...settled,\n }));\n const cancel = condition(isCancelRequested, remaining).then((woke) =>\n woke ? {kind: 'cancelled' as const} : {kind: 'timed-out' as const},\n );\n return await Promise.race([childSettled, cancel]);\n}\n"],"names":["condition","defineSignal","executeChild","log","ParentClosePolicy","proxyActivities","setHandler","createRuntimeRunProgress","recordRuntimeJobResult","recordSkippedRuntimeJob","runtimeJobVersion","shouldContinueStartedRun","scheduleRuntimeDag","RUN_CANCEL_SIGNAL","deadlineReached","remainingMs","jobExecutionOrchestration","jobListenerOrchestration","loadRunAttemptDag","evaluateJobActivationsActivity","setRunAttemptStatus","setJobStatus","startToCloseTimeout","failRunAsTimedOutActivity","retry","maximumAttempts","runCancelSignal","runOrchestration","input","cancelRequested","dag","runAttemptId","runDeadline","Date","now","runTimeoutMs","runVersion","newVersion","status","version","progress","jobs","inFlight","Map","commands","completed","running","Set","keys","completeRun","find","command","kind","startJobs","skipJob","job","statusReason","activationJobsById","map","id","decisions","jobId","expectedVersion","decision","get","set","key","jobVersion","values","has","launchJob","size","settled","waitForNextSettlement","delete","result","run","mode","workflowId","args","executionTimeoutMs","undefined","listeningTimeoutMs","maxExecutions","onResolve","batchDebounceMs","batchMaxSize","batchMaxWaitMs","requiredLabels","runner","parentClosePolicy","TERMINATE","then","catch","error","warn","String","failed","jobExecutionId","Error","executionVersion","isCancelRequested","remaining","childSettled","Promise","race","cancel","woke"],"mappings":"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"}