diff --git a/tasks/todo.md b/tasks/todo.md index dcd13a9..cbbea97 100644 --- a/tasks/todo.md +++ b/tasks/todo.md @@ -1,3 +1,38 @@ +# v3.3.94 — comprehensive measurement build (user: "mach alles messen was man messen kann") + +Localization so far (each step EMPIRICAL, not by elimination — advisor caught the elimination-leap): +- Renderer queue render PROVEN cheap: loaded the REAL app.js in headless Chromium (Playwright) with a mocked + window.api, populated Q=1000 / 61 active / progress sort, drove the real onUploadProgressBatch + + renderQueueTable + scroll → ALL <0.5ms. (Caveat: component cost, not frame rate.) +- User CONFIRMED the discriminator: a full 1000-row queue scrolls SMOOTH when idle, ruckelt ONLY while ~61–70 + uploads are active → the lag is driven by the active uploads (main-process / system load), not the table. +- Screenshot: 70 connections, 1413 files, 41.3 MB/s, "write ECONNRESET". ECONNRESET is already classified + transient (upload-manager _isTransientNetworkError line 171 → retried, not account-fatal) — it's the + SIGNATURE of oversubscription (servers RST the excess connections). Same root cause as the lag. + +Immediate user lever (already exists): Settings → Uploads → "Globale parallele Uploads" (parallelUploadCount, +global semaphore, default 0=off). Capping total concurrent uploads (~20) should fix lag AND ECONNRESET AND +likely keep throughput (bandwidth-limited at 41 MB/s; reset connections waste bandwidth on retries). + +SHIPPED measurement (all additive, zero upload-behavior change) to pinpoint CPU-vs-IO vs renderer from the +user's REAL 70-connection run: +- main.js ELD line now also logs: cpu=X%core (process.cpuUsage delta / wall, >100% = multi-core), + rss=YMB, active-by-hoster={dood:.., voe:.., ...} (per-hoster live connection distribution → shows which + hoster is oversubscribed), transient-errs=N (cumulative ECONNRESET-class on the primary path), pending=M. +- lib/upload-manager.js: getDiagnostics() {activeByHoster, transientErrors, pending, active}; activeEntry + now carries hoster; _transientErrorTotal++ in the primary catch when _isTransientNetworkError. +- renderer/app.js: PerformanceObserver('longtask') + a rAF frame-time monitor → logs every 5s WHILE + uploading: `renderer-perf active=N fps=X jankFrames=Y worstFrame=Zms longtasks=W maxTask=Vms`. This is the + DIRECT renderer ground truth (the component-timing harness couldn't capture real frame rate). Low fps / + high jankFrames / longtasks → renderer IS blocked; ~60fps + no jank while it still feels laggy → it's the + main-process/system, and the cpu=/eld= numbers in the same log say CPU-bound (→ workers/cap) vs IO-bound. +Both logs land in the normal debug log (logInfo / window.api.debugLog). 397/397 tests, eslint clean. + +NEXT: user runs the 70-load on v3.3.94, shares the `eventloop-delay` + `renderer-perf` log lines (or connects +diagnostics). Those two lines together localize it definitively. Do NOT build workers/cap before that. + +--- + # v3.3.93 — THE renderer lag knot FOUND + FIXED + MEASURED: formatDateTime per progress event User gave the decisive data: "25 connections okay, 50+61 laggt, EVTL wenn die uploadenden Zeilen nicht im