@torrent-tv/proxy 2.58.2 → 2.58.3
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 +7 -0
- package/bin/cli.js +7 -0
- package/package.json +1 -1
- package/services/memory-report.js +166 -0
- package/services/piece-store/shared-piece-store.js +791 -717
- package/services/torrent-worker/worker.js +5 -0
- package/test/memory-budget.test.js +69 -0
|
@@ -499,7 +499,12 @@ setInterval(() => {
|
|
|
499
499
|
const reads = stats.fromMemory + stats.fromDisk;
|
|
500
500
|
const fromMemoryShare = reads > 0 ? ((stats.fromMemory / reads) * 100).toFixed(1) : "—";
|
|
501
501
|
log(
|
|
502
|
+
// In BYTES as well as in pieces. The count alone says nothing without the
|
|
503
|
+
// piece size, and the piece size differs per torrent: on the film the
|
|
504
|
+
// proxy was killed under, 2026-08-28, "63" meant 504 MB.
|
|
502
505
|
`piece-store "${stats.name.slice(0, 40)}": resident=${stats.resident}/${stats.capacity} ` +
|
|
506
|
+
`(${Math.round((stats.residentBytes || 0) / 1048576)}MB of ` +
|
|
507
|
+
`${Math.round((stats.budgetBytes || 0) / 1048576)}MB allowed) ` +
|
|
503
508
|
`pinned=${stats.pinned} spilled=${stats.spilled} reads=${reads} (${fromMemoryShare}% from memory) ` +
|
|
504
509
|
`spills=${stats.spills} revivals=${stats.revivals}` +
|
|
505
510
|
(stats.blockedByPins > 0 ? ` blocked-by-pins=${stats.blockedByPins}` : "")
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
|
|
4
|
+
import { describeMemory } from "../services/memory-report.js";
|
|
5
|
+
import {
|
|
6
|
+
budgetForNewStore,
|
|
7
|
+
totalStoreBudgetBytes
|
|
8
|
+
} from "../services/piece-store/shared-piece-store.js";
|
|
9
|
+
|
|
10
|
+
const MEGABYTE = 1024 * 1024;
|
|
11
|
+
const GIGABYTE = 1024 * MEGABYTE;
|
|
12
|
+
|
|
13
|
+
test("the whole of the torrent stores is bounded, not each one of them", () => {
|
|
14
|
+
// The failure this replaces: the budget was per torrent, so two torrents took
|
|
15
|
+
// two of it. Whatever the machine has, the total is one budget.
|
|
16
|
+
const available = 8 * GIGABYTE;
|
|
17
|
+
const alone = budgetForNewStore(available, 1);
|
|
18
|
+
const withThree = budgetForNewStore(available, 3);
|
|
19
|
+
assert.equal(alone, totalStoreBudgetBytes(available));
|
|
20
|
+
assert.ok(withThree < alone, "a third store must not be given a first store's share");
|
|
21
|
+
assert.ok(withThree * 3 <= totalStoreBudgetBytes(available) + 3);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test("the budget is a share of what the machine can give, capped", () => {
|
|
25
|
+
// A quarter of two gigabytes is under the ceiling and is what is taken.
|
|
26
|
+
assert.equal(totalStoreBudgetBytes(2 * GIGABYTE), 512 * MEGABYTE);
|
|
27
|
+
// A quarter of one gigabyte is 256 MB — below the ceiling, so not capped.
|
|
28
|
+
assert.equal(totalStoreBudgetBytes(GIGABYTE), 256 * MEGABYTE);
|
|
29
|
+
// And it never exceeds the ceiling however much is free.
|
|
30
|
+
assert.equal(totalStoreBudgetBytes(64 * GIGABYTE), 512 * MEGABYTE);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test("a machine with almost nothing left still gets a workable floor", () => {
|
|
34
|
+
// Refusing to serve is worse than exceeding the share, and the memory line
|
|
35
|
+
// says plainly what is held either way.
|
|
36
|
+
const tiny = budgetForNewStore(32 * MEGABYTE, 4);
|
|
37
|
+
assert.equal(tiny, 64 * MEGABYTE);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test("the memory line says bytes, and names what it could not measure", () => {
|
|
41
|
+
const usage = {
|
|
42
|
+
rss: 2422628 * 1024,
|
|
43
|
+
heapUsed: 180 * MEGABYTE,
|
|
44
|
+
heapTotal: 220 * MEGABYTE,
|
|
45
|
+
external: 900 * MEGABYTE,
|
|
46
|
+
arrayBuffers: 850 * MEGABYTE
|
|
47
|
+
};
|
|
48
|
+
const measured = describeMemory({
|
|
49
|
+
process: usage,
|
|
50
|
+
availableBytes: 1900 * MEGABYTE,
|
|
51
|
+
availableMeasured: true,
|
|
52
|
+
stores: [
|
|
53
|
+
{ name: "a film", residentBytes: 504 * MEGABYTE, budgetBytes: 512 * MEGABYTE }
|
|
54
|
+
]
|
|
55
|
+
});
|
|
56
|
+
// The figures the kernel's own kill line quoted, so the two can be compared.
|
|
57
|
+
assert.match(measured, /rss=2366MB/);
|
|
58
|
+
assert.match(measured, /1 torrent store\(s\) holding 504MB of 512MB allowed/);
|
|
59
|
+
assert.match(measured, /machine has 1900MB available$/);
|
|
60
|
+
|
|
61
|
+
const estimated = describeMemory({
|
|
62
|
+
process: usage,
|
|
63
|
+
availableBytes: 1900 * MEGABYTE,
|
|
64
|
+
availableMeasured: false,
|
|
65
|
+
stores: []
|
|
66
|
+
});
|
|
67
|
+
assert.match(estimated, /no torrent stores/);
|
|
68
|
+
assert.match(estimated, /estimated — \/proc\/meminfo could not be read/);
|
|
69
|
+
});
|