Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit 0fceae3d5d465a1924120fb3ffc9e5ea99000042
parent 0ff9ad4f43e42d1b06b0838532ebbd65aafaffed
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Mon,  5 Oct 2026 16:06:58 -0400

sources: aria2c hash-checks only a resumed torrent; its DHT notice is never the failure

Seen in the live smoke: on a fresh run --check-integrity makes aria2c print
"Checksum error detected" for pieces not fetched yet, and a first run's empty
dht.dat an [ERROR] — both noise. --check-integrity is now passed only when the
file or its .aria2 control file is already in the staging dir (a cancelled
run, a run killed while seeding), and DHT lines are left out of a failed
run's reason.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Diffstat:
Mcommon/lib/archiveOrgTorrent-server.ts | 8+++++++-
Mcommon/lib/archiveOrgTorrent.test.ts | 6++++++
Mcommon/lib/archiveOrgTorrent.ts | 10+++++++---
3 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/common/lib/archiveOrgTorrent-server.ts b/common/lib/archiveOrgTorrent-server.ts @@ -148,6 +148,7 @@ export async function fetchFileByTorrent(opts: TorrentFetchOpts): Promise<Torren userAgent: opts.userAgent, parentPid: process.pid, summaryIntervalSec: opts.summaryIntervalSec ?? 5, + resume: (await exists(target)) || (await exists(`${target}.aria2`)), }); log( `torrent: fetching ${label} (${pieces} pieces of ${opts.parsed.pieceLength} bytes, ` + @@ -287,7 +288,12 @@ export async function fetchFileByTorrent(opts: TorrentFetchOpts): Promise<Torren return { ok: true, file: target, seeded }; } if (why) return { ok: false, reason: why.reason, ...(why.stalled ? { stalled: true } : {}) }; - const tail = lastLines.filter((l) => /ERROR|errorCode|Exception/.test(l)).slice(-2).join(" | "); + // aria2c's DHT routing-table complaint (an empty or first-run dht.dat) is + // noise, never the reason a run failed. + const tail = lastLines + .filter((l) => /ERROR|errorCode|Exception/.test(l) && !/DHT/.test(l)) + .slice(-2) + .join(" | "); return { ok: false, reason: `aria2c exited ${exit.code ?? exit.signal}${tail ? `: ${tail}` : ""}`, diff --git a/common/lib/archiveOrgTorrent.test.ts b/common/lib/archiveOrgTorrent.test.ts @@ -153,6 +153,12 @@ test("aria2c arguments: one file, seeding bounds, politeness, the hook, no word- userAgent: "u", }); assert.ok(none.includes("--seed-time=0")); + // A fresh run does not hash-check pieces that are not there; a resume does. + assert.ok(!args.includes("--check-integrity=true")); + assert.ok( + aria2cArgs({ torrentPath: "t", dir: "d", fileIndex: 1, settings: DEFAULT_ARCHIVE_ORG_FETCH_SETTINGS, onCompleteHook: "h", userAgent: "u", resume: true }) + .includes("--check-integrity=true"), + ); assert.ok(!none.some((a) => a.startsWith("--stop-with-process"))); }); diff --git a/common/lib/archiveOrgTorrent.ts b/common/lib/archiveOrgTorrent.ts @@ -179,6 +179,11 @@ export type Aria2cSpec = { // leaves a seeder behind. parentPid?: number; summaryIntervalSec?: number; + // Part of the file is already in --dir (a cancelled run's partial, or a run + // killed while seeding): hash-check it and carry on, rather than refusing it + // or fetching it again. Off on a fresh run, where aria2c's check of pieces + // that are not there yet prints a "Checksum error" that means nothing. + resume?: boolean; }; // Every flag is spelled `--name=value`, one argv entry each, so nothing here @@ -202,10 +207,9 @@ export function aria2cArgs(spec: Aria2cSpec): string[] { "--follow-torrent=mem", "--file-allocation=none", // A re-run resumes: the partial and its .aria2 control file are kept on a - // cancel, and a complete file (a run killed while seeding) is hash-checked - // and seeded rather than refused or fetched again. + // cancel (see `resume`). "--continue=true", - "--check-integrity=true", + ...(spec.resume ? ["--check-integrity=true"] : []), "--auto-file-renaming=false", "--bt-save-metadata=false", `--on-bt-download-complete=${spec.onCompleteHook}`,