smart queue fix
This commit is contained in:
@@ -369,15 +369,15 @@ def _cleanup_auto_labels(client: Any, profile_id: int, torrents: list[dict[str,
|
|||||||
|
|
||||||
def _is_running_download_slot(t: dict[str, Any]) -> bool:
|
def _is_running_download_slot(t: dict[str, Any]) -> bool:
|
||||||
"""Return True for incomplete torrents that already occupy a Smart Queue slot."""
|
"""Return True for incomplete torrents that already occupy a Smart Queue slot."""
|
||||||
# Note: Limit Smart Queue oznacza docelową liczbę slotów włączonych do pobierania.
|
# Note: Limit Smart Queue oznacza docelową liczbę realnie uruchomionych slotów.
|
||||||
# rTorrent często pokazuje d.is_active=0 dla torrentów bez chwilowego transferu, więc slot liczymy
|
# rTorrent potrafi trzymać paused jako state=1, dlatego slot liczymy po state=1 tylko wtedy,
|
||||||
# po d.state=1. Techniczny label Smart Queue jest wyjątkiem: oznacza pozycję oczekującą/pauzowaną,
|
# gdy torrent nie ma statusu Paused i nie jest oznaczony technicznym labelem Smart Queue.
|
||||||
# której nie wolno liczyć jako aktywnej. Dzięki temu przy limicie 100 i 82 slotach dobieramy 18.
|
|
||||||
if int(t.get('complete') or 0):
|
if int(t.get('complete') or 0):
|
||||||
return False
|
return False
|
||||||
if str(t.get('label') or '') == SMART_QUEUE_LABEL:
|
if str(t.get('label') or '') == SMART_QUEUE_LABEL:
|
||||||
return False
|
return False
|
||||||
if str(t.get('status') or '').lower() == 'checking':
|
status = str(t.get('status') or '').lower()
|
||||||
|
if status == 'checking' or status == 'paused' or bool(t.get('paused')):
|
||||||
return False
|
return False
|
||||||
return bool(int(t.get('state') or 0))
|
return bool(int(t.get('state') or 0))
|
||||||
|
|
||||||
@@ -484,9 +484,9 @@ def check(profile: dict | None = None, user_id: int | None = None, force: bool =
|
|||||||
to_pause: list[dict[str, Any]] = pause_rank[:max(0, len(downloading) - max_active)]
|
to_pause: list[dict[str, Any]] = pause_rank[:max(0, len(downloading) - max_active)]
|
||||||
pause_hashes = {str(t.get('hash') or '') for t in to_pause}
|
pause_hashes = {str(t.get('hash') or '') for t in to_pause}
|
||||||
|
|
||||||
# When the cap is not exceeded, stalled downloads can still be rotated out
|
# Note: Rotacja stalled działa tylko przy pełnej kolejce. Gdy brakuje slotów, Smart Queue ma
|
||||||
# one-for-one with better stopped candidates while staying within max_active.
|
# najpierw dobrać brakujące pozycje, a nie pauzować już istniejące lub błędnie uznane za stalled.
|
||||||
if candidates:
|
if candidates and len(downloading) >= max_active:
|
||||||
replaceable_stalled = [t for t in stalled if str(t.get('hash') or '') not in pause_hashes]
|
replaceable_stalled = [t for t in stalled if str(t.get('hash') or '') not in pause_hashes]
|
||||||
for t in replaceable_stalled[:max(0, len(candidates) - len(to_pause))]:
|
for t in replaceable_stalled[:max(0, len(candidates) - len(to_pause))]:
|
||||||
to_pause.append(t)
|
to_pause.append(t)
|
||||||
@@ -547,6 +547,6 @@ def check(profile: dict | None = None, user_id: int | None = None, force: bool =
|
|||||||
| {str(t.get('hash') or '') for t in stopped if str(t.get('label') or '') == SMART_QUEUE_LABEL and str(t.get('hash') or '') not in set(resumed)}
|
| {str(t.get('hash') or '') for t in stopped if str(t.get('label') or '') == SMART_QUEUE_LABEL and str(t.get('hash') or '') not in set(resumed)}
|
||||||
)
|
)
|
||||||
restored = _cleanup_auto_labels(c, profile_id, torrents, keep_labels, manage_stopped)
|
restored = _cleanup_auto_labels(c, profile_id, torrents, keep_labels, manage_stopped)
|
||||||
details = {'excluded': len(excluded), 'enabled': bool(settings.get('enabled')), 'auto_label': SMART_QUEUE_LABEL, 'labels_restored': restored, 'labels_failed': label_failed, 'start_failed': start_failed, 'start_no_effect': start_no_effect, 'resume_requested': resume_requested, 'active_verified': active_verified, 'waiting_labeled': len(to_label_waiting), 'manage_stopped': manage_stopped, 'max_active_downloads': max_active, 'active_before': len(downloading), 'active_after': active_after_pause + len(resumed), 'rtorrent_cap': rtorrent_cap}
|
details = {'excluded': len(excluded), 'enabled': bool(settings.get('enabled')), 'auto_label': SMART_QUEUE_LABEL, 'labels_restored': restored, 'labels_failed': label_failed, 'start_failed': start_failed, 'start_no_effect': start_no_effect, 'resume_requested': resume_requested, 'active_verified': active_verified, 'waiting_labeled': len(to_label_waiting), 'manage_stopped': manage_stopped, 'max_active_downloads': max_active, 'active_before': len(downloading), 'active_after_expected': active_after_pause + len(resumed), 'paused_planned': len(to_pause), 'resumed_planned': len(to_resume), 'rtorrent_cap': rtorrent_cap}
|
||||||
add_history(profile_id, 'force_check' if force else 'auto_check', paused, resumed, len(torrents), details, user_id)
|
add_history(profile_id, 'force_check' if force else 'auto_check', paused, resumed, len(torrents), details, user_id)
|
||||||
return {'ok': True, 'enabled': bool(settings.get('enabled')), 'paused': paused, 'resumed': resumed, 'resume_requested': resume_requested, 'waiting_labeled': len(to_label_waiting), 'labels_restored': restored, 'labels_failed': label_failed, 'start_failed': start_failed, 'start_no_effect': start_no_effect, 'active_verified': active_verified, 'rtorrent_cap': rtorrent_cap, 'checked': len(torrents), 'excluded': len(excluded), 'settings': settings}
|
return {'ok': True, 'enabled': bool(settings.get('enabled')), 'paused': paused, 'resumed': resumed, 'resume_requested': resume_requested, 'waiting_labeled': len(to_label_waiting), 'labels_restored': restored, 'labels_failed': label_failed, 'start_failed': start_failed, 'start_no_effect': start_no_effect, 'active_verified': active_verified, 'rtorrent_cap': rtorrent_cap, 'checked': len(torrents), 'excluded': len(excluded), 'settings': settings}
|
||||||
|
|||||||
Reference in New Issue
Block a user