@torrent-tv/proxy 2.55.7 → 2.55.8
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/CHANGELOG.md +4 -0
- package/package.json +1 -1
- package/services/torrent-worker/worker.js +27 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
## 2.55.8
|
|
2
|
+
|
|
3
|
+
- **Fix**: The proxy died twice in one evening (2026-08-22, 15:50:12 and 16:12:21 UTC) with no stop order given, and both deaths are the same fault. The torrent worker thread ends itself when its event loop drains — every recurring interval there is unref'd, upload is disabled by default, and idle peer connections close about half a minute after the traffic stops — so when a viewer paused or left, the thread finished ~35 s later on its own and Node began tearing it down. That teardown touched memory already freed or overwritten (SIGSEGV inside `uv_timer_stop`, reached through `PerIsolatePlatformData::Shutdown`; two core dumps captured identical stacks), and a fault in any thread kills the whole process instantly — HTTP server, tunnel and data channels together, with no log line and no way to restart anything from inside. The HA supervisor restarted the container each time (~15 s), but the browser's reconnect ladder had already given up by then. The worker now keeps ONE interval accounted for (no `.unref()`): an empty tick every 5 s costs nothing, the event loop can never drain while the process lives, and the teardown path — with whatever structure is corrupted inside it — stays unreachable, regardless of which native module is guilty; the three earlier crashes of this family (2026-08-18..21) stay documented under roadmap item 1.
|
|
4
|
+
|
|
1
5
|
## 2.55.7
|
|
2
6
|
|
|
3
7
|
- **Fix**: The subtitle push subscription is now recorded under the torrent pool's own key, not the browser's registry key — the two are different strings whenever a source was added by a `.torrent` file (a `.torrent` and a magnet for the same film are different request bytes, hashed into different registry keys, but the SAME infohash) and were silently different in every other case too: a registry key is `sha1(sourceType:source)`, one per API session; the pool's key is `torrent:<infohash>`, deliberately shared across a magnet and a `.torrent` for the same content (item 10). The diagnostic logging added in 2.55.6 caught it directly, field case 2026-08-22: cues were found and logged repeatedly, and every push answered `found no subscribed channel` — the subscription and the publish had never been able to agree on a key, for any torrent, since the push feature shipped in 2.55.5. `data-channel-handler.js` now resolves the browser's registry key through `sourceRegistry` to `(sourceType, source)` and runs it through the same `deriveSourceKey` the pool itself uses, at the one point both keys are in hand — the subscribe intercept, before the request is even forwarded.
|
package/package.json
CHANGED
|
@@ -590,4 +590,31 @@ setInterval(() => {
|
|
|
590
590
|
}
|
|
591
591
|
}, SUBTITLE_WARMUP_INTERVAL_MS).unref();
|
|
592
592
|
|
|
593
|
+
/**
|
|
594
|
+
* Keeps this thread alive ON PURPOSE — the one interval left accounted for
|
|
595
|
+
* (no `.unref()`).
|
|
596
|
+
*
|
|
597
|
+
* Every other recurring handle here is unref'd, upload is disabled by
|
|
598
|
+
* default, and idle peer connections close about half a minute after the
|
|
599
|
+
* traffic stops — so once nothing is being read, every handle can be gone
|
|
600
|
+
* at once, the event loop drains, and this thread ends BY ITSELF. Node then
|
|
601
|
+
* tears the isolate down, that teardown touches memory some native module
|
|
602
|
+
* has already freed, and the fault (SIGSEGV inside `uv_timer_stop`, reached
|
|
603
|
+
* through `PerIsolatePlatformData::Shutdown`) kills the whole process at
|
|
604
|
+
* once — HTTP server, tunnel, data channels — before any JS handler runs.
|
|
605
|
+
* Field evidence: two deaths on 2026-08-22 (15:50:12 and 16:12:21 UTC),
|
|
606
|
+
* each ~35 s after the last byte of traffic, identical core dumps;
|
|
607
|
+
* same crash family as the utp-native faults of 2026-08-18..21
|
|
608
|
+
* (`research/worker-thread-drain-crash-2026-08-22.md`).
|
|
609
|
+
*
|
|
610
|
+
* An empty repeating interval costs nothing, keeps the loop from draining
|
|
611
|
+
* while the process lives, and thereby keeps that teardown path — and the
|
|
612
|
+
* corrupted structure inside it — unreachable, whichever module is guilty.
|
|
613
|
+
*/
|
|
614
|
+
const WORKER_KEEPALIVE_INTERVAL_MS = 5_000;
|
|
615
|
+
|
|
616
|
+
setInterval(() => {
|
|
617
|
+
void process.uptime();
|
|
618
|
+
}, WORKER_KEEPALIVE_INTERVAL_MS);
|
|
619
|
+
|
|
593
620
|
log("torrent worker started");
|