feat(torrents): harden lifecycle and web-seed management

- Enforce generation-safe seed admission and budget tracking.
- Make web-seed RPC, persistence, rollback, and startup attachment lifecycle-safe.
- Keep Torrent progress, DHT, seed-capacity, and web-seed validation covered.
- Ignore local TORRENT_FEATURES.md roadmap notes.
This commit is contained in:
NimBold
2026-08-03 16:56:01 +03:30
parent 79c0e48c43
commit c4d3a2be51
31 changed files with 3398 additions and 258 deletions
+25
View File
@@ -31,6 +31,7 @@ const ACTIVE_DOWNLOAD_STATUSES: ReadonlySet<DownloadStatus> = new Set([
'downloading',
'processing',
'seeding',
'waitingToSeed',
'retrying',
]);
@@ -70,6 +71,12 @@ export const MAX_TORRENT_TRACKER_INTERVAL = 604800;
export const DEFAULT_TORRENT_MAX_OPEN_FILES = 100;
export const MIN_TORRENT_MAX_OPEN_FILES = 1;
export const MAX_TORRENT_MAX_OPEN_FILES = 4096;
export const DEFAULT_TORRENT_DHT_MESSAGE_TIMEOUT = 10;
export const MIN_TORRENT_DHT_MESSAGE_TIMEOUT = 1;
export const MAX_TORRENT_DHT_MESSAGE_TIMEOUT = 600;
export const DEFAULT_TORRENT_MAX_CONCURRENT_SEEDS = 2;
export const MIN_TORRENT_MAX_CONCURRENT_SEEDS = 1;
export const MAX_TORRENT_MAX_CONCURRENT_SEEDS = 64;
const parseIntegerOption = (value: unknown): number | undefined => {
if (typeof value === 'number') {
@@ -105,6 +112,24 @@ export const normalizeTorrentMaxOpenFiles = (value: unknown): number | undefined
: undefined;
};
export const normalizeTorrentDhtMessageTimeout = (value: unknown): number | undefined => {
const parsed = parseIntegerOption(value);
return parsed !== undefined
&& parsed >= MIN_TORRENT_DHT_MESSAGE_TIMEOUT
&& parsed <= MAX_TORRENT_DHT_MESSAGE_TIMEOUT
? parsed
: undefined;
};
export const normalizeTorrentMaxConcurrentSeeds = (value: unknown): number | undefined => {
const parsed = parseIntegerOption(value);
return parsed !== undefined
&& parsed >= MIN_TORRENT_MAX_CONCURRENT_SEEDS
&& parsed <= MAX_TORRENT_MAX_CONCURRENT_SEEDS
? parsed
: undefined;
};
// Keep every filename component within the common cross-platform filesystem
// limit. Count UTF-8 bytes because POSIX filesystems enforce bytes, while this
// bound is also conservative for Windows filename components.