GeezerVison is showing github.com — fs: improve error performance of writevSync · nodejs/node@eb52f73
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboard +55Lines changed: 55 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 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 | +} |
Collapse file Copy file name to clipboardExpand all lines: lib/fs.js +1-6Lines changed: 1 addition & 6 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -996,15 +996,10 @@ function writevSync(fd, buffers, position) { | 996 | 996 | return 0; | 997 | 997 | } | 998 | 998 |
| 999 | | - const ctx = {}; | 1000 | | - | 1001 | 999 | if (typeof position !== 'number') | 1002 | 1000 | position = null; | 1003 | 1001 |
| 1004 | | - const result = binding.writeBuffers(fd, buffers, position, undefined, ctx); | 1005 | | - | 1006 | | - handleErrorFromBinding(ctx); | 1007 | | - return result; | | 1002 | + return binding.writeBuffers(fd, buffers, position); | 1008 | 1003 | } | 1009 | 1004 |
| 1010 | 1005 | /** | |
Collapse file Copy file name to clipboardExpand all lines: src/node_file.cc +20-9Lines changed: 20 additions & 9 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -2238,18 +2238,29 @@ static void WriteBuffers(const FunctionCallbackInfo<Value>& args) { | 2238 | 2238 | iovs[i] = uv_buf_init(Buffer::Data(chunk), Buffer::Length(chunk)); | 2239 | 2239 | } | 2240 | 2240 |
| 2241 | | - FSReqBase* req_wrap_async = GetReqWrap(args, 3); | 2242 | | - if (req_wrap_async != nullptr) { // writeBuffers(fd, chunks, pos, req) | | 2241 | + if (argc > 3) { // writeBuffers(fd, chunks, pos, req) | | 2242 | + FSReqBase* req_wrap_async = GetReqWrap(args, 3); | 2243 | 2243 | FS_ASYNC_TRACE_BEGIN0(UV_FS_WRITE, req_wrap_async) | 2244 | | - AsyncCall(env, req_wrap_async, args, "write", UTF8, AfterInteger, | 2245 | | - uv_fs_write, fd, *iovs, iovs.length(), pos); | 2246 | | - } else { // writeBuffers(fd, chunks, pos, undefined, ctx) | 2247 | | - CHECK_EQ(argc, 5); | 2248 | | - FSReqWrapSync req_wrap_sync; | | 2244 | + AsyncCall(env, | | 2245 | + req_wrap_async, | | 2246 | + args, | | 2247 | + "write", | | 2248 | + UTF8, | | 2249 | + AfterInteger, | | 2250 | + uv_fs_write, | | 2251 | + fd, | | 2252 | + *iovs, | | 2253 | + iovs.length(), | | 2254 | + pos); | | 2255 | + } else { // writeBuffers(fd, chunks, pos) | | 2256 | + FSReqWrapSync req_wrap_sync("write"); | 2249 | 2257 | FS_SYNC_TRACE_BEGIN(write); | 2250 | | - int bytesWritten = SyncCall(env, args[4], &req_wrap_sync, "write", | 2251 | | - uv_fs_write, fd, *iovs, iovs.length(), pos); | | 2258 | + int bytesWritten = SyncCallAndThrowOnError( | | 2259 | + env, &req_wrap_sync, uv_fs_write, fd, *iovs, iovs.length(), pos); | 2252 | 2260 | FS_SYNC_TRACE_END(write, "bytesWritten", bytesWritten); | | 2261 | + if (is_uv_error(bytesWritten)) { | | 2262 | + return; | | 2263 | + } | 2253 | 2264 | args.GetReturnValue().Set(bytesWritten); | 2254 | 2265 | } | 2255 | 2266 | } | |
|