GeezerVison is showing github.com — fs: improve error performance of `symlinkSync` · nodejs/node@dc9ac8d
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 +51Lines changed: 51 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 | + | | 8 | +if (process.platform === 'win32') { | | 9 | + console.log('Skipping: Windows does not play well with `symlink`'); | | 10 | + process.exit(0); | | 11 | +} | | 12 | + | | 13 | +const bench = common.createBenchmark(main, { | | 14 | + type: ['valid', 'invalid'], | | 15 | + n: [1e3], | | 16 | +}); | | 17 | + | | 18 | +function main({ n, type }) { | | 19 | + switch (type) { | | 20 | + case 'valid': { | | 21 | + tmpdir.refresh(); | | 22 | + bench.start(); | | 23 | + for (let i = 0; i < n; i++) { | | 24 | + fs.symlinkSync(tmpdir.resolve('.non-existent-symlink-file'), tmpdir.resolve(`.valid-${i}`), 'file'); | | 25 | + } | | 26 | + bench.end(n); | | 27 | + break; | | 28 | + } | | 29 | + | | 30 | + case 'invalid': { | | 31 | + let hasError = false; | | 32 | + bench.start(); | | 33 | + for (let i = 0; i < n; i++) { | | 34 | + try { | | 35 | + fs.symlinkSync( | | 36 | + tmpdir.resolve('.non-existent-symlink-file'), | | 37 | + __filename, | | 38 | + 'file', | | 39 | + ); | | 40 | + } catch { | | 41 | + hasError = true; | | 42 | + } | | 43 | + } | | 44 | + bench.end(n); | | 45 | + assert(hasError); | | 46 | + break; | | 47 | + } | | 48 | + default: | | 49 | + new Error('Invalid type'); | | 50 | + } | | 51 | +} |
Collapse file Copy file name to clipboardExpand all lines: lib/fs.js +5-6Lines changed: 5 additions & 6 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -1804,13 +1804,12 @@ function symlinkSync(target, path, type) { | 1804 | 1804 | } | 1805 | 1805 | target = getValidatedPath(target, 'target'); | 1806 | 1806 | path = getValidatedPath(path); | 1807 | | - const flags = stringToSymlinkType(type); | 1808 | | - | 1809 | | - const ctx = { path: target, dest: path }; | 1810 | | - binding.symlink(preprocessSymlinkDestination(target, type, path), | 1811 | | - pathModule.toNamespacedPath(path), flags, undefined, ctx); | 1812 | 1807 |
| 1813 | | - handleErrorFromBinding(ctx); | | 1808 | + binding.symlink( | | 1809 | + preprocessSymlinkDestination(target, type, path), | | 1810 | + pathModule.toNamespacedPath(path), | | 1811 | + stringToSymlinkType(type), | | 1812 | + ); | 1814 | 1813 | } | 1815 | 1814 |
| 1816 | 1815 | /** | |
Collapse file Copy file name to clipboardExpand all lines: src/node_file.cc +6-7Lines changed: 6 additions & 7 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -1298,7 +1298,7 @@ static void Symlink(const FunctionCallbackInfo<Value>& args) { | 1298 | 1298 | Isolate* isolate = env->isolate(); | 1299 | 1299 |
| 1300 | 1300 | const int argc = args.Length(); | 1301 | | - CHECK_GE(argc, 4); | | 1301 | + CHECK_GE(argc, 3); | 1302 | 1302 |
| 1303 | 1303 | BufferValue target(isolate, args[0]); | 1304 | 1304 | CHECK_NOT_NULL(*target); | @@ -1317,8 +1317,8 @@ static void Symlink(const FunctionCallbackInfo<Value>& args) { | 1317 | 1317 | CHECK(args[2]->IsInt32()); | 1318 | 1318 | int flags = args[2].As<Int32>()->Value(); | 1319 | 1319 |
| 1320 | | - FSReqBase* req_wrap_async = GetReqWrap(args, 3); | 1321 | | - if (req_wrap_async != nullptr) { // symlink(target, path, flags, req) | | 1320 | + if (argc > 3) { // symlink(target, path, flags, req) | | 1321 | + FSReqBase* req_wrap_async = GetReqWrap(args, 3); | 1322 | 1322 | FS_ASYNC_TRACE_BEGIN2(UV_FS_SYMLINK, | 1323 | 1323 | req_wrap_async, | 1324 | 1324 | "target", | @@ -1328,11 +1328,10 @@ static void Symlink(const FunctionCallbackInfo<Value>& args) { | 1328 | 1328 | AsyncDestCall(env, req_wrap_async, args, "symlink", *path, path.length(), | 1329 | 1329 | UTF8, AfterNoArgs, uv_fs_symlink, *target, *path, flags); | 1330 | 1330 | } else { // symlink(target, path, flags, undefined, ctx) | 1331 | | - CHECK_EQ(argc, 5); | 1332 | | - FSReqWrapSync req_wrap_sync; | | 1331 | + FSReqWrapSync req_wrap_sync("symlink", *target, *path); | 1333 | 1332 | FS_SYNC_TRACE_BEGIN(symlink); | 1334 | | - SyncCall(env, args[4], &req_wrap_sync, "symlink", | 1335 | | - uv_fs_symlink, *target, *path, flags); | | 1333 | + SyncCallAndThrowOnError( | | 1334 | + env, &req_wrap_sync, uv_fs_symlink, *target, *path, flags); | 1336 | 1335 | FS_SYNC_TRACE_END(symlink); | 1337 | 1336 | } | 1338 | 1337 | } | |
Collapse file Copy file name to clipboardExpand all lines: typings/internalBinding/fs.d.ts +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -206,6 +206,7 @@ declare namespace InternalFSBinding { | 206 | 206 | function symlink(target: StringOrBuffer, path: StringOrBuffer, type: number, req: FSReqCallback): void; | 207 | 207 | function symlink(target: StringOrBuffer, path: StringOrBuffer, type: number, req: undefined, ctx: FSSyncContext): void; | 208 | 208 | function symlink(target: StringOrBuffer, path: StringOrBuffer, type: number, usePromises: typeof kUsePromises): Promise<void>; | | 209 | + function symlink(target: StringOrBuffer, path: StringOrBuffer, type: number): void; | 209 | 210 |
| 210 | 211 | function unlink(path: string, req: FSReqCallback): void; | 211 | 212 | function unlink(path: string): void; | |
|