@torrent-tv/proxy 2.107.56 → 2.107.58
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/bin/cli.js +24 -15
- package/package.json +1 -1
- package/server.js +195 -1139
- package/services/encode/EncodeInputResolution.js +157 -0
- package/services/encode/LocalObservations.js +20 -2
- package/services/encode/measure-host.js +147 -0
- package/services/identity/installation-id.js +17 -6
- package/services/media/SegmentSourceRanges.js +95 -0
- package/services/media/SubtitleWalk.js +172 -0
- package/services/media/WorkTagsReport.js +30 -0
- package/services/media/segment-reading.js +36 -0
- package/services/server/MediaReadParams.js +134 -0
- package/services/server/PreparationReads.js +175 -0
- package/services/server/forwarded-response-log.js +55 -0
- package/services/server/start-playback.js +34 -0
- package/services/server/torrent-pool-ports.js +105 -0
- package/services/server/wire-outputs.js +62 -49
- package/services/storage/files/CompletedFiles.js +6 -1
- package/services/storage/memory-report.js +5 -5
- package/services/storage/processor-share.js +24 -0
- package/services/storage/segment-store/SegmentStore.js +2 -1
- package/services/torrent/PlaybackResolution.js +397 -0
- package/services/torrent/worker/worker.js +1 -6
- package/services/viewer/watched-addresses.js +51 -0
- package/utils/atomic-json.js +46 -0
package/bin/cli.js
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
// for the measurement that made it necessary.
|
|
15
15
|
import "./thread-pool.js";
|
|
16
16
|
import { Command } from "commander";
|
|
17
|
+
import { mkdirSync } from "node:fs";
|
|
17
18
|
import os from "node:os";
|
|
18
19
|
import { spawnSync } from "node:child_process";
|
|
19
20
|
import { createRequire } from "node:module";
|
|
@@ -35,6 +36,7 @@ import { collectHealthMetrics } from "../services/transport/health-collector.js"
|
|
|
35
36
|
import { LOAD_REFRESH_MS, ProxyStateReporter } from "../services/transport/proxy-state.js";
|
|
36
37
|
import { createPortMapper } from "../services/transport/port-mapper.js";
|
|
37
38
|
import { installationId } from "../services/identity/installation-id.js";
|
|
39
|
+
import { PROXY_ROOT } from "../services/encode/LocalObservations.js";
|
|
38
40
|
import { classifyNat } from "../services/transport/nat-classifier.js";
|
|
39
41
|
import { DEFAULT_SEGMENT_FORMAT_ID, SEGMENT_FORMAT_IDS } from "../services/encode/segment-formats/index.js";
|
|
40
42
|
import { logToFile, logger } from "../utils/logger.js";
|
|
@@ -100,7 +102,7 @@ program
|
|
|
100
102
|
"--usrsctp-state",
|
|
101
103
|
"Read usrsctp's association state with gdb when a wedge is declared. OFF by default: gdb attaches to THIS process and stops every thread of it while it works."
|
|
102
104
|
)
|
|
103
|
-
.option("--memory-bytes <bytes>", "Per-torrent budget for pieces kept in memory before spilling to disk (default
|
|
105
|
+
.option("--memory-bytes <bytes>", "Per-torrent budget for pieces kept in memory before spilling to disk (default: derived from the memory available when the torrent opens, shared equally between open torrents)")
|
|
104
106
|
.option("--budget <kind>", "How much of this machine the proxy may take: adaptive (default), share or fixed")
|
|
105
107
|
.option("--budget-share <fraction>", "With --budget share: the fraction of what is free, 0..1")
|
|
106
108
|
.option("--budget-bytes <bytes>", "With --budget fixed: the ceiling, per resource")
|
|
@@ -109,7 +111,7 @@ program
|
|
|
109
111
|
.option("--ffmpeg-bin <path>", "Path to ffmpeg binary")
|
|
110
112
|
.option(
|
|
111
113
|
"--state-dir <path>",
|
|
112
|
-
"Where to keep what this host has measured about itself (default:
|
|
114
|
+
"Where to keep this installation's id, what this host has measured about itself, and diagnostic dumps (default: the installed proxy's own directory; pass an empty value to keep nothing)"
|
|
113
115
|
)
|
|
114
116
|
.option(
|
|
115
117
|
"--log-file <path>",
|
|
@@ -137,7 +139,19 @@ const bindHost = String(options.host);
|
|
|
137
139
|
const explicitBaseUrl = options.publicBaseUrl
|
|
138
140
|
? String(options.publicBaseUrl).replace(/\/+$/, "")
|
|
139
141
|
: "";
|
|
140
|
-
|
|
142
|
+
// THE STATE DIRECTORY, resolved once: the one named, the installed proxy's own
|
|
143
|
+
// directory when none is named, or "" when the operator passes an empty value
|
|
144
|
+
// (nothing is kept). Every consumer below is handed this value and none reads
|
|
145
|
+
// the option again.
|
|
146
|
+
const stateDir = options.stateDir === undefined ? PROXY_ROOT : String(options.stateDir);
|
|
147
|
+
if (stateDir) {
|
|
148
|
+
try {
|
|
149
|
+
mkdirSync(stateDir, { recursive: true });
|
|
150
|
+
} catch (error) {
|
|
151
|
+
logger.warn(`Could not create the state directory ${stateDir}: ${error instanceof Error ? error.message : String(error)}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const clientId = installationId({ stateDir, explicitId: options.id });
|
|
141
155
|
const clientName = options.name ? String(options.name) : `proxy-${clientId.slice(0, 8)}`;
|
|
142
156
|
const token = String(options.token ?? "");
|
|
143
157
|
const transcodeAudio = options.transcodeAudio !== false;
|
|
@@ -347,15 +361,15 @@ async function shutdown(signal) {
|
|
|
347
361
|
const diagnostics = new Diagnostics({
|
|
348
362
|
logger,
|
|
349
363
|
kinds: [
|
|
350
|
-
{ name: "core dumps", directory: () =>
|
|
364
|
+
{ name: "core dumps", directory: () => stateDir, matches: (name) => name.startsWith("core.") },
|
|
351
365
|
{
|
|
352
366
|
name: "heap snapshots",
|
|
353
|
-
directory: () =>
|
|
367
|
+
directory: () => stateDir,
|
|
354
368
|
matches: (name) => name.endsWith(".heapsnapshot")
|
|
355
369
|
},
|
|
356
370
|
{
|
|
357
371
|
name: "packet captures",
|
|
358
|
-
directory: () =>
|
|
372
|
+
directory: () => stateDir,
|
|
359
373
|
matches: (name) => name.startsWith("packet-witness")
|
|
360
374
|
}
|
|
361
375
|
]
|
|
@@ -391,7 +405,7 @@ try {
|
|
|
391
405
|
ffmpegBin,
|
|
392
406
|
memoryBytes,
|
|
393
407
|
segmentFormat: options.segmentFormat,
|
|
394
|
-
stateDir
|
|
408
|
+
stateDir,
|
|
395
409
|
diagnostics,
|
|
396
410
|
budgetPolicy,
|
|
397
411
|
logFile: options.logFile ?? "",
|
|
@@ -444,11 +458,11 @@ try {
|
|
|
444
458
|
// A native fault writes the whole address space out — 4.18 GB each on the
|
|
445
459
|
// field host, and four of them nearly filled a 235 GB disk. Keep the newest
|
|
446
460
|
// two, which are the evidence for the fault still open, and drop the rest.
|
|
447
|
-
void pruneCoreDumps(
|
|
461
|
+
void pruneCoreDumps(stateDir);
|
|
448
462
|
// Same policy for the packet captures the send-queue witness writes.
|
|
449
463
|
packetWitness = createPacketWitness({
|
|
450
464
|
log: (message) => logger.info(message),
|
|
451
|
-
dir:
|
|
465
|
+
dir: stateDir,
|
|
452
466
|
port: actualPort,
|
|
453
467
|
// Evidence takes room from the product, so a capture is asked for rather
|
|
454
468
|
// than taken. Refused, it is a line and not a silence.
|
|
@@ -517,8 +531,6 @@ try {
|
|
|
517
531
|
// read stayed behind the decision to write, so a quiet second costs one
|
|
518
532
|
// call to `process.memoryUsage()`.
|
|
519
533
|
intervalMs: 1_000,
|
|
520
|
-
quietMs: 60_000,
|
|
521
|
-
changeBytes: 25 * 1024 * 1024,
|
|
522
534
|
diskPath: os.tmpdir(),
|
|
523
535
|
// WHERE A SNAPSHOT SURVIVES THE PROCESS IT IS ABOUT, and how many are kept
|
|
524
536
|
// — the same answer the torrent worker already had. This scope had neither:
|
|
@@ -526,11 +538,8 @@ try {
|
|
|
526
538
|
// on every restart, and all of them were kept. Fifty-four were written on
|
|
527
539
|
// 2026-09-07 and every one was gone by the time the process that wrote them
|
|
528
540
|
// died of a heap it had never been possible to look at.
|
|
529
|
-
snapshotDir:
|
|
541
|
+
snapshotDir: stateDir || undefined,
|
|
530
542
|
heapSnapshots: options.heapSnapshots === true,
|
|
531
|
-
snapshotFloorBytes: 400 * 1024 * 1024,
|
|
532
|
-
snapshotGrowthBytes: 400 * 1024 * 1024,
|
|
533
|
-
keepSnapshots: 3
|
|
534
543
|
});
|
|
535
544
|
|
|
536
545
|
logger.info(`Starting @torrent-tv/proxy v${PROXY_VERSION}`);
|