openvidu-testapp: fix starvation when serializing events

v2compatibility
pabloFuente 2026-07-13 01:42:19 +02:00
parent 8949b4bf7a
commit 934d2274f9
3 changed files with 911 additions and 847 deletions

File diff suppressed because it is too large Load Diff

View File

@ -14,8 +14,8 @@
"colormap": "2.3.2", "colormap": "2.3.2",
"core-js": "3.26.1", "core-js": "3.26.1",
"json-stringify-safe": "5.0.1", "json-stringify-safe": "5.0.1",
"openvidu-browser-v2compatibility": "3.6.0", "openvidu-browser-v2compatibility": "3.8.0",
"openvidu-node-client-v2compatibility": "3.6.0", "openvidu-node-client-v2compatibility": "3.8.0",
"rxjs": "7.8.1", "rxjs": "7.8.1",
"tslib": "2.4.1", "tslib": "2.4.1",
"zone.js": "0.13.3" "zone.js": "0.13.3"

View File

@ -76,6 +76,13 @@ export class TestFeedService {
"rtcConfig", "rtcConfig",
"options", "options",
"connectOptions", "connectOptions",
"processor",
"processorElement",
"transformer",
"trackGenerator",
"sourceDummy",
"canvas",
"displayCanvas",
]); ]);
// 2. SCOPED BLOCKLIST (Parent -> Child removal) // 2. SCOPED BLOCKLIST (Parent -> Child removal)
@ -85,12 +92,18 @@ export class TestFeedService {
}; };
const seen = new WeakSet(); const seen = new WeakSet();
// Global traversal budget: an event should never serialize into a huge
// object graph (e.g. a track processor referencing the MediaPipe WASM
// module, whose HEAP* typed arrays would otherwise be enumerated
// byte by byte and freeze the tab).
let nodeBudget = 5000;
// 3. RECURSIVE WALKER // 3. RECURSIVE WALKER
const traverse = ( const traverse = (
current: any, current: any,
nodeName: string | null, nodeName: string | null,
parentName: string | null parentName: string | null,
depth: number = 0
): any => { ): any => {
// JSON.stringify cannot handle BigInt. Convert it to string. // JSON.stringify cannot handle BigInt. Convert it to string.
if (typeof current === "bigint") { if (typeof current === "bigint") {
@ -102,6 +115,17 @@ export class TestFeedService {
return current; return current;
} }
// A2. Never enumerate binary buffers (typed arrays have one enumerable
// entry PER BYTE: a WASM heap view would explode the JS heap).
if (ArrayBuffer.isView(current) || current instanceof ArrayBuffer) {
return undefined;
}
// A3. Depth / size guards
if (depth > 10 || --nodeBudget <= 0) {
return undefined;
}
// B. Handle Circular References // B. Handle Circular References
if (seen.has(current)) { if (seen.has(current)) {
return undefined; return undefined;
@ -111,7 +135,7 @@ export class TestFeedService {
// C. Handle Arrays // C. Handle Arrays
if (Array.isArray(current)) { if (Array.isArray(current)) {
return current return current
.map((item) => traverse(item, null, nodeName)) .map((item) => traverse(item, null, nodeName, depth + 1))
.filter((item) => item !== undefined); .filter((item) => item !== undefined);
} }
@ -147,7 +171,7 @@ export class TestFeedService {
} }
} }
const cleanedValue = traverse(childValue, childKey, nodeName); const cleanedValue = traverse(childValue, childKey, nodeName, depth + 1);
if (cleanedValue !== undefined) { if (cleanedValue !== undefined) {
copy[childKey] = cleanedValue; copy[childKey] = cleanedValue;
} }