@descryy/runtime-orchestrator 0.4.12 → 0.5.1
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/attach-log-sources.d.ts +60 -0
- package/dist/attach-log-sources.d.ts.map +1 -0
- package/dist/attach-log-sources.js +238 -0
- package/dist/attach-log-sources.js.map +1 -0
- package/dist/attach-to-running-jvm-process.d.ts.map +1 -1
- package/dist/attach-to-running-jvm-process.js +129 -37
- package/dist/attach-to-running-jvm-process.js.map +1 -1
- package/dist/attach-to-running-node-process.d.ts +2 -0
- package/dist/attach-to-running-node-process.d.ts.map +1 -1
- package/dist/attach-to-running-node-process.js +222 -27
- package/dist/attach-to-running-node-process.js.map +1 -1
- package/dist/attach-to-running-process.d.ts.map +1 -1
- package/dist/attach-to-running-process.js +57 -11
- package/dist/attach-to-running-process.js.map +1 -1
- package/dist/cdp-client.d.ts +7 -1
- package/dist/cdp-client.d.ts.map +1 -1
- package/dist/cdp-client.js +83 -7
- package/dist/cdp-client.js.map +1 -1
- package/dist/cgroup-partial-restriction.d.ts.map +1 -1
- package/dist/cgroup-partial-restriction.js +4 -1
- package/dist/cgroup-partial-restriction.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/instrumented-execution.d.ts +2 -0
- package/dist/instrumented-execution.d.ts.map +1 -1
- package/dist/instrumented-execution.js +166 -24
- package/dist/instrumented-execution.js.map +1 -1
- package/dist/jvm-agent/build.d.ts +2 -2
- package/dist/jvm-agent/build.d.ts.map +1 -1
- package/dist/jvm-agent/build.js +46 -17
- package/dist/jvm-agent/build.js.map +1 -1
- package/dist/polling-output-source.d.ts +16 -6
- package/dist/polling-output-source.d.ts.map +1 -1
- package/dist/polling-output-source.js +38 -22
- package/dist/polling-output-source.js.map +1 -1
- package/dist/profile-backend-observation.d.ts +7 -0
- package/dist/profile-backend-observation.d.ts.map +1 -1
- package/dist/profile-backend-observation.js +87 -25
- package/dist/profile-backend-observation.js.map +1 -1
- package/dist/respawn-and-supervise.d.ts +1 -0
- package/dist/respawn-and-supervise.d.ts.map +1 -1
- package/dist/respawn-and-supervise.js +29 -1
- package/dist/respawn-and-supervise.js.map +1 -1
- package/package.json +17 -17
package/dist/cdp-client.js
CHANGED
|
@@ -11,30 +11,82 @@
|
|
|
11
11
|
* one `{id, result}` or `{id, error}` reply; an event has `method`/`params`, no `id`.
|
|
12
12
|
* This client does only that framing — method names and event shapes are the caller's.
|
|
13
13
|
*/
|
|
14
|
+
const DEFAULT_CONNECT_TIMEOUT_MS = 10_000;
|
|
15
|
+
const DEFAULT_COMMAND_TIMEOUT_MS = 10_000;
|
|
16
|
+
const DEFAULT_MAX_EVENTS_PER_SESSION = 200_000;
|
|
17
|
+
const MAX_REPORTED_HANDLER_ERRORS = 10;
|
|
14
18
|
/**
|
|
15
19
|
* Resolves once the socket is open, or rejects if it errors/closes first —
|
|
16
20
|
* so a caller never has to race `open` against `error` itself.
|
|
17
21
|
*/
|
|
18
|
-
export function connectCdp(webSocketUrl) {
|
|
22
|
+
export function connectCdp(webSocketUrl, options = {}) {
|
|
23
|
+
const connectTimeoutMs = options.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;
|
|
24
|
+
const commandTimeoutMs = options.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;
|
|
25
|
+
const maxEvents = options.maxEventsPerSession ?? DEFAULT_MAX_EVENTS_PER_SESSION;
|
|
26
|
+
let eventsSeen = 0;
|
|
27
|
+
let handlerErrors = 0;
|
|
28
|
+
let closedByCaller = false;
|
|
29
|
+
const reportHandlerError = (method, error) => {
|
|
30
|
+
handlerErrors += 1;
|
|
31
|
+
if (handlerErrors > MAX_REPORTED_HANDLER_ERRORS + 1)
|
|
32
|
+
return;
|
|
33
|
+
const reported = handlerErrors === MAX_REPORTED_HANDLER_ERRORS + 1 ? new Error("further CDP event handler errors are suppressed") : error;
|
|
34
|
+
try {
|
|
35
|
+
if (options.onHandlerError !== undefined)
|
|
36
|
+
options.onHandlerError(method, reported);
|
|
37
|
+
else
|
|
38
|
+
console.error(`[cdp-client] a handler for ${method} threw: ${reported instanceof Error ? reported.message : String(reported)}`);
|
|
39
|
+
}
|
|
40
|
+
catch (callbackError) {
|
|
41
|
+
console.error(`[cdp-client] onHandlerError threw while reporting a ${method} handler error: ${callbackError instanceof Error ? callbackError.message : String(callbackError)}`);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
19
44
|
return new Promise((resolveConnect, rejectConnect) => {
|
|
20
45
|
const socket = new WebSocket(webSocketUrl);
|
|
46
|
+
const connectTimer = setTimeout(() => {
|
|
47
|
+
if (settled)
|
|
48
|
+
return;
|
|
49
|
+
settled = true;
|
|
50
|
+
socket.close();
|
|
51
|
+
rejectConnect(new Error(`CDP WebSocket to ${webSocketUrl} did not open within ${connectTimeoutMs} ms`));
|
|
52
|
+
}, connectTimeoutMs);
|
|
21
53
|
const pending = new Map();
|
|
22
54
|
const listeners = new Map();
|
|
23
55
|
let nextId = 1;
|
|
24
56
|
let settled = false;
|
|
25
57
|
function failAllPending(error) {
|
|
26
|
-
for (const { reject } of pending.values())
|
|
58
|
+
for (const { reject, timer } of pending.values()) {
|
|
59
|
+
clearTimeout(timer);
|
|
27
60
|
reject(error);
|
|
61
|
+
}
|
|
28
62
|
pending.clear();
|
|
29
63
|
}
|
|
30
64
|
socket.addEventListener("open", () => {
|
|
65
|
+
clearTimeout(connectTimer);
|
|
66
|
+
if (settled)
|
|
67
|
+
return;
|
|
31
68
|
settled = true;
|
|
32
69
|
resolveConnect({
|
|
33
70
|
send(method, params = {}) {
|
|
71
|
+
if (socket.readyState !== WebSocket.OPEN) {
|
|
72
|
+
return Promise.reject(new Error(`CDP WebSocket to ${webSocketUrl} is not open; ${method} was not sent`));
|
|
73
|
+
}
|
|
34
74
|
const id = nextId++;
|
|
35
75
|
return new Promise((resolve, reject) => {
|
|
36
|
-
|
|
37
|
-
|
|
76
|
+
const timer = setTimeout(() => {
|
|
77
|
+
if (!pending.delete(id))
|
|
78
|
+
return;
|
|
79
|
+
reject(new Error(`CDP command ${method} got no reply within ${commandTimeoutMs} ms`));
|
|
80
|
+
}, commandTimeoutMs);
|
|
81
|
+
pending.set(id, { resolve: resolve, reject, timer });
|
|
82
|
+
try {
|
|
83
|
+
socket.send(JSON.stringify({ id, method, params }));
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
clearTimeout(timer);
|
|
87
|
+
pending.delete(id);
|
|
88
|
+
reject(error instanceof Error ? error : new Error(String(error)));
|
|
89
|
+
}
|
|
38
90
|
});
|
|
39
91
|
},
|
|
40
92
|
on(method, handler) {
|
|
@@ -47,6 +99,7 @@ export function connectCdp(webSocketUrl) {
|
|
|
47
99
|
return () => set.delete(handler);
|
|
48
100
|
},
|
|
49
101
|
close() {
|
|
102
|
+
closedByCaller = true;
|
|
50
103
|
socket.close();
|
|
51
104
|
},
|
|
52
105
|
});
|
|
@@ -66,6 +119,7 @@ export function connectCdp(webSocketUrl) {
|
|
|
66
119
|
if (waiting === undefined)
|
|
67
120
|
return;
|
|
68
121
|
pending.delete(msg.id);
|
|
122
|
+
clearTimeout(waiting.timer);
|
|
69
123
|
if (msg.error !== undefined) {
|
|
70
124
|
waiting.reject(new Error(`CDP error for message ${String(msg.id)}: ${msg.error.message}`));
|
|
71
125
|
}
|
|
@@ -75,23 +129,45 @@ export function connectCdp(webSocketUrl) {
|
|
|
75
129
|
return;
|
|
76
130
|
}
|
|
77
131
|
if (msg.method !== undefined) {
|
|
132
|
+
if (closedByCaller)
|
|
133
|
+
return;
|
|
78
134
|
const set = listeners.get(msg.method);
|
|
79
135
|
if (set === undefined)
|
|
80
136
|
return;
|
|
81
|
-
|
|
82
|
-
|
|
137
|
+
eventsSeen += 1;
|
|
138
|
+
if (eventsSeen > maxEvents) {
|
|
139
|
+
if (eventsSeen === maxEvents + 1)
|
|
140
|
+
reportHandlerError(msg.method, new Error(`more than ${String(maxEvents)} CDP events arrived in this session; the rest are dropped`));
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const params = typeof msg.params === "object" && msg.params !== null ? msg.params : {};
|
|
144
|
+
for (const handler of set) {
|
|
145
|
+
try {
|
|
146
|
+
handler(params);
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
reportHandlerError(msg.method, error);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
83
152
|
}
|
|
84
153
|
});
|
|
85
154
|
socket.addEventListener("error", () => {
|
|
86
155
|
const error = new Error(`CDP WebSocket error connecting to ${webSocketUrl}`);
|
|
87
156
|
if (!settled) {
|
|
88
157
|
settled = true;
|
|
158
|
+
clearTimeout(connectTimer);
|
|
89
159
|
rejectConnect(error);
|
|
90
160
|
}
|
|
91
161
|
failAllPending(error);
|
|
92
162
|
});
|
|
93
163
|
socket.addEventListener("close", () => {
|
|
94
|
-
|
|
164
|
+
const error = new Error(`CDP WebSocket to ${webSocketUrl} closed`);
|
|
165
|
+
if (!settled) {
|
|
166
|
+
settled = true;
|
|
167
|
+
clearTimeout(connectTimer);
|
|
168
|
+
rejectConnect(error);
|
|
169
|
+
}
|
|
170
|
+
failAllPending(error);
|
|
95
171
|
});
|
|
96
172
|
});
|
|
97
173
|
}
|
package/dist/cdp-client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cdp-client.js","sourceRoot":"","sources":["../src/cdp-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"cdp-client.js","sourceRoot":"","sources":["../src/cdp-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAwBH,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAC1C,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAC1C,MAAM,8BAA8B,GAAG,OAAO,CAAC;AAC/C,MAAM,2BAA2B,GAAG,EAAE,CAAC;AAEvC;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,YAAoB,EAAE,UAA6B,EAAE;IAC9E,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,0BAA0B,CAAC;IAChF,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,0BAA0B,CAAC;IAChF,MAAM,SAAS,GAAG,OAAO,CAAC,mBAAmB,IAAI,8BAA8B,CAAC;IAChF,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,MAAM,kBAAkB,GAAG,CAAC,MAAc,EAAE,KAAc,EAAQ,EAAE;QAClE,aAAa,IAAI,CAAC,CAAC;QACnB,IAAI,aAAa,GAAG,2BAA2B,GAAG,CAAC;YAAE,OAAO;QAC5D,MAAM,QAAQ,GAAG,aAAa,KAAK,2BAA2B,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAC1I,IAAI,CAAC;YACH,IAAI,OAAO,CAAC,cAAc,KAAK,SAAS;gBAAE,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;;gBAC9E,OAAO,CAAC,KAAK,CAAC,8BAA8B,MAAM,WAAW,QAAQ,YAAY,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACvI,CAAC;QAAC,OAAO,aAAa,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,uDAAuD,MAAM,mBAAmB,aAAa,YAAY,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QAClL,CAAC;IACH,CAAC,CAAC;IACF,OAAO,IAAI,OAAO,CAAC,CAAC,cAAc,EAAE,aAAa,EAAE,EAAE;QACnD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,YAAY,CAAC,CAAC;QAC3C,MAAM,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE;YACnC,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,aAAa,CAAC,IAAI,KAAK,CAAC,oBAAoB,YAAY,wBAAwB,gBAAgB,KAAK,CAAC,CAAC,CAAC;QAC1G,CAAC,EAAE,gBAAgB,CAAC,CAAC;QACrB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAwB,CAAC;QAChD,MAAM,SAAS,GAAG,IAAI,GAAG,EAA0D,CAAC;QACpF,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,SAAS,cAAc,CAAC,KAAY;YAClC,KAAK,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;gBACjD,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC;YACD,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;QAED,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE;YACnC,YAAY,CAAC,YAAY,CAAC,CAAC;YAC3B,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,cAAc,CAAC;gBACb,IAAI,CAAI,MAAc,EAAE,SAAkC,EAAE;oBAC1D,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;wBACzC,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,oBAAoB,YAAY,iBAAiB,MAAM,eAAe,CAAC,CAAC,CAAC;oBAC3G,CAAC;oBACD,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;oBACpB,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;wBACxC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;4BAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gCAAE,OAAO;4BAChC,MAAM,CAAC,IAAI,KAAK,CAAC,eAAe,MAAM,wBAAwB,gBAAgB,KAAK,CAAC,CAAC,CAAC;wBACxF,CAAC,EAAE,gBAAgB,CAAC,CAAC;wBACrB,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,OAAmC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;wBACjF,IAAI,CAAC;4BACH,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;wBACtD,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,YAAY,CAAC,KAAK,CAAC,CAAC;4BACpB,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;4BACnB,MAAM,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;wBACpE,CAAC;oBACH,CAAC,CAAC,CAAC;gBACL,CAAC;gBACD,EAAE,CAAC,MAAc,EAAE,OAAkD;oBACnE,IAAI,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;oBAChC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;wBACtB,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;wBAChB,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;oBAC7B,CAAC;oBACD,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oBACjB,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBACnC,CAAC;gBACD,KAAK;oBACH,cAAc,GAAG,IAAI,CAAC;oBACtB,MAAM,CAAC,KAAK,EAAE,CAAC;gBACjB,CAAC;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,KAAmB,EAAE,EAAE;YACzD,MAAM,GAAG,GAAG,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC7E,IAAI,GAAsH,CAAC;YAC3H,IAAI,CAAC;gBACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAe,CAAC;YACtC,CAAC;YAAC,MAAM,CAAC;gBACP,sEAAsE;gBACtE,OAAO;YACT,CAAC;YAED,IAAI,GAAG,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACpC,IAAI,OAAO,KAAK,SAAS;oBAAE,OAAO;gBAClC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACvB,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC5B,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;oBAC5B,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBAC7F,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAC9B,CAAC;gBACD,OAAO;YACT,CAAC;YAED,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC7B,IAAI,cAAc;oBAAE,OAAO;gBAC3B,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACtC,IAAI,GAAG,KAAK,SAAS;oBAAE,OAAO;gBAC9B,UAAU,IAAI,CAAC,CAAC;gBAChB,IAAI,UAAU,GAAG,SAAS,EAAE,CAAC;oBAC3B,IAAI,UAAU,KAAK,SAAS,GAAG,CAAC;wBAAE,kBAAkB,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,aAAa,MAAM,CAAC,SAAS,CAAC,2DAA2D,CAAC,CAAC,CAAC;oBACvK,OAAO;gBACT,CAAC;gBACD,MAAM,MAAM,GAAG,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvF,KAAK,MAAM,OAAO,IAAI,GAAG,EAAE,CAAC;oBAC1B,IAAI,CAAC;wBACH,OAAO,CAAC,MAAM,CAAC,CAAC;oBAClB,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,kBAAkB,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;oBACxC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;YACpC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,qCAAqC,YAAY,EAAE,CAAC,CAAC;YAC7E,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,GAAG,IAAI,CAAC;gBACf,YAAY,CAAC,YAAY,CAAC,CAAC;gBAC3B,aAAa,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC;YACD,cAAc,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;YACpC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,oBAAoB,YAAY,SAAS,CAAC,CAAC;YACnE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,GAAG,IAAI,CAAC;gBACf,YAAY,CAAC,YAAY,CAAC,CAAC;gBAC3B,aAAa,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC;YACD,cAAc,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cgroup-partial-restriction.d.ts","sourceRoot":"","sources":["../src/cgroup-partial-restriction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"cgroup-partial-restriction.d.ts","sourceRoot":"","sources":["../src/cgroup-partial-restriction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAMnE,iIAAiI;AACjI,eAAO,MAAM,gCAAgC,EAAG,qEAA8E,CAAC;AA2C/H;;;;;GAKG;AACH,wBAAgB,2BAA2B,IAAI,MAAM,GAAG,IAAI,CAc3D;AAED,wBAAgB,kBAAkB,IAAI,gBAAgB,CAkBrD;AAED,MAAM,WAAW,oBAAoB;IACnC;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,4FAA4F;IAC5F,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,oEAAoE;IACpE,QAAQ,CAAC,KAAK,EAAE,OAAO,gCAAgC,CAAC;IACxD,QAAQ,CAAC,aAAa,EAAE,oBAAoB,CAAC;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC;CACjC;AAED;;;;;;;;GAQG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE;IACvD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,GAAG,gBAAgB,CAwEnB"}
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
*/
|
|
23
23
|
import { existsSync, mkdirSync, readFileSync, rmdirSync, writeFileSync } from "node:fs";
|
|
24
24
|
import { dirname, join } from "node:path";
|
|
25
|
+
import { assertTargetPid } from "@descryy/runtime-controller";
|
|
25
26
|
import { isProcessAlive } from "./attach-to-running-process.js";
|
|
26
27
|
const CGROUP_ROOT = "/sys/fs/cgroup";
|
|
27
28
|
/** Literal scope string every `CgroupMoveResult` carries under `scope` — never restated by hand, so quotes of it can't drift. */
|
|
@@ -120,6 +121,7 @@ export function cgroupV2Capability() {
|
|
|
120
121
|
* removed and the error rethrown, never left orphaned.
|
|
121
122
|
*/
|
|
122
123
|
export function moveProcessIntoRestrictedCgroup(options) {
|
|
124
|
+
assertTargetPid(options.pid);
|
|
123
125
|
if (!isProcessAlive(options.pid)) {
|
|
124
126
|
throw new Error(`moveProcessIntoRestrictedCgroup: pid ${String(options.pid)} is not running -- cannot move a target that does not exist.`);
|
|
125
127
|
}
|
|
@@ -132,7 +134,8 @@ export function moveProcessIntoRestrictedCgroup(options) {
|
|
|
132
134
|
// unreachable given availability check above; narrows the type honestly
|
|
133
135
|
throw new Error("moveProcessIntoRestrictedCgroup: no delegated cgroup ancestor found despite capability reporting available -- internal inconsistency.");
|
|
134
136
|
}
|
|
135
|
-
const
|
|
137
|
+
const safeNameHint = (options.nameHint ?? String(options.pid)).replace(/[^A-Za-z0-9_.-]/g, "_").slice(0, 64);
|
|
138
|
+
const cgroupPath = join(ancestor, `descry-restrict-${safeNameHint}-${String(Date.now())}`);
|
|
136
139
|
mkdirSync(cgroupPath);
|
|
137
140
|
try {
|
|
138
141
|
if (options.limits.cpuMax !== undefined && !existsSync(join(cgroupPath, "cpu.max"))) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cgroup-partial-restriction.js","sourceRoot":"","sources":["../src/cgroup-partial-restriction.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cgroup-partial-restriction.js","sourceRoot":"","sources":["../src/cgroup-partial-restriction.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -16,4 +16,7 @@ export type { InstrumentedExecutionInput, InstrumentedExecutionResult, Execution
|
|
|
16
16
|
export { runInstrumentedExecution, createSourceRootResolver, applyOutboundLaunch } from "./instrumented-execution.ts";
|
|
17
17
|
export type { BackendObservationMechanism, RunRemoteLogObservationInput, RunRemoteLogObservationResult, } from "./profile-backend-observation.ts";
|
|
18
18
|
export { backendObservationMechanismFor, runRemoteLogObservation } from "./profile-backend-observation.ts";
|
|
19
|
+
export type { ProcessSpawner } from "./attach-log-sources.ts";
|
|
20
|
+
export { createDockerAttachLogSource, createKubernetesAttachLogSource, createPodmanAttachLogSource, createSystemdAttachLogSource } from "./attach-log-sources.ts";
|
|
21
|
+
export type { KubernetesContainerTarget } from "./attach-log-sources.ts";
|
|
19
22
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iCAAiC,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,gCAAgC,EAAE,MAAM,4BAA4B,CAAC;AAC9E,YAAY,EAAE,6BAA6B,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AACjH,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACxF,YAAY,EAAE,iCAAiC,EAAE,MAAM,qCAAqC,CAAC;AAC7F,OAAO,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAC3G,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,gCAAgC,EAAE,MAAM,oCAAoC,CAAC;AAC3F,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAC/E,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAC9F,YAAY,EACV,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,gCAAgC,EAChC,kBAAkB,EAClB,2BAA2B,EAC3B,+BAA+B,GAChC,MAAM,iCAAiC,CAAC;AACzC,YAAY,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACnI,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACtH,YAAY,EACV,2BAA2B,EAC3B,4BAA4B,EAC5B,6BAA6B,GAC9B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,8BAA8B,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iCAAiC,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,gCAAgC,EAAE,MAAM,4BAA4B,CAAC;AAC9E,YAAY,EAAE,6BAA6B,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AACjH,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACxF,YAAY,EAAE,iCAAiC,EAAE,MAAM,qCAAqC,CAAC;AAC7F,OAAO,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAC3G,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,gCAAgC,EAAE,MAAM,oCAAoC,CAAC;AAC3F,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAC/E,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAC9F,YAAY,EACV,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,gCAAgC,EAChC,kBAAkB,EAClB,2BAA2B,EAC3B,+BAA+B,GAChC,MAAM,iCAAiC,CAAC;AACzC,YAAY,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACnI,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACtH,YAAY,EACV,2BAA2B,EAC3B,4BAA4B,EAC5B,6BAA6B,GAC9B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,8BAA8B,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAE3G,YAAY,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,2BAA2B,EAAE,+BAA+B,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAC;AAClK,YAAY,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -7,4 +7,5 @@ export { respawnAndSupervise, inferRespawnCommandFromProc } from "./respawn-and-
|
|
|
7
7
|
export { CGROUP_PARTIAL_RESTRICTION_SCOPE, cgroupV2Capability, findDelegatedCgroupAncestor, moveProcessIntoRestrictedCgroup, } from "./cgroup-partial-restriction.js";
|
|
8
8
|
export { runInstrumentedExecution, createSourceRootResolver, applyOutboundLaunch } from "./instrumented-execution.js";
|
|
9
9
|
export { backendObservationMechanismFor, runRemoteLogObservation } from "./profile-backend-observation.js";
|
|
10
|
+
export { createDockerAttachLogSource, createKubernetesAttachLogSource, createPodmanAttachLogSource, createSystemdAttachLogSource } from "./attach-log-sources.js";
|
|
10
11
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gCAAgC,EAAE,MAAM,4BAA4B,CAAC;AAE9E,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAExF,OAAO,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAE3G,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAO/E,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAK9F,OAAO,EACL,gCAAgC,EAChC,kBAAkB,EAClB,2BAA2B,EAC3B,+BAA+B,GAChC,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAMtH,OAAO,EAAE,8BAA8B,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gCAAgC,EAAE,MAAM,4BAA4B,CAAC;AAE9E,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAExF,OAAO,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAE3G,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAO/E,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAK9F,OAAO,EACL,gCAAgC,EAChC,kBAAkB,EAClB,2BAA2B,EAC3B,+BAA+B,GAChC,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAMtH,OAAO,EAAE,8BAA8B,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAG3G,OAAO,EAAE,2BAA2B,EAAE,+BAA+B,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -29,6 +29,8 @@ export interface InstrumentedExecutionInput {
|
|
|
29
29
|
* window is rather than this module guessing.
|
|
30
30
|
*/
|
|
31
31
|
readonly observeForMs: number;
|
|
32
|
+
readonly collectorStopTimeoutMs?: number;
|
|
33
|
+
readonly collectorStartTimeoutMs?: number;
|
|
32
34
|
/**
|
|
33
35
|
* Opt-in, per service name: front that service with `InboundProxy` (RT-192,
|
|
34
36
|
* DEC-271) once its own readiness has already succeeded — reads the answer
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumented-execution.d.ts","sourceRoot":"","sources":["../src/instrumented-execution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"instrumented-execution.d.ts","sourceRoot":"","sources":["../src/instrumented-execution.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,12 +11,13 @@
|
|
|
11
11
|
* nodes, or drive a browser — separate stages, separate contracts.
|
|
12
12
|
*/
|
|
13
13
|
import { delimiter } from "node:path";
|
|
14
|
-
import { resolveServiceRootForOrigin } from "@descryy/runtime-contracts";
|
|
14
|
+
import { isTerminalExecutionState, resolveServiceRootForOrigin } from "@descryy/runtime-contracts";
|
|
15
15
|
import { createInboundProxy } from "@descryy/runtime-backend-observation";
|
|
16
16
|
import { createExternalRequestCollector } from "@descryy/runtime-external-service-observation";
|
|
17
17
|
import { ExecutionController, checkDependencyVersions, checkEnvironmentVersion, runPreflight, portFreeCheck, readinessTargetCheck, createProcessOutputReader, } from "@descryy/runtime-controller";
|
|
18
18
|
import { EvidenceStore } from "@descryy/runtime-evidence-store";
|
|
19
19
|
import { createPollingProcessOutputSource } from "./polling-output-source.js";
|
|
20
|
+
import { createDockerAttachLogSource, createKubernetesAttachLogSource, createPodmanAttachLogSource, createSystemdAttachLogSource } from "./attach-log-sources.js";
|
|
20
21
|
import { COLLECTOR_VERSION } from "./collector-version.js";
|
|
21
22
|
/**
|
|
22
23
|
* Every spawned service's captured output, read off the controller at the
|
|
@@ -132,6 +133,18 @@ export async function runInstrumentedExecution(input) {
|
|
|
132
133
|
};
|
|
133
134
|
};
|
|
134
135
|
const controller = ExecutionController.create(launchedExecution);
|
|
136
|
+
const runSignal = input.runOptions.signal;
|
|
137
|
+
const timingProblem = invalidTimingReason(input.observeForMs, configuration.timeoutMs);
|
|
138
|
+
if (timingProblem !== null) {
|
|
139
|
+
return {
|
|
140
|
+
execution: controller.execution,
|
|
141
|
+
evidence: [],
|
|
142
|
+
collectorCapabilities: [],
|
|
143
|
+
validationError: `${timingProblem}; nothing was started.`,
|
|
144
|
+
budget: budgetOutcome(0),
|
|
145
|
+
serviceOutput: {},
|
|
146
|
+
};
|
|
147
|
+
}
|
|
135
148
|
// B7: the execution row, minted here and nowhere else in production.
|
|
136
149
|
// `EvidenceStore.recordExecution` was complete and tested since the
|
|
137
150
|
// `executions` table was added -- schema, redaction, environment capture,
|
|
@@ -237,27 +250,53 @@ export async function runInstrumentedExecution(input) {
|
|
|
237
250
|
// backend log collector eat every DESCRY_EXTERNAL_REQUEST line and the outbound
|
|
238
251
|
// collector report nothing, reading as "no outbound calls".
|
|
239
252
|
const namedSources = [];
|
|
253
|
+
// H-attach-log-discovery: a service attached via a discovered stream source
|
|
254
|
+
// (Docker/systemd -- `resolveLogSourceForPid`, `@descryy/runtime-controller`)
|
|
255
|
+
// has no file for `ManagedProcess.readOutput()` to tail at all, so it gets a
|
|
256
|
+
// live `createDockerAttachLogSource`/`createSystemdAttachLogSource` instead
|
|
257
|
+
// of the ordinary polling source. Both spawn on first read, stop on `finished`, and start from `attachedAt` -- no
|
|
258
|
+
// RT-N3 fence applies to either (`DiscoveredAttachLogSource`'s own doc,
|
|
259
|
+
// `@descryy/runtime-contracts`), so `preExistingLineCount` is simply omitted.
|
|
260
|
+
// One boundary for every stream source this run builds, fixed before any of them is read.
|
|
261
|
+
const attachedAt = new Date();
|
|
262
|
+
function buildSourceFor(handle, serviceName) {
|
|
263
|
+
const discovered = configuration.services[serviceName]?.attach?.discoveredLogSource;
|
|
264
|
+
if (discovered !== undefined) {
|
|
265
|
+
const streamOptions = { processId: handle.processId, serviceName, isFinished: () => finished, attachedAt };
|
|
266
|
+
switch (discovered.kind) {
|
|
267
|
+
case "docker":
|
|
268
|
+
return createDockerAttachLogSource(discovered.container, streamOptions);
|
|
269
|
+
case "podman":
|
|
270
|
+
return createPodmanAttachLogSource(discovered.container, streamOptions);
|
|
271
|
+
case "kubernetes":
|
|
272
|
+
return createKubernetesAttachLogSource(discovered, streamOptions);
|
|
273
|
+
case "systemd":
|
|
274
|
+
return createSystemdAttachLogSource(discovered.unit, streamOptions);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// RT-N3 bug fix: an attached service's pre-existing log backlog (anything
|
|
278
|
+
// already written before this run attached, including a stale crash from
|
|
279
|
+
// an earlier, unrelated process on the same log path) must never be
|
|
280
|
+
// reported as evidence this run witnessed. `attachFenceFor` is `null` for
|
|
281
|
+
// a spawned service -- nothing predates observation there -- so this is a
|
|
282
|
+
// no-op (0) for every case except a real file-based attach.
|
|
283
|
+
const preExistingLineCount = controller.attachFenceFor(serviceName)?.preExistingLineCount ?? 0;
|
|
284
|
+
return createPollingProcessOutputSource({
|
|
285
|
+
processId: handle.processId,
|
|
286
|
+
serviceName,
|
|
287
|
+
readOutputFrom: (cursor) => controller.readProcessOutputFrom(serviceName, cursor),
|
|
288
|
+
isFinished: () => finished,
|
|
289
|
+
preExistingLineCount,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
240
292
|
for (const handle of execution.processes) {
|
|
241
293
|
if (handle.serviceName === null)
|
|
242
294
|
continue;
|
|
243
295
|
const serviceName = handle.serviceName;
|
|
244
296
|
// stamped here, at construction -- by the time evidence reaches
|
|
245
297
|
// correlateExecution the handle is out of scope and this association is gone
|
|
246
|
-
sources.push(
|
|
247
|
-
|
|
248
|
-
serviceName,
|
|
249
|
-
readOutput: () => controller.readProcessOutput(serviceName),
|
|
250
|
-
isFinished: () => finished,
|
|
251
|
-
}));
|
|
252
|
-
namedSources.push({
|
|
253
|
-
serviceName,
|
|
254
|
-
source: createPollingProcessOutputSource({
|
|
255
|
-
processId: handle.processId,
|
|
256
|
-
serviceName,
|
|
257
|
-
readOutput: () => controller.readProcessOutput(serviceName),
|
|
258
|
-
isFinished: () => finished,
|
|
259
|
-
}),
|
|
260
|
-
});
|
|
298
|
+
sources.push(buildSourceFor(handle, serviceName));
|
|
299
|
+
namedSources.push({ serviceName, source: buildSourceFor(handle, serviceName) });
|
|
261
300
|
}
|
|
262
301
|
const backendCollectors = input.adapter.createBackendCollectors(sources);
|
|
263
302
|
// only started when the launch above actually installed instrumentation --
|
|
@@ -272,6 +311,8 @@ export async function runInstrumentedExecution(input) {
|
|
|
272
311
|
stackTraceParser: input.adapter.stackTraceParser,
|
|
273
312
|
}));
|
|
274
313
|
const emitted = [];
|
|
314
|
+
let emissionClosed = false;
|
|
315
|
+
let lateEmitsDropped = 0;
|
|
275
316
|
// RT-261: bounds on the evidence THIS run accumulates in memory, on top of
|
|
276
317
|
// (not instead of) each collector's own bounds -- a noisy app that clears
|
|
277
318
|
// every per-collector cap by fanning across many sources could still grow
|
|
@@ -445,6 +486,14 @@ export async function runInstrumentedExecution(input) {
|
|
|
445
486
|
// MAX_EVENTS_PER_SOURCE/MAX_RUN_EVIDENCE_BYTES block above this function.
|
|
446
487
|
emit: (evidenceInput) => {
|
|
447
488
|
const { source } = evidenceInput;
|
|
489
|
+
if (emissionClosed) {
|
|
490
|
+
lateEmitsDropped += 1;
|
|
491
|
+
if (lateEmitsDropped === 1) {
|
|
492
|
+
console.error(`[runInstrumentedExecution] a collector emitted "${evidenceInput.eventType}" from source "${source}" after this run had returned; ` +
|
|
493
|
+
"evidence arriving after the run ended is dropped (the store may already be closed), and further late events are dropped without another message.");
|
|
494
|
+
}
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
448
497
|
const countSoFar = eventCountBySource.get(source) ?? 0;
|
|
449
498
|
if (countSoFar >= MAX_EVENTS_PER_SOURCE) {
|
|
450
499
|
if (!sourcesAtCap.has(source)) {
|
|
@@ -485,11 +534,15 @@ export async function runInstrumentedExecution(input) {
|
|
|
485
534
|
// "I looked and could not" -- so it's caught here and tagged "harness" rather
|
|
486
535
|
// than the collector's domain source, instead of aborting this Promise.all
|
|
487
536
|
// uncaught with zero evidence trail.
|
|
537
|
+
const startBoundMs = Math.max(1, Math.min(input.collectorStartTimeoutMs ?? Number.POSITIVE_INFINITY, budgetStartedAt + configuration.timeoutMs - Date.now()));
|
|
488
538
|
const startOutcomes = await Promise.all(collectors.map(async (collector) => {
|
|
489
539
|
try {
|
|
490
|
-
return { collector, result: await collector
|
|
540
|
+
return { collector, result: await startWithinBound(collector, context, startBoundMs, runSignal), threw: false };
|
|
491
541
|
}
|
|
492
542
|
catch (error) {
|
|
543
|
+
if (error instanceof CollectorStartAbandonedError) {
|
|
544
|
+
return { collector, result: { available: false, reason: error.message }, threw: false };
|
|
545
|
+
}
|
|
493
546
|
const detail = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
494
547
|
emitted.push(input.store.write({
|
|
495
548
|
executionId: execution.executionId,
|
|
@@ -564,6 +617,8 @@ export async function runInstrumentedExecution(input) {
|
|
|
564
617
|
let teardownFailure = null;
|
|
565
618
|
try {
|
|
566
619
|
await input.onReady?.({ execution, proxyPorts });
|
|
620
|
+
const stateBeforeWindow = controller.execution.state;
|
|
621
|
+
const endedBeforeWindow = isTerminalExecutionState(stateBeforeWindow);
|
|
567
622
|
// observation window is bounded by the declared budget, not just observeForMs
|
|
568
623
|
// -- unconditionally sleeping the full window used to leave timeoutMs bounding
|
|
569
624
|
// only the service, not the wait; measured, a 1500ms budget with a 12000ms
|
|
@@ -571,15 +626,24 @@ export async function runInstrumentedExecution(input) {
|
|
|
571
626
|
// remainder). Clamped rather than aborted: teardown still owns OS resources
|
|
572
627
|
// and must run; the overshoot is reported via budget.exceeded, not hidden.
|
|
573
628
|
const remainingMs = budgetStartedAt + configuration.timeoutMs - Date.now();
|
|
574
|
-
observationMs = Math.max(0, Math.min(input.observeForMs, remainingMs));
|
|
629
|
+
observationMs = endedBeforeWindow ? 0 : Math.max(0, Math.min(input.observeForMs, remainingMs));
|
|
575
630
|
if (observationMs > 0) {
|
|
576
|
-
|
|
631
|
+
observationMs = await observeUnlessCancelled(observationMs, runSignal);
|
|
632
|
+
}
|
|
633
|
+
if (endedBeforeWindow) {
|
|
634
|
+
emitted.push(harnessDisclosure(`the application was no longer running when the observation window would have started (execution state ${stateBeforeWindow}), so no live observation took place: ` +
|
|
635
|
+
`observed for 0ms of the ${String(input.observeForMs)}ms requested. Evidence is limited to what collectors could read from the output the run left behind — ` +
|
|
636
|
+
`absence of an event is not evidence the application did not produce one.`, "orchestrator:no-live-observation"));
|
|
637
|
+
}
|
|
638
|
+
if (runSignal?.aborted === true) {
|
|
639
|
+
emitted.push(harnessDisclosure(`the run was cancelled by its caller after ${String(observationMs)}ms of the ${String(input.observeForMs)}ms observation window. ` +
|
|
640
|
+
`Evidence from this run is partial — absence of an event is not evidence the application did not produce one.`, "orchestrator:cancellation"));
|
|
577
641
|
}
|
|
578
642
|
// rule 7: cut-short window is a labelled degradation. execution.state's
|
|
579
643
|
// TIMED_OUT says the services stopped early, not that observation did --
|
|
580
644
|
// tagged "harness"/COLLECTOR_ERROR to keep "found nothing" apart from
|
|
581
645
|
// "stopped looking".
|
|
582
|
-
if (observationMs < input.observeForMs) {
|
|
646
|
+
if (observationMs < input.observeForMs && runSignal?.aborted !== true && !endedBeforeWindow) {
|
|
583
647
|
emitted.push(input.store.write({
|
|
584
648
|
executionId: execution.executionId,
|
|
585
649
|
timestamp: new Date().toISOString(),
|
|
@@ -622,14 +686,20 @@ export async function runInstrumentedExecution(input) {
|
|
|
622
686
|
// completion regardless of any other's outcome; a rejection becomes a
|
|
623
687
|
// disclosed COLLECTOR_ERROR (its own evidence survives this run, it just
|
|
624
688
|
// named what went wrong) instead of an exception that skips the rest.
|
|
625
|
-
const
|
|
689
|
+
const stopBoundMs = input.collectorStopTimeoutMs ?? DEFAULT_COLLECTOR_STOP_TIMEOUT_MS;
|
|
690
|
+
const stopOutcomes = await Promise.allSettled(collectors.map((collector) => stopWithinBound(collector, stopBoundMs)));
|
|
626
691
|
for (let index = 0; index < stopOutcomes.length; index++) {
|
|
627
692
|
const outcome = stopOutcomes[index];
|
|
628
693
|
if (outcome?.status !== "rejected")
|
|
629
694
|
continue;
|
|
630
695
|
const collector = collectors[index];
|
|
696
|
+
const collectorId = collector?.collectorId ?? "unknown";
|
|
697
|
+
if (outcome.reason instanceof CollectorStopTimeoutError) {
|
|
698
|
+
emitted.push(harnessDisclosure(`collector "${collectorId}" did not finish stopping within ${stopBoundMs} ms; it was abandoned so the application could be stopped, and evidence it had not yet flushed is missing`, collectorId, outcome.reason.message));
|
|
699
|
+
continue;
|
|
700
|
+
}
|
|
631
701
|
const detail = outcome.reason instanceof Error ? `${outcome.reason.name}: ${outcome.reason.message}` : String(outcome.reason);
|
|
632
|
-
emitted.push(harnessDisclosure(`collector "${
|
|
702
|
+
emitted.push(harnessDisclosure(`collector "${collectorId}" threw during stop(): ${detail}`, collectorId, detail));
|
|
633
703
|
}
|
|
634
704
|
try {
|
|
635
705
|
// Always runs, even if one or more collectors above threw during
|
|
@@ -637,7 +707,10 @@ export async function runInstrumentedExecution(input) {
|
|
|
637
707
|
// collector's own teardown succeeding. This is the one failure RT-262
|
|
638
708
|
// still escalates: a process Descry cannot confirm it killed is a
|
|
639
709
|
// leaked process, not a degraded observation.
|
|
640
|
-
if (
|
|
710
|
+
if (runSignal?.aborted === true) {
|
|
711
|
+
await controller.cancel();
|
|
712
|
+
}
|
|
713
|
+
else if (observationMs < input.observeForMs) {
|
|
641
714
|
await controller.timeout();
|
|
642
715
|
}
|
|
643
716
|
else {
|
|
@@ -679,6 +752,7 @@ export async function runInstrumentedExecution(input) {
|
|
|
679
752
|
}
|
|
680
753
|
}
|
|
681
754
|
}
|
|
755
|
+
emissionClosed = true;
|
|
682
756
|
// rethrown untouched, same object/stack; caller's failure wins over teardown's
|
|
683
757
|
if (bodyFailure !== null)
|
|
684
758
|
throw bodyFailure.error;
|
|
@@ -686,11 +760,79 @@ export async function runInstrumentedExecution(input) {
|
|
|
686
760
|
throw teardownFailure.error;
|
|
687
761
|
return {
|
|
688
762
|
execution: controller.execution,
|
|
689
|
-
evidence: emitted,
|
|
763
|
+
evidence: [...emitted],
|
|
690
764
|
collectorCapabilities: collectors.map((collector) => ({ collectorId: collector.collectorId, capabilities: collector.capabilities() })),
|
|
691
765
|
validationError: null,
|
|
692
766
|
budget: budgetOutcome(observationMs),
|
|
693
767
|
serviceOutput: captureServiceOutput(controller),
|
|
694
768
|
};
|
|
695
769
|
}
|
|
770
|
+
const DEFAULT_COLLECTOR_STOP_TIMEOUT_MS = 15_000;
|
|
771
|
+
const LARGEST_TIMER_DELAY_MS = 2_147_483_647;
|
|
772
|
+
class CollectorStopTimeoutError extends Error {
|
|
773
|
+
}
|
|
774
|
+
class CollectorStartAbandonedError extends Error {
|
|
775
|
+
}
|
|
776
|
+
function timerDelay(ms) {
|
|
777
|
+
return Math.min(Math.max(1, Math.ceil(ms)), LARGEST_TIMER_DELAY_MS);
|
|
778
|
+
}
|
|
779
|
+
function invalidTimingReason(observeForMs, timeoutMs) {
|
|
780
|
+
if (!Number.isFinite(observeForMs) || observeForMs < 0) {
|
|
781
|
+
return `observeForMs must be a finite, non-negative number of milliseconds, got ${String(observeForMs)}`;
|
|
782
|
+
}
|
|
783
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || timeoutMs > LARGEST_TIMER_DELAY_MS) {
|
|
784
|
+
return `timeoutMs must be a positive number of milliseconds no larger than ${String(LARGEST_TIMER_DELAY_MS)} (a larger delay makes the timer fire at once), got ${String(timeoutMs)}`;
|
|
785
|
+
}
|
|
786
|
+
return null;
|
|
787
|
+
}
|
|
788
|
+
function startWithinBound(collector, context, boundMs, signal) {
|
|
789
|
+
let timer;
|
|
790
|
+
let onAbort;
|
|
791
|
+
const abandoned = new Promise((_, reject) => {
|
|
792
|
+
timer = setTimeout(() => reject(new CollectorStartAbandonedError(`collector "${collector.collectorId}" did not finish starting within ${String(boundMs)} ms and was abandoned; it is stopped with the others at the end of the run`)), timerDelay(boundMs));
|
|
793
|
+
if (signal?.aborted === true) {
|
|
794
|
+
reject(new CollectorStartAbandonedError(`collector "${collector.collectorId}" was still starting when the run was cancelled and was abandoned`));
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
onAbort = () => reject(new CollectorStartAbandonedError(`collector "${collector.collectorId}" was still starting when the run was cancelled and was abandoned`));
|
|
798
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
799
|
+
});
|
|
800
|
+
return Promise.race([Promise.resolve().then(() => collector.start(context)), abandoned]).finally(() => {
|
|
801
|
+
clearTimeout(timer);
|
|
802
|
+
if (onAbort !== undefined)
|
|
803
|
+
signal?.removeEventListener("abort", onAbort);
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
function stopWithinBound(collector, boundMs) {
|
|
807
|
+
let timer;
|
|
808
|
+
const expired = new Promise((_, reject) => {
|
|
809
|
+
timer = setTimeout(() => reject(new CollectorStopTimeoutError(`stop() still pending after ${boundMs} ms`)), timerDelay(boundMs));
|
|
810
|
+
});
|
|
811
|
+
return Promise.race([Promise.resolve().then(() => collector.stop()), expired]).finally(() => clearTimeout(timer));
|
|
812
|
+
}
|
|
813
|
+
function observeUnlessCancelled(windowMs, signal) {
|
|
814
|
+
const startedAt = Date.now();
|
|
815
|
+
return new Promise((resolve) => {
|
|
816
|
+
if (signal?.aborted === true) {
|
|
817
|
+
resolve(0);
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
let timer;
|
|
821
|
+
const onAbort = () => {
|
|
822
|
+
clearTimeout(timer);
|
|
823
|
+
resolve(Math.min(windowMs, Date.now() - startedAt));
|
|
824
|
+
};
|
|
825
|
+
const waitRemaining = () => {
|
|
826
|
+
const remaining = windowMs - (Date.now() - startedAt);
|
|
827
|
+
if (remaining <= 0) {
|
|
828
|
+
signal?.removeEventListener("abort", onAbort);
|
|
829
|
+
resolve(windowMs);
|
|
830
|
+
return;
|
|
831
|
+
}
|
|
832
|
+
timer = setTimeout(waitRemaining, timerDelay(remaining));
|
|
833
|
+
};
|
|
834
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
835
|
+
waitRemaining();
|
|
836
|
+
});
|
|
837
|
+
}
|
|
696
838
|
//# sourceMappingURL=instrumented-execution.js.map
|