@oisincoveney/pipeline 2.11.1 → 2.11.2
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.
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//#region src/run-control/run-state-lock.ts
|
|
2
|
+
/**
|
|
3
|
+
* Process-wide serialization for critical sections that read, write, or
|
|
4
|
+
* temporarily relocate the `.pipeline/runs` run-state directory.
|
|
5
|
+
*
|
|
6
|
+
* The mechanical-check builtins (`lint`, `fallow`) hide `.pipeline/runs` for the
|
|
7
|
+
* duration of their command so those tools do not scan supervisor run-state
|
|
8
|
+
* (see builtins.ts `hidePipelineRunsDirectory`). Under the parallel
|
|
9
|
+
* mechanical-checks fan-out that hide window overlapped the run-control
|
|
10
|
+
* reporter's persistence of sibling node-status events, which then observed a
|
|
11
|
+
* momentarily-missing run directory and failed the whole run with
|
|
12
|
+
* "Run <id> does not exist". This lock makes the hide window and run-state
|
|
13
|
+
* persistence mutually exclusive without serializing any unrelated parallel
|
|
14
|
+
* work: only the run-state critical sections contend for it.
|
|
15
|
+
*/
|
|
16
|
+
let chain = Promise.resolve();
|
|
17
|
+
/**
|
|
18
|
+
* Acquire the lock, resolving with a release function once every previously
|
|
19
|
+
* queued holder has released. Callers MUST invoke the returned release exactly
|
|
20
|
+
* once (use `withRunStateLock` unless you must span non-promise boundaries, as
|
|
21
|
+
* the builtin hide/restore does).
|
|
22
|
+
*/
|
|
23
|
+
function acquireRunStateLock() {
|
|
24
|
+
const previous = chain;
|
|
25
|
+
let release = () => {};
|
|
26
|
+
chain = new Promise((resolve) => {
|
|
27
|
+
release = resolve;
|
|
28
|
+
});
|
|
29
|
+
return previous.then(() => release);
|
|
30
|
+
}
|
|
31
|
+
/** Run `fn` while holding the run-state lock, releasing on success or failure. */
|
|
32
|
+
async function withRunStateLock(fn) {
|
|
33
|
+
const release = await acquireRunStateLock();
|
|
34
|
+
try {
|
|
35
|
+
return await fn();
|
|
36
|
+
} finally {
|
|
37
|
+
release();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { acquireRunStateLock, withRunStateLock };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { withRunStateLock } from "./run-state-lock.js";
|
|
1
2
|
import { updateNodeSessionEffect, updateNodeStatusEffect, updateRunStatusEffect } from "./store.js";
|
|
2
3
|
import { Effect } from "effect";
|
|
3
4
|
import { isAbsolute, join } from "node:path";
|
|
@@ -23,7 +24,7 @@ function createRunStoreRuntimeReporterRuntime(input) {
|
|
|
23
24
|
activeHookPreviousStatuses,
|
|
24
25
|
observedNodeStatuses
|
|
25
26
|
});
|
|
26
|
-
writeChain = writeChain.then(() => Effect.runPromise(persistRuntimeEventEffect(input, event, projection, now)));
|
|
27
|
+
writeChain = writeChain.then(() => withRunStateLock(() => Effect.runPromise(persistRuntimeEventEffect(input, event, projection, now))));
|
|
27
28
|
};
|
|
28
29
|
const flushEffect = () => Effect.tryPromise({
|
|
29
30
|
catch: (error) => error,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { parseJson } from "../../safe-json.js";
|
|
2
|
+
import { acquireRunStateLock } from "../../run-control/run-state-lock.js";
|
|
2
3
|
import { executeDrainMergeBuiltin } from "../drain-merge/drain-merge.js";
|
|
3
4
|
import "../drain-merge/index.js";
|
|
4
5
|
import { CommandExecutor, CommandExecutorLive } from "../services/command-executor-service.js";
|
|
@@ -95,7 +96,7 @@ function executeVisibleProjectCommand(command, context) {
|
|
|
95
96
|
});
|
|
96
97
|
}
|
|
97
98
|
function withHiddenPipelineRuns(worktreePath, effect) {
|
|
98
|
-
return Effect.acquireUseRelease(Effect.sync(() => hidePipelineRunsDirectory(worktreePath)), () => effect, (hiddenRuns) => Effect.sync(() => hiddenRuns?.restore()));
|
|
99
|
+
return Effect.acquireUseRelease(Effect.promise(() => acquireRunStateLock()), () => Effect.acquireUseRelease(Effect.sync(() => hidePipelineRunsDirectory(worktreePath)), () => effect, (hiddenRuns) => Effect.sync(() => hiddenRuns?.restore())), (release) => Effect.sync(() => release()));
|
|
99
100
|
}
|
|
100
101
|
function resolveRequiredScriptCommand(worktreePath, envName, scriptName) {
|
|
101
102
|
return Effect.gen(function* () {
|
package/package.json
CHANGED
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
"prepack": "bun run build:cli"
|
|
128
128
|
},
|
|
129
129
|
"type": "module",
|
|
130
|
-
"version": "2.11.
|
|
130
|
+
"version": "2.11.2",
|
|
131
131
|
"description": "Config-driven multi-agent pipeline runner for repository work",
|
|
132
132
|
"main": "./dist/index.js",
|
|
133
133
|
"types": "./dist/index.d.ts",
|