@decentnetwork/lan 0.1.179 → 0.1.180
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.
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -131,6 +131,11 @@ const STALL_MIN_BYTES = 16 * 1024; // delivered at least this = a healthy, real
|
|
|
131
131
|
const STALL_DEAD_BYTES = 1024; // relayed LESS than this = the exit is genuinely dead (only THIS counts as a stall); a small-but-real request (playlist/key/keep-alive, 1-16 KB) is NEUTRAL, so it can't flap a healthy exit out of the pool
|
|
132
132
|
const TRIP_AFTER_STALLS = 3; // consecutive DEAD tunnels before an exit is tripped out (hysteresis)
|
|
133
133
|
const TRIP_AFTER_UPSTREAM_FAILS = 5; // consecutive non-200 CONNECT responses (exit's proxy broken, e.g. 502s everything) before tripping
|
|
134
|
+
// Keep a proven exit in rotation only if its measured speed is at least this
|
|
135
|
+
// fraction of the region's FASTEST proven exit. Below it (e.g. a 0.4 Mbps node
|
|
136
|
+
// next to a 1.2 Mbps one) it's benched while a healthy exit exists, so heavy
|
|
137
|
+
// streams don't stall on it. Unproven (unmeasured) exits are never benched.
|
|
138
|
+
const SLOW_EXIT_FLOOR_FRACTION = 0.4;
|
|
134
139
|
const TRIP_COOLDOWN_MS = 30_000; // how long a tripped exit stays excluded before it's retried
|
|
135
140
|
// Measures peak short-window throughput of a byte stream. Feed it every chunk
|
|
136
141
|
// length via add(); read peakBps at the end. Peak (not average) shrugs off TCP
|
|
@@ -430,6 +435,20 @@ export function startMultiExitRouter(opts) {
|
|
|
430
435
|
// Unproven exits still get overflow traffic once the proven ones fill up,
|
|
431
436
|
// which measures them safely without risking the video.
|
|
432
437
|
const unprovenBps = measuredVals.length > 0 ? measuredVals[0] : 800_000;
|
|
438
|
+
// Speed FLOOR: exclude exits that are dramatically slower than the best
|
|
439
|
+
// PROVEN exit. `score = speed/(active+1)` self-balances, but once the fast
|
|
440
|
+
// exit fills, a bandwidth-heavy stream (CCTV opens dozens of parallel
|
|
441
|
+
// segment tunnels) spills onto a degraded node (observed 0.4 Mbps vs 1.2
|
|
442
|
+
// Mbps) and stalls/rebuffers. Keep such nodes OUT of rotation while a
|
|
443
|
+
// healthy-speed exit exists; unproven exits (null speed) stay in so they
|
|
444
|
+
// still get measured, and we never empty the pool.
|
|
445
|
+
if (measuredVals.length >= 2) {
|
|
446
|
+
const best = measuredVals[measuredVals.length - 1];
|
|
447
|
+
const floor = best * SLOW_EXIT_FLOOR_FRACTION;
|
|
448
|
+
const fast = pool.filter((e) => e.speedEwma === null || e.speedEwma >= floor);
|
|
449
|
+
if (fast.length > 0)
|
|
450
|
+
pool = fast;
|
|
451
|
+
}
|
|
433
452
|
const score = (e) => (e.speedEwma ?? unprovenBps) / (e.active + 1);
|
|
434
453
|
return [...pool].sort((a, b) => score(b) - score(a) || a.served - b.served);
|
|
435
454
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decentnetwork/lan",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.180",
|
|
4
4
|
"description": "Private virtual LAN for self-hosted services and AI agents, built on Elastos Carrier. NAT-traversal, name service, ACL, all over a peer-to-peer mesh — no public IP required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|