Skip to content

Commit bf0f078

Browse files
authored
fs: improve error performance of writevSync
PR-URL: #50038 Refs: nodejs/performance#106 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
1 parent 0d8faf2 commit bf0f078

File tree

3 files changed

+76
-15
lines changed

3 files changed

+76
-15
lines changed

benchmark/fs/bench-writevSync.js

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const fs = require('fs');
5+
const assert = require('assert');
6+
const tmpdir = require('../../test/common/tmpdir');
7+
tmpdir.refresh();
8+
9+
const path = tmpdir.resolve(`new-file-${process.pid}`);
10+
fs.writeFileSync(path, 'Some content.');
11+
12+
const bench = common.createBenchmark(main, {
13+
type: ['valid', 'invalid'],
14+
n: [1e5],
15+
});
16+
17+
const buffer = Buffer.from('Benchmark data.');
18+
19+
function main({ n, type }) {
20+
let fd;
21+
let result;
22+
23+
switch (type) {
24+
case 'valid':
25+
fd = fs.openSync(path, 'r+');
26+
27+
bench.start();
28+
for (let i = 0; i < n; i++) {
29+
result = fs.writevSync(fd, [buffer]);
30+
}
31+
32+
bench.end(n);
33+
assert(result);
34+
fs.closeSync(fd);
35+
break;
36+
case 'invalid': {
37+
fd = 1 << 30;
38+
let hasError = false;
39+
bench.start();
40+
for (let i = 0; i < n; i++) {
41+
try {
42+
result = fs.writevSync(fd, [buffer]);
43+
} catch {
44+
hasError = true;
45+
}
46+
}
47+
48+
bench.end(n);
49+
assert(hasError);
50+
break;
51+
}
52+
default:
53+
throw new Error('Invalid type');
54+
}
55+
}

lib/fs.js

+1-6
Original file line numberDiff line numberDiff line change
@@ -998,15 +998,10 @@ function writevSync(fd, buffers, position) {
998998
return 0;
999999
}
10001000

1001-
const ctx = {};
1002-
10031001
if (typeof position !== 'number')
10041002
position = null;
10051003

1006-
const result = binding.writeBuffers(fd, buffers, position, undefined, ctx);
1007-
1008-
handleErrorFromBinding(ctx);
1009-
return result;
1004+
return binding.writeBuffers(fd, buffers, position);
10101005
}
10111006

10121007
/**

src/node_file.cc

+20-9
Original file line numberDiff line numberDiff line change
@@ -2203,18 +2203,29 @@ static void WriteBuffers(const FunctionCallbackInfo<Value>& args) {
22032203
iovs[i] = uv_buf_init(Buffer::Data(chunk), Buffer::Length(chunk));
22042204
}
22052205

2206-
FSReqBase* req_wrap_async = GetReqWrap(args, 3);
2207-
if (req_wrap_async != nullptr) { // writeBuffers(fd, chunks, pos, req)
2206+
if (argc > 3) { // writeBuffers(fd, chunks, pos, req)
2207+
FSReqBase* req_wrap_async = GetReqWrap(args, 3);
22082208
FS_ASYNC_TRACE_BEGIN0(UV_FS_WRITE, req_wrap_async)
2209-
AsyncCall(env, req_wrap_async, args, "write", UTF8, AfterInteger,
2210-
uv_fs_write, fd, *iovs, iovs.length(), pos);
2211-
} else { // writeBuffers(fd, chunks, pos, undefined, ctx)
2212-
CHECK_EQ(argc, 5);
2213-
FSReqWrapSync req_wrap_sync;
2209+
AsyncCall(env,
2210+
req_wrap_async,
2211+
args,
2212+
"write",
2213+
UTF8,
2214+
AfterInteger,
2215+
uv_fs_write,
2216+
fd,
2217+
*iovs,
2218+
iovs.length(),
2219+
pos);
2220+
} else { // writeBuffers(fd, chunks, pos)
2221+
FSReqWrapSync req_wrap_sync("write");
22142222
FS_SYNC_TRACE_BEGIN(write);
2215-
int bytesWritten = SyncCall(env, args[4], &req_wrap_sync, "write",
2216-
uv_fs_write, fd, *iovs, iovs.length(), pos);
2223+
int bytesWritten = SyncCallAndThrowOnError(
2224+
env, &req_wrap_sync, uv_fs_write, fd, *iovs, iovs.length(), pos);
22172225
FS_SYNC_TRACE_END(write, "bytesWritten", bytesWritten);
2226+
if (is_uv_error(bytesWritten)) {
2227+
return;
2228+
}
22182229
args.GetReturnValue().Set(bytesWritten);
22192230
}
22202231
}

0 commit comments

Comments
 (0)