@torrent-tv/proxy 2.104.0 → 2.104.1
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/package.json
CHANGED
|
@@ -494,43 +494,50 @@ async function runCommand(command, params, id) {
|
|
|
494
494
|
const statsStartedAt = performance.now();
|
|
495
495
|
emitWaitTrace(params.sourceKey, "W10", "begin", { startedAt: statsStartedAt,
|
|
496
496
|
fileIndex: params.fileIndex, forecast: params.forecast === true });
|
|
497
|
-
const
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
endedAt: performance.now(), outcome: whole ? "whole-file" : "pending", fileIndex: params.fileIndex });
|
|
502
|
-
return whole ? wholeFileStats(whole.length) : { pending: true };
|
|
503
|
-
}
|
|
504
|
-
// What this file's own interruptions demand, measured by the reader in
|
|
505
|
-
// this thread. It travels with the stats because the caller asking for
|
|
506
|
-
// them is the one that has to decide with them — the browser's smallest
|
|
507
|
-
// safe buffer, and the speed a quality step must sustain. Null until a
|
|
508
|
-
// second interruption has been seen: one wait shows no interval, and an
|
|
509
|
-
// interval invented from one point is exactly what this work removes.
|
|
510
|
-
const file = Array.isArray(torrent?.files) ? torrent.files[params.fileIndex] : null;
|
|
511
|
-
const forecastAt = performance.now();
|
|
512
|
-
const forecast = file && params.forecast === true ? downloadForecastOf(torrent) : null;
|
|
513
|
-
const forecastMs = params.forecast === true ? performance.now() - forecastAt : 0;
|
|
514
|
-
const stats = pool.getFileStats(torrent, params.fileIndex);
|
|
515
|
-
const ranges = [];
|
|
516
|
-
if (forecast) for (const [piece, availableAt] of forecast.arrivals) {
|
|
517
|
-
const start = piece * torrent.pieceLength;
|
|
518
|
-
const end = Math.min(torrent.length, (piece + 1) * torrent.pieceLength);
|
|
519
|
-
if (end > start) ranges.push({ start, end, availableAt });
|
|
520
|
-
}
|
|
521
|
-
emitWaitTrace(params.sourceKey, "W10", "end", { startedAt: statsStartedAt,
|
|
522
|
-
endedAt: performance.now(), outcome: "ok", fileIndex: params.fileIndex,
|
|
523
|
-
forecast: params.forecast === true });
|
|
524
|
-
return {
|
|
525
|
-
...stats,
|
|
526
|
-
...(params.forecast === true ? { downloadForecast: {
|
|
527
|
-
measuredAt: forecast?.measuredAt ?? Date.now(), global: true, ranges
|
|
528
|
-
} } : {}),
|
|
529
|
-
supply: supplyFiguresFor(torrent?.infoHash, file?.name, params.segmentSeconds ?? 4),
|
|
530
|
-
// How long this answer waited for the arrival forecast, which the
|
|
531
|
-
// caller says beside its own time (ViewerRequests, torrent-tv/meta#178).
|
|
532
|
-
forecastMs
|
|
497
|
+
const finishStatsTrace = (outcome, fields = {}) => {
|
|
498
|
+
const endedAt = performance.now();
|
|
499
|
+
emitWaitTrace(params.sourceKey, "W10", "end", { startedAt: statsStartedAt, endedAt,
|
|
500
|
+
durationMs: endedAt - statsStartedAt, outcome, fileIndex: params.fileIndex, ...fields });
|
|
533
501
|
};
|
|
502
|
+
try {
|
|
503
|
+
const torrent = await knownTorrent(params.sourceKey);
|
|
504
|
+
if (!torrent) {
|
|
505
|
+
const whole = wholeSources.fileOf(params.sourceKey, params.fileIndex);
|
|
506
|
+
finishStatsTrace(whole ? "whole-file" : "pending");
|
|
507
|
+
return whole ? wholeFileStats(whole.length) : { pending: true };
|
|
508
|
+
}
|
|
509
|
+
// What this file's own interruptions demand, measured by the reader in
|
|
510
|
+
// this thread. It travels with the stats because the caller asking for
|
|
511
|
+
// them is the one that has to decide with them — the browser's smallest
|
|
512
|
+
// safe buffer, and the speed a quality step must sustain. Null until a
|
|
513
|
+
// second interruption has been seen: one wait shows no interval, and an
|
|
514
|
+
// interval invented from one point is exactly what this work removes.
|
|
515
|
+
const file = Array.isArray(torrent?.files) ? torrent.files[params.fileIndex] : null;
|
|
516
|
+
const forecastAt = performance.now();
|
|
517
|
+
const forecast = file && params.forecast === true ? downloadForecastOf(torrent) : null;
|
|
518
|
+
const forecastMs = params.forecast === true ? performance.now() - forecastAt : 0;
|
|
519
|
+
const stats = pool.getFileStats(torrent, params.fileIndex);
|
|
520
|
+
const ranges = [];
|
|
521
|
+
if (forecast) for (const [piece, availableAt] of forecast.arrivals) {
|
|
522
|
+
const start = piece * torrent.pieceLength;
|
|
523
|
+
const end = Math.min(torrent.length, (piece + 1) * torrent.pieceLength);
|
|
524
|
+
if (end > start) ranges.push({ start, end, availableAt });
|
|
525
|
+
}
|
|
526
|
+
finishStatsTrace("ok", { forecast: params.forecast === true });
|
|
527
|
+
return {
|
|
528
|
+
...stats,
|
|
529
|
+
...(params.forecast === true ? { downloadForecast: {
|
|
530
|
+
measuredAt: forecast?.measuredAt ?? Date.now(), global: true, ranges
|
|
531
|
+
} } : {}),
|
|
532
|
+
supply: supplyFiguresFor(torrent?.infoHash, file?.name, params.segmentSeconds ?? 4),
|
|
533
|
+
// How long this answer waited for the arrival forecast, which the
|
|
534
|
+
// caller says beside its own time (ViewerRequests, torrent-tv/meta#178).
|
|
535
|
+
forecastMs
|
|
536
|
+
};
|
|
537
|
+
} catch (error) {
|
|
538
|
+
finishStatsTrace("error", { error: String(error?.message ?? error) });
|
|
539
|
+
throw error;
|
|
540
|
+
}
|
|
534
541
|
}
|
|
535
542
|
|
|
536
543
|
case Command.PRIORITY_MAP: {
|
|
@@ -544,18 +551,27 @@ async function runCommand(command, params, id) {
|
|
|
544
551
|
// Nor may one for a file held whole, which has nothing left to fetch.
|
|
545
552
|
const torrent = await knownTorrent(params.sourceKey);
|
|
546
553
|
if (!torrent) {
|
|
554
|
+
emitWaitTrace(params.sourceKey, "W7", "event", { outcome: "source-not-ready", fileIndex: params.fileIndex });
|
|
547
555
|
return { appliedMs: null, receivedAt, repliedAt: performance.timeOrigin + performance.now() };
|
|
548
556
|
}
|
|
549
557
|
// What applying a map costs this thread, told to whoever sent it: every
|
|
550
558
|
// zone becomes a window of the register and the swarm is told again
|
|
551
559
|
// (torrent-tv/meta#166).
|
|
552
560
|
const startedAt = performance.now();
|
|
553
|
-
emitWaitTrace(params.sourceKey, "W7", "begin", { fileIndex: params.fileIndex });
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
561
|
+
emitWaitTrace(params.sourceKey, "W7", "begin", { startedAt, fileIndex: params.fileIndex });
|
|
562
|
+
try {
|
|
563
|
+
ensureArrivalsWired(params.sourceKey, torrent);
|
|
564
|
+
pool.applyPriorityMap(torrent, params.fileIndex, zones, params.durationSeconds);
|
|
565
|
+
torrent.emit("priority-map-changed", params.fileIndex);
|
|
566
|
+
const endedAt = performance.now();
|
|
567
|
+
emitWaitTrace(params.sourceKey, "W7", "end", { startedAt, endedAt, durationMs: endedAt - startedAt,
|
|
568
|
+
outcome: "applied", fileIndex: params.fileIndex });
|
|
569
|
+
} catch (error) {
|
|
570
|
+
const endedAt = performance.now();
|
|
571
|
+
emitWaitTrace(params.sourceKey, "W7", "end", { startedAt, endedAt, durationMs: endedAt - startedAt,
|
|
572
|
+
outcome: "error", error: String(error?.message ?? error), fileIndex: params.fileIndex });
|
|
573
|
+
throw error;
|
|
574
|
+
}
|
|
559
575
|
return { appliedMs: performance.now() - startedAt, receivedAt, repliedAt: performance.timeOrigin + performance.now() };
|
|
560
576
|
}
|
|
561
577
|
|