mirror of
https://github.com/xCyanGrizzly/DragonsStash.git
synced 2026-09-21 05:21:43 +00:00
feat(worker): ranged TDLib file download (downloadFileRange)
Implements Task 4 Step 2 of the provenance-backfill plan. The live spike (Step 1) and manual verification (Step 3) were not run in this environment because a second TDLib client would corrupt the running worker's authenticated session; the absolute-offset assumption is noted as pending live verification on deploy. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
import { open } from "fs/promises";
|
||||
import type { Client } from "tdl";
|
||||
import { childLogger } from "../util/logger.js";
|
||||
import { withFloodWait } from "../util/retry.js";
|
||||
|
||||
const log = childLogger("range-download");
|
||||
const RANGE_TIMEOUT_MS = 120_000;
|
||||
|
||||
// NOTE (from Task 4 spike): TDLib writes the requested region into
|
||||
// file.local.path at its ABSOLUTE file offset; file.local.downloaded_prefix_size
|
||||
// counts contiguous bytes from download_offset. We request a 1KB-aligned offset
|
||||
// so downloaded_prefix_size covers our whole [offset, offset+limit) window.
|
||||
// This absolute-offset assumption is PENDING LIVE VERIFICATION ON DEPLOY —
|
||||
// the authenticated TDLib session could not be spiked in this environment.
|
||||
export async function downloadFileRange(
|
||||
client: Client,
|
||||
fileId: string,
|
||||
offset: number,
|
||||
limit: number,
|
||||
expectedSize: bigint,
|
||||
): Promise<Buffer> {
|
||||
const numericId = parseInt(fileId, 10);
|
||||
const alignedOffset = Math.max(0, offset - (offset % 1024));
|
||||
const alignedLimit = limit + (offset - alignedOffset);
|
||||
|
||||
const file = await withFloodWait(
|
||||
() =>
|
||||
new Promise<{ local: { path: string; download_offset: number; downloaded_prefix_size: number } }>(
|
||||
(resolve, reject) => {
|
||||
const timer = setTimeout(() => reject(new Error(`Range download timed out for ${fileId}`)), RANGE_TIMEOUT_MS);
|
||||
client
|
||||
.invoke({
|
||||
_: "downloadFile",
|
||||
file_id: numericId,
|
||||
priority: 1,
|
||||
offset: alignedOffset,
|
||||
limit: alignedLimit,
|
||||
synchronous: true,
|
||||
} as never)
|
||||
.then((f) => { clearTimeout(timer); resolve(f as never); })
|
||||
.catch((e) => { clearTimeout(timer); reject(e); });
|
||||
},
|
||||
),
|
||||
`downloadFileRange:${fileId}`,
|
||||
);
|
||||
|
||||
const start = offset;
|
||||
const fh = await open(file.local.path, "r");
|
||||
try {
|
||||
const buf = Buffer.alloc(limit);
|
||||
const { bytesRead } = await fh.read(buf, 0, limit, start);
|
||||
log.debug({ fileId, offset, limit, bytesRead }, "range read");
|
||||
return bytesRead < limit ? buf.subarray(0, bytesRead) : buf;
|
||||
} finally {
|
||||
await fh.close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user