Fix extraction speed: I/O priority only in hybrid mode, more threads
Some checks are pending
Build and Release / build (push) Waiting to run

- setWindowsBackgroundIO (Very Low I/O) now only applied in hybrid mode,
  not for all extractions (was causing massive slowdown)
- Hybrid threads changed from -mt1 to half CPU count (e.g. -mt4 on 8-core)
- Move retry count (R9, R22 etc.) from status text to tooltip only

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Sucukdeluxe 2026-03-03 01:08:40 +01:00
parent 311fb00430
commit 9a646d516b
3 changed files with 16 additions and 12 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "real-debrid-downloader", "name": "real-debrid-downloader",
"version": "1.5.40", "version": "1.5.41",
"description": "Real-Debrid Downloader Desktop (Electron + React + TypeScript)", "description": "Real-Debrid Downloader Desktop (Electron + React + TypeScript)",
"main": "build/main/main/main.js", "main": "build/main/main/main.js",
"author": "Sucukdeluxe", "author": "Sucukdeluxe",

View File

@ -471,7 +471,9 @@ function extractCpuBudgetPercent(): number {
function extractorThreadSwitch(hybridMode = false): string { function extractorThreadSwitch(hybridMode = false): string {
if (hybridMode) { if (hybridMode) {
return "-mt1"; const cpuCount = Math.max(1, os.cpus().length || 1);
const hybridThreads = Math.max(1, Math.min(8, Math.floor(cpuCount / 2)));
return `-mt${hybridThreads}`;
} }
const envValue = Number(process.env.RD_EXTRACT_THREADS ?? NaN); const envValue = Number(process.env.RD_EXTRACT_THREADS ?? NaN);
if (Number.isFinite(envValue) && envValue >= 1 && envValue <= 32) { if (Number.isFinite(envValue) && envValue >= 1 && envValue <= 32) {
@ -502,7 +504,7 @@ function setWindowsBackgroundIO(pid: number): void {
} }
} }
function lowerExtractProcessPriority(childPid: number | undefined): void { function lowerExtractProcessPriority(childPid: number | undefined, lowIo = false): void {
if (process.platform !== "win32") { if (process.platform !== "win32") {
return; return;
} }
@ -516,8 +518,10 @@ function lowerExtractProcessPriority(childPid: number | undefined): void {
} catch { } catch {
// ignore: priority lowering is best-effort // ignore: priority lowering is best-effort
} }
// Also lower I/O + page priority via Windows API (fire-and-forget) // Lower I/O + page priority only in hybrid mode (download + extract simultaneously)
setWindowsBackgroundIO(pid); if (lowIo) {
setWindowsBackgroundIO(pid);
}
} }
type ExtractSpawnResult = { type ExtractSpawnResult = {
@ -574,7 +578,8 @@ function runExtractCommand(
args: string[], args: string[],
onChunk?: (chunk: string) => void, onChunk?: (chunk: string) => void,
signal?: AbortSignal, signal?: AbortSignal,
timeoutMs?: number timeoutMs?: number,
hybridMode = false
): Promise<ExtractSpawnResult> { ): Promise<ExtractSpawnResult> {
if (signal?.aborted) { if (signal?.aborted) {
return Promise.resolve({ ok: false, missingCommand: false, aborted: true, timedOut: false, errorText: "aborted:extract" }); return Promise.resolve({ ok: false, missingCommand: false, aborted: true, timedOut: false, errorText: "aborted:extract" });
@ -584,7 +589,7 @@ function runExtractCommand(
let settled = false; let settled = false;
let output = ""; let output = "";
const child = spawn(command, args, { windowsHide: true }); const child = spawn(command, args, { windowsHide: true });
lowerExtractProcessPriority(child.pid); lowerExtractProcessPriority(child.pid, hybridMode);
let timeoutId: NodeJS.Timeout | null = null; let timeoutId: NodeJS.Timeout | null = null;
let timedOutByWatchdog = false; let timedOutByWatchdog = false;
let abortedBySignal = false; let abortedBySignal = false;
@ -841,7 +846,7 @@ async function runExternalExtractInner(
} }
bestPercent = parsed; bestPercent = parsed;
onArchiveProgress?.(bestPercent); onArchiveProgress?.(bestPercent);
}, signal, timeoutMs); }, signal, timeoutMs, hybridMode);
if (!result.ok && usePerformanceFlags && isUnsupportedExtractorSwitchError(result.errorText)) { if (!result.ok && usePerformanceFlags && isUnsupportedExtractorSwitchError(result.errorText)) {
usePerformanceFlags = false; usePerformanceFlags = false;
@ -855,7 +860,7 @@ async function runExternalExtractInner(
} }
bestPercent = parsed; bestPercent = parsed;
onArchiveProgress?.(bestPercent); onArchiveProgress?.(bestPercent);
}, signal, timeoutMs); }, signal, timeoutMs, hybridMode);
} }
if (result.ok) { if (result.ok) {
@ -1379,7 +1384,7 @@ export async function extractPackageArchives(options: ExtractOptions): Promise<{
emitProgress(extracted + failed, archiveName, "extracting", archivePercent, Date.now() - archiveStartedAt); emitProgress(extracted + failed, archiveName, "extracting", archivePercent, Date.now() - archiveStartedAt);
}, 1100); }, 1100);
const hybrid = Boolean(options.hybridMode); const hybrid = Boolean(options.hybridMode);
logger.info(`Entpacke Archiv: ${path.basename(archivePath)} -> ${options.targetDir}${hybrid ? " (hybrid, -mt1, low I/O)" : ""}`); logger.info(`Entpacke Archiv: ${path.basename(archivePath)} -> ${options.targetDir}${hybrid ? " (hybrid, reduced threads, low I/O)" : ""}`);
try { try {
const ext = path.extname(archivePath).toLowerCase(); const ext = path.extname(archivePath).toLowerCase();
if (ext === ".zip") { if (ext === ".zip") {

View File

@ -2890,9 +2890,8 @@ const PackageCard = memo(function PackageCard({ pkg, items, packageSpeed, isFirs
) : "-"; ) : "-";
})()}</span> })()}</span>
<span className="pkg-col pkg-col-hoster" title={formatHoster(item)}>{formatHoster(item)}</span> <span className="pkg-col pkg-col-hoster" title={formatHoster(item)}>{formatHoster(item)}</span>
<span className="pkg-col pkg-col-status" title={item.fullStatus}> <span className="pkg-col pkg-col-status" title={item.retries > 0 ? `${item.fullStatus} · R${item.retries}` : item.fullStatus}>
{item.fullStatus} {item.fullStatus}
{item.retries > 0 && ` · R${item.retries}`}
</span> </span>
<span className="pkg-col pkg-col-speed">{item.speedBps > 0 ? formatSpeedMbps(item.speedBps) : "-"}</span> <span className="pkg-col pkg-col-speed">{item.speedBps > 0 ? formatSpeedMbps(item.speedBps) : "-"}</span>
</div> </div>