Multi-Hoster-Upload/tasks/todo.md
Administrator 04e535c709 fix(main): batch-done race could orphan a freshly-spawned UploadManager
The batch-done event handler awaits configStore.appendHistory(summary)
before nulling the global uploadManager reference. If the renderer
fires start-upload while that await is pending, the start-upload IPC
creates a fresh UploadManager and assigns it to the same global. The
old handler resumes, sets uploadManager = null, and orphans the new
manager: cancel-upload, add-jobs-to-batch, save-config re-resolve etc.
all see null and become no-ops, while the new batch keeps running
invisibly in the background.

Capture the manager identity at listener registration time and only
null the global if it still points at THIS manager. If a newer one
replaced it mid-await, leave it alone and log the near-miss for
diagnostics.

Found by deep-audit subagent. Tests still 119/119 (no test for this
because it needs a coordinated IPC + async-mock harness; the fix is
small and the diagnostic log will catch regressions).
2026-04-28 09:12:48 +02:00

3.9 KiB

Verbesserungs-Loop — open items

Released

  • 3.3.0 — Performance-Fixes (queue-cap, sort-throttle, history-delegation, recent-cap) + Log-Recovery
  • 3.3.1 — removeFromQueueOnDone coalesced via microtask (kein O(N²) mehr bei done-Bursts)
  • 3.3.2 — fileuploader.log Auto-Rotation bei 50 MB (max 3 Backups: .1 .2 .3)
  • 3.3.3 — _jobLogCollector Cap auf 1000 tracked jobs (FIFO-eviction beim Überschreiten)
  • 3.3.4 — applyQueueSelectionClasses + applyRecentSelectionClasses nutzen getElementsByClassName (live HTMLCollection statt querySelectorAll re-query bei jedem Klick)
  • 3.3.5 — Log-Rotation extrahiert nach lib/log-rotation.js + 10 neue Unit-Tests (cap, shift, eviction, idempotency, maxBackups=1, invalid input, no-extension)
  • 3.3.6 — CSS .queue-row transition nur noch auf :hover (kein 150ms compositor-tween bei status-flips)
  • 3.3.7 — _sessionTrackedJobs/_sessionDoneJobs werden bei handleBatchDone gegen current queueJobs geprunt (no more unbounded session memory growth across batches)
  • 3.3.8 — queue-cap-prune-Logik nach lib/queue-prune.js extrahiert (dual-environment: Node + Browser-global) + 10 Unit-Tests (insertion-order, limit=0, malformed entries, large-queue 5000-job sweep)
  • 3.3.9 — Throttled-Cache nach lib/throttled-cache.js extrahiert (von sortQueueJobs dynamic-throttle genutzt) + 12 Unit-Tests (TTL-Boundary, identity-tracking, fake-clock, peek/clear, refreshMs=0, large-input)
  • 3.3.10 — npm audit fix (non-breaking): 4 vulnerabilities geschlossen (16 → 12), nur Lock-file Update
  • 3.3.11 — Patch-Bumps eslint 10.1→10.2, undici 7.24→7.25, ws 8.19→8.20 (semver-compatible)
  • 3.3.12 — Race condition fix: uploadManager = null in batch-done clobberte einen frisch gespawnten Manager wenn user mid-await neuen batch startete (deep-audit finding HIGH-1)

Open items (priorisiert)

Stabilität (neu aus deep-audit)

  • save-global-settings-sync swallows write errors silently (main.js:1612-1628) — returns true even on disk-full / AV-lock. Should set returnValue=false + debugLog.
  • parseByseResult / parseDoodstreamResult crash on null payload (lib/hosters.js:202, 214, 163, 491) — JSON.parse('null') returns null, then payload.files throws TypeError. Guard if (!payload || typeof payload !== 'object') throw... after JSON.parse.
  • Cancellation latency in retry-loop's account-rotation block (lib/upload-manager.js:680-792) — re-check signal.aborted after each await.
  • TOCTOU on backup write in _atomicWrite (lib/config-store.js:254-258) — readFileSync after existsSync without try/catch; can fail if AV briefly locks file.

Code-Qualität (deferred)

  • removeFromQueueOnDone microtask-coalesce (3.3.1) — Microtask-Timing schwer zu testen ohne fake-timer setup
  • 12 weitere Vulnerabilities (10 high, 2 low) in electron-builder dev-chain — bräuchten npm audit fix --force mit Major-Bump electron-builder@26.8.1 (breaking). Skip bis User explizit ein Major-Update erlaubt.

Loop-Status

Alle initial im 3.3.0-Audit identifizierten Items sind nun adressiert. Beide verbliebenen open items sind explizit deferred (microtask-fake-timer-Setup ist Refactor, audit-fix --force ist Major-Bump und braucht User-OK).

Iteration 11 (skipped, no release): kein nicht-deferred Item übrig. Loop läuft idle weiter — bei nächstem Cron-Tick prüft er erneut, falls inzwischen neue Issues aufgetaucht sind.

Sinnvolle nächste Schritte für den User:

  • "Loop stop" wenn nichts mehr passieren soll (CronDelete 01e33ae1)
  • "Major bump genehmigt" für npm audit fix --force (closes 12 deferred vulns, bumpt electron-builder@26)
  • Neue konkrete User-Beschwerden / Bug-Reports
  • Manuelle Anweisung was als nächstes interessant wäre

Loop-Notes

  • Cron-Job 01e33ae1 läuft alle 30min (:07/:37), Session-only.
  • Pro Iteration: GENAU EIN Issue. Auto-Release bei grünen Tests. Boundary: keine Features, keine Major-Refactors.