From 1e854fee26b7307cfc06ec08831959b32f46ed24 Mon Sep 17 00:00:00 2001 From: neverland Date: Mon, 3 Aug 2026 11:35:27 +0800 Subject: [PATCH] perf(fmt): disable fsync for atomic writes --- packages/rstack/src/fmt/worker.ts | 12 +++++++- packages/rstack/tests/fmt/worker.test.ts | 35 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 packages/rstack/tests/fmt/worker.test.ts diff --git a/packages/rstack/src/fmt/worker.ts b/packages/rstack/src/fmt/worker.ts index e3ccf48..7e50c74 100644 --- a/packages/rstack/src/fmt/worker.ts +++ b/packages/rstack/src/fmt/worker.ts @@ -5,6 +5,16 @@ import { format } from 'prettier'; import { getPrettierPlugins } from './prettierPlugins.ts'; import type { FmtFileRequest } from './types.ts'; +/** + * Formatting output can be regenerated, so avoid waiting for a durability sync + * after every file, which is especially expensive during parallel formatting. + * `atomically` still uses a temporary file and rename for atomic replacement. + */ +const atomicWriteOptions = { + encoding: 'utf8', + fsync: false, +} as const; + const formatFile = async ( { path, options }: FmtFileRequest, shouldWrite: boolean, @@ -20,7 +30,7 @@ const formatFile = async ( } if (shouldWrite) { - await writeFile(path, formatted, 'utf8'); + await writeFile(path, formatted, atomicWriteOptions); } return true; diff --git a/packages/rstack/tests/fmt/worker.test.ts b/packages/rstack/tests/fmt/worker.test.ts new file mode 100644 index 0000000..6adaf89 --- /dev/null +++ b/packages/rstack/tests/fmt/worker.test.ts @@ -0,0 +1,35 @@ +import { expect, rs, test } from 'rstack/test'; +import { formatFile } from '../../src/fmt/worker.ts'; + +const mocks = rs.hoisted(() => ({ + writeFileCalls: [] as [string, string, unknown][], +})); + +rs.mock('atomically', () => ({ + readFile: () => Promise.resolve('const value=1'), + writeFile: (path: string, data: string, options: unknown) => { + mocks.writeFileCalls.push([path, data, options]); + return Promise.resolve(); + }, +})); + +test('disables fsync for atomic writes', async () => { + const filePath = '/virtual/example.ts'; + + await expect( + formatFile( + { + path: filePath, + options: { + filepath: filePath, + parser: 'typescript', + }, + }, + true, + ), + ).resolves.toBe(true); + + expect(mocks.writeFileCalls).toEqual([ + [filePath, 'const value = 1;\n', { encoding: 'utf8', fsync: false }], + ]); +});