feat: add provider ssh tcp data pool
This commit is contained in:
@@ -50,12 +50,13 @@ class SshFileTransferError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
const fileTransferReadBlockBytes = 45_000;
|
||||
const fileTransferReadBlockBytes = 1_048_576;
|
||||
const fileTransferWriteB64ArgvLimit = 48_000;
|
||||
const fileTransferWriteB64ChunkChars = 12_000;
|
||||
const fileTransferWriteRawChunkBytes = 1_048_576;
|
||||
const fileTransferWriteB64ChunkChars = 1_398_104;
|
||||
const fileTransferReadBlockMaxAttempts = 12;
|
||||
const fileTransferReadEmptyRetryDelayMs = 250;
|
||||
const fileTransferProgressEveryChunks = 64;
|
||||
const fileTransferProgressEveryChunks = 16;
|
||||
|
||||
export function isSshFileTransferOperation(args: string[]): boolean {
|
||||
const subcommand = args[0] ?? "";
|
||||
@@ -163,7 +164,7 @@ function parseSshFileTransferCliOptions(args: string[]): SshFileTransferCliOptio
|
||||
function boundedTransferChunkBytes(raw: string, option: string): number {
|
||||
const value = Number(raw);
|
||||
if (!Number.isInteger(value) || value <= 0) throw new Error(`${option} must be a positive integer`);
|
||||
return Math.min(96_000, Math.max(1024, value));
|
||||
return Math.min(4 * 1024 * 1024, Math.max(1024, value));
|
||||
}
|
||||
|
||||
async function writeRemoteFileVerified(
|
||||
@@ -173,26 +174,33 @@ async function writeRemoteFileVerified(
|
||||
remotePath: string,
|
||||
content: Buffer,
|
||||
): Promise<SshFileTransferWriteResult> {
|
||||
const encoded = content.toString("base64");
|
||||
const expectedBytes = String(content.length);
|
||||
const expectedSha256 = sha256HexBuffer(content);
|
||||
const encoded = content.length <= fileTransferWriteB64ArgvLimit
|
||||
? content.toString("base64")
|
||||
: "";
|
||||
if (invocation.route.plane !== "win" && encoded.length <= fileTransferWriteB64ArgvLimit) {
|
||||
await checkedFileTransfer(invocation, executor, builders, "write-b64-argv", [remotePath, expectedBytes, expectedSha256, ...chunkString(encoded, fileTransferWriteB64ChunkChars)]);
|
||||
return { strategy: "argv", chunks: encoded.length === 0 ? 0 : Math.ceil(encoded.length / fileTransferWriteB64ChunkChars) };
|
||||
}
|
||||
try {
|
||||
await checkedFileTransfer(invocation, executor, builders, "write-b64-stdin", [remotePath, expectedBytes, expectedSha256], encoded);
|
||||
return { strategy: "stdin", chunks: 1 };
|
||||
} catch {
|
||||
const token = `${process.pid}-${Date.now()}-${randomBytes(4).toString("hex")}-${expectedSha256.slice(0, 12)}`;
|
||||
const chunks = chunkString(encoded, fileTransferWriteB64ChunkChars);
|
||||
await checkedFileTransfer(invocation, executor, builders, "write-b64-begin", [remotePath, token]);
|
||||
for (const chunk of chunks) {
|
||||
await checkedFileTransfer(invocation, executor, builders, "write-b64-append-stdin", [remotePath, token], chunk);
|
||||
if (content.length <= fileTransferWriteRawChunkBytes) {
|
||||
try {
|
||||
await checkedFileTransfer(invocation, executor, builders, "write-b64-stdin", [remotePath, expectedBytes, expectedSha256], content.toString("base64"));
|
||||
return { strategy: "stdin", chunks: 1 };
|
||||
} catch {
|
||||
// Fall through to chunked upload with per-block base64 encoding.
|
||||
}
|
||||
await checkedFileTransfer(invocation, executor, builders, "write-b64-commit", [remotePath, token, expectedBytes, expectedSha256]);
|
||||
return { strategy: "chunked-stdin", chunks: encoded.length === 0 ? 0 : chunks.length };
|
||||
}
|
||||
const token = `${process.pid}-${Date.now()}-${randomBytes(4).toString("hex")}-${expectedSha256.slice(0, 12)}`;
|
||||
let chunks = 0;
|
||||
await checkedFileTransfer(invocation, executor, builders, "write-b64-begin", [remotePath, token]);
|
||||
for (let offset = 0; offset < content.length; offset += fileTransferWriteRawChunkBytes) {
|
||||
const encodedChunk = content.subarray(offset, Math.min(content.length, offset + fileTransferWriteRawChunkBytes)).toString("base64");
|
||||
await checkedFileTransfer(invocation, executor, builders, "write-b64-append-stdin", [remotePath, token], encodedChunk);
|
||||
chunks += 1;
|
||||
}
|
||||
await checkedFileTransfer(invocation, executor, builders, "write-b64-commit", [remotePath, token, expectedBytes, expectedSha256]);
|
||||
return { strategy: "chunked-stdin", chunks };
|
||||
}
|
||||
|
||||
async function readRemoteFileVerified(
|
||||
|
||||
Reference in New Issue
Block a user