Multi-Hoster-Upload/tasks/todo.md
Administrator 66f8b47b6d perf+fix: long-session lag, tab-switch lag, log-recovery
Bundles four findings from a stability audit plus the missing-log bug
the user reported.

1. main.js _flushUploadLog: ENOENT after the log file's directory got
   deleted mid-session was swallowed; the buffer was cleared before
   appendFile so entries were silently lost and the cached target kept
   pointing at the dead path. Now: mkdirSync(recursive) before every
   flush idempotently recreates a missing dir; on any append error we
   invalidate the cache, prepend the chunk back to the buffer and
   schedule a retry. Survives "user dragged the log folder into the
   trash and didn't notice".

2. renderer/app.js queueJobs auto-prune: with the default
   removeFromQueueOnDone=false the queue grew forever. Past ~5000
   entries every render became O(N) on a perpetually-growing N and
   the user saw progressive scroll/tab lag. Cap the in-queue
   terminal jobs (done/skipped/error/aborted) at 500 most-recent on
   each batch-done; oldest get pruned with their index entries.

3. sortQueueJobs dynamic-key throttle: status/speed/progress/size
   sorts ran a full O(N log N) sort on every progress tick. Added a
   200ms-window cache for the dynamic-key path so the sort is reused
   within the same UI_UPDATE_INTERVAL — invisibly small reorder lag,
   massive cost savings at 5000+ jobs.

4. renderHistoryTable delegated listeners: every Verlauf-tab switch
   was binding one click listener per row (5000 listeners on a
   long-history user) and rebuilding the entire <tbody> innerHTML.
   Single delegated tbody listener covers both row-click (copy link)
   and th-click (sort), bound once per container via dataset flag.

5. sessionFilesData (recent-files panel) cap at 2000 entries with
   matching _sessionFileKeys cleanup using the existing  separator.
   Stops the lower-panel innerHTML write from inflating to multiple
   MB on long sessions.

87/87 tests still green.
2026-04-28 03:30:33 +02:00

2.0 KiB
Raw Blame History

3.3.0 — Performance + Log-Recovery

Probleme (User-Bericht)

  1. Lag beim Tab-Wechsel + Scrollen nach langer Session.
  2. File-Uploader-Log: bei einem von zwei Hostern gar keine Log-Einträge — möglicherweise nach Datei/Verzeichnis-Löschung kein Recovery.

Root Causes (aus Audit)

Performance

  • queueJobs wächst unbounded (Default removeFromQueueOnDone=false). Sortierung + Stats + In-place-Render skalieren O(N) und O(N log N) je render. Nach ~5000 Jobs spürbar.
  • sortQueueJobs cached nur für static keys (filename, host). Bei status/speed/progress: voller Sort jedes Mal.
  • renderHistoryTable bindet per-row click listener + voller innerHTML-Rebuild bei jedem Tab-Switch.
  • renderRecentUploadsPanel baut komplettes innerHTML bei sort-change neu, sessionFilesData Array ungecapt.

Log-Bug

  • _flushUploadLog clear buffer vor appendFile. Bei ENOENT (Datei oder Dir wurde gelöscht) → silent log + buffer verloren.
  • _resolveUploadLogTarget cached den Path. Bei mid-session Verzeichnis-Löschung wird der cached target wiederverwendet → permanent ENOENT bis Neustart.

Plan

  • Log: bei error in appendFile → cache invalidieren + buffer prepend + retry
  • Log: vor jedem flush mkdirSync (idempotent, recreated deleted dir)
  • queueJobs: auto-prune nach handleBatchDone für älteste 'done' jobs jenseits Cap (z.B. 500)
  • sortQueueJobs: für dynamic keys → coalesce auf 1× pro UI_UPDATE_INTERVAL (200ms)
  • renderHistoryTable: delegated click-listener auf tbody (nicht per-row), short-circuit wenn _historyDirty=false
  • renderRecentUploadsPanel: sessionFilesData auf letzten 2000 Einträge cappen, _sessionFileKeys parallel prunen
  • removeFromQueueOnDone: O(N²) → splice via _jobIndexById (oder defer auf batch-done)
  • Tests: Log-recovery, queue-prune, sort-throttle
  • Release als 3.3.0

Skip (Low Impact / kosmetisch)

  • CSS transition fix
  • Module-level Sets clearing (genug Memory bisher)