@amalgm/shell 0.1.135 → 0.1.136
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/bounded-for-each.d.ts +3 -0
- package/dist/bounded-for-each.js +26 -0
- package/dist/bounded-for-each.js.map +1 -0
- package/dist/filesystem.d.ts +3 -0
- package/dist/filesystem.js +11 -0
- package/dist/filesystem.js.map +1 -1
- package/dist/transfer-instrumentation.d.ts +18 -0
- package/dist/transfer-instrumentation.js +70 -0
- package/dist/transfer-instrumentation.js.map +1 -1
- package/dist/user-ground-host.js +43 -30
- package/dist/user-ground-host.js.map +1 -1
- package/dist/workspace-add-staging.d.ts +98 -34
- package/dist/workspace-add-staging.js +255 -149
- package/dist/workspace-add-staging.js.map +1 -1
- package/npm-shrinkwrap.json +4 -4
- package/package.json +2 -2
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/** Run `perform` over every item with at most `concurrency` in flight. The
|
|
2
|
+
* first failure stops admission and rejects the whole loop. */
|
|
3
|
+
export declare function boundedForEach<T>(items: readonly T[], concurrency: number, perform: (item: T) => Promise<void>): Promise<void>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Run `perform` over every item with at most `concurrency` in flight. The
|
|
2
|
+
* first failure stops admission and rejects the whole loop. */
|
|
3
|
+
export async function boundedForEach(items, concurrency, perform) {
|
|
4
|
+
if (!Number.isSafeInteger(concurrency) || concurrency < 1) {
|
|
5
|
+
throw new Error("bounded loop concurrency must be a positive integer");
|
|
6
|
+
}
|
|
7
|
+
let next = 0;
|
|
8
|
+
let stopped = false;
|
|
9
|
+
const worker = async () => {
|
|
10
|
+
while (!stopped) {
|
|
11
|
+
const index = next;
|
|
12
|
+
next += 1;
|
|
13
|
+
if (index >= items.length)
|
|
14
|
+
return;
|
|
15
|
+
try {
|
|
16
|
+
await perform(items[index]);
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
stopped = true;
|
|
20
|
+
throw error;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=bounded-for-each.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bounded-for-each.js","sourceRoot":"","sources":["../src/bounded-for-each.ts"],"names":[],"mappings":"AAAA;+DAC+D;AAC/D,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,KAAmB,EACnB,WAAmB,EACnB,OAAmC;IAEnC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IACD,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE;QACxB,OAAO,CAAC,OAAO,EAAE,CAAC;YAChB,MAAM,KAAK,GAAG,IAAI,CAAC;YACnB,IAAI,IAAI,CAAC,CAAC;YACV,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM;gBAAE,OAAO;YAClC,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,KAAK,CAAC,KAAK,CAAM,CAAC,CAAC;YACnC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,GAAG,IAAI,CAAC;gBACf,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IACF,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAC1B,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,EAC/C,GAAG,EAAE,CAAC,MAAM,EAAE,CACf,CAAC,CAAC;AACL,CAAC"}
|
package/dist/filesystem.d.ts
CHANGED
|
@@ -3,6 +3,9 @@ export declare function ensurePrivateDir(directory: string): void;
|
|
|
3
3
|
* gets 0755 — the same default a fresh mkdir gives the user — and an
|
|
4
4
|
* existing directory keeps whatever mode the user chose. */
|
|
5
5
|
export declare function ensureUserDir(directory: string): void;
|
|
6
|
+
/** The batch form of ensureUserDir: the same mode law for a whole directory
|
|
7
|
+
* skeleton, created ahead of the files it will hold and off the event loop. */
|
|
8
|
+
export declare function ensureUserDirs(directories: readonly string[], concurrency: number): Promise<void>;
|
|
6
9
|
export declare function atomicWrite(file: string, bytes: string | Uint8Array, mode?: number): void;
|
|
7
10
|
export declare function atomicCopy(source: string, destination: string, mode?: number): void;
|
|
8
11
|
/** Assemble verified chunk files without holding the complete artifact in RAM. */
|
package/dist/filesystem.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
2
|
import { constants, chmodSync, copyFileSync, createReadStream, createWriteStream, existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync, } from "node:fs";
|
|
3
|
+
import { chmod, mkdir } from "node:fs/promises";
|
|
3
4
|
import { dirname } from "node:path";
|
|
4
5
|
import { once } from "node:events";
|
|
6
|
+
import { boundedForEach } from "./bounded-for-each.js";
|
|
5
7
|
export function ensurePrivateDir(directory) {
|
|
6
8
|
mkdirSync(directory, { recursive: true, mode: 0o700 });
|
|
7
9
|
chmodSync(directory, 0o700);
|
|
@@ -14,6 +16,15 @@ export function ensureUserDir(directory) {
|
|
|
14
16
|
chmodSync(directory, 0o755);
|
|
15
17
|
}
|
|
16
18
|
}
|
|
19
|
+
/** The batch form of ensureUserDir: the same mode law for a whole directory
|
|
20
|
+
* skeleton, created ahead of the files it will hold and off the event loop. */
|
|
21
|
+
export async function ensureUserDirs(directories, concurrency) {
|
|
22
|
+
await boundedForEach(directories, concurrency, async (directory) => {
|
|
23
|
+
if (await mkdir(directory, { recursive: true, mode: 0o755 }) !== undefined) {
|
|
24
|
+
await chmod(directory, 0o755);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
17
28
|
/** File helpers own the file, never the parent's mode: an absent parent is
|
|
18
29
|
* created private, an existing one — private or user-visible — keeps its
|
|
19
30
|
* mode. */
|
package/dist/filesystem.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filesystem.js","sourceRoot":"","sources":["../src/filesystem.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"filesystem.js","sourceRoot":"","sources":["../src/filesystem.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,3 +26,21 @@ export declare class TransferLegs {
|
|
|
26
26
|
private enter;
|
|
27
27
|
private exit;
|
|
28
28
|
}
|
|
29
|
+
/** Partition one concurrent phase by three named activities. Counts preserve
|
|
30
|
+
* a bit until the last operation of that kind settles; the eight reported
|
|
31
|
+
* states therefore sum to wall time instead of double-counting overlap. */
|
|
32
|
+
export declare class ConcurrentActivityClock<Activity extends string> {
|
|
33
|
+
private readonly activities;
|
|
34
|
+
private readonly counts;
|
|
35
|
+
private readonly totals;
|
|
36
|
+
private state;
|
|
37
|
+
private changedAt;
|
|
38
|
+
constructor(activities: readonly [Activity, Activity, Activity]);
|
|
39
|
+
time<T>(activity: Activity, work: () => Promise<T>): Promise<T>;
|
|
40
|
+
timeSync<T>(activity: Activity, work: () => T): T;
|
|
41
|
+
/** Prefix + active activity names form stable ledger keys. */
|
|
42
|
+
report(prefix: string): Record<string, number>;
|
|
43
|
+
private index;
|
|
44
|
+
private transition;
|
|
45
|
+
private record;
|
|
46
|
+
}
|
|
@@ -65,4 +65,74 @@ export class TransferLegs {
|
|
|
65
65
|
this.quietSince = now;
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
+
/** Partition one concurrent phase by three named activities. Counts preserve
|
|
69
|
+
* a bit until the last operation of that kind settles; the eight reported
|
|
70
|
+
* states therefore sum to wall time instead of double-counting overlap. */
|
|
71
|
+
export class ConcurrentActivityClock {
|
|
72
|
+
activities;
|
|
73
|
+
counts = [0, 0, 0];
|
|
74
|
+
totals = Array.from({ length: 8 }, () => 0);
|
|
75
|
+
state = 0;
|
|
76
|
+
changedAt = performance.now();
|
|
77
|
+
constructor(activities) {
|
|
78
|
+
this.activities = activities;
|
|
79
|
+
if (activities.some((activity) => activity.length === 0)
|
|
80
|
+
|| new Set(activities).size !== activities.length) {
|
|
81
|
+
throw new Error("concurrent activity names must be distinct");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async time(activity, work) {
|
|
85
|
+
const index = this.index(activity);
|
|
86
|
+
this.transition(index, 1);
|
|
87
|
+
try {
|
|
88
|
+
return await work();
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
this.transition(index, -1);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
timeSync(activity, work) {
|
|
95
|
+
const index = this.index(activity);
|
|
96
|
+
this.transition(index, 1);
|
|
97
|
+
try {
|
|
98
|
+
return work();
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
this.transition(index, -1);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/** Prefix + active activity names form stable ledger keys. */
|
|
105
|
+
report(prefix) {
|
|
106
|
+
if (!prefix)
|
|
107
|
+
throw new Error("concurrent activity report needs a prefix");
|
|
108
|
+
this.record(performance.now());
|
|
109
|
+
const key = (state) => {
|
|
110
|
+
if (state === 0)
|
|
111
|
+
return `${prefix}NeitherMs`;
|
|
112
|
+
const names = this.activities.filter((_activity, index) => (state & (1 << index)) !== 0);
|
|
113
|
+
const suffix = names.length === 1 ? "Only" : "";
|
|
114
|
+
return `${prefix}${names.map((name) => name.charAt(0).toUpperCase() + name.slice(1)).join("")}${suffix}Ms`;
|
|
115
|
+
};
|
|
116
|
+
return Object.fromEntries(this.totals.map((duration, state) => [key(state), Math.round(duration)]));
|
|
117
|
+
}
|
|
118
|
+
index(activity) {
|
|
119
|
+
const index = this.activities.indexOf(activity);
|
|
120
|
+
if (index < 0)
|
|
121
|
+
throw new Error(`unknown concurrent activity ${activity}`);
|
|
122
|
+
return index;
|
|
123
|
+
}
|
|
124
|
+
transition(index, delta) {
|
|
125
|
+
const now = performance.now();
|
|
126
|
+
this.record(now);
|
|
127
|
+
const next = (this.counts[index] ?? 0) + delta;
|
|
128
|
+
if (next < 0)
|
|
129
|
+
throw new Error("concurrent activity clock lost an operation");
|
|
130
|
+
this.counts[index] = next;
|
|
131
|
+
this.state = this.counts.reduce((mask, count, bit) => count > 0 ? mask | (1 << bit) : mask, 0);
|
|
132
|
+
}
|
|
133
|
+
record(now) {
|
|
134
|
+
this.totals[this.state] = (this.totals[this.state] ?? 0) + (now - this.changedAt);
|
|
135
|
+
this.changedAt = now;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
68
138
|
//# sourceMappingURL=transfer-instrumentation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transfer-instrumentation.js","sourceRoot":"","sources":["../src/transfer-instrumentation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,YAAY;IACN,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC5C,QAAQ,GAAG,CAAC,CAAC;IACb,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAC/B,MAAM,GAAG,CAAC,CAAC;IAEnB;2EACuE;IACvE,GAAG,CAAC,GAAW,EAAE,EAAU;QACzB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;YAAE,OAAO;QAC5C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,IAAI,CAAI,GAAW,EAAE,IAAsB;QAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,EAAE,CAAC;QACtB,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,QAAQ,CAAI,GAAW,EAAE,IAAa;QACpC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED;yCACqC;IACrC,MAAM;QACJ,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QACrE,OAAO;YACL,GAAG,MAAM,CAAC,WAAW,CACnB,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAC3D;YACD,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC;SAC/C,CAAC;IACJ,CAAC;IAEO,KAAK;QACX,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC9B,IAAI,IAAI,CAAC,QAAQ,KAAK,CAAC;YAAE,IAAI,CAAC,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC;QAC9D,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;QACnB,OAAO,GAAG,CAAC;IACb,CAAC;IAEO,IAAI,CAAC,GAAW,EAAE,SAAiB;QACzC,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,SAAS,CAAC,CAAC;QAC/B,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;QACnB,IAAI,IAAI,CAAC,QAAQ,KAAK,CAAC;YAAE,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;IACjD,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"transfer-instrumentation.js","sourceRoot":"","sources":["../src/transfer-instrumentation.ts"],"names":[],"mappings":"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"}
|
package/dist/user-ground-host.js
CHANGED
|
@@ -14,6 +14,7 @@ import { indexRowsByOutermostRoot } from "./ground-root-index.js";
|
|
|
14
14
|
import { ContentCacheDownloadSet, captureContentFile, contentBlockCollector, hasSealedContent, hashContentFile, pruneSettledContentCache, sealCapturedArtifact, } from "./content-cache-host.js";
|
|
15
15
|
import { RegisterUploadFusion } from "./register-upload-fusion.js";
|
|
16
16
|
import { StagedContentSet, addStagingEvidenceDir, clearAddStagingEvidence, } from "./workspace-add-staging.js";
|
|
17
|
+
import { boundedForEach } from "./bounded-for-each.js";
|
|
17
18
|
import { DirectContentPlane } from "./content-direct.js";
|
|
18
19
|
import { encodeContentWireBytes } from "./content-wire-codec.js";
|
|
19
20
|
import { TransferLegs } from "./transfer-instrumentation.js";
|
|
@@ -400,7 +401,7 @@ export class UserGroundHost {
|
|
|
400
401
|
});
|
|
401
402
|
}
|
|
402
403
|
},
|
|
403
|
-
onStage: async (stage) => {
|
|
404
|
+
onStage: async (stage, measurements) => {
|
|
404
405
|
const now = performance.now();
|
|
405
406
|
this.stage({
|
|
406
407
|
primitive: stage === "watching" ? "watch" : "download",
|
|
@@ -408,6 +409,7 @@ export class UserGroundHost {
|
|
|
408
409
|
status: "completed",
|
|
409
410
|
workspaceId: input.workspace.uuid,
|
|
410
411
|
durationMs: now - milestoneAt,
|
|
412
|
+
...(measurements ? { measurements } : {}),
|
|
411
413
|
});
|
|
412
414
|
milestoneAt = now;
|
|
413
415
|
await this.options.onWorkspaceAddStage?.({
|
|
@@ -1870,7 +1872,7 @@ export class UserGroundHost {
|
|
|
1870
1872
|
},
|
|
1871
1873
|
});
|
|
1872
1874
|
const downloads = new ContentCacheDownloadSet(cacheDir);
|
|
1873
|
-
|
|
1875
|
+
let stagedSet = null;
|
|
1874
1876
|
const targets = new Map();
|
|
1875
1877
|
const target = (artifact) => {
|
|
1876
1878
|
const found = targets.get(artifact.contentHash);
|
|
@@ -1883,16 +1885,22 @@ export class UserGroundHost {
|
|
|
1883
1885
|
// which stays on the cache rail so a warm re-Add remains a local
|
|
1884
1886
|
// clone instead of a fresh download.
|
|
1885
1887
|
const route = (artifact, manifest) => {
|
|
1886
|
-
const
|
|
1887
|
-
|
|
1888
|
+
const set = stagedSet;
|
|
1889
|
+
const stagedPaths = set && staged?.destinations.get(artifact.contentHash);
|
|
1890
|
+
if (set && stagedPaths && !hasSealedContent(cacheDir, artifact.contentHash, manifest.bytes)) {
|
|
1888
1891
|
stagedArtifacts += 1;
|
|
1889
|
-
targets.set(artifact.contentHash,
|
|
1892
|
+
targets.set(artifact.contentHash, set.target(artifact, manifest, stagedPaths));
|
|
1890
1893
|
}
|
|
1891
1894
|
else {
|
|
1892
1895
|
targets.set(artifact.contentHash, downloads.target(artifact, manifest));
|
|
1893
1896
|
}
|
|
1894
1897
|
};
|
|
1895
1898
|
try {
|
|
1899
|
+
// The staged rail's directory skeleton is the set's first act, so no
|
|
1900
|
+
// chunk's store path includes a mkdir.
|
|
1901
|
+
stagedSet = staged
|
|
1902
|
+
? await StagedContentSet.open(staged.evidenceDir, staged.destinations)
|
|
1903
|
+
: null;
|
|
1896
1904
|
// Every storage object — manifests and blocks alike — is fetched
|
|
1897
1905
|
// straight from content storage over a presigned URL and opened
|
|
1898
1906
|
// locally; the engine plans whole waves against these primitives, so
|
|
@@ -1983,9 +1991,9 @@ export class UserGroundHost {
|
|
|
1983
1991
|
// plan (manifest cache + routing), fetch (storage waits, whose
|
|
1984
1992
|
// decrypt share the plane delta names), hash (chunk verification),
|
|
1985
1993
|
// reuse (retained-chunk re-proof), write (chunk placement), seal
|
|
1986
|
-
// (whole-file proof +
|
|
1987
|
-
// nothing in flight. The staged rail decomposes its own
|
|
1988
|
-
//
|
|
1994
|
+
// (whole-file proof assertion + duplicates), and idle — wall time
|
|
1995
|
+
// with nothing in flight. The staged rail decomposes its own
|
|
1996
|
+
// placement legs below; `stagedArtifacts` counts its placements.
|
|
1989
1997
|
requests,
|
|
1990
1998
|
// The engine's own geometry: how manifests were known (local vs
|
|
1991
1999
|
// fetched, packed vs standalone) and how many planned pack spans
|
|
@@ -5726,9 +5734,11 @@ async function materializeRecords(input) {
|
|
|
5726
5734
|
for (const list of stagedDestinations.values())
|
|
5727
5735
|
list.sort();
|
|
5728
5736
|
}
|
|
5737
|
+
const contentStarted = performance.now();
|
|
5729
5738
|
const fileContent = await readContent([...wanted.values()], staged && stagedDestinations
|
|
5730
5739
|
? { evidenceDir: staged.evidenceDir, destinations: stagedDestinations }
|
|
5731
5740
|
: undefined);
|
|
5741
|
+
const chainStarted = performance.now();
|
|
5732
5742
|
const repositoryChains = new Map();
|
|
5733
5743
|
const walking = repositoryHeads.map(({ record, artifact }) => {
|
|
5734
5744
|
const local = fileContent.get(artifact.contentHash);
|
|
@@ -5773,11 +5783,15 @@ async function materializeRecords(input) {
|
|
|
5773
5783
|
walk.parent = inspectRepositoryTransportFile(parent.file).parentTransportVersion;
|
|
5774
5784
|
}
|
|
5775
5785
|
}
|
|
5786
|
+
const walkStarted = performance.now();
|
|
5787
|
+
let repositoriesMs = 0;
|
|
5776
5788
|
const materializeRepository = async (record, destination) => {
|
|
5777
5789
|
const chain = repositoryChains.get(record.uuid);
|
|
5778
5790
|
if (!chain)
|
|
5779
5791
|
throw new Error(`cloud repository ${record.uuid} transport was not downloaded`);
|
|
5792
|
+
const started = performance.now();
|
|
5780
5793
|
const applied = await applyRepositoryFiles(destination, chain);
|
|
5794
|
+
repositoriesMs += performance.now() - started;
|
|
5781
5795
|
const repository = { record, state: applied };
|
|
5782
5796
|
repositories.push(repository);
|
|
5783
5797
|
repositoriesByUuid.set(record.uuid, repository);
|
|
@@ -5931,6 +5945,7 @@ async function materializeRecords(input) {
|
|
|
5931
5945
|
throw new Error(`materialization for ${record.type} requires its dedicated adapter`);
|
|
5932
5946
|
}
|
|
5933
5947
|
}
|
|
5948
|
+
const rowsStarted = performance.now();
|
|
5934
5949
|
const rows = records.map((record) => {
|
|
5935
5950
|
const relativePath = paths.get(record.uuid);
|
|
5936
5951
|
const absolutePath = relativePath ? join(rootPath, ...relativePath.split("/")) : rootPath;
|
|
@@ -5944,7 +5959,18 @@ async function materializeRecords(input) {
|
|
|
5944
5959
|
...statFingerprint(stats),
|
|
5945
5960
|
};
|
|
5946
5961
|
});
|
|
5947
|
-
|
|
5962
|
+
const finished = performance.now();
|
|
5963
|
+
return {
|
|
5964
|
+
rows,
|
|
5965
|
+
repositories,
|
|
5966
|
+
timing: {
|
|
5967
|
+
contentMs: Math.round(chainStarted - contentStarted),
|
|
5968
|
+
transportChainMs: Math.round(walkStarted - chainStarted),
|
|
5969
|
+
repositoriesMs: Math.round(repositoriesMs),
|
|
5970
|
+
groundWalkMs: Math.round(rowsStarted - walkStarted - repositoriesMs),
|
|
5971
|
+
rowsMs: Math.round(finished - rowsStarted),
|
|
5972
|
+
},
|
|
5973
|
+
};
|
|
5948
5974
|
}
|
|
5949
5975
|
/** Refresh the always-materialized portable reference inventory selected by
|
|
5950
5976
|
* Live. Paths and bindings are local; UUIDs, parents, names, and versions are
|
|
@@ -6193,6 +6219,7 @@ async function installCloudWorkspace(input) {
|
|
|
6193
6219
|
staged: { evidenceDir: addStagingEvidenceDir(database, intent.workspaceId) },
|
|
6194
6220
|
readContent,
|
|
6195
6221
|
});
|
|
6222
|
+
const graphStarted = performance.now();
|
|
6196
6223
|
const rows = projectMaterializedGraph(materialized.rows, materialized.repositories.map((repository) => ({
|
|
6197
6224
|
record: repository.record,
|
|
6198
6225
|
identity: repository.state.identity,
|
|
@@ -6202,7 +6229,13 @@ async function installCloudWorkspace(input) {
|
|
|
6202
6229
|
? join(intent.destinationPath, ...row.relativePath.split("/"))
|
|
6203
6230
|
: intent.destinationPath,
|
|
6204
6231
|
}));
|
|
6205
|
-
|
|
6232
|
+
// The milestone's duration spans the whole materialization; its legs say
|
|
6233
|
+
// where that wall time went after the content set itself.
|
|
6234
|
+
await onStage?.("materialization-verified", {
|
|
6235
|
+
...materialized.timing,
|
|
6236
|
+
graphMs: Math.round(performance.now() - graphStarted),
|
|
6237
|
+
repositories: materialized.repositories.length,
|
|
6238
|
+
});
|
|
6206
6239
|
persistRows(database, identity, intent.resourceId, intent.workspaceId, rows);
|
|
6207
6240
|
input.adoptMaterialization(intent.workspaceId);
|
|
6208
6241
|
await onStage?.("rows-committed");
|
|
@@ -6292,26 +6325,6 @@ async function retryContent(operation, eventualNotFound = false, attempts = 10)
|
|
|
6292
6325
|
}
|
|
6293
6326
|
throw last;
|
|
6294
6327
|
}
|
|
6295
|
-
async function boundedForEach(items, concurrency, perform) {
|
|
6296
|
-
let next = 0;
|
|
6297
|
-
let stopped = false;
|
|
6298
|
-
const worker = async () => {
|
|
6299
|
-
while (!stopped) {
|
|
6300
|
-
const index = next;
|
|
6301
|
-
next += 1;
|
|
6302
|
-
if (index >= items.length)
|
|
6303
|
-
return;
|
|
6304
|
-
try {
|
|
6305
|
-
await perform(items[index]);
|
|
6306
|
-
}
|
|
6307
|
-
catch (error) {
|
|
6308
|
-
stopped = true;
|
|
6309
|
-
throw error;
|
|
6310
|
-
}
|
|
6311
|
-
}
|
|
6312
|
-
};
|
|
6313
|
-
await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
|
|
6314
|
-
}
|
|
6315
6328
|
/** Admit queued async tasks with at most `limit` in flight. Scheduling never
|
|
6316
6329
|
* blocks the caller; each task's settlement is its returned promise. The
|
|
6317
6330
|
* admitted task re-checks the bound because a released slot may be claimed
|