Multi-Hoster-Upload/tasks/todo.md
Administrator bf806cb069 fix(rotation): session-learning for account failures is now complete
Three related gaps closed so one full byse account stops wasting
attempts on every subsequent job and later-added accounts get picked
up without an app restart.

1. Pre-job-swap moved BEHIND the semaphore acquire. At scale (500 jobs
   / 1 slot) every worker was checking _failedAccounts at spawn time
   before the first upload had even tried — so none of them saw the
   failed state. Now each worker re-checks right before its first
   upload attempt.

2. save-config IPC handler re-resolves fallbacks for any account that
   is already in _failedAccounts but has no override set. Previously
   account-failed only fired once per account, so a config change
   after the first mark-failed was silently ignored and the batch
   stayed stuck on the dead account until the app restarted.

3. UploadManager exposes getFailedAccountKeys() and getOverride(hoster)
   so main.js can drive the late re-resolve without poking private
   fields.

4 new tests: pre-job-swap after semaphore, getters contract, fresh
manager resets learned state, late-added fallback is honored by
subsequent jobs. 80/80 green.
2026-04-21 17:03:59 +02:00

2.1 KiB

Account-Rotation: vollständiger Session-Lernprozess

Problem

  1. Byse "disk space full" wurde als file-rejected klassifiziert → keine Rotation. (3.1.4 ✓)
  2. pre-job-swap checkte _failedAccounts VOR Semaphore-Acquire → alle parallelen Jobs probierten weiter den vollen Account. (3.1.5 ✓)
  3. Wenn beim ersten Fail noch kein Fallback-Account existierte und der User DANACH einen hinzufügt → _accountOverrides blieb leer, keine weitere account-failed-Emission (nur einmalig pro Account) → System blieb stuck bis zum Neustart. (3.1.5 ✓)

Fix

  • lib/upload-manager.js — Pre-Job-Swap hinter semaphore.acquire verschoben, plus zwei public getter: getFailedAccountKeys(), getOverride(hoster).
  • main.jssave-config IPC-Handler ruft nach dem Speichern getNextFallbackAccount für alle failed-ohne-Override accounts im aktiven UploadManager. Findet er was, ruft er switchAccount. Emittiert account-switched an den Renderer.
  • Tests (4 neue):
    • pre-job-swap greift für parallele Worker nach Semaphore-Queue.
    • getFailedAccountKeys + getOverride als public API.
    • Neustart-Reset: fresh Manager hat keine gelernte failed-Historie.
    • Late-resolved Override wird von Folgejobs genutzt (mid-batch config add).
  • npm test — 80/80 grün.
  • Release als 3.1.5 (auf User-OK).

Behavior-Matrix

Szenario Verhalten
acc1 + acc2 gleich aktiv, acc1 wird voll acc1→acc2 Rotation, alle weiteren Jobs direkt acc2 ✓
Nur acc1 aktiv, acc2 mid-batch hinzugefügt BEVOR acc1 voll Erster Fail resolved gegen frische Config, acc2 wird gezogen ✓
Nur acc1 aktiv, acc1 wird voll, DANACH acc2 hinzugefügt save-config trigert Late-Resolve, switchAccount(acc2) wird aufgerufen, Folgejobs swappen pre-job ✓
App-Neustart _failedAccounts in-memory → fresh, acc1 wird wieder probiert ✓

Review

Drei Ebenen zusammen (3.1.4 Classifier + 3.1.5 pre-swap-after-queue + 3.1.5 late-resolve) machen das Session-Lernen komplett: disk-space-voll wird erkannt, markiert, alle wartenden Jobs sehen es wenn sie dran sind, und spätere Config-Änderungen werden reaktiv aufgegriffen.