taskflow-core 0.3.0-beta.1.2 → 1.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.
- package/README.md +34 -25
- package/dist/build-info.json +2 -2
- package/dist/control-execution.d.ts +6 -0
- package/dist/control-execution.d.ts.map +1 -0
- package/dist/control-execution.js +5 -0
- package/dist/control-execution.js.map +1 -0
- package/dist/exec/step-kinds.d.ts.map +1 -1
- package/dist/exec/step-kinds.js +1 -0
- package/dist/exec/step-kinds.js.map +1 -1
- package/dist/exec/step.d.ts.map +1 -1
- package/dist/exec/step.js +1 -0
- package/dist/exec/step.js.map +1 -1
- package/dist/host/runner-types.d.ts +3 -0
- package/dist/host/runner-types.d.ts.map +1 -1
- package/dist/legacy-writer-lifecycle.d.ts +22 -0
- package/dist/legacy-writer-lifecycle.d.ts.map +1 -0
- package/dist/legacy-writer-lifecycle.js +205 -0
- package/dist/legacy-writer-lifecycle.js.map +1 -0
- package/dist/persistent-mutex.d.ts +9 -0
- package/dist/persistent-mutex.d.ts.map +1 -0
- package/dist/persistent-mutex.js +27 -0
- package/dist/persistent-mutex.js.map +1 -0
- package/dist/resources/mutex-bootstrap.d.ts +12 -0
- package/dist/resources/mutex-bootstrap.d.ts.map +1 -0
- package/dist/resources/mutex-bootstrap.js +176 -0
- package/dist/resources/mutex-bootstrap.js.map +1 -0
- package/dist/resources/persistence.d.ts.map +1 -1
- package/dist/resources/persistence.js +145 -77
- package/dist/resources/persistence.js.map +1 -1
- package/dist/resume.d.ts +21 -1
- package/dist/resume.d.ts.map +1 -1
- package/dist/resume.js +75 -1
- package/dist/resume.js.map +1 -1
- package/dist/runner-core.d.ts +5 -0
- package/dist/runner-core.d.ts.map +1 -1
- package/dist/runner-core.js +40 -3
- package/dist/runner-core.js.map +1 -1
- package/dist/runtime.d.ts +6 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +28 -0
- package/dist/runtime.js.map +1 -1
- package/dist/store.d.ts +17 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/** Explicit upgrade boundary for a closed set of directly supervised writers.
|
|
2
|
+
*
|
|
3
|
+
* This gate must own a NEW namespace before any old writer is admitted. It is
|
|
4
|
+
* not an attestation API for an existing installation. A restarted supervisor
|
|
5
|
+
* cannot recover proof of exclusion from PIDs or an empty queue; it must remain
|
|
6
|
+
* stopped for operator/service-manager reconciliation. Writers that fork other
|
|
7
|
+
* writers must be supervised at that outer service boundary instead.
|
|
8
|
+
*/
|
|
9
|
+
import * as fs from "node:fs";
|
|
10
|
+
import * as path from "node:path";
|
|
11
|
+
import { randomUUID } from "node:crypto";
|
|
12
|
+
import { spawn } from "node:child_process";
|
|
13
|
+
import { bindMutexQueue } from "./resources/mutex-bootstrap.js";
|
|
14
|
+
import { defaultProcessIdentity } from "./resources/persistence.js";
|
|
15
|
+
const fault = (detail) => new Error(`TFWS_LEGACY_EXCLUSION_REQUIRED: ${detail}`);
|
|
16
|
+
const same = (a, b) => a.dev === b.dev && a.ino === b.ino;
|
|
17
|
+
function directory(file) {
|
|
18
|
+
const stat = fs.lstatSync(file);
|
|
19
|
+
if (!stat.isDirectory() || stat.isSymbolicLink())
|
|
20
|
+
throw fault("namespace must be a real directory");
|
|
21
|
+
return { dev: stat.dev, ino: stat.ino };
|
|
22
|
+
}
|
|
23
|
+
function syncDirectory(file) {
|
|
24
|
+
const fd = fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
|
|
25
|
+
try {
|
|
26
|
+
fs.fsyncSync(fd);
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
fs.closeSync(fd);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function durableExclusive(file, value) {
|
|
33
|
+
const fd = fs.openSync(file, "wx", 0o600);
|
|
34
|
+
try {
|
|
35
|
+
fs.writeFileSync(fd, JSON.stringify(value));
|
|
36
|
+
fs.fsyncSync(fd);
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
fs.closeSync(fd);
|
|
40
|
+
}
|
|
41
|
+
syncDirectory(path.dirname(file));
|
|
42
|
+
}
|
|
43
|
+
export class LegacyWriterLifecycle {
|
|
44
|
+
directory;
|
|
45
|
+
lockPath;
|
|
46
|
+
#root;
|
|
47
|
+
#parent;
|
|
48
|
+
#genesis;
|
|
49
|
+
#genesisBytes;
|
|
50
|
+
#generation = randomUUID();
|
|
51
|
+
#children = new Set();
|
|
52
|
+
#closed = false;
|
|
53
|
+
#closedEvidence;
|
|
54
|
+
#draining = false;
|
|
55
|
+
#result;
|
|
56
|
+
#completionProof = new Map();
|
|
57
|
+
constructor(scope) {
|
|
58
|
+
this.directory = path.resolve(scope);
|
|
59
|
+
this.lockPath = path.join(this.directory, "writer.lock");
|
|
60
|
+
this.#parent = directory(path.dirname(this.directory));
|
|
61
|
+
// No recursive mkdir and no adoption, including after a supervisor crash.
|
|
62
|
+
try {
|
|
63
|
+
fs.mkdirSync(this.directory, { mode: 0o700 });
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
throw fault(`new managed namespace required (${error.code ?? "unknown"})`);
|
|
67
|
+
}
|
|
68
|
+
this.#root = directory(this.directory);
|
|
69
|
+
const record = path.join(this.directory, "lifecycle.json");
|
|
70
|
+
this.#genesisBytes = JSON.stringify({ version: 1, generation: this.#generation, root: this.#root, owner: defaultProcessIdentity() });
|
|
71
|
+
durableExclusive(record, JSON.parse(this.#genesisBytes));
|
|
72
|
+
this.#genesis = fs.lstatSync(record);
|
|
73
|
+
syncDirectory(path.dirname(this.directory));
|
|
74
|
+
}
|
|
75
|
+
static create(scopeDirectory) {
|
|
76
|
+
return new LegacyWriterLifecycle(scopeDirectory);
|
|
77
|
+
}
|
|
78
|
+
#assertIdentity() {
|
|
79
|
+
try {
|
|
80
|
+
if (!same(directory(path.dirname(this.directory)), this.#parent) || !same(directory(this.directory), this.#root))
|
|
81
|
+
throw fault("namespace replaced");
|
|
82
|
+
const record = path.join(this.directory, "lifecycle.json");
|
|
83
|
+
const fd = fs.openSync(record, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
|
|
84
|
+
try {
|
|
85
|
+
const stat = fs.fstatSync(fd);
|
|
86
|
+
if (!stat.isFile() || !same(stat, this.#genesis) || !same(stat, fs.lstatSync(record)) || fs.readFileSync(fd, "utf8") !== this.#genesisBytes)
|
|
87
|
+
throw fault("lifecycle evidence replaced");
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
fs.closeSync(fd);
|
|
91
|
+
}
|
|
92
|
+
if (this.#closed) {
|
|
93
|
+
const closed = path.join(this.directory, "admission.closed.json");
|
|
94
|
+
const closedFd = fs.openSync(closed, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
|
|
95
|
+
try {
|
|
96
|
+
const stat = fs.fstatSync(closedFd);
|
|
97
|
+
if (!this.#closedEvidence || !stat.isFile() || !same(stat, this.#closedEvidence) || !same(stat, fs.lstatSync(closed)) ||
|
|
98
|
+
fs.readFileSync(closedFd, "utf8") !== JSON.stringify({ generation: this.#generation }))
|
|
99
|
+
throw fault("admission closure evidence replaced");
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
fs.closeSync(closedFd);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
throw fault(`lifecycle evidence unavailable: ${error.message}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** Only direct child writers are covered. Do not use for daemonizing programs.
|
|
111
|
+
* The caller may request shutdown, but this module never signals a process. */
|
|
112
|
+
spawn(command, args = [], options = {}) {
|
|
113
|
+
this.#assertIdentity();
|
|
114
|
+
if (this.#closed)
|
|
115
|
+
throw fault("writer admission is closed");
|
|
116
|
+
if (options.detached || options.shell)
|
|
117
|
+
throw fault("detached and shell writers require external service exclusion");
|
|
118
|
+
// Persist reservation BEFORE spawn. Lost supervisor state can never be
|
|
119
|
+
// mistaken for a namespace with no historical admissions.
|
|
120
|
+
durableExclusive(path.join(this.directory, `admission-${randomUUID()}.json`), { generation: this.#generation });
|
|
121
|
+
const child = spawn(command, [...args], options);
|
|
122
|
+
this.#children.add(child);
|
|
123
|
+
child.once("exit", () => { this.#children.delete(child); });
|
|
124
|
+
child.once("error", () => {
|
|
125
|
+
// A failed spawn has no OS process; errors on an existing child are not
|
|
126
|
+
// evidence of exit and do not remove it from the admitted population.
|
|
127
|
+
if (child.pid === undefined)
|
|
128
|
+
this.#children.delete(child);
|
|
129
|
+
});
|
|
130
|
+
return child;
|
|
131
|
+
}
|
|
132
|
+
/** Close admission now; finish only after actual exit observations. A timeout
|
|
133
|
+
* leaves the gate closed, the queue untouched, and may be retried. */
|
|
134
|
+
async drainAndMigrate(options) {
|
|
135
|
+
if (!Number.isFinite(options.timeoutMs) || options.timeoutMs < 0)
|
|
136
|
+
throw new RangeError("timeoutMs must be finite and nonnegative");
|
|
137
|
+
this.#assertIdentity();
|
|
138
|
+
if (this.#result) {
|
|
139
|
+
for (const [file, proof] of this.#completionProof) {
|
|
140
|
+
try {
|
|
141
|
+
const stat = fs.lstatSync(file);
|
|
142
|
+
if (stat.isSymbolicLink() || !same(stat, proof.identity) ||
|
|
143
|
+
(proof.bytes === undefined ? !stat.isDirectory() : !stat.isFile() || fs.readFileSync(file, "utf8") !== proof.bytes))
|
|
144
|
+
throw fault("completed migration evidence replaced");
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
throw fault(`completed migration evidence unavailable: ${error.message}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return this.#result;
|
|
151
|
+
}
|
|
152
|
+
if (this.#draining)
|
|
153
|
+
throw fault("migration is already running");
|
|
154
|
+
this.#draining = true;
|
|
155
|
+
try {
|
|
156
|
+
if (!this.#closed) {
|
|
157
|
+
this.#closed = true;
|
|
158
|
+
durableExclusive(path.join(this.directory, "admission.closed.json"), { generation: this.#generation });
|
|
159
|
+
this.#closedEvidence = fs.lstatSync(path.join(this.directory, "admission.closed.json"));
|
|
160
|
+
}
|
|
161
|
+
const deadline = performance.now() + options.timeoutMs;
|
|
162
|
+
while (this.#children.size > 0) {
|
|
163
|
+
this.#assertIdentity();
|
|
164
|
+
if (performance.now() >= deadline)
|
|
165
|
+
throw fault("owned writers have not exited");
|
|
166
|
+
await new Promise(resolve => setTimeout(resolve, Math.min(10, Math.max(1, deadline - performance.now()))));
|
|
167
|
+
}
|
|
168
|
+
this.#assertIdentity();
|
|
169
|
+
const queue = `${this.lockPath}.queue`;
|
|
170
|
+
// Missing queue is not permission to bootstrap after a failed upgrade.
|
|
171
|
+
const oldQueue = directory(queue);
|
|
172
|
+
for (const suffix of [".identity", ".initializing", ".initialized"]) {
|
|
173
|
+
try {
|
|
174
|
+
fs.lstatSync(`${queue}${suffix}`);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
if (error.code === "ENOENT")
|
|
178
|
+
continue;
|
|
179
|
+
throw error;
|
|
180
|
+
}
|
|
181
|
+
throw fault("namespace is already anchored or has partial initialization evidence");
|
|
182
|
+
}
|
|
183
|
+
const preservedQueue = `${queue}.legacy-${this.#generation}`;
|
|
184
|
+
durableExclusive(path.join(this.directory, "migration.intent.json"), { generation: this.#generation, queue: oldQueue, preservedQueue });
|
|
185
|
+
this.#assertIdentity();
|
|
186
|
+
if (!same(directory(queue), oldQueue))
|
|
187
|
+
throw fault("legacy queue changed before preservation");
|
|
188
|
+
fs.renameSync(queue, preservedQueue);
|
|
189
|
+
syncDirectory(this.directory);
|
|
190
|
+
bindMutexQueue(queue, defaultProcessIdentity(), () => false, syncDirectory);
|
|
191
|
+
this.#assertIdentity();
|
|
192
|
+
durableExclusive(path.join(this.directory, "migration.complete.json"), { generation: this.#generation, preservedQueue });
|
|
193
|
+
for (const file of [queue, preservedQueue, `${queue}.identity`, `${queue}.initializing`, `${queue}.initialized`, path.join(this.directory, "migration.complete.json")]) {
|
|
194
|
+
const stat = fs.lstatSync(file);
|
|
195
|
+
this.#completionProof.set(file, { identity: stat, bytes: stat.isFile() ? fs.readFileSync(file, "utf8") : undefined });
|
|
196
|
+
}
|
|
197
|
+
this.#result = Object.freeze({ lockPath: this.lockPath, preservedQueue, generation: this.#generation });
|
|
198
|
+
return this.#result;
|
|
199
|
+
}
|
|
200
|
+
finally {
|
|
201
|
+
this.#draining = false;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=legacy-writer-lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-writer-lifecycle.js","sourceRoot":"","sources":["../src/legacy-writer-lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Narrow durable-mutex entry point for cooperating local control services.
|
|
2
|
+
* Unknown process observations never authorize reclamation of a live lock. */
|
|
3
|
+
import { PersistentFileMutex as BasePersistentFileMutex, type ObservedProcess, type PersistentCoordinatorOptions } from "./resources/persistence.ts";
|
|
4
|
+
export { defaultProcessIdentity, readProcessBirthToken, type ObservedProcess, type PersistentCoordinatorOptions, type ProcessIdentity, type ProcessInspector, } from "./resources/persistence.ts";
|
|
5
|
+
export declare function inspectPersistentOwner(pid: number): ObservedProcess;
|
|
6
|
+
export declare class PersistentFileMutex extends BasePersistentFileMutex {
|
|
7
|
+
constructor(lockPath: string, options?: Omit<PersistentCoordinatorOptions, "directory">);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=persistent-mutex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistent-mutex.d.ts","sourceRoot":"","sources":["../src/persistent-mutex.ts"],"names":[],"mappings":"AAAA;8EAC8E;AAC9E,OAAO,EACN,mBAAmB,IAAI,uBAAuB,EAG9C,KAAK,eAAe,EACpB,KAAK,4BAA4B,EACjC,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACN,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,4BAA4B,EACjC,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACrB,MAAM,4BAA4B,CAAC;AAEpC,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAWnE;AAED,qBAAa,mBAAoB,SAAQ,uBAAuB;IAC/D,YAAY,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,4BAA4B,EAAE,WAAW,CAAM,EAE1F;CACD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Narrow durable-mutex entry point for cooperating local control services.
|
|
2
|
+
* Unknown process observations never authorize reclamation of a live lock. */
|
|
3
|
+
import { PersistentFileMutex as BasePersistentFileMutex, defaultProcessIdentity, readProcessBirthToken, } from "./resources/persistence.js";
|
|
4
|
+
export { defaultProcessIdentity, readProcessBirthToken, } from "./resources/persistence.js";
|
|
5
|
+
export function inspectPersistentOwner(pid) {
|
|
6
|
+
if (!Number.isSafeInteger(pid) || pid <= 0 || pid > 0x7fffffff)
|
|
7
|
+
return { alive: true };
|
|
8
|
+
if (pid === process.pid)
|
|
9
|
+
return { alive: true, ...defaultProcessIdentity() };
|
|
10
|
+
try {
|
|
11
|
+
process.kill(pid, 0);
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
// EPERM and unexpected OS errors mean unknown, not proof of death.
|
|
15
|
+
if (error.code === "ESRCH")
|
|
16
|
+
return { alive: false };
|
|
17
|
+
return { alive: true };
|
|
18
|
+
}
|
|
19
|
+
const birthToken = readProcessBirthToken(pid);
|
|
20
|
+
return birthToken === undefined ? { alive: true } : { alive: true, birthToken, birthTokenKind: "native" };
|
|
21
|
+
}
|
|
22
|
+
export class PersistentFileMutex extends BasePersistentFileMutex {
|
|
23
|
+
constructor(lockPath, options = {}) {
|
|
24
|
+
super(lockPath, { ...options, inspectProcess: options.inspectProcess ?? inspectPersistentOwner });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=persistent-mutex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistent-mutex.js","sourceRoot":"","sources":["../src/persistent-mutex.ts"],"names":[],"mappings":"AAAA;8EAC8E;AAC9E,OAAO,EACN,mBAAmB,IAAI,uBAAuB,EAC9C,sBAAsB,EACtB,qBAAqB,GAGrB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACN,sBAAsB,EACtB,qBAAqB,GAKrB,MAAM,4BAA4B,CAAC;AAEpC,MAAM,UAAU,sBAAsB,CAAC,GAAW;IACjD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,GAAG,UAAU;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACvF,IAAI,GAAG,KAAK,OAAO,CAAC,GAAG;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,sBAAsB,EAAE,EAAE,CAAC;IAC7E,IAAI,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAAC,CAAC;IAC7B,OAAO,KAAK,EAAE,CAAC;QACd,mEAAmE;QACnE,IAAK,KAA+B,CAAC,IAAI,KAAK,OAAO;YAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAC/E,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACxB,CAAC;IACD,MAAM,UAAU,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAC9C,OAAO,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC;AAC3G,CAAC;AAED,MAAM,OAAO,mBAAoB,SAAQ,uBAAuB;IAC/D,YAAY,QAAgB,EAAE,OAAO,GAAoD,EAAE;QAC1F,KAAK,CAAC,QAAQ,EAAE,EAAE,GAAG,OAAO,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,sBAAsB,EAAE,CAAC,CAAC;IACnG,CAAC;CACD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface DirectoryIdentity {
|
|
2
|
+
dev: number;
|
|
3
|
+
ino: number;
|
|
4
|
+
}
|
|
5
|
+
interface BootstrapOwner {
|
|
6
|
+
pid: number;
|
|
7
|
+
birthToken: string;
|
|
8
|
+
birthTokenKind: "native" | "opaque";
|
|
9
|
+
}
|
|
10
|
+
export declare function bindMutexQueue(queue: string, owner: BootstrapOwner, canRecover: (owner: BootstrapOwner) => boolean, syncDirectory: (directory: string) => void): DirectoryIdentity;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=mutex-bootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutex-bootstrap.d.ts","sourceRoot":"","sources":["../../src/resources/mutex-bootstrap.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,iBAAiB;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;CAAE;AAChE,UAAU,cAAc;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAAE;AAyDlG,wBAAgB,cAAc,CAC7B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,cAAc,EACrB,UAAU,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,EAC9C,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GACxC,iBAAiB,CA8EnB"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/** Crash-recoverable creation of a new mutex namespace. Existing unanchored
|
|
2
|
+
* queues are never migrated here: that requires a host-wide old-writer fence. */
|
|
3
|
+
import * as crypto from "node:crypto";
|
|
4
|
+
import * as fs from "node:fs";
|
|
5
|
+
import * as path from "node:path";
|
|
6
|
+
const same = (a, b) => a.dev === b.dev && a.ino === b.ino;
|
|
7
|
+
const fault = (message) => new Error(`TFWS_MUTEX_IDENTITY: ${message}`);
|
|
8
|
+
const waiting = () => Object.assign(fault("mutex initialization is pending"), { code: "ENOENT" });
|
|
9
|
+
function exists(file) {
|
|
10
|
+
try {
|
|
11
|
+
fs.lstatSync(file);
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
if (error.code === "ENOENT")
|
|
16
|
+
return false;
|
|
17
|
+
throw error;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function directoryIdentity(directory) {
|
|
21
|
+
const stat = fs.lstatSync(directory);
|
|
22
|
+
if (!stat.isDirectory())
|
|
23
|
+
throw fault("bootstrap path must be a real directory");
|
|
24
|
+
return { dev: stat.dev, ino: stat.ino };
|
|
25
|
+
}
|
|
26
|
+
function read(file) {
|
|
27
|
+
const fd = fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
|
|
28
|
+
try {
|
|
29
|
+
const stat = fs.fstatSync(fd);
|
|
30
|
+
if (!stat.isFile() || !same(stat, fs.lstatSync(file)))
|
|
31
|
+
throw fault("bootstrap record was replaced");
|
|
32
|
+
return { value: JSON.parse(fs.readFileSync(fd, "utf8")), identity: { dev: stat.dev, ino: stat.ino } };
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
fs.closeSync(fd);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function identity(value) {
|
|
39
|
+
if (!value || typeof value !== "object")
|
|
40
|
+
return false;
|
|
41
|
+
const v = value;
|
|
42
|
+
return Number.isSafeInteger(v.dev) && Number.isSafeInteger(v.ino) && v.dev >= 0 && v.ino > 0;
|
|
43
|
+
}
|
|
44
|
+
function intent(value, queueName) {
|
|
45
|
+
if (!value || typeof value !== "object")
|
|
46
|
+
throw fault("invalid bootstrap intent");
|
|
47
|
+
const v = value;
|
|
48
|
+
if (v.version !== 1 || typeof v.token !== "string" || !/^[0-9a-f-]{36}$/.test(v.token) ||
|
|
49
|
+
v.stage !== `${queueName}.staging-${v.token}` || !identity(v.parent) || !identity(v.directory) ||
|
|
50
|
+
!v.owner || !Number.isSafeInteger(v.owner.pid) || v.owner.pid <= 0 || v.owner.pid > 0x7fffffff ||
|
|
51
|
+
typeof v.owner.birthToken !== "string" || v.owner.birthToken.length === 0 ||
|
|
52
|
+
(v.owner.birthTokenKind !== "native" && v.owner.birthTokenKind !== "opaque"))
|
|
53
|
+
throw fault("invalid bootstrap intent");
|
|
54
|
+
return v;
|
|
55
|
+
}
|
|
56
|
+
function publish(file, value, syncDirectory) {
|
|
57
|
+
const temp = `${file}.tmp.${crypto.randomUUID()}`;
|
|
58
|
+
const fd = fs.openSync(temp, "wx", 0o600);
|
|
59
|
+
try {
|
|
60
|
+
fs.writeFileSync(fd, JSON.stringify(value));
|
|
61
|
+
fs.fsyncSync(fd);
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
fs.closeSync(fd);
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
try {
|
|
68
|
+
fs.linkSync(temp, file);
|
|
69
|
+
syncDirectory(path.dirname(file));
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (error.code !== "EEXIST")
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
fs.unlinkSync(temp);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export function bindMutexQueue(queue, owner, canRecover, syncDirectory) {
|
|
81
|
+
const parentPath = path.dirname(queue);
|
|
82
|
+
fs.mkdirSync(parentPath, { recursive: true });
|
|
83
|
+
const parent = directoryIdentity(parentPath);
|
|
84
|
+
const anchor = `${queue}.identity`;
|
|
85
|
+
const journal = `${queue}.initializing`;
|
|
86
|
+
const completed = `${queue}.initialized`;
|
|
87
|
+
let ownToken;
|
|
88
|
+
// Compatibility for already anchored namespaces from the preceding mutex
|
|
89
|
+
// version. A completion record without its genesis is corruption, not legacy.
|
|
90
|
+
if (!exists(journal) && exists(anchor)) {
|
|
91
|
+
if (exists(completed))
|
|
92
|
+
throw fault("bootstrap genesis is missing");
|
|
93
|
+
const saved = read(anchor).value;
|
|
94
|
+
const current = directoryIdentity(queue);
|
|
95
|
+
if (!identity(saved) || !same(saved, current))
|
|
96
|
+
throw fault("mutex queue was replaced");
|
|
97
|
+
return current;
|
|
98
|
+
}
|
|
99
|
+
if (!exists(journal)) {
|
|
100
|
+
if (exists(completed))
|
|
101
|
+
throw fault("bootstrap genesis is missing");
|
|
102
|
+
if (exists(queue))
|
|
103
|
+
throw waiting(); // legacy or interrupted old protocol
|
|
104
|
+
const token = crypto.randomUUID();
|
|
105
|
+
const stage = `${path.basename(queue)}.staging-${token}`;
|
|
106
|
+
const stagePath = path.join(parentPath, stage);
|
|
107
|
+
fs.mkdirSync(stagePath, { mode: 0o700 });
|
|
108
|
+
const stagedIdentity = directoryIdentity(stagePath);
|
|
109
|
+
syncDirectory(stagePath);
|
|
110
|
+
syncDirectory(parentPath);
|
|
111
|
+
const proposed = { version: 1, token, owner, parent, directory: stagedIdentity, stage };
|
|
112
|
+
publish(journal, proposed, syncDirectory);
|
|
113
|
+
const winner = intent(read(journal).value, path.basename(queue));
|
|
114
|
+
if (winner.token === token)
|
|
115
|
+
ownToken = token;
|
|
116
|
+
else {
|
|
117
|
+
if (same(directoryIdentity(stagePath), stagedIdentity))
|
|
118
|
+
fs.rmdirSync(stagePath);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const selected = intent(read(journal).value, path.basename(queue));
|
|
122
|
+
const assertParent = () => {
|
|
123
|
+
if (!same(directoryIdentity(parentPath), selected.parent))
|
|
124
|
+
throw fault("bootstrap parent was replaced");
|
|
125
|
+
};
|
|
126
|
+
const assertPublished = () => {
|
|
127
|
+
assertParent();
|
|
128
|
+
const saved = read(anchor).value;
|
|
129
|
+
if (!identity(saved) || !same(saved, selected.directory) || !same(directoryIdentity(queue), selected.directory)) {
|
|
130
|
+
throw fault("bootstrap anchor does not match queue");
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
assertParent();
|
|
134
|
+
if (exists(completed)) {
|
|
135
|
+
if (JSON.stringify(read(completed).value) !== JSON.stringify(selected))
|
|
136
|
+
throw fault("bootstrap completion does not match genesis");
|
|
137
|
+
assertPublished();
|
|
138
|
+
return selected.directory;
|
|
139
|
+
}
|
|
140
|
+
if (selected.token !== ownToken && !canRecover(selected.owner))
|
|
141
|
+
throw waiting();
|
|
142
|
+
const stagePath = path.join(parentPath, selected.stage);
|
|
143
|
+
if (!exists(queue)) {
|
|
144
|
+
if (exists(anchor))
|
|
145
|
+
throw fault("anchored mutex queue is missing");
|
|
146
|
+
if (!same(directoryIdentity(stagePath), selected.directory))
|
|
147
|
+
throw fault("bootstrap staging directory was replaced");
|
|
148
|
+
try {
|
|
149
|
+
fs.renameSync(stagePath, queue);
|
|
150
|
+
syncDirectory(parentPath);
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
// Multiple recoverers operate on one permanent selected inode. Only
|
|
154
|
+
// one rename can succeed; another may observe its completed result.
|
|
155
|
+
if (error.code !== "ENOENT" || !exists(queue))
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (!same(directoryIdentity(queue), selected.directory))
|
|
160
|
+
throw fault("bootstrap queue was replaced");
|
|
161
|
+
publish(anchor, selected.directory, syncDirectory);
|
|
162
|
+
assertPublished();
|
|
163
|
+
// The selected genesis is permanent, closing delayed-creator ABA without a
|
|
164
|
+
// mutable recovery claim. Completion is also immutable and is published only
|
|
165
|
+
// after the anchor. No choosing/ticket record can precede this commit point.
|
|
166
|
+
// A later missing anchor is therefore corruption, never initialization work.
|
|
167
|
+
const latest = intent(read(journal).value, path.basename(queue));
|
|
168
|
+
if (JSON.stringify(latest) !== JSON.stringify(selected))
|
|
169
|
+
throw fault("bootstrap genesis was replaced");
|
|
170
|
+
publish(completed, selected, syncDirectory);
|
|
171
|
+
if (JSON.stringify(read(completed).value) !== JSON.stringify(selected))
|
|
172
|
+
throw fault("bootstrap completion does not match genesis");
|
|
173
|
+
assertPublished();
|
|
174
|
+
return selected.directory;
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=mutex-bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutex-bootstrap.js","sourceRoot":"","sources":["../../src/resources/mutex-bootstrap.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../src/resources/persistence.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../src/resources/persistence.ts"],"names":[],"mappings":"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"}
|