Compare commits

...
Author SHA1 Message Date
Cursor Agentand陈大猫 28ffdc5e9b perf(sftp): skip the second promotion lstat when there is no mode to restore
New-file uploads have a null existingMode, so restoreRemoteMode is a no-op.
Recheck the destination only after a real mode restore and keep one
pre-rename safety lstat otherwise.

Co-authored-by: 陈大猫 <binaricat@users.noreply.github.com>
2026-10-22 15:27:43 +00:00
2 changed files with 119 additions and 15 deletions

No files matched your search

+21 -15
View File
@@ -1656,21 +1656,27 @@ async function runRemoteUploadTransaction(client, localPath, remotePath, options
signal,
));
assertCanPromote();
// Apply the old mode to the stage before promotion. A failed chmod must not
// replace an executable final with a non-executable file and report success.
await restoreRemoteMode(client, encodedStagedPath, plan.existingMode, {
bestEffort: false,
});
assertCanPromote();
await runCancelablePreflight(() => assertStagedPromotionTargetSafe(
client,
encodedPath,
remotePath,
plan.destinationExisted,
plan.destinationSnapshot,
signal,
));
assertCanPromote();
// Mode restore is a remote chmod on the stage. Recheck the destination
// only after that round trip. A non-finite existingMode (new files, and
// targets whose mode could not be captured) makes restore a no-op, so a
// second lstat would be a serial RTT on every such upload.
if (Number.isFinite(plan.existingMode)) {
// Apply the old mode to the stage before promotion. A failed chmod must not
// replace an executable final with a non-executable file and report success.
await restoreRemoteMode(client, encodedStagedPath, plan.existingMode, {
bestEffort: false,
});
assertCanPromote();
await runCancelablePreflight(() => assertStagedPromotionTargetSafe(
client,
encodedPath,
remotePath,
plan.destinationExisted,
plan.destinationSnapshot,
signal,
));
assertCanPromote();
}
commitPromotion();
await renameRemotePath(client, encodedStagedPath, encodedPath, encodedBackupPath, {
stagePath: stagedLogical,
@@ -571,6 +571,104 @@ test("existing destinations stage then restore mode after rename", async (t) =>
assert.equal(remoteMeta.get("/usr/local/bin/tool")?.mode & 0o777, 0o755);
});
test("new-file staged upload lstats the destination once before rename", async (t) => {
const tempRoot = await fs.promises.mkdtemp(path.join(os.tmpdir(), "netcatty-new-file-lstat-"));
t.after(async () => {
await fs.promises.rm(tempRoot, { recursive: true, force: true });
});
tempDirBridge.init?.({ getPath: () => tempRoot });
const localPath = path.join(tempRoot, "payload.bin");
const payload = Buffer.from("new-file");
await fs.promises.writeFile(localPath, payload);
const remotePath = "/home/alice/new-file.bin";
const { channel, remoteFiles, chmodCalls } = createSessionChannel();
const originalLstat = channel.lstat.bind(channel);
let destinationLstats = 0;
channel.lstat = (targetPath, callback) => {
if (String(targetPath) === remotePath) destinationLstats += 1;
originalLstat(targetPath, callback);
};
const sftpClients = new Map();
sftpBridge.init({
electronModule: { webContents: { fromId: () => null } },
sessions: new Map([["session-new-file-lstat", { conn: { sftp: (cb) => cb(null, channel) } }]]),
sftpClients,
});
const opened = await sftpBridge.openSftpForSession(null, {
sessionId: "session-new-file-lstat",
fileProtocol: "sftp",
});
const result = await sftpBridge.uploadLocalToSftp(null, {
sftpId: opened.sftpId,
localPath,
remotePath,
encoding: "utf-8",
});
assert.equal(result.success, true);
assert.deepEqual(remoteFiles.get(remotePath), payload);
assert.deepEqual(chmodCalls, []);
// Plan lstat plus one pre-rename check. existingMode is null, so the
// post-restore lstat would be a no-op round trip.
assert.equal(destinationLstats, 2);
});
test("existing-file staged upload rechecks the destination after mode restore", async (t) => {
const tempRoot = await fs.promises.mkdtemp(path.join(os.tmpdir(), "netcatty-existing-file-lstat-"));
t.after(async () => {
await fs.promises.rm(tempRoot, { recursive: true, force: true });
});
tempDirBridge.init?.({ getPath: () => tempRoot });
const localPath = path.join(tempRoot, "tool.bin");
const payload = Buffer.from("replaced-tool");
await fs.promises.writeFile(localPath, payload);
const remotePath = "/usr/local/bin/tool";
const { channel, remoteFiles, remoteMeta, chmodCalls } = createSessionChannel();
remoteFiles.set(remotePath, Buffer.from("old-tool"));
remoteMeta.set(remotePath, { mode: 0o100755, mtime: 1, uid: 1000, gid: 1000 });
const originalLstat = channel.lstat.bind(channel);
let destinationLstats = 0;
channel.lstat = (targetPath, callback) => {
if (String(targetPath) === remotePath) destinationLstats += 1;
originalLstat(targetPath, callback);
};
const sftpClients = new Map();
sftpBridge.init({
electronModule: { webContents: { fromId: () => null } },
sessions: new Map([["session-existing-file-lstat", { conn: { sftp: (cb) => cb(null, channel) } }]]),
sftpClients,
});
const opened = await sftpBridge.openSftpForSession(null, {
sessionId: "session-existing-file-lstat",
fileProtocol: "sftp",
});
const result = await sftpBridge.uploadLocalToSftp(null, {
sftpId: opened.sftpId,
localPath,
remotePath,
encoding: "utf-8",
});
assert.equal(result.success, true);
assert.deepEqual(remoteFiles.get(remotePath), payload);
assert.equal(remoteMeta.get(remotePath)?.mode & 0o777, 0o755);
assert.ok(
chmodCalls.some((call) => String(call.targetPath).includes(".netcatty-upload-")),
`expected staged chmod, got ${JSON.stringify(chmodCalls)}`,
);
// Plan lstat, pre-restore check, and the post-chmod recheck that covers the
// mode-restore round trip.
assert.equal(destinationLstats, 3);
});
test("mode restore failure leaves the existing destination untouched", async (t) => {
const tempRoot = await fs.promises.mkdtemp(path.join(os.tmpdir(), "netcatty-stage-mode-fail-"));
t.after(async () => {