From d5465e9768a71d93bcfb72fb0d614085f3a95600 Mon Sep 17 00:00:00 2001 From: zarzet Date: Sun, 30 Aug 2026 00:17:27 +0700 Subject: [PATCH] fix(download): throttle progress diagnostics --- lib/providers/download_queue_provider.dart | 2 ++ .../download_queue_provider_progress.dart | 34 +++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/lib/providers/download_queue_provider.dart b/lib/providers/download_queue_provider.dart index 1f1f9660..88398a82 100644 --- a/lib/providers/download_queue_provider.dart +++ b/lib/providers/download_queue_provider.dart @@ -328,6 +328,7 @@ class DownloadQueueNotifier extends Notifier { 'download_queue_native_worker_run_id'; static const _userPausedQueuePrefsKey = 'download_queue_user_paused_v1'; static const _bytesUiStep = 104857; // ~0.1 MiB, matches one-decimal MB UI. + static const _progressLogStepPercent = 5; static const _serviceProgressStepPercent = 2; static const _decryptStageSafAccess = 'safAccess'; static const _decryptStageDecrypt = 'decrypt'; @@ -369,6 +370,7 @@ class DownloadQueueNotifier extends Notifier { Future? _appFolderStorageFallback; final Set _rejectedAppFolderRoots = {}; int _idleProgressPollTick = 0; + final Map _lastProgressLogBucketByItem = {}; Future _withQualityVariantFileLock( String path, diff --git a/lib/providers/download_queue_provider_progress.dart b/lib/providers/download_queue_provider_progress.dart index 9ed43d99..30a5793e 100644 --- a/lib/providers/download_queue_provider_progress.dart +++ b/lib/providers/download_queue_provider_progress.dart @@ -20,6 +20,26 @@ class _ProgressUpdate { } extension _DownloadQueueProgress on DownloadQueueNotifier { + bool _shouldLogDownloadProgress( + String itemId, + double progress, { + bool preparing = false, + }) { + final bucket = preparing + ? -1 + : (() { + final percent = (progress * 100).floor().clamp(0, 100).toInt(); + if (percent == 100) return 100; + return (percent ~/ DownloadQueueNotifier._progressLogStepPercent) * + DownloadQueueNotifier._progressLogStepPercent; + })(); + if (_lastProgressLogBucketByItem[itemId] == bucket) { + return false; + } + _lastProgressLogBucketByItem[itemId] = bucket; + return true; + } + double _normalizeProgressForUi(double value) { final clamped = value.clamp(0.0, 1.0).toDouble(); if (clamped <= 0) return 0; @@ -106,6 +126,13 @@ extension _DownloadQueueProgress on DownloadQueueNotifier { : const {}; final currentItems = state.items; final lookup = state.lookup; + _lastProgressLogBucketByItem.removeWhere((itemId, _) { + final item = lookup.byItemId[itemId]; + return item == null || + item.status == DownloadStatus.completed || + item.status == DownloadStatus.failed || + item.status == DownloadStatus.skipped; + }); final queuedCount = lookup.queuedCount; final downloadingCount = lookup.activeDownloadsCount; DownloadItem? firstDownloading; @@ -195,7 +222,8 @@ extension _DownloadQueueProgress on DownloadQueueNotifier { preparationStage: itemProgress['stage']?.toString() ?? '', ); - if (LogBuffer.loggingEnabled) { + if (LogBuffer.loggingEnabled && + _shouldLogDownloadProgress(itemId, 0, preparing: true)) { _log.d('Preparing [$itemId]: waiting for real download bytes'); } continue; @@ -220,7 +248,8 @@ extension _DownloadQueueProgress on DownloadQueueNotifier { bytesTotal: bytesTotal, ); - if (LogBuffer.loggingEnabled) { + if (LogBuffer.loggingEnabled && + _shouldLogDownloadProgress(itemId, percentage)) { final mbReceived = bytesReceived / (1024 * 1024); final mbTotal = bytesTotal / (1024 * 1024); if (bytesTotal > 0) { @@ -439,6 +468,7 @@ extension _DownloadQueueProgress on DownloadQueueNotifier { void _stopProgressPolling() { _progressPoller.stop(); _idleProgressPollTick = 0; + _lastProgressLogBucketByItem.clear(); _lastServiceTrackName = null; _lastServiceArtistName = null; _lastServiceStatus = null;