@ricsam/r5d-worker 0.0.162 → 0.0.164
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/dist/cjs/package.json +1 -1
- package/dist/mjs/internal-r5dctl.cjs +1 -1
- package/dist/mjs/main.mjs +2 -2
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/personal/client.mjs +2 -2
- package/dist/mjs/personal/publication-refusal.mjs +9 -0
- package/dist/mjs/personal/runtime.mjs +47 -42
- package/dist/mjs/runtime/workspace/authority.mjs +517 -72
- package/dist/mjs/runtime/workspace/files.mjs +28 -5
- package/dist/mjs/runtime/workspace/outer.mjs +286 -0
- package/dist/mjs/runtime/workspace/storage-wire.mjs +5 -2
- package/dist/types/personal/publication-refusal.d.ts +4 -0
- package/dist/types/personal/runtime.d.ts +3 -2
- package/dist/types/runtime/workspace/authority.d.ts +82 -4
- package/dist/types/runtime/workspace/contracts.d.ts +26 -0
- package/dist/types/runtime/workspace/files.d.ts +27 -1
- package/dist/types/runtime/workspace/outer.d.ts +105 -0
- package/dist/types/runtime/workspace/storage-wire.d.ts +2 -1
- package/package.json +2 -2
package/dist/cjs/package.json
CHANGED
|
@@ -20605,7 +20605,7 @@ function resolveEntrypointPath(entrypoint) {
|
|
|
20605
20605
|
}
|
|
20606
20606
|
}
|
|
20607
20607
|
function getR5dctlVersion() {
|
|
20608
|
-
if (true) return "0.0.
|
|
20608
|
+
if (true) return "0.0.164";
|
|
20609
20609
|
const entrypoint = process.argv[1] ? resolveEntrypointPath(process.argv[1]) : null;
|
|
20610
20610
|
let current = entrypoint ? import_node_path2.default.dirname(entrypoint) : process.cwd();
|
|
20611
20611
|
for (let index = 0; index < 12; index += 1) {
|
package/dist/mjs/main.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import { startManagerRpc } from "./runtime/releases/rpc-main.mjs";
|
|
|
7
7
|
import { ManagerRpcConfig } from "./runtime/releases/rpc-protocol.mjs";
|
|
8
8
|
const args = process.argv.slice(2);
|
|
9
9
|
if (args.includes("--version")) {
|
|
10
|
-
console.log(`r5d-worker ${true ? "0.0.
|
|
10
|
+
console.log(`r5d-worker ${true ? "0.0.164" : "development"}`);
|
|
11
11
|
} else if (!args.length || args.includes("--help")) {
|
|
12
12
|
console.log(
|
|
13
13
|
"Usage: r5d-worker start --label <label> [--root <dir>] [--base-url <url>] [--token <worker-token>]\n r5d-worker executor /absolute/private/config.json\n r5d-worker manager /absolute/private/config.json\n\nRun independently supervised durable runtime services. Provision configuration with r5dinfra."
|
|
@@ -15,7 +15,7 @@ if (args.includes("--version")) {
|
|
|
15
15
|
} else if (args[0] === "start") {
|
|
16
16
|
const runtime = await startPersonalWorker(
|
|
17
17
|
parsePersonalWorkerOptions(args.slice(1)),
|
|
18
|
-
true ? "0.0.
|
|
18
|
+
true ? "0.0.164" : "development"
|
|
19
19
|
);
|
|
20
20
|
console.log(`Worker connected: ${runtime.resourceId}`);
|
|
21
21
|
let closing = false;
|
package/dist/mjs/package.json
CHANGED
|
@@ -103,7 +103,7 @@ async function startPersonalWorker(options, version) {
|
|
|
103
103
|
platform: process.platform,
|
|
104
104
|
arch: process.arch,
|
|
105
105
|
hostname: os.hostname(),
|
|
106
|
-
capabilities: { updateClis: true, durableWorkspace: true }
|
|
106
|
+
capabilities: { updateClis: true, durableWorkspace: true, outerWorkspace: true }
|
|
107
107
|
});
|
|
108
108
|
const grant = PersonalWorkerGrant.parse(
|
|
109
109
|
await request("/api/personal/resources/register", { kind: "worker", ...identity, label: options.label, metadata: metadata() })
|
|
@@ -116,7 +116,7 @@ async function startPersonalWorker(options, version) {
|
|
|
116
116
|
try {
|
|
117
117
|
const response = await request(`${endpoint}/storage`, {
|
|
118
118
|
instanceId: identity.instanceId,
|
|
119
|
-
request: { sessionId, envelope: { protocol: 1, installationId: grant.installationId, request: storageRequest } }
|
|
119
|
+
request: { ...sessionId === null ? { scope: "account" } : { sessionId }, envelope: { protocol: 1, installationId: grant.installationId, request: storageRequest } }
|
|
120
120
|
});
|
|
121
121
|
if (!response || !("result" in response)) throw new Error("Invalid scoped storage response");
|
|
122
122
|
return response.result;
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
const CONFLICT_PUBLICATION_CODES = /* @__PURE__ */ new Set([
|
|
2
2
|
"conflict",
|
|
3
|
+
"sync_conflict",
|
|
3
4
|
"workbench_conflict",
|
|
4
5
|
"workbench_operation_in_progress"
|
|
5
6
|
]);
|
|
7
|
+
const TRANSIENT_PUBLICATION_CODES = /* @__PURE__ */ new Set([
|
|
8
|
+
"not_initialized",
|
|
9
|
+
"apply_refused",
|
|
10
|
+
"mirror_advanced",
|
|
11
|
+
"authority_closed",
|
|
12
|
+
"busy"
|
|
13
|
+
]);
|
|
6
14
|
const BLOCKED_PUBLICATION_CODES = /* @__PURE__ */ new Set([
|
|
7
15
|
"secret_or_runtime_path",
|
|
8
16
|
"secret_content",
|
|
@@ -33,6 +41,7 @@ export {
|
|
|
33
41
|
OPERATION_IN_PROGRESS_CODE,
|
|
34
42
|
PUBLICATION_OBSERVATION_THRESHOLDS,
|
|
35
43
|
STUCK_OPERATION_OBSERVATIONS,
|
|
44
|
+
TRANSIENT_PUBLICATION_CODES,
|
|
36
45
|
publicationRefusalElects,
|
|
37
46
|
publicationRefusalOutcome
|
|
38
47
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { publicationRefusalElects, publicationRefusalOutcome } from "./publication-refusal.mjs";
|
|
2
|
+
import { publicationRefusalElects, publicationRefusalOutcome, TRANSIENT_PUBLICATION_CODES } from "./publication-refusal.mjs";
|
|
3
3
|
import { PersonalTcpManager } from "./tcp.mjs";
|
|
4
4
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
5
5
|
import { promises as fs } from "node:fs";
|
|
@@ -12,6 +12,7 @@ import { EXECUTOR_CAPABILITY, ExecutorCredential } from "../runtime/protocol.mjs
|
|
|
12
12
|
import { privateDirectory, readPrivateJson } from "../runtime/storage.mjs";
|
|
13
13
|
import { WorkspaceAuthority } from "../runtime/workspace/authority.mjs";
|
|
14
14
|
import { ApprovedWorkbench, WorkspaceError } from "../runtime/workspace/contracts.mjs";
|
|
15
|
+
import { OuterSnapshotRefusal } from "../runtime/workspace/outer.mjs";
|
|
15
16
|
import { WorkspaceStorageClient } from "../runtime/workspace/storage-client.mjs";
|
|
16
17
|
import { BranchName, GitOid, StorageId } from "../runtime/workspace/storage-wire.mjs";
|
|
17
18
|
const PersonalWorkerGrant = z.object({
|
|
@@ -204,7 +205,11 @@ exec ${quote(executable)} ${quote(cli)} "$@"
|
|
|
204
205
|
config: { installationId: grant.installationId, root: authorityRoot, workspaceRoot, dynamicWorkbenches: true, workbenches: [] },
|
|
205
206
|
executor: async () => ({ client, workerFence: current.workerFence }),
|
|
206
207
|
resolveWorkbench: async (identity) => identity.userId === grant.userId ? manifests.get(routes.get(identity.sessionId) ?? "") ?? null : null,
|
|
207
|
-
storage: async (identity) => new WorkspaceStorageClient(grant.installationId, options.storage(identity.sessionId), async () => current.workerFence)
|
|
208
|
+
storage: async (identity) => new WorkspaceStorageClient(grant.installationId, options.storage(identity.sessionId), async () => current.workerFence),
|
|
209
|
+
accountStorage: async (userId) => {
|
|
210
|
+
if (userId !== grant.userId) throw new Error("Wrong personal worker principal");
|
|
211
|
+
return new WorkspaceStorageClient(grant.installationId, options.storage(null), async () => current.workerFence);
|
|
212
|
+
}
|
|
208
213
|
});
|
|
209
214
|
async function approve(input) {
|
|
210
215
|
const cwd = input.rootProfile === "account" ? workspaceRoot : input.namespace && input.projectName ? path.join(workspaceRoot, "projects", input.namespace, input.projectName, ...input.branch.split("/")) : path.join(workspaceRoot, "workbenches", input.id);
|
|
@@ -260,51 +265,40 @@ exec ${quote(executable)} ${quote(cli)} "$@"
|
|
|
260
265
|
if (publication) return publication;
|
|
261
266
|
const next = (async () => {
|
|
262
267
|
const results = [];
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
} else {
|
|
288
|
-
attempt.observations++;
|
|
289
|
-
}
|
|
290
|
-
let workbenchHasLiveRun = false;
|
|
291
|
-
try {
|
|
292
|
-
workbenchHasLiveRun = await authority.workbenchHasLiveRun({ userId: grant.userId, sessionId });
|
|
293
|
-
} catch {
|
|
294
|
-
}
|
|
295
|
-
if (!publicationRefusalElects(code, attempt.observations, { workbenchHasLiveRun })) continue;
|
|
268
|
+
try {
|
|
269
|
+
const outer = await authority.synchronizeOuter(grant.userId);
|
|
270
|
+
failedPublicationAttempts.delete("workspace");
|
|
271
|
+
results.push({ workbenchId: "workspace", ...outer });
|
|
272
|
+
} catch (error) {
|
|
273
|
+
const code = error instanceof WorkspaceError ? error.code : "publication_failed";
|
|
274
|
+
results.push({ workbenchId: "workspace", error: code });
|
|
275
|
+
if (!TRANSIENT_PUBLICATION_CODES.has(code) && options.publicationReport) {
|
|
276
|
+
let startingHead = null;
|
|
277
|
+
try {
|
|
278
|
+
startingHead = (await authority.outerStatus(grant.userId)).publishedHead;
|
|
279
|
+
} catch {
|
|
280
|
+
}
|
|
281
|
+
const outcome = publicationRefusalOutcome(code);
|
|
282
|
+
const paths = error instanceof OuterSnapshotRefusal ? error.paths : [];
|
|
283
|
+
const fingerprint = canonicalJson({ code, startingHead, outcome, paths });
|
|
284
|
+
let attempt = failedPublicationAttempts.get("workspace");
|
|
285
|
+
if (!attempt || attempt.fingerprint !== fingerprint) {
|
|
286
|
+
attempt = { fingerprint, attemptId: randomUUID(), observations: 1 };
|
|
287
|
+
failedPublicationAttempts.set("workspace", attempt);
|
|
288
|
+
} else {
|
|
289
|
+
attempt.observations++;
|
|
290
|
+
}
|
|
291
|
+
if (publicationRefusalElects(code, attempt.observations)) {
|
|
296
292
|
try {
|
|
297
293
|
await options.publicationReport(WorkspacePublicationReport.parse({
|
|
298
294
|
protocol: 1,
|
|
299
295
|
attemptId: attempt.attemptId,
|
|
300
|
-
|
|
301
|
-
workbenchId,
|
|
302
|
-
repositoryId: manifest.repositoryId,
|
|
303
|
-
branch: manifest.branch,
|
|
296
|
+
scope: "workspace",
|
|
304
297
|
outcome,
|
|
305
298
|
startingHead,
|
|
306
299
|
diffSizeBytes: outcome === "large_diff_blocked" && code === "too_large" ? 5 * 1024 * 1024 + 1 : 0,
|
|
307
|
-
error: code
|
|
300
|
+
error: code,
|
|
301
|
+
...paths.length ? { paths } : {}
|
|
308
302
|
}));
|
|
309
303
|
} catch (reportError) {
|
|
310
304
|
process.stderr.write(`[r5d-worker] publication report deferred: ${reportError instanceof WorkspaceError ? reportError.code : "publication_report_failed"}
|
|
@@ -313,13 +307,24 @@ exec ${quote(executable)} ${quote(cli)} "$@"
|
|
|
313
307
|
}
|
|
314
308
|
}
|
|
315
309
|
}
|
|
310
|
+
for (const [workbenchId, sessionId] of publicationSessions) {
|
|
311
|
+
if (closing) break;
|
|
312
|
+
const manifest = manifests.get(workbenchId);
|
|
313
|
+
if (!manifest || manifest.rootProfile !== "project") continue;
|
|
314
|
+
try {
|
|
315
|
+
results.push({ workbenchId, ...await authority.mirror({ userId: grant.userId, sessionId }) });
|
|
316
|
+
} catch (error) {
|
|
317
|
+
results.push({ workbenchId, error: error instanceof WorkspaceError ? error.code : "mirror_failed" });
|
|
318
|
+
}
|
|
319
|
+
}
|
|
316
320
|
return results;
|
|
317
321
|
})();
|
|
318
322
|
publication = next;
|
|
319
323
|
void next.then(
|
|
320
324
|
(results) => {
|
|
321
|
-
|
|
322
|
-
|
|
325
|
+
const deferred = results.filter((result) => result.error && !TRANSIENT_PUBLICATION_CODES.has(result.error));
|
|
326
|
+
if (deferred.length)
|
|
327
|
+
process.stderr.write(`[r5d-worker] periodic workspace publication deferred: ${deferred.map((result) => `${result.workbenchId}:${result.error}`).join(", ")}
|
|
323
328
|
`);
|
|
324
329
|
if (publication === next) publication = null;
|
|
325
330
|
},
|