From d1853743da5c4b6749e878d75935b1d96fdde2fd Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Fri, 30 Jan 2026 09:30:55 -0500 Subject: [PATCH] Throttle torrent status updates and logging --- js/ui/torrentStatusController.js | 128 ++++++++++++++++++++++--------- 1 file changed, 91 insertions(+), 37 deletions(-) diff --git a/js/ui/torrentStatusController.js b/js/ui/torrentStatusController.js index 855aae11..f3f2204d 100644 --- a/js/ui/torrentStatusController.js +++ b/js/ui/torrentStatusController.js @@ -1,3 +1,4 @@ +import { isVerboseDevMode } from "../config.js"; import { devLogger } from "../utils/logger.js"; export default class TorrentStatusController { @@ -7,16 +8,38 @@ export default class TorrentStatusController { } this.getVideoModal = getVideoModal; this.onRemovePoster = typeof onRemovePoster === "function" ? onRemovePoster : () => {}; + this.lastEmitted = { + status: null, + progress: null, + peers: null, + speed: null, + downloaded: null, + }; + this.lastVerboseLogAt = 0; + this.lastVerboseSummaryKey = ""; + this.verboseLogIntervalMs = 3000; } update(torrent) { - devLogger.log("[DEBUG] TorrentStatusController.update called with torrent:", torrent); - if (!torrent) { - devLogger.log("[DEBUG] torrent is null/undefined!"); + if (isVerboseDevMode) { + this.logVerboseSummary({ hasTorrent: false }); + } return; } + if (isVerboseDevMode) { + this.logVerboseSummary({ + hasTorrent: true, + progress: torrent.progress, + numPeers: torrent.numPeers, + downloadSpeed: torrent.downloadSpeed, + downloaded: torrent.downloaded, + length: torrent.length, + ready: torrent.ready, + }); + } + if (torrent.ready || (typeof torrent.progress === "number" && torrent.progress > 0)) { // Belt-and-suspenders: if WebTorrent reports progress but the DOM events // failed to fire we still rip off the loading GIF. This regression has @@ -26,48 +49,79 @@ export default class TorrentStatusController { ); } - // Log only fields that actually exist on the torrent: - devLogger.log("[DEBUG] torrent.progress =", torrent.progress); - devLogger.log("[DEBUG] torrent.numPeers =", torrent.numPeers); - devLogger.log("[DEBUG] torrent.downloadSpeed =", torrent.downloadSpeed); - devLogger.log("[DEBUG] torrent.downloaded =", torrent.downloaded); - devLogger.log("[DEBUG] torrent.length =", torrent.length); - devLogger.log("[DEBUG] torrent.ready =", torrent.ready); - const videoModal = this.getVideoModal(); // Use "Complete" vs. "Downloading" as the textual status. if (videoModal) { - const fullyDownloaded = torrent.progress >= 1; - if (typeof videoModal.updateStatus === "function") { - videoModal.updateStatus(fullyDownloaded ? "Complete" : "Downloading"); - } + const fullyDownloaded = Number(torrent.progress) >= 1; + const status = torrent.ready + ? "Ready to play" + : fullyDownloaded + ? "Complete" + : "Downloading"; + this.updateIfChanged("status", status, () => { + if (typeof videoModal.updateStatus === "function") { + videoModal.updateStatus(status); + } + }); - if (typeof videoModal.updateProgress === "function") { - const percent = (torrent.progress * 100).toFixed(2); - videoModal.updateProgress(`${percent}%`); - } + const progressValue = Number.isFinite(torrent.progress) + ? `${(torrent.progress * 100).toFixed(2)}%` + : "0.00%"; + this.updateIfChanged("progress", progressValue, () => { + if (typeof videoModal.updateProgress === "function") { + videoModal.updateProgress(progressValue); + } + }); - if (typeof videoModal.updatePeers === "function") { - videoModal.updatePeers(`Peers: ${torrent.numPeers}`); - } + const peersValue = `Peers: ${Number.isFinite(torrent.numPeers) ? torrent.numPeers : 0}`; + this.updateIfChanged("peers", peersValue, () => { + if (typeof videoModal.updatePeers === "function") { + videoModal.updatePeers(peersValue); + } + }); - if (typeof videoModal.updateSpeed === "function") { - const kb = (torrent.downloadSpeed / 1024).toFixed(2); - videoModal.updateSpeed(`${kb} KB/s`); - } + const speedValue = Number.isFinite(torrent.downloadSpeed) + ? `${(torrent.downloadSpeed / 1024).toFixed(2)} KB/s` + : "0.00 KB/s"; + this.updateIfChanged("speed", speedValue, () => { + if (typeof videoModal.updateSpeed === "function") { + videoModal.updateSpeed(speedValue); + } + }); - if (typeof videoModal.updateDownloaded === "function") { - const downloadedMb = (torrent.downloaded / (1024 * 1024)).toFixed(2); - const lengthMb = (torrent.length / (1024 * 1024)).toFixed(2); - videoModal.updateDownloaded( - `${downloadedMb} MB / ${lengthMb} MB` - ); - } - - if (torrent.ready && typeof videoModal.updateStatus === "function") { - videoModal.updateStatus("Ready to play"); - } + const downloadedMb = Number.isFinite(torrent.downloaded) + ? (torrent.downloaded / (1024 * 1024)).toFixed(2) + : "0.00"; + const lengthMb = Number.isFinite(torrent.length) + ? (torrent.length / (1024 * 1024)).toFixed(2) + : "0.00"; + const downloadedValue = `${downloadedMb} MB / ${lengthMb} MB`; + this.updateIfChanged("downloaded", downloadedValue, () => { + if (typeof videoModal.updateDownloaded === "function") { + videoModal.updateDownloaded(downloadedValue); + } + }); } } + + updateIfChanged(key, nextValue, updater) { + if (this.lastEmitted[key] === nextValue) { + return; + } + this.lastEmitted[key] = nextValue; + updater(); + } + + logVerboseSummary(summary) { + const summaryKey = JSON.stringify(summary); + const now = Date.now(); + const shouldSample = now - this.lastVerboseLogAt >= this.verboseLogIntervalMs; + if (summaryKey === this.lastVerboseSummaryKey && !shouldSample) { + return; + } + this.lastVerboseSummaryKey = summaryKey; + this.lastVerboseLogAt = now; + devLogger.debug("[DEBUG] TorrentStatusController.update", summary); + } }