@auto-engineer/job-graph-processor 1.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +5 -0
- package/.turbo/turbo-test.log +14 -0
- package/.turbo/turbo-type-check.log +4 -0
- package/CHANGELOG.md +12 -0
- package/LICENSE +10 -0
- package/README.md +408 -0
- package/dist/src/apply-policy.d.ts +3 -0
- package/dist/src/apply-policy.d.ts.map +1 -0
- package/dist/src/apply-policy.js +24 -0
- package/dist/src/apply-policy.js.map +1 -0
- package/dist/src/apply-policy.specs.d.ts +2 -0
- package/dist/src/apply-policy.specs.d.ts.map +1 -0
- package/dist/src/apply-policy.specs.js +75 -0
- package/dist/src/apply-policy.specs.js.map +1 -0
- package/dist/src/commands/process-job-graph.d.ts +31 -0
- package/dist/src/commands/process-job-graph.d.ts.map +1 -0
- package/dist/src/commands/process-job-graph.js +64 -0
- package/dist/src/commands/process-job-graph.js.map +1 -0
- package/dist/src/commands/process-job-graph.specs.d.ts +2 -0
- package/dist/src/commands/process-job-graph.specs.d.ts.map +1 -0
- package/dist/src/commands/process-job-graph.specs.js +73 -0
- package/dist/src/commands/process-job-graph.specs.js.map +1 -0
- package/dist/src/evolve.d.ts +70 -0
- package/dist/src/evolve.d.ts.map +1 -0
- package/dist/src/evolve.js +82 -0
- package/dist/src/evolve.js.map +1 -0
- package/dist/src/evolve.specs.d.ts +2 -0
- package/dist/src/evolve.specs.d.ts.map +1 -0
- package/dist/src/evolve.specs.js +209 -0
- package/dist/src/evolve.specs.js.map +1 -0
- package/dist/src/graph-processor.d.ts +22 -0
- package/dist/src/graph-processor.d.ts.map +1 -0
- package/dist/src/graph-processor.js +82 -0
- package/dist/src/graph-processor.js.map +1 -0
- package/dist/src/graph-processor.specs.d.ts +2 -0
- package/dist/src/graph-processor.specs.d.ts.map +1 -0
- package/dist/src/graph-processor.specs.js +286 -0
- package/dist/src/graph-processor.specs.js.map +1 -0
- package/dist/src/graph-validator.d.ts +19 -0
- package/dist/src/graph-validator.d.ts.map +1 -0
- package/dist/src/graph-validator.js +65 -0
- package/dist/src/graph-validator.js.map +1 -0
- package/dist/src/graph-validator.specs.d.ts +2 -0
- package/dist/src/graph-validator.specs.d.ts.map +1 -0
- package/dist/src/graph-validator.specs.js +86 -0
- package/dist/src/graph-validator.specs.js.map +1 -0
- package/dist/src/handle-job-event.d.ts +16 -0
- package/dist/src/handle-job-event.d.ts.map +1 -0
- package/dist/src/handle-job-event.js +46 -0
- package/dist/src/handle-job-event.js.map +1 -0
- package/dist/src/handle-job-event.specs.d.ts +2 -0
- package/dist/src/handle-job-event.specs.d.ts.map +1 -0
- package/dist/src/handle-job-event.specs.js +136 -0
- package/dist/src/handle-job-event.specs.js.map +1 -0
- package/dist/src/index.d.ts +41 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +11 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/integration.specs.d.ts +2 -0
- package/dist/src/integration.specs.d.ts.map +1 -0
- package/dist/src/integration.specs.js +225 -0
- package/dist/src/integration.specs.js.map +1 -0
- package/dist/src/process-graph.d.ts +14 -0
- package/dist/src/process-graph.d.ts.map +1 -0
- package/dist/src/process-graph.js +26 -0
- package/dist/src/process-graph.js.map +1 -0
- package/dist/src/process-graph.specs.d.ts +2 -0
- package/dist/src/process-graph.specs.d.ts.map +1 -0
- package/dist/src/process-graph.specs.js +41 -0
- package/dist/src/process-graph.specs.js.map +1 -0
- package/dist/src/process-job-graph.e2e.specs.d.ts +2 -0
- package/dist/src/process-job-graph.e2e.specs.d.ts.map +1 -0
- package/dist/src/process-job-graph.e2e.specs.js +81 -0
- package/dist/src/process-job-graph.e2e.specs.js.map +1 -0
- package/dist/src/retry-manager.d.ts +10 -0
- package/dist/src/retry-manager.d.ts.map +1 -0
- package/dist/src/retry-manager.js +17 -0
- package/dist/src/retry-manager.js.map +1 -0
- package/dist/src/retry-manager.specs.d.ts +2 -0
- package/dist/src/retry-manager.specs.d.ts.map +1 -0
- package/dist/src/retry-manager.specs.js +55 -0
- package/dist/src/retry-manager.specs.js.map +1 -0
- package/dist/src/timeout-manager.d.ts +7 -0
- package/dist/src/timeout-manager.d.ts.map +1 -0
- package/dist/src/timeout-manager.js +25 -0
- package/dist/src/timeout-manager.js.map +1 -0
- package/dist/src/timeout-manager.specs.d.ts +2 -0
- package/dist/src/timeout-manager.specs.d.ts.map +1 -0
- package/dist/src/timeout-manager.specs.js +44 -0
- package/dist/src/timeout-manager.specs.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/ketchup-plan.md +31 -0
- package/package.json +25 -0
- package/src/apply-policy.specs.ts +85 -0
- package/src/apply-policy.ts +27 -0
- package/src/commands/process-job-graph.specs.ts +93 -0
- package/src/commands/process-job-graph.ts +80 -0
- package/src/evolve.specs.ts +235 -0
- package/src/evolve.ts +121 -0
- package/src/graph-processor.specs.ts +331 -0
- package/src/graph-processor.ts +121 -0
- package/src/graph-validator.specs.ts +105 -0
- package/src/graph-validator.ts +94 -0
- package/src/handle-job-event.specs.ts +154 -0
- package/src/handle-job-event.ts +59 -0
- package/src/index.ts +17 -0
- package/src/integration.specs.ts +249 -0
- package/src/process-graph.specs.ts +44 -0
- package/src/process-graph.ts +42 -0
- package/src/process-job-graph.e2e.specs.ts +121 -0
- package/src/retry-manager.specs.ts +66 -0
- package/src/retry-manager.ts +29 -0
- package/src/timeout-manager.specs.ts +55 -0
- package/src/timeout-manager.ts +34 -0
- package/tsconfig.json +9 -0
- package/vitest.config.ts +22 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
> @auto-engineer/job-graph-processor@1.12.1 test /home/runner/work/auto-engineer/auto-engineer/packages/job-graph-processor
|
|
3
|
+
> vitest run --reporter=dot
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
[1m[46m RUN [49m[22m [36mv3.2.4 [39m[90m/home/runner/work/auto-engineer/auto-engineer/packages/job-graph-processor[39m
|
|
7
|
+
|
|
8
|
+
[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m
|
|
9
|
+
|
|
10
|
+
[2m Test Files [22m [1m[32m11 passed[39m[22m[90m (11)[39m
|
|
11
|
+
[2m Tests [22m [1m[32m73 passed[39m[22m[90m (73)[39m
|
|
12
|
+
[2m Start at [22m 12:30:06
|
|
13
|
+
[2m Duration [22m 5.76s[2m (transform 1.36s, setup 0ms, collect 3.19s, tests 1.41s, environment 2ms, prepare 4.31s)[22m
|
|
14
|
+
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# @auto-engineer/job-graph-processor
|
|
2
|
+
|
|
3
|
+
## 1.12.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`6557224`](https://github.com/BeOnAuto/auto-engineer/commit/6557224ec6f51c704855e5058931e81ab1de1544) Thanks [@osamanar](https://github.com/osamanar)! - - Updated project dependency lock file to ensure consistent package installations
|
|
8
|
+
|
|
9
|
+
- [`cd5f56b`](https://github.com/BeOnAuto/auto-engineer/commit/cd5f56b01951cd27392c51a384706a8c2a7401c5) Thanks [@osamanar](https://github.com/osamanar)! - - Removed unused packages to keep the project lean and reduce maintenance overhead
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [[`6557224`](https://github.com/BeOnAuto/auto-engineer/commit/6557224ec6f51c704855e5058931e81ab1de1544), [`cd5f56b`](https://github.com/BeOnAuto/auto-engineer/commit/cd5f56b01951cd27392c51a384706a8c2a7401c5)]:
|
|
12
|
+
- @auto-engineer/message-bus@1.12.1
|
package/LICENSE
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Elastic License 2.0
|
|
2
|
+
|
|
3
|
+
Copyright 2024 Sam Hatoum
|
|
4
|
+
|
|
5
|
+
This software and associated documentation files (the "Software") are licensed under the Elastic License 2.0 (the "License"). You may not use this file except in compliance with the License.
|
|
6
|
+
|
|
7
|
+
You may obtain a copy of the License at:
|
|
8
|
+
https://www.elastic.co/licensing/elastic-license
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
# @auto-engineer/job-graph-processor
|
|
2
|
+
|
|
3
|
+
DAG-based job orchestration with dependency tracking, parallel dispatch, and configurable failure policies.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Purpose
|
|
8
|
+
|
|
9
|
+
Without `@auto-engineer/job-graph-processor`, you would have to manually track job dependencies, determine which jobs are ready to run, handle failures across dependency chains, and wire up event correlation to know when downstream work completes.
|
|
10
|
+
|
|
11
|
+
This package implements job graph processing as a pure event-sourced state machine. State is computed by folding events through an `evolve` function -- no mutable state, no side effects in the core logic. The `createGraphProcessor` factory wires the pure logic to a `MessageBus` for correlation-based event routing, so any domain event type can complete or fail a job as long as it carries the correct correlation ID.
|
|
12
|
+
|
|
13
|
+
The package exports a `COMMANDS` array, so `PipelineServer` discovers it via `PluginLoader` and exposes `ProcessJobGraph` as a dispatchable command.
|
|
14
|
+
|
|
15
|
+
## Key Concepts
|
|
16
|
+
|
|
17
|
+
- **Event-sourced state machine**: Graph state is derived by replaying events through a pure `evolve` reducer. No mutable state.
|
|
18
|
+
- **Correlation-based routing**: Jobs are tracked via `graph:<graphId>:<jobId>` correlation IDs. Downstream handlers don't need to know about the job graph.
|
|
19
|
+
- **Failure policies**: Three strategies (`halt`, `skip-dependents`, `continue`) control what happens when a job fails.
|
|
20
|
+
- **Maximum parallelism**: All jobs whose dependencies are satisfied dispatch simultaneously.
|
|
21
|
+
- **Target handlers required**: Each job's `target` field names a command handler that must also be registered as a plugin. The graph processor dispatches jobs by subscribing to correlated events on the messageBus, but the actual job execution depends on those target handlers existing and emitting events with the inherited correlation ID. Without matching handlers, the graph will dispatch but jobs will never complete.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pnpm add @auto-engineer/job-graph-processor
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
### 1. Register the Plugin
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
// auto.config.ts
|
|
37
|
+
export const plugins = [
|
|
38
|
+
'@auto-engineer/job-graph-processor',
|
|
39
|
+
'@auto-engineer/server-checks', // target handlers for your jobs
|
|
40
|
+
];
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 2. Send a Command
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
curl -X POST http://localhost:3000/command \
|
|
47
|
+
-H 'Content-Type: application/json' \
|
|
48
|
+
-d '{
|
|
49
|
+
"type": "ProcessJobGraph",
|
|
50
|
+
"data": {
|
|
51
|
+
"graphId": "deploy-1",
|
|
52
|
+
"jobs": [
|
|
53
|
+
{ "id": "build", "dependsOn": [], "target": "RunBuild", "payload": { "src": "./app" } },
|
|
54
|
+
{ "id": "test", "dependsOn": ["build"], "target": "RunTests", "payload": {} },
|
|
55
|
+
{ "id": "deploy", "dependsOn": ["test"], "target": "Deploy", "payload": {} }
|
|
56
|
+
],
|
|
57
|
+
"failurePolicy": "halt"
|
|
58
|
+
}
|
|
59
|
+
}'
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The server returns an ack. The handler creates a `createGraphProcessor(messageBus)`, validates the graph, and dispatches `build` immediately (no dependencies). When the `RunBuild` handler emits an event with `correlationId: 'graph:deploy-1:build'`, the processor dispatches `test`, and so on until `graph.completed` is published to the messageBus.
|
|
63
|
+
|
|
64
|
+
Each job's `target` must match a registered command handler name. If `RunBuild` is not registered as a plugin, the build job dispatches but never receives a completion event, so the graph stalls.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## How-to Guides
|
|
69
|
+
|
|
70
|
+
### Run via CLI
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
auto process:job-graph --graphId=g1 --jobs='[{"id":"a","dependsOn":[],"target":"build","payload":{}}]' --failurePolicy=halt
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Run Programmatically
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { COMMANDS } from '@auto-engineer/job-graph-processor';
|
|
80
|
+
|
|
81
|
+
const handler = COMMANDS[0];
|
|
82
|
+
const result = await handler.handle(
|
|
83
|
+
{
|
|
84
|
+
type: 'ProcessJobGraph',
|
|
85
|
+
data: {
|
|
86
|
+
graphId: 'g1',
|
|
87
|
+
jobs: [{ id: 'a', dependsOn: [], target: 'build', payload: {} }],
|
|
88
|
+
failurePolicy: 'halt',
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{ messageBus },
|
|
92
|
+
);
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The second argument is the pipeline context. The handler extracts `messageBus` from it. Without a messageBus, the handler returns `graph.failed` with reason `messageBus not available in context`.
|
|
96
|
+
|
|
97
|
+
### Handle Errors
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
if (result.type === 'graph.failed') {
|
|
101
|
+
console.error(result.data.reason);
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Listen for Graph Completion
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
bus.subscribeToEvent('graph.completed', {
|
|
109
|
+
name: 'onComplete',
|
|
110
|
+
handle: (event) => console.log('Graph done:', event.data.graphId),
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Complete a Job via Correlated Events
|
|
115
|
+
|
|
116
|
+
Downstream handlers emit their normal domain events. The graph processor picks them up via correlation ID:
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
await bus.publishEvent({
|
|
120
|
+
type: 'BuildCompleted',
|
|
121
|
+
data: { output: 'ok' },
|
|
122
|
+
correlationId: 'graph:deploy-pipeline:build',
|
|
123
|
+
});
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Any event without an `error` field in its data is treated as success. Any event with an `error` field is treated as failure.
|
|
127
|
+
|
|
128
|
+
### Handle Failures with Policies
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
processor.submit({
|
|
132
|
+
type: 'ProcessGraph',
|
|
133
|
+
data: {
|
|
134
|
+
graphId: 'g1',
|
|
135
|
+
jobs: [
|
|
136
|
+
{ id: 'a', dependsOn: [], target: 'build', payload: {} },
|
|
137
|
+
{ id: 'b', dependsOn: ['a'], target: 'test', payload: {} },
|
|
138
|
+
{ id: 'c', dependsOn: [], target: 'lint', payload: {} },
|
|
139
|
+
],
|
|
140
|
+
failurePolicy: 'skip-dependents',
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
| Policy | When `a` Fails |
|
|
146
|
+
| ----------------- | -------------------------------------------------------- |
|
|
147
|
+
| `halt` | `b` and `c` are skipped. Graph completes immediately. |
|
|
148
|
+
| `skip-dependents` | `b` is skipped (depends on `a`). `c` continues. |
|
|
149
|
+
| `continue` | `b` is dispatched anyway. Failure is treated as resolved. |
|
|
150
|
+
|
|
151
|
+
### Use the Pure State Machine Directly
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
import { evolve, getReadyJobs, initialState, isGraphComplete } from '@auto-engineer/job-graph-processor';
|
|
155
|
+
|
|
156
|
+
let state = evolve(initialState(), {
|
|
157
|
+
type: 'GraphSubmitted',
|
|
158
|
+
data: {
|
|
159
|
+
graphId: 'g1',
|
|
160
|
+
jobs: [
|
|
161
|
+
{ id: 'a', dependsOn: [], target: 'build', payload: {} },
|
|
162
|
+
{ id: 'b', dependsOn: ['a'], target: 'test', payload: {} },
|
|
163
|
+
],
|
|
164
|
+
failurePolicy: 'halt',
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
getReadyJobs(state); // ['a']
|
|
169
|
+
isGraphComplete(state); // false
|
|
170
|
+
|
|
171
|
+
state = evolve(state, { type: 'JobDispatched', data: { jobId: 'a', target: 'build', correlationId: 'graph:g1:a' } });
|
|
172
|
+
state = evolve(state, { type: 'JobSucceeded', data: { jobId: 'a', result: { output: 'ok' } } });
|
|
173
|
+
|
|
174
|
+
getReadyJobs(state); // ['b']
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Add Per-Job Timeouts
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
import { createTimeoutManager } from '@auto-engineer/job-graph-processor';
|
|
181
|
+
|
|
182
|
+
const timeouts = createTimeoutManager((jobId) => {
|
|
183
|
+
// Handle timeout -- emit JobTimedOut event
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
timeouts.start('build', 30000);
|
|
187
|
+
timeouts.clear('build'); // Cancel if job completes in time
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Add Retry with Exponential Backoff
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
import { createRetryManager } from '@auto-engineer/job-graph-processor';
|
|
194
|
+
|
|
195
|
+
const retries = createRetryManager((jobId, attempt) => {
|
|
196
|
+
// Re-dispatch the job
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
const config = { maxRetries: 3, backoffMs: 100, maxBackoffMs: 5000 };
|
|
200
|
+
const exhausted = retries.recordFailure('build', config);
|
|
201
|
+
// false: will retry after 100ms
|
|
202
|
+
// Subsequent failures: 200ms, 400ms, then returns true (exhausted)
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## API Reference
|
|
208
|
+
|
|
209
|
+
### Exports
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
import {
|
|
213
|
+
COMMANDS,
|
|
214
|
+
createGraphProcessor,
|
|
215
|
+
evolve,
|
|
216
|
+
initialState,
|
|
217
|
+
getReadyJobs,
|
|
218
|
+
getTransitiveDependents,
|
|
219
|
+
isGraphComplete,
|
|
220
|
+
applyPolicy,
|
|
221
|
+
validateGraph,
|
|
222
|
+
classifyJobEvent,
|
|
223
|
+
handleJobEvent,
|
|
224
|
+
isJobFailure,
|
|
225
|
+
parseCorrelationId,
|
|
226
|
+
handleProcessGraph,
|
|
227
|
+
createTimeoutManager,
|
|
228
|
+
createRetryManager,
|
|
229
|
+
} from '@auto-engineer/job-graph-processor';
|
|
230
|
+
|
|
231
|
+
import type {
|
|
232
|
+
GraphState,
|
|
233
|
+
JobStatus,
|
|
234
|
+
FailurePolicy,
|
|
235
|
+
JobGraphEvent,
|
|
236
|
+
Job,
|
|
237
|
+
RetryConfig,
|
|
238
|
+
RetryManager,
|
|
239
|
+
TimeoutManager,
|
|
240
|
+
} from '@auto-engineer/job-graph-processor';
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Commands
|
|
244
|
+
|
|
245
|
+
| Command | CLI Alias | Description |
|
|
246
|
+
| ----------------- | ------------------ | -------------------------------------------------------------------------- |
|
|
247
|
+
| `ProcessJobGraph` | `process:job-graph`| Process a DAG of jobs with dependency tracking and failure policies |
|
|
248
|
+
|
|
249
|
+
#### Command Fields
|
|
250
|
+
|
|
251
|
+
| Field | Type | Required | Description |
|
|
252
|
+
| --------------- | --------------- | -------- | ------------------------------------------------------------------- |
|
|
253
|
+
| `graphId` | `string` | yes | Unique identifier for the graph |
|
|
254
|
+
| `jobs` | `Job[]` | yes | Array of jobs with dependencies. Each job's `target` must match a registered command handler |
|
|
255
|
+
| `failurePolicy` | `FailurePolicy` | yes | How to handle failures: `halt`, `skip-dependents`, or `continue` |
|
|
256
|
+
|
|
257
|
+
#### Events Produced
|
|
258
|
+
|
|
259
|
+
| Event | When |
|
|
260
|
+
| ------------------ | --------------------------------------- |
|
|
261
|
+
| `graph.dispatching`| Graph validated, ready jobs dispatched |
|
|
262
|
+
| `graph.failed` | Validation error or missing messageBus |
|
|
263
|
+
| `graph.completed` | All jobs reached terminal status (published to messageBus, not returned from handler) |
|
|
264
|
+
|
|
265
|
+
### Functions
|
|
266
|
+
|
|
267
|
+
#### `createGraphProcessor(messageBus): { submit }`
|
|
268
|
+
|
|
269
|
+
Stateful processor that wires the pure state machine to a MessageBus. Tracks active graphs, subscribes to correlation events, dispatches ready jobs, and publishes `graph.completed`.
|
|
270
|
+
|
|
271
|
+
#### `evolve(state, event): GraphState`
|
|
272
|
+
|
|
273
|
+
Pure reducer. Applies a `JobGraphEvent` to a `GraphState` and returns a new state.
|
|
274
|
+
|
|
275
|
+
#### `initialState(): GraphState`
|
|
276
|
+
|
|
277
|
+
Returns `{ status: 'pending' }`.
|
|
278
|
+
|
|
279
|
+
#### `getReadyJobs(state): string[]`
|
|
280
|
+
|
|
281
|
+
Returns job IDs whose dependencies are all resolved (respects `continue` policy).
|
|
282
|
+
|
|
283
|
+
#### `isGraphComplete(state): boolean`
|
|
284
|
+
|
|
285
|
+
Returns `true` when every job has reached a terminal status.
|
|
286
|
+
|
|
287
|
+
#### `getTransitiveDependents(state, jobId): string[]`
|
|
288
|
+
|
|
289
|
+
BFS traversal returning all downstream dependents of a job.
|
|
290
|
+
|
|
291
|
+
#### `validateGraph(jobs): { valid: true } | { valid: false, error: string }`
|
|
292
|
+
|
|
293
|
+
Validates DAG structure: unique IDs, valid dependency references, no self-loops, no cycles.
|
|
294
|
+
|
|
295
|
+
#### `applyPolicy(state, failedJobId): JobGraphEvent[]`
|
|
296
|
+
|
|
297
|
+
Returns `JobSkipped` events based on the graph's failure policy.
|
|
298
|
+
|
|
299
|
+
#### `classifyJobEvent(event): JobGraphEvent | null`
|
|
300
|
+
|
|
301
|
+
Maps a domain event (with correlation ID) to a typed `JobSucceeded` or `JobFailed` event.
|
|
302
|
+
|
|
303
|
+
#### `handleJobEvent(state, event): { events, readyJobs, graphComplete } | null`
|
|
304
|
+
|
|
305
|
+
Full orchestration: classifies event, evolves state, applies failure policy, returns results.
|
|
306
|
+
|
|
307
|
+
#### `parseCorrelationId(id): { graphId, jobId } | null`
|
|
308
|
+
|
|
309
|
+
Extracts graph and job identifiers from a `graph:<graphId>:<jobId>` string.
|
|
310
|
+
|
|
311
|
+
#### `isJobFailure(event): boolean`
|
|
312
|
+
|
|
313
|
+
Returns `true` if the event's data contains an `error` field.
|
|
314
|
+
|
|
315
|
+
#### `createTimeoutManager(onTimeout): TimeoutManager`
|
|
316
|
+
|
|
317
|
+
Per-job timeout tracking with `start`, `clear`, and `clearAll`.
|
|
318
|
+
|
|
319
|
+
#### `createRetryManager(onRetry): RetryManager`
|
|
320
|
+
|
|
321
|
+
Exponential backoff retry with `recordFailure(jobId, config)` returning `true` when exhausted.
|
|
322
|
+
|
|
323
|
+
### Interfaces
|
|
324
|
+
|
|
325
|
+
#### `Job`
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
interface Job {
|
|
329
|
+
id: string;
|
|
330
|
+
dependsOn: readonly string[];
|
|
331
|
+
target: string;
|
|
332
|
+
payload: unknown;
|
|
333
|
+
timeoutMs?: number;
|
|
334
|
+
retries?: number;
|
|
335
|
+
backoffMs?: number;
|
|
336
|
+
maxBackoffMs?: number;
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
#### `FailurePolicy`
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
type FailurePolicy = 'halt' | 'skip-dependents' | 'continue';
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
#### `JobGraphEvent`
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
type JobGraphEvent =
|
|
350
|
+
| { type: 'GraphSubmitted'; data: { graphId: string; jobs: readonly Job[]; failurePolicy: FailurePolicy } }
|
|
351
|
+
| { type: 'JobDispatched'; data: { jobId: string; target: string; correlationId: string } }
|
|
352
|
+
| { type: 'JobSucceeded'; data: { jobId: string; result?: unknown } }
|
|
353
|
+
| { type: 'JobFailed'; data: { jobId: string; error: string } }
|
|
354
|
+
| { type: 'JobSkipped'; data: { jobId: string; reason: string } }
|
|
355
|
+
| { type: 'JobTimedOut'; data: { jobId: string; timeoutMs: number } };
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## Architecture
|
|
361
|
+
|
|
362
|
+
```
|
|
363
|
+
src/
|
|
364
|
+
├── index.ts Barrel exports + COMMANDS array
|
|
365
|
+
├── commands/
|
|
366
|
+
│ └── process-job-graph.ts Pipeline command handler (ProcessJobGraph)
|
|
367
|
+
├── evolve.ts Pure event-sourced state machine
|
|
368
|
+
├── graph-validator.ts DAG validation (cycles, duplicates, refs)
|
|
369
|
+
├── handle-job-event.ts Domain event classification and orchestration
|
|
370
|
+
├── apply-policy.ts Failure policy engine (halt/skip-dependents/continue)
|
|
371
|
+
├── graph-processor.ts Stateful MessageBus coordinator
|
|
372
|
+
├── process-graph.ts Standalone command handler
|
|
373
|
+
├── timeout-manager.ts Per-job setTimeout wrapper
|
|
374
|
+
└── retry-manager.ts Exponential backoff retry
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
```mermaid
|
|
378
|
+
flowchart LR
|
|
379
|
+
Submit[submit command] --> Validate[validateGraph]
|
|
380
|
+
Validate --> Evolve[evolve: GraphSubmitted]
|
|
381
|
+
Evolve --> Ready[getReadyJobs]
|
|
382
|
+
Ready --> Dispatch[dispatch via MessageBus]
|
|
383
|
+
Dispatch --> Correlate[onCorrelationPrefix]
|
|
384
|
+
Correlate --> Classify[classifyJobEvent]
|
|
385
|
+
Classify --> EvolveAgain[evolve: JobSucceeded/Failed]
|
|
386
|
+
EvolveAgain --> Policy{failure?}
|
|
387
|
+
Policy -->|yes| Apply[applyPolicy]
|
|
388
|
+
Policy -->|no| ReadyAgain[getReadyJobs]
|
|
389
|
+
Apply --> ReadyAgain
|
|
390
|
+
ReadyAgain --> Complete{all terminal?}
|
|
391
|
+
Complete -->|yes| Done[graph.completed]
|
|
392
|
+
Complete -->|no| Dispatch
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### Dependencies
|
|
396
|
+
|
|
397
|
+
**Monorepo:**
|
|
398
|
+
|
|
399
|
+
| Package | Usage |
|
|
400
|
+
| ---------------------------- | ---------------------------------- |
|
|
401
|
+
| `@auto-engineer/message-bus` | Correlation subscriptions, pub/sub |
|
|
402
|
+
|
|
403
|
+
**External:**
|
|
404
|
+
|
|
405
|
+
| Package | Usage |
|
|
406
|
+
| ------------------------- | ---------------------- |
|
|
407
|
+
| `@event-driven-io/emmett` | Event type import only |
|
|
408
|
+
| `nanoid` | Unique ID generation |
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-policy.d.ts","sourceRoot":"","sources":["../../src/apply-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG1D,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,aAAa,EAAE,CAuBnF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { getTransitiveDependents } from './evolve.js';
|
|
2
|
+
export function applyPolicy(state, failedJobId) {
|
|
3
|
+
if (state.status !== 'processing')
|
|
4
|
+
return [];
|
|
5
|
+
switch (state.failurePolicy) {
|
|
6
|
+
case 'continue':
|
|
7
|
+
return [];
|
|
8
|
+
case 'skip-dependents':
|
|
9
|
+
return getTransitiveDependents(state, failedJobId).map((id) => ({
|
|
10
|
+
type: 'JobSkipped',
|
|
11
|
+
data: { jobId: id, reason: 'dependency failed' },
|
|
12
|
+
}));
|
|
13
|
+
case 'halt': {
|
|
14
|
+
const events = [];
|
|
15
|
+
for (const [id, job] of state.jobs) {
|
|
16
|
+
if (job.status === 'pending') {
|
|
17
|
+
events.push({ type: 'JobSkipped', data: { jobId: id, reason: 'halt policy' } });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return events;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=apply-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-policy.js","sourceRoot":"","sources":["../../src/apply-policy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAEnD,MAAM,UAAU,WAAW,CAAC,KAAiB,EAAE,WAAmB;IAChE,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY;QAAE,OAAO,EAAE,CAAC;IAE7C,QAAQ,KAAK,CAAC,aAAa,EAAE,CAAC;QAC5B,KAAK,UAAU;YACb,OAAO,EAAE,CAAC;QACZ,KAAK,iBAAiB;YACpB,OAAO,uBAAuB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,GAAG,CACpD,CAAC,EAAE,EAAiB,EAAE,CAAC,CAAC;gBACtB,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,mBAAmB,EAAE;aACjD,CAAC,CACH,CAAC;QACJ,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,MAAM,GAAoB,EAAE,CAAC;YACnC,KAAK,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACnC,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oBAC7B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,CAAC,CAAC;gBAClF,CAAC;YACH,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-policy.specs.d.ts","sourceRoot":"","sources":["../../src/apply-policy.specs.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { applyPolicy } from './apply-policy.js';
|
|
3
|
+
import { evolve, initialState } from './evolve.js';
|
|
4
|
+
describe('applyPolicy', () => {
|
|
5
|
+
it('returns empty array before graph submission', () => {
|
|
6
|
+
const events = applyPolicy(initialState(), 'a');
|
|
7
|
+
expect(events).toEqual([]);
|
|
8
|
+
});
|
|
9
|
+
it('halt policy skips all pending jobs when a job fails', () => {
|
|
10
|
+
let state = evolve(initialState(), {
|
|
11
|
+
type: 'GraphSubmitted',
|
|
12
|
+
data: {
|
|
13
|
+
graphId: 'g1',
|
|
14
|
+
jobs: [
|
|
15
|
+
{ id: 'a', dependsOn: [], target: 'build', payload: {} },
|
|
16
|
+
{ id: 'b', dependsOn: ['a'], target: 'test', payload: {} },
|
|
17
|
+
{ id: 'c', dependsOn: ['a'], target: 'lint', payload: {} },
|
|
18
|
+
],
|
|
19
|
+
failurePolicy: 'halt',
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
state = evolve(state, {
|
|
23
|
+
type: 'JobDispatched',
|
|
24
|
+
data: { jobId: 'a', target: 'build', correlationId: 'graph:g1:a' },
|
|
25
|
+
});
|
|
26
|
+
state = evolve(state, { type: 'JobFailed', data: { jobId: 'a', error: 'build error' } });
|
|
27
|
+
const events = applyPolicy(state, 'a');
|
|
28
|
+
expect(events).toEqual([
|
|
29
|
+
{ type: 'JobSkipped', data: { jobId: 'b', reason: 'halt policy' } },
|
|
30
|
+
{ type: 'JobSkipped', data: { jobId: 'c', reason: 'halt policy' } },
|
|
31
|
+
]);
|
|
32
|
+
});
|
|
33
|
+
it('skip-dependents policy skips only transitive dependents of failed job', () => {
|
|
34
|
+
let state = evolve(initialState(), {
|
|
35
|
+
type: 'GraphSubmitted',
|
|
36
|
+
data: {
|
|
37
|
+
graphId: 'g1',
|
|
38
|
+
jobs: [
|
|
39
|
+
{ id: 'a', dependsOn: [], target: 'build', payload: {} },
|
|
40
|
+
{ id: 'b', dependsOn: ['a'], target: 'test', payload: {} },
|
|
41
|
+
{ id: 'c', dependsOn: [], target: 'lint', payload: {} },
|
|
42
|
+
],
|
|
43
|
+
failurePolicy: 'skip-dependents',
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
state = evolve(state, {
|
|
47
|
+
type: 'JobDispatched',
|
|
48
|
+
data: { jobId: 'a', target: 'build', correlationId: 'graph:g1:a' },
|
|
49
|
+
});
|
|
50
|
+
state = evolve(state, { type: 'JobFailed', data: { jobId: 'a', error: 'build error' } });
|
|
51
|
+
const events = applyPolicy(state, 'a');
|
|
52
|
+
expect(events).toEqual([{ type: 'JobSkipped', data: { jobId: 'b', reason: 'dependency failed' } }]);
|
|
53
|
+
});
|
|
54
|
+
it('continue policy returns no skip events', () => {
|
|
55
|
+
let state = evolve(initialState(), {
|
|
56
|
+
type: 'GraphSubmitted',
|
|
57
|
+
data: {
|
|
58
|
+
graphId: 'g1',
|
|
59
|
+
jobs: [
|
|
60
|
+
{ id: 'a', dependsOn: [], target: 'build', payload: {} },
|
|
61
|
+
{ id: 'b', dependsOn: ['a'], target: 'test', payload: {} },
|
|
62
|
+
],
|
|
63
|
+
failurePolicy: 'continue',
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
state = evolve(state, {
|
|
67
|
+
type: 'JobDispatched',
|
|
68
|
+
data: { jobId: 'a', target: 'build', correlationId: 'graph:g1:a' },
|
|
69
|
+
});
|
|
70
|
+
state = evolve(state, { type: 'JobFailed', data: { jobId: 'a', error: 'build error' } });
|
|
71
|
+
const events = applyPolicy(state, 'a');
|
|
72
|
+
expect(events).toEqual([]);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
//# sourceMappingURL=apply-policy.specs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-policy.specs.js","sourceRoot":"","sources":["../../src/apply-policy.specs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Command, Event } from '@auto-engineer/message-bus';
|
|
2
|
+
export declare const commandHandler: {
|
|
3
|
+
name: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
alias: string;
|
|
6
|
+
description: string;
|
|
7
|
+
category: string;
|
|
8
|
+
icon: string;
|
|
9
|
+
fields: {
|
|
10
|
+
graphId: {
|
|
11
|
+
description: string;
|
|
12
|
+
required: boolean;
|
|
13
|
+
};
|
|
14
|
+
jobs: {
|
|
15
|
+
description: string;
|
|
16
|
+
required: boolean;
|
|
17
|
+
};
|
|
18
|
+
failurePolicy: {
|
|
19
|
+
description: string;
|
|
20
|
+
required: boolean;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
examples: string[];
|
|
24
|
+
events: {
|
|
25
|
+
name: string;
|
|
26
|
+
displayName: string;
|
|
27
|
+
}[];
|
|
28
|
+
handle: (command: Command, context?: unknown) => Promise<Event | Event[]>;
|
|
29
|
+
};
|
|
30
|
+
export default commandHandler;
|
|
31
|
+
//# sourceMappingURL=process-job-graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-job-graph.d.ts","sourceRoot":"","sources":["../../../src/commands/process-job-graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAc,MAAM,4BAA4B,CAAC;AAkC7E,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;sBA6BD,OAAO,YAAY,OAAO,KAAG,OAAO,CAAC,KAAK,GAAG,KAAK,EAAE,CAAC;CAc9E,CAAC;AAEF,eAAe,cAAc,CAAC"}
|