@torrent-tv/proxy 2.38.1 → 2.39.0

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,123 @@
1
+ /**
2
+ * @file Asking a second wire for the blocks a reader is still waiting on.
3
+ *
4
+ * Measured on a real swarm 2026-08-19: a blocked read's tail is 2-14 blocks of
5
+ * 512, and it sits on wires at 109-886 KB/s — above the 48 KB/s gate that
6
+ * WebTorrent's own `_hotswap` requires, so the library never duplicates them.
7
+ * The mechanism is the library's: free the reservation with `Piece.cancel` and
8
+ * leave the first request in flight, then ask a second wire through the
9
+ * library's own request path.
10
+ */
11
+
12
+ import test from "node:test";
13
+ import assert from "node:assert/strict";
14
+ import { duplicateTailFor } from "../services/torrent-worker/fastest-wires.js";
15
+
16
+ /** A piece with `chunks` blocks, of which `missing` at the end are absent. */
17
+ function piece(chunks, missing) {
18
+ const buffer = new Array(chunks);
19
+ for (let index = 0; index < chunks - missing; index += 1) {
20
+ buffer[index] = new Uint8Array(1);
21
+ }
22
+ const cancelled = [];
23
+ return {
24
+ _buffer: buffer,
25
+ _chunks: chunks,
26
+ cancel: (index) => cancelled.push(index),
27
+ cancelled
28
+ };
29
+ }
30
+
31
+ function wire({ speed = 500_000, has = true } = {}) {
32
+ return {
33
+ peerPieces: { get: () => has },
34
+ downloadSpeed: () => speed,
35
+ peerChoking: false,
36
+ destroyed: false,
37
+ requests: []
38
+ };
39
+ }
40
+
41
+ test("the missing blocks are freed and asked of a second wire", () => {
42
+ const target = piece(512, 3);
43
+ const placed = [];
44
+ const torrent = {
45
+ pieces: [target],
46
+ wires: [wire({ speed: 900_000 }), wire({ speed: 800_000 }), wire({ speed: 700_000 })],
47
+ _request: (wireAsked, index) => {
48
+ placed.push({ wireAsked, index });
49
+ return true;
50
+ }
51
+ };
52
+
53
+ const result = duplicateTailFor(torrent, 0);
54
+
55
+ assert.equal(result.missing, 3, "the tail is what is still absent from the piece");
56
+ assert.equal(result.duplicated, 3);
57
+ assert.deepEqual(target.cancelled, [509, 510, 511], "each block's reservation is freed first");
58
+ assert.equal(placed.length, 3, "and each is then asked of a wire through the library's own path");
59
+ assert.equal(placed[0].wireAsked, torrent.wires[0], "fastest wire first");
60
+ });
61
+
62
+ test("at most one duplicate per wire, however long the tail", () => {
63
+ const target = piece(512, 40);
64
+ const torrent = {
65
+ pieces: [target],
66
+ wires: [wire(), wire()],
67
+ _request: () => true
68
+ };
69
+
70
+ const result = duplicateTailFor(torrent, 0);
71
+
72
+ assert.equal(result.duplicated, 2, "two wires, two duplicates — the rest waits for the next attempt");
73
+ assert.equal(target.cancelled.length, 2, "and no reservation is freed that nobody was asked for");
74
+ });
75
+
76
+ test("a wire whose pipeline is full ends the attempt", () => {
77
+ const target = piece(512, 5);
78
+ const torrent = {
79
+ pieces: [target],
80
+ wires: [wire(), wire(), wire()],
81
+ // The library refuses when the wire already has as many requests as its
82
+ // measured speed justifies.
83
+ _request: () => false
84
+ };
85
+
86
+ const result = duplicateTailFor(torrent, 0);
87
+
88
+ assert.equal(result.duplicated, 0);
89
+ assert.equal(
90
+ target.cancelled.length,
91
+ 1,
92
+ "only the block that was actually offered is freed; the rest keep their reservations"
93
+ );
94
+ });
95
+
96
+ test("a piece with nothing missing is left alone", () => {
97
+ const target = piece(4, 0);
98
+ const torrent = { pieces: [target], wires: [wire()], _request: () => true };
99
+
100
+ const result = duplicateTailFor(torrent, 0);
101
+
102
+ assert.equal(result.duplicated, 0);
103
+ assert.equal(result.missing, 0);
104
+ assert.equal(target.cancelled.length, 0);
105
+ });
106
+
107
+ test("with no wire holding the piece there is nothing to duplicate onto", () => {
108
+ const target = piece(8, 2);
109
+ const torrent = { pieces: [target], wires: [wire({ has: false })], _request: () => true };
110
+
111
+ const result = duplicateTailFor(torrent, 0);
112
+
113
+ assert.equal(result.wires, 0);
114
+ assert.equal(result.duplicated, 0);
115
+ assert.equal(target.cancelled.length, 0, "and no reservation is freed for nobody");
116
+ });
117
+
118
+ test("a completed piece is not touched", () => {
119
+ assert.deepEqual(
120
+ duplicateTailFor({ pieces: [null], wires: [wire()], _request: () => true }, 0),
121
+ { duplicated: 0, missing: 0, wires: 0 }
122
+ );
123
+ });