@torrent-tv/proxy 2.80.13 → 2.80.15

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.
@@ -0,0 +1,116 @@
1
+ /**
2
+ * @file What the master playlist declares a variant carries.
3
+ *
4
+ * Measured, and the measurement was available all along: it used to be
5
+ * `height * height * 3.2`, justified by a comment saying no measurement existed
6
+ * before encoding starts. Field 2026-09-08: 3.73 Mbit/s declared for a file
7
+ * carrying 18.4, and the browser sizes its cushion in BYTES from that figure —
8
+ * 120 s asked bought 26 s of film, and the deepest it ever held was 17.1 s.
9
+ */
10
+
11
+ import test from "node:test";
12
+ import assert from "node:assert/strict";
13
+ import { declaredRates } from "../services/output/rates.js";
14
+ import { bitrateFor } from "../services/output/playlists.js";
15
+
16
+ // The field file: 2 806 246 976 bytes over 20:18, cut into 291 pieces.
17
+ const FIELD = { fileLength: 2_806_246_976, durationSeconds: 1218.73 };
18
+
19
+ test("the average is the file's own length over its duration", () => {
20
+ const { averageBitsPerSecond } = declaredRates(FIELD);
21
+
22
+ // 18.4 Mbit/s, against the 3.73 that was declared.
23
+ assert.ok(
24
+ Math.abs(averageBitsPerSecond / 1_000_000 - 18.42) < 0.01,
25
+ `got ${averageBitsPerSecond}`
26
+ );
27
+ });
28
+
29
+ test("nothing measured is stated as nothing, not as a guess", () => {
30
+ assert.deepEqual(
31
+ declaredRates({ fileLength: 0, durationSeconds: 0 }),
32
+ { averageBitsPerSecond: 0, peakOverAverage: 1 }
33
+ );
34
+ assert.deepEqual(
35
+ declaredRates({ fileLength: 100, durationSeconds: 0 }),
36
+ { averageBitsPerSecond: 0, peakOverAverage: 1 }
37
+ );
38
+ });
39
+
40
+ test("the peak comes from the biggest piece made and the span it covers", () => {
41
+ // The field peak: 38.4 MB over 4.2 s is 73 Mbit/s, four times the average.
42
+ const boundaries = Array.from({ length: 292 }, (_, index) => index * 4.2);
43
+ const { averageBitsPerSecond, peakOverAverage } = declaredRates({
44
+ ...FIELD,
45
+ largest: { index: 2, size: 40_288_299 },
46
+ boundaries
47
+ });
48
+
49
+ const peak = averageBitsPerSecond * peakOverAverage;
50
+ assert.ok(Math.abs(peak / 1_000_000 - 76.7) < 0.5, `got ${peak / 1_000_000}Mbit/s`);
51
+ });
52
+
53
+ test("no piece made yet means the peak is not yet measured, so it equals the average", () => {
54
+ // A ratio invented meanwhile is exactly the fabrication this replaced.
55
+ assert.equal(declaredRates(FIELD).peakOverAverage, 1);
56
+ assert.equal(
57
+ declaredRates({ ...FIELD, largest: { index: -1, size: 0 }, boundaries: [0, 4] }).peakOverAverage,
58
+ 1
59
+ );
60
+ });
61
+
62
+ test("the peak is never below the average", () => {
63
+ // A short session whose only piece happens to be a small one must not lower
64
+ // the figure the player sizes its cushion from.
65
+ const boundaries = Array.from({ length: 292 }, (_, index) => index * 4.2);
66
+ assert.equal(
67
+ declaredRates({ ...FIELD, largest: { index: 5, size: 1000 }, boundaries }).peakOverAverage,
68
+ 1
69
+ );
70
+ });
71
+
72
+ test("a smaller picture is declared at the pixel share of the source's rate", () => {
73
+ const measured = 18_420_000;
74
+
75
+ assert.equal(
76
+ bitrateFor({ averageBitsPerSecond: measured, height: 1080, sourceHeight: 1080 }),
77
+ Math.round(measured),
78
+ "the source's own height carries the source's bits"
79
+ );
80
+ assert.equal(
81
+ bitrateFor({ averageBitsPerSecond: measured, height: 2160, sourceHeight: 1080 }),
82
+ Math.round(measured),
83
+ "and a height above it carries no more — there is nothing to upscale from"
84
+ );
85
+ assert.equal(
86
+ bitrateFor({ averageBitsPerSecond: measured, height: 540, sourceHeight: 1080 }),
87
+ Math.round(measured / 4),
88
+ "half the height is a quarter of the pixels"
89
+ );
90
+ });
91
+
92
+ test("a capped height is declared at its cap, which is exact", () => {
93
+ assert.equal(
94
+ bitrateFor({ averageBitsPerSecond: 18_420_000, height: 720, sourceHeight: 1080, capKbps: 2500 }),
95
+ 2_500_000,
96
+ "what we impose is known, not estimated"
97
+ );
98
+ assert.equal(
99
+ bitrateFor({ averageBitsPerSecond: 1_000_000, height: 1080, sourceHeight: 1080, capKbps: 99_000 }),
100
+ 1_000_000,
101
+ "and a cap above what the source carries takes nothing away from it"
102
+ );
103
+ });
104
+
105
+ test("the floor is a floor on what may be declared, not a belief about content", () => {
106
+ assert.equal(
107
+ bitrateFor({ averageBitsPerSecond: 0, height: 1080, sourceHeight: 1080 }),
108
+ 400_000,
109
+ "a file whose rate is not known yet"
110
+ );
111
+ assert.equal(
112
+ bitrateFor({ averageBitsPerSecond: 18_420_000, height: 4, sourceHeight: 1080 }),
113
+ 400_000,
114
+ "and a variant so small the arithmetic would go under it"
115
+ );
116
+ });
@@ -367,9 +367,15 @@ test("the one machine goes to whoever is due soonest, not to the smallest number
367
367
  ...HOST,
368
368
  maxRuns: 2
369
369
  });
