Async FS optimizations, exponential backoff, cleanup dedup and release v1.4.72
Build and Release / build (push) Has been cancelled

- Convert all sync FS ops (existsSync, readdirSync, statSync, writeFileSync,
  rmSync, renameSync) to async equivalents across download-manager, extractor,
  cleanup, storage, and logger to prevent UI freezes
- Replace linear retry delays with exponential backoff + jitter to prevent
  retry storms with many parallel downloads
- Deduplicate resolveArchiveItems into single shared function
- Replace Array.shift() O(N) in bandwidth chart with slice-based trimming
- Make logger rotation async in the async flush path

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Sucukdeluxe
2026-03-01 21:53:07 +01:00
co-authored by Claude Opus 4.6
parent 520ef91d2d
commit e485cf734b
8 changed files with 299 additions and 239 deletions
+22 -2
View File
@@ -118,6 +118,26 @@ function rotateIfNeeded(filePath: string): void {
}
}
async function rotateIfNeededAsync(filePath: string): Promise<void> {
try {
const now = Date.now();
const lastRotateCheckAt = rotateCheckAtByFile.get(filePath) || 0;
if (now - lastRotateCheckAt < 60_000) {
return;
}
rotateCheckAtByFile.set(filePath, now);
const stat = await fs.promises.stat(filePath);
if (stat.size < LOG_MAX_FILE_BYTES) {
return;
}
const backup = `${filePath}.old`;
await fs.promises.rm(backup, { force: true }).catch(() => {});
await fs.promises.rename(filePath, backup);
} catch {
// ignore - file may not exist yet
}
}
async function flushAsync(): Promise<void> {
if (flushInFlight || pendingLines.length === 0) {
return;
@@ -128,11 +148,11 @@ async function flushAsync(): Promise<void> {
const chunk = linesSnapshot.join("");
try {
rotateIfNeeded(logFilePath);
await rotateIfNeededAsync(logFilePath);
const primary = await appendChunk(logFilePath, chunk);
let wroteAny = primary.ok;
if (fallbackLogFilePath) {
rotateIfNeeded(fallbackLogFilePath);
await rotateIfNeededAsync(fallbackLogFilePath);
const fallback = await appendChunk(fallbackLogFilePath, chunk);
wroteAny = wroteAny || fallback.ok;
if (!primary.ok && !fallback.ok) {