From 0ac000e0db3feb235fae37389d0af18609e91c50 Mon Sep 17 00:00:00 2001 From: Luke Hoersten Date: Fri, 17 Jul 2026 18:56:17 -0500 Subject: scrypted: code-review fixes — reload drain order, reconnect storm, wake guards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - bootstrap: drain the shutdown-cleaner array FIRST, not after the child re-discovery loop. The old order tore down the listeners the loop had just attached, and since the instance maps still referenced them the attachListener fast-path blocked the 5-min register-cycle self-heal from ever re-attaching after a warm re-paste. The attach cleaner now also invalidates listeners/attachedCameraId (one cleaner per attach), so a drain by another instance can't strand dead registrations either. - stream socket: single-flight reconnect scheduled from 'close' only. A failed connect emits 'error' then 'close'; scheduling from both doubled outstanding attempts every 500ms against a rebooting device. openStreamSocket also destroys the previous socket first. - onRequest wake: same streams/streamStarting guard as every other start path (a concurrent second startStream overwrote the streams entry and orphaned the first ffmpeg), respond 204 immediately (the device's POST times out at 1s — awaiting startStream turned every tap-wake into a firmware state_post_failure), and skip the redundant wake POST back. - startStream: bail-out paths after the wake POST (camera missing, no usable stream, ffmpeg-input conversion failure) now send a compensating sleep instead of stranding the panel on Loading; the last-ditch getVideoStream fallback no longer rejects out of the call. - key streams/streamStarting/stopStream by nativeId — v.name drifts to the nativeId on reload, stranding or duplicating streams keyed under the drifted value; findByName matches display_name first for the same reason. - idle_timeout_ms=0: the Scrypted-side safety timeout still reclaims ffmpeg/socket but no longer POSTs sleep over the always-on setting. - pending bindingDebounce timers cleared across re-paste (they fired against the dead instance and attached duplicate listeners); releaseDevice drops lastRegisterSig/streamStarting/debounce entries. - start() single-flights bootstrap; createDevice drops its redundant second registerViewport; streamLogger rolls its window on quiet ticks (post-lull rates were diluted) and lastLogUs -> lastLogMs; hoist the JPEG EOI needle + resume-scan offset in the demux loop; postJSON drops the dead 204 check; remove unused sandbox declares and the legacy streams.interval field. - tsconfig: moduleResolution Node -> Bundler (removed in TS 6). --- scrypted/tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scrypted/tsconfig.json') diff --git a/scrypted/tsconfig.json b/scrypted/tsconfig.json index 69cc356..fd0d0df 100644 --- a/scrypted/tsconfig.json +++ b/scrypted/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "target": "ES2022", "module": "ESNext", - "moduleResolution": "Node", + "moduleResolution": "Bundler", "lib": ["ES2022", "DOM"], "types": ["node"], "strict": false, -- cgit v1.2.3