@camstack/server 1.2.135 → 1.2.137
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.
|
@@ -54,6 +54,7 @@ const prune_misplaced_addons_js_1 = require("./prune-misplaced-addons.js");
|
|
|
54
54
|
const require_cache_js_1 = require("./require-cache.js");
|
|
55
55
|
const runner_convergence_1 = require("./runner-convergence");
|
|
56
56
|
const runner_spawn_fanout_js_1 = require("./runner-spawn-fanout.js");
|
|
57
|
+
const single_flight_refresh_js_1 = require("./single-flight-refresh.js");
|
|
57
58
|
/**
|
|
58
59
|
* Decide whether an in-memory addon entry should be evicted because it is no
|
|
59
60
|
* longer on disk (the uninstall path in `loadNewAddons`).
|
|
@@ -1153,11 +1154,18 @@ class AddonRegistryService {
|
|
|
1153
1154
|
}
|
|
1154
1155
|
return out;
|
|
1155
1156
|
};
|
|
1157
|
+
/** One full-fleet rebuild in flight, at most one queued behind it. Every
|
|
1158
|
+
* event below asks for the SAME total rebuild, so running it once per event
|
|
1159
|
+
* was ~1 000 rebuilds of a 974-row mirror on a boot — each one a 625 KB read
|
|
1160
|
+
* and parse on hub-main's event loop. No timer: the first event still
|
|
1161
|
+
* refreshes immediately, because this mirror backs scope enforcement.
|
|
1162
|
+
* See `single-flight-refresh.ts`. */
|
|
1163
|
+
deviceMirrorGate = (0, single_flight_refresh_js_1.createSingleFlightRefresh)(() => this.refreshDeviceParentMirror());
|
|
1156
1164
|
/** Subscribe the mirror to every device-meta lifecycle event, and warm it once
|
|
1157
1165
|
* the addon set (device-manager included) is up. */
|
|
1158
1166
|
wireDeviceParentMirror() {
|
|
1159
1167
|
const refresh = () => {
|
|
1160
|
-
void this.
|
|
1168
|
+
void this.deviceMirrorGate.request();
|
|
1161
1169
|
};
|
|
1162
1170
|
for (const category of [
|
|
1163
1171
|
types_1.EventCategory.DeviceMetaChanged,
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createSingleFlightRefresh = createSingleFlightRefresh;
|
|
4
|
+
/**
|
|
5
|
+
* @param run the total rebuild. Called with no arguments, never concurrently
|
|
6
|
+
* with itself.
|
|
7
|
+
*/
|
|
8
|
+
function createSingleFlightRefresh(run) {
|
|
9
|
+
let inFlight = null;
|
|
10
|
+
// Set while a run is active and another request arrived. One flag, not a
|
|
11
|
+
// counter: N requests during one run need exactly ONE follow-up between
|
|
12
|
+
// them, because the follow-up reads the world as it is when it starts.
|
|
13
|
+
let pending = false;
|
|
14
|
+
let pendingPromise = null;
|
|
15
|
+
let releasePending = () => { };
|
|
16
|
+
const start = () => {
|
|
17
|
+
const active = (async () => {
|
|
18
|
+
try {
|
|
19
|
+
await run();
|
|
20
|
+
}
|
|
21
|
+
finally {
|
|
22
|
+
inFlight = null;
|
|
23
|
+
if (pending) {
|
|
24
|
+
pending = false;
|
|
25
|
+
const release = releasePending;
|
|
26
|
+
releasePending = () => { };
|
|
27
|
+
pendingPromise = null;
|
|
28
|
+
// Chain the follow-up, then settle everyone who waited for it.
|
|
29
|
+
void start().finally(release);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
})();
|
|
33
|
+
inFlight = active;
|
|
34
|
+
return active;
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
request: async () => {
|
|
38
|
+
if (inFlight === null) {
|
|
39
|
+
await start();
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (!pending) {
|
|
43
|
+
pending = true;
|
|
44
|
+
pendingPromise = new Promise((resolve) => {
|
|
45
|
+
releasePending = resolve;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
// `pendingPromise` is non-null whenever `pending` is set; the local
|
|
49
|
+
// binding keeps that visible to the type checker after the await.
|
|
50
|
+
const wait = pendingPromise;
|
|
51
|
+
if (wait !== null)
|
|
52
|
+
await wait;
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/server",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.137",
|
|
4
4
|
"private": false,
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
"@camstack/addon-auth": "1.2.26",
|
|
39
39
|
"@camstack/addon-decoder-nodeav": "1.2.22",
|
|
40
40
|
"@camstack/addon-notifiers": "1.2.27",
|
|
41
|
-
"@camstack/addon-pipeline": "1.2.
|
|
41
|
+
"@camstack/addon-pipeline": "1.2.100",
|
|
42
42
|
"@camstack/addon-pipeline-orchestrator": "1.2.83",
|
|
43
|
-
"@camstack/addon-post-analysis": "1.2.
|
|
43
|
+
"@camstack/addon-post-analysis": "1.2.100",
|
|
44
44
|
"@camstack/sdk": "1.2.25",
|
|
45
45
|
"@camstack/shm-ring": "1.1.22",
|
|
46
|
-
"@camstack/system": "1.2.
|
|
46
|
+
"@camstack/system": "1.2.108",
|
|
47
47
|
"@camstack/types": "1.2.90",
|
|
48
48
|
"@camstack/ui-library": "1.2.62",
|
|
49
49
|
"@fastify/compress": "^9.0.0",
|