diff --git a/src/server/services/progress_service.py b/src/server/services/progress_service.py index 06d1beb..31717d8 100644 --- a/src/server/services/progress_service.py +++ b/src/server/services/progress_service.py @@ -8,6 +8,7 @@ to connected clients. from __future__ import annotations import asyncio +import time from dataclasses import dataclass, field from datetime import datetime, timezone from enum import Enum @@ -168,6 +169,9 @@ class ProgressService: - Support for different progress types (download, scan, queue) """ + # Minimum interval between broadcasts in seconds (300ms) + MIN_BROADCAST_INTERVAL: float = 0.3 + def __init__(self): """Initialize the progress service.""" # Active progress operations: id -> ProgressUpdate @@ -182,6 +186,9 @@ class ProgressService: str, List[Callable[[ProgressEvent], None]] ] = {} + # Track last broadcast time per progress_id for time-based throttling + self._last_broadcast_time: Dict[str, float] = {} + # Lock for thread-safe operations self._lock = asyncio.Lock() @@ -389,11 +396,21 @@ class ProgressService: update.status = ProgressStatus.IN_PROGRESS update.updated_at = datetime.now(timezone.utc) - # Only broadcast if significant change or forced + # Time-based throttle: broadcast at most every 300ms, + # or immediately for significant changes / forced broadcasts + now = time.monotonic() + last_broadcast = self._last_broadcast_time.get(progress_id, 0.0) + time_since_last = now - last_broadcast percent_change = abs(update.percent - old_percent) - should_broadcast = force_broadcast or percent_change >= 1.0 + + should_broadcast = ( + force_broadcast + or percent_change >= 1.0 + or time_since_last >= self.MIN_BROADCAST_INTERVAL + ) if should_broadcast: + self._last_broadcast_time[progress_id] = time.monotonic() room = _get_room_for_progress_type(update.type) event = ProgressEvent( event_type=f"{update.type.value}_progress", @@ -442,6 +459,7 @@ class ProgressService: # Move to history del self._active_progress[progress_id] + self._last_broadcast_time.pop(progress_id, None) self._add_to_history(update) logger.info( @@ -497,6 +515,7 @@ class ProgressService: # Move to history del self._active_progress[progress_id] + self._last_broadcast_time.pop(progress_id, None) self._add_to_history(update) logger.error( @@ -548,6 +567,7 @@ class ProgressService: # Move to history del self._active_progress[progress_id] + self._last_broadcast_time.pop(progress_id, None) self._add_to_history(update) logger.info(