Compare commits
3 Commits
854740d57c
...
10854a8f43
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10854a8f43 | ||
|
|
5e8a34de40 | ||
|
|
901cd823dd |
10
main.js
10
main.js
@ -197,7 +197,15 @@ function _maybeLogEventLoopDelay(activeJobs) {
|
|||||||
const max = (_eventLoopDelay.max / ns).toFixed(1);
|
const max = (_eventLoopDelay.max / ns).toFixed(1);
|
||||||
const p99 = (_eventLoopDelay.percentile(99) / ns).toFixed(1);
|
const p99 = (_eventLoopDelay.percentile(99) / ns).toFixed(1);
|
||||||
const stddev = (_eventLoopDelay.stddev / ns).toFixed(1);
|
const stddev = (_eventLoopDelay.stddev / ns).toFixed(1);
|
||||||
logInfo('perf', `eventloop-delay active=${activeJobs} mean=${mean}ms p99=${p99}ms max=${max}ms stddev=${stddev}ms threadpool=${process.env.UV_THREADPOOL_SIZE}`);
|
let resStr = '';
|
||||||
|
try {
|
||||||
|
const info = process.getActiveResourcesInfo();
|
||||||
|
const hist = {};
|
||||||
|
for (const t of info) hist[t] = (hist[t] || 0) + 1;
|
||||||
|
const top = Object.entries(hist).sort((a, b) => b[1] - a[1]).slice(0, 6).map(([k, v]) => `${k}:${v}`).join(',');
|
||||||
|
resStr = ` resources=${info.length} {${top}}`;
|
||||||
|
} catch {}
|
||||||
|
logInfo('perf', `eventloop-delay active=${activeJobs} mean=${mean}ms p99=${p99}ms max=${max}ms stddev=${stddev}ms threadpool=${process.env.UV_THREADPOOL_SIZE}${resStr}`);
|
||||||
_eventLoopDelay.reset();
|
_eventLoopDelay.reset();
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "multi-hoster-uploader",
|
"name": "multi-hoster-uploader",
|
||||||
"version": "3.3.91",
|
"version": "3.3.92",
|
||||||
"description": "Upload files to doodstream, voe, vidmoly, byse simultaneously",
|
"description": "Upload files to doodstream, voe, vidmoly, byse simultaneously",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@ -66,8 +66,25 @@ from the user's real load, not the sandbox. Per-uploader undici Agent audit: clo
|
|||||||
module-level Agent (connections:50); doodstream/voe/vidmoly use the global dispatcher (pooled per origin, NO
|
module-level Agent (connections:50); doodstream/voe/vidmoly use the global dispatcher (pooled per origin, NO
|
||||||
per-call agent explosion) — so no agent fix needed.
|
per-call agent explosion) — so no agent fix needed.
|
||||||
|
|
||||||
|
## v3.3.92 — make the single measurement decisive + breadth audit of un-checked main.js hot paths
|
||||||
|
Enriched the ELD log line with `process.getActiveResourcesInfo()` as a compact type-histogram:
|
||||||
|
`eventloop-delay active=N mean/p99/max/stddev ms threadpool=64 resources=K {TCPSocketWrap:50,FSReqCallback:4,...}`.
|
||||||
|
Now ONE run splits all three readings in a single line: high mean/p99 → CPU-blocked (workers/cap);
|
||||||
|
low delay + many TCP/FS/GetAddrInfo resources → IO-bound queueing (threadpool/sockets, NOT workers);
|
||||||
|
low delay + few resources → not saturated (lag elsewhere / perception). Pure numbers, no redaction surface.
|
||||||
|
|
||||||
|
Breadth audit this round (4th /goal re-fire, code I wrote, NOT re-measuring cleared render/persist):
|
||||||
|
- main.js logging (debug/rot/upload): all buffered + ASYNC fs.appendFile (write-guard flag, 500ms timer,
|
||||||
|
setImmediate re-flush). Sync appendFileSync ONLY in crash/signal/exit handlers (correct there). CLEAN.
|
||||||
|
- main.js progress coalescing (_progressByJob Map + 100ms batch → one upload-progress-batch via safeSend):
|
||||||
|
non-terminal = Map.set (keeps latest/job); gated upstream to 4/sec/job. CLEAN at N=50.
|
||||||
|
- _appendJobLog: capped in-memory ring buffer (Map, FIFO-evict). CLEAN.
|
||||||
|
- All 5 uploaders: doodstream/voe/vidmoly/clouddrop-simple stream via async createReadStream + for-await +
|
||||||
|
async throttle.consume; clouddrop-chunked now async fh.read. NONE block the main loop per chunk. CLEAN
|
||||||
|
(clouddrop's old readSync was the unique outlier, fixed v3.3.90).
|
||||||
|
|
||||||
## NEXT (gated on the real-app ELD number + user's explicit nod)
|
## NEXT (gated on the real-app ELD number + user's explicit nod)
|
||||||
User runs their 50-concurrent load once; the `eventloop-delay` log lines decide:
|
User runs their 50-concurrent load once; the enriched `eventloop-delay` log line decides:
|
||||||
- mean/p99 HIGH (tens–hundreds ms) → CPU-blocked → propose worker_threads/child-process upload pool OR a
|
- mean/p99 HIGH (tens–hundreds ms) → CPU-blocked → propose worker_threads/child-process upload pool OR a
|
||||||
smart concurrency cap (WITH the user's nod — it's hard to reverse and touches credentials/abort/rotation).
|
smart concurrency cap (WITH the user's nod — it's hard to reverse and touches credentials/abort/rotation).
|
||||||
- delay LOW while it still lags → IO-bound → threadpool bump already addresses it; if not, look at socket
|
- delay LOW while it still lags → IO-bound → threadpool bump already addresses it; if not, look at socket
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user