From 02dff20468527c7856d3f572af256d6787c23583 Mon Sep 17 00:00:00 2001 From: Jungku Lee Date: Sat, 21 Oct 2023 08:39:14 +0900 Subject: [PATCH] fs: improve error performance for `fsyncSync` PR-URL: https://github.com/nodejs/node/pull/49880 Refs: https://github.com/nodejs/performance/issues/106 Reviewed-By: Yagiz Nizipli Reviewed-By: Joyee Cheung --- benchmark/fs/bench-fsyncSync.js | 42 +++++++++++++++++++++++++++++++++ lib/fs.js | 4 +--- src/node_file.cc | 12 +++++----- typings/internalBinding/fs.d.ts | 2 +- 4 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 benchmark/fs/bench-fsyncSync.js diff --git a/benchmark/fs/bench-fsyncSync.js b/benchmark/fs/bench-fsyncSync.js new file mode 100644 index 00000000000000..fc7ef29266790b --- /dev/null +++ b/benchmark/fs/bench-fsyncSync.js @@ -0,0 +1,42 @@ +'use strict'; + +const common = require('../common'); +const fs = require('fs'); +const tmpdir = require('../../test/common/tmpdir'); +tmpdir.refresh(); + +const tmpfile = tmpdir.resolve(`.existing-file-${process.pid}`); +fs.writeFileSync(tmpfile, 'this-is-for-a-benchmark', 'utf8'); + +const bench = common.createBenchmark(main, { + type: ['existing', 'non-existing'], + n: [1e4], +}); + +function main({ n, type }) { + let fd; + + switch (type) { + case 'existing': + fd = fs.openSync(tmpfile, 'r', 0o666); + break; + case 'non-existing': + fd = 1 << 30; + break; + default: + new Error('Invalid type'); + } + + bench.start(); + for (let i = 0; i < n; i++) { + try { + fs.fsyncSync(fd); + } catch { + // do nothing + } + } + + bench.end(n); + + if (type === 'existing') fs.closeSync(fd); +} diff --git a/lib/fs.js b/lib/fs.js index 69e328885f895c..abc1c33bff0e50 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1323,9 +1323,7 @@ function fsync(fd, callback) { */ function fsyncSync(fd) { fd = getValidatedFd(fd); - const ctx = {}; - binding.fsync(fd, undefined, ctx); - handleErrorFromBinding(ctx); + return binding.fsync(fd); } /** diff --git a/src/node_file.cc b/src/node_file.cc index 0e3d7dfd00eb1c..f20b8a5b8e3dfc 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -1516,21 +1516,21 @@ static void Fsync(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); const int argc = args.Length(); - CHECK_GE(argc, 2); + CHECK_GE(argc, 1); CHECK(args[0]->IsInt32()); const int fd = args[0].As()->Value(); - FSReqBase* req_wrap_async = GetReqWrap(args, 1); - if (req_wrap_async != nullptr) { + if (argc > 1) { + FSReqBase* req_wrap_async = GetReqWrap(args, 1); + CHECK_NOT_NULL(req_wrap_async); FS_ASYNC_TRACE_BEGIN0(UV_FS_FSYNC, req_wrap_async) AsyncCall(env, req_wrap_async, args, "fsync", UTF8, AfterNoArgs, uv_fs_fsync, fd); } else { - CHECK_EQ(argc, 3); - FSReqWrapSync req_wrap_sync; + FSReqWrapSync req_wrap_sync("fsync"); FS_SYNC_TRACE_BEGIN(fsync); - SyncCall(env, args[2], &req_wrap_sync, "fsync", uv_fs_fsync, fd); + SyncCallAndThrowOnError(env, &req_wrap_sync, uv_fs_fsync, fd); FS_SYNC_TRACE_END(fsync); } } diff --git a/typings/internalBinding/fs.d.ts b/typings/internalBinding/fs.d.ts index 8b49b7456cbf3c..e3b74c9ab671a2 100644 --- a/typings/internalBinding/fs.d.ts +++ b/typings/internalBinding/fs.d.ts @@ -100,8 +100,8 @@ declare namespace InternalFSBinding { function fstat(fd: number, useBigint: false, usePromises: typeof kUsePromises): Promise; function fsync(fd: number, req: FSReqCallback): void; - function fsync(fd: number, req: undefined, ctx: FSSyncContext): void; function fsync(fd: number, usePromises: typeof kUsePromises): Promise; + function fsync(fd: number): void; function ftruncate(fd: number, len: number, req: FSReqCallback): void; function ftruncate(fd: number, len: number, req: undefined, ctx: FSSyncContext): void;