370
- const started = actions.filter((action) => action.type === "start").map((action) => action.from);
371
-
372
- assert.deepEqual(started, [500], "the one machine goes where somebody is stopped");
370
+ // WHERE the machine ends up, not how it got there. A run standing at #900
371
+ // reaches nothing anybody wants, so it is taken to #500 rather than killed and
372
+ // replaced one process instead of a death and a cold start, which is
373
+ // strictly better and is what the plan now answers.
374
+ const placed = actions
375
+ .filter((action) => action.type === "start" || action.type === "move")
376
+ .map((action) => action.from);
377
+
378
+ assert.deepEqual(placed, [500], "the one machine goes where somebody is stopped");
373
379
  });
374
380
 
375
381
  test("two viewers far apart are both served, by however many encoders serve them soonest", () => {
@@ -0,0 +1,138 @@
1
+ /**
2
+ * @file What moving a running encoder costs, and what the plan does while
3
+ * nobody has measured it.
4
+ *
5
+ * Field 2026-09-08: 39 moves in one session, 24 of them between three adjacent
6
+ * numbers — #58 to #59, #59 to #58, #58 to #60, #60 to #58, six times each,
7
+ * about 0.8 s apart — while the viewer's picture stood still for 116.7 s in
8
+ * three interruptions, the worst of them 91.8 s. The zone the viewer's own
9
+ * position defines slides forward one number at a time, and every slide made
10
+ * standing one number behind it score worse than standing in it.
11
+ *
12
+ * FOUR THINGS, and the first is the one that mattered.
13
+ *
14
+ * 1. The map states `withinSeconds: null` for the film BEHIND the viewers —
15
+ * nobody is waiting there. `deadlineReaderFor` read it through `Number()`,
16
+ * where `null` is 0, so that film was due NOW and was the most urgent
17
+ * material in the file. It bought encoders and it took the run standing in
18
+ * front of the viewer, because that run was the nearest body to it.
19
+ * 2. Residual work took a live run. A zone with no deadline is done with
20
+ * capacity that is left over, and a run already serving a viewer is not left
21
+ * over.
22
+ * 3. `moveSec` was 0 until measured, so a move was free in the arithmetic — and
23
+ * the blindness sustained itself, because the first-output figure takes a
24
+ * reading only from a run that produced something and every run in a thrash
25
+ * is killed before it finishes anything.
26
+ * 4. A staying run was priced as though it would produce instantly, however
27
+ * recently it had started, so the score had no memory of a decision it was
28
+ * still carrying out.
29
+ */
30
+
31
+ import test from "node:test";
32
+ import assert from "node:assert/strict";
33
+ import { RunCosts } from "../services/encode/run-costs.js";
34
+ import { planEncoders } from "../services/encode/EncodePlan.js";
35
+ import { CoverageMap } from "../services/encode/CoverageMap.js";
36
+
37
+ test("nothing measured means a move is refused, not priced at zero", () => {
38
+ const costs = new RunCosts();
39
+
40
+ const { moveCostSec, firstByteWaitSec, killCostSec } = costs.seconds();
41
+ assert.equal(moveCostSec, Number.POSITIVE_INFINITY, "moving is not free while unpriced");
42
+ // Placing one where there is none is the OTHER question, and it has no
43
+ // alternative: the film gets made or it does not.
44
+ assert.equal(firstByteWaitSec, 0, "placing an encoder is not blocked by an unknown price");
45
+ assert.equal(killCostSec, 0);
46
+ });
47
+
48
+ test("a run killed before producing anything is a lower bound on the first output", () => {
49
+ const costs = new RunCosts();
50
+
51
+ // Exactly what a thrash supplies: a run that lived 800 ms and finished
52
+ // nothing. It says the first output takes AT LEAST that long, which is a fact.
53
+ costs.note({ livedMs: 800, dyingMs: 40 });
54
+
55
+ const { moveCostSec } = costs.seconds();
56
+ assert.ok(Number.isFinite(moveCostSec), "one killed run is enough to stop the blindness");
57
+ assert.ok(Math.abs(moveCostSec - 0.84) < 0.001, `got ${moveCostSec}`);
58
+ });
59
+
60
+ test("a run that produced something is measured by its first output, not its life", () => {
61
+ const costs = new RunCosts();
62
+
63
+ costs.note({ livedMs: 60_000, firstOutputMs: 900, dyingMs: 100 });
64
+
65
+ const { moveCostSec, firstByteWaitSec } = costs.seconds();
66
+ assert.ok(Math.abs(firstByteWaitSec - 0.9) < 0.001, `got ${firstByteWaitSec}`);
67
+ assert.ok(Math.abs(moveCostSec - 1.0) < 0.001, `got ${moveCostSec}`);
68
+ });
69
+
70
+ test("the zone sliding one number does not move an encoder that is already reaching it", () => {
71
+ // The field shape exactly: a run standing at #58 with the viewer's urgent zone
72
+ // sliding #58..#59 → #59..#60. Driving through one segment costs the encoder a
73
+ // fraction of a second; moving costs a kill and a cold start.
74
+ const coverage = new CoverageMap();
75
+ coverage.setSegmentCount(482);
76
+ const run = { from: 58, to: 481, head: 58, speedX: 4.45, isAlive: true };
77
+ coverage.claim(run, 58, 481);
78
+
79
+ const actions = planEncoders({
80
+ coverage,
81
+ windows: [
82
+ { from: 0, to: 57, priority: 1, withinSeconds: null, behind: true },
83
+ { from: 59, to: 60, priority: 100, withinSeconds: 0, behind: false }
84
+ ],
85
+ runs: [run],
86
+ maxRuns: 3,
87
+ segmentSeconds: 4.2,
88
+ speedX: 4.45,
89
+ // Measured on this host: killing takes 40 ms, a fresh encoder's first piece
90
+ // 900 ms. Against that, driving one segment at 4.45x costs 0.94 s — so the
91
+ // two are close, and what settles it is that the move ALSO has to encode
92
+ // the same segment afterwards.
93
+ killCostSec: 0.04,
94
+ firstByteWaitSec: 0.9,
95
+ moveCostSec: 0.94,
96
+ refetchSecPerFilmSecond: 0,
97
+ contentionPenaltyFor: () => 1
98
+ });
99
+
100
+ assert.deepEqual(
101
+ actions.filter((one) => one.type === "move"),
102
+ [],
103
+ "a run one number behind the zone is already on its way into it"
104
+ );
105
+ });
106
+
107
+ test("a move that genuinely saves the viewer time still happens", () => {
108
+ // The other half: the viewer jumped fourteen segments ahead, and driving there
109
+ // at 4.45x would take 13 s while a cold start takes 0.94 s. Refusing this
110
+ // would be the opposite fault.
111
+ const coverage = new CoverageMap();
112
+ coverage.setSegmentCount(482);
113
+ const run = { from: 0, to: 481, head: 44, speedX: 4.45, isAlive: true };
114
+ coverage.claim(run, 0, 481);
115
+
116
+ const actions = planEncoders({
117
+ coverage,
118
+ windows: [{ from: 58, to: 59, priority: 100, withinSeconds: 0, behind: false }],
119
+ runs: [run],
120
+ maxRuns: 3,
121
+ segmentSeconds: 4.2,
122
+ speedX: 4.45,
123
+ killCostSec: 0.04,
124
+ firstByteWaitSec: 0.9,
125
+ moveCostSec: 0.94,
126
+ refetchSecPerFilmSecond: 0,
127
+ contentionPenaltyFor: () => 1
128
+ });
129
+
130
+ // WHERE the encoder ends up, not how it got there: the run at #44 reaches
131
+ // nothing anybody waits for, so the plan may either take it to #58 or stop it
132
+ // and start one there. Both are one process at #58, and which is cheaper is
133
+ // the measured difference between a kill and a cold start.
134
+ const placed = actions
135
+ .filter((one) => one.type === "move" || one.type === "start")
136
+ .map((one) => one.from);
137
+ assert.deepEqual(placed, [58], "fourteen segments of driving is worth a cold start");
138
+ });
@@ -199,6 +199,10 @@ test("the demand is the union of the readers' windows, not their sum", () => {
199
199
 
200
200
  const demand = lru.demand();
201
201
  assert.equal(demand.readers, 2);
202
+ // NAMED, because the count read as five encoders on a session that had two:
203
+ // four of the five were zones of the priority map, and only the names could
204
+ // say so.
205
+ assert.deepEqual(demand.names, ["audio", "video"]);
202
206
  assert.equal(demand.unionPieces, 80, "100..179 is eighty pieces, not a hundred");
203
207
  assert.equal(demand.widestPieces, 50);
204
208
  assert.equal(demand.capacity, 88);
@@ -211,7 +215,7 @@ test("the demand is the union of the readers' windows, not their sum", () => {
211
215
  lru.unprotect("video");
212
216
  assert.deepEqual(
213
217
  lru.demand(),
214
- { readers: 0, unionPieces: 0, widestPieces: 0, capacity: 88 },
218
+ { readers: 0, names: [], unionPieces: 0, widestPieces: 0, capacity: 88 },
215
219
  "no reader asking for anything is not the same as asking for one piece"
216
220
  );
217
221
  });
@@ -50,10 +50,22 @@ test("the margin is what the supply's own interruptions demand", () => {
50
50
  // derivation calls T: `(v - 1) x T > W` prices what is GAINED between
51
51
  // interruptions, and nothing is gained during one.
52
52
  assert.ok(Math.abs(answer.medianIntervalSec - 0.73) < 0.001, `got ${answer.medianIntervalSec}`);
53
- // 1 + 3.16 / 0.73 = 5.33. Measuring end-to-end instead gave 2.42, and the
54
- // symptom that this whole file was written against is that a step admitted at
55
- // 1.5 ran at 1.05x and stalled so the bar was too low, not too high.
56
- assert.ok(Math.abs(answer.requiredSpeed - 5.3288) < 0.001, `got ${answer.requiredSpeed}`);
53
+ // THE SHARE OF ITS TIME THE SUPPLY LOST, over whole cycles: from the first
54
+ // interruption's start to the last one's, 12.77 s, of which 9.12 s was
55
+ // interruption. So the reading delivered for 3.65 s of every 12.77, and
56
+ // producing film at that share costs 1/(1 - 0.714) = 3.50x.
57
+ //
58
+ // The formula it replaced divided the WORST interruption by the TYPICAL gap —
59
+ // 1 + 3.16/0.73 = 5.33 — which asks what would happen if the worst recurred
60
+ // at the typical rate, a case that never occurred in this data, and which
61
+ // divides by a gap that goes to zero whenever interruptions arrive in a burst.
62
+ // Field 2026-09-08: 0.79 s over 0.01 s gave 158.60x on a file already
63
+ // downloaded whole, and every quality step was refused against it.
64
+ //
65
+ // The failure this file was written for is still caught: a step admitted at
66
+ // 1.5 ran at 1.05x and stalled, and 3.91x refuses 1.5 exactly as 5.33x did.
67
+ assert.ok(Math.abs(answer.lostShare - 0.7142) < 0.001, `got ${answer.lostShare}`);
68
+ assert.ok(Math.abs(answer.requiredSpeed - 3.4986) < 0.001, `got ${answer.requiredSpeed}`);
57
69
  });
58
70
 
59
71
  test("one stall seen by three readers is one interruption, not three", () => {
@@ -87,7 +99,11 @@ test("overlapping waits merge, and the gap between stalls is what is left", () =
87
99
  assert.equal(answer.waits, 4, "from four waits");
88
100
  assert.equal(answer.worstWaitSec, 10, "the merged stall, not one reader's view of it");
89
101
  assert.equal(answer.medianIntervalSec, 10, "20s to 30s is when the encoder ran");
90
- assert.equal(answer.requiredSpeed, 2, "1 + 10/10");
102
+ // One whole cycle: 10 s to 30 s, of which the 10 s interruption is half. The
103
+ // supply delivered for the other half, so a step must run at twice realtime.
104
+ assert.equal(answer.spanSec, 20);
105
+ assert.equal(answer.lostSec, 10);
106
+ assert.equal(answer.requiredSpeed, 2);
91
107
  });
92
108
 
93
109
  test("a copy at 8x clears its own supply with room to spare", () => {
@@ -95,9 +111,10 @@ test("a copy at 8x clears its own supply with room to spare", () => {
95
111
  const waits = evenlySpaced(6, 15.5, 4.82);
96
112
  const answer = requiredSpeedFrom(waits);
97
113
  assert.ok(answer);
98
- // Waits end 15.5 s apart and last 4.82 s, so the encoder runs 10.68 s between
99
- // them: 1 + 4.82/10.68 = 1.45, against 8x measured. Which is why a copy is the
100
- // step a stranded viewer is always able to return to.
114
+ // Waits end 15.5 s apart and last 4.82 s, so the supply delivers for 10.68 s
115
+ // of every 15.5: 0.311 of its time lost, and 1/(1 - 0.311) = 1.45 against the
116
+ // 8x measured. Which is why a copy is the step a stranded viewer is always
117
+ // able to return to.
101
118
  assert.ok(answer.requiredSpeed < 1.5, `got ${answer.requiredSpeed}`);
102
119
  });
103
120