Skip to content

Commit c6f7f55

Browse files
committed
async_hooks: merge run and exit methods
PR-URL: nodejs#31950 Reviewed-By: Vladimir de Turckheim <vlad2t@hotmail.com> Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
1 parent 4cd19bc commit c6f7f55

12 files changed

+29
-214
lines changed

benchmark/async_hooks/async-resource-vs-destroy.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ function buildDestroy(getServe) {
103103
function buildAsyncLocalStorage(getServe) {
104104
const asyncLocalStorage = new AsyncLocalStorage();
105105
const server = createServer((req, res) => {
106-
asyncLocalStorage.runSyncAndReturn({}, () => {
106+
asyncLocalStorage.run({}, () => {
107107
getServe(getCLS, setCLS)(req, res);
108108
});
109109
});

doc/api/async_hooks.md

+16-130
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,7 @@ added: REPLACEME
915915
-->
916916

917917
Creates a new instance of `AsyncLocalStorage`. Store is only provided within a
918-
`run` or a `runSyncAndReturn` method call.
918+
`run` method call.
919919

920920
### `asyncLocalStorage.disable()`
921921
<!-- YAML
@@ -924,8 +924,7 @@ added: REPLACEME
924924

925925
This method disables the instance of `AsyncLocalStorage`. All subsequent calls
926926
to `asyncLocalStorage.getStore()` will return `undefined` until
927-
`asyncLocalStorage.run()` or `asyncLocalStorage.runSyncAndReturn()`
928-
is called again.
927+
`asyncLocalStorage.run()` is called again.
929928

930929
When calling `asyncLocalStorage.disable()`, all current contexts linked to the
931930
instance will be exited.
@@ -947,8 +946,7 @@ added: REPLACEME
947946

948947
This method returns the current store.
949948
If this method is called outside of an asynchronous context initialized by
950-
calling `asyncLocalStorage.run` or `asyncLocalStorage.runAndReturn`, it will
951-
return `undefined`.
949+
calling `asyncLocalStorage.run`, it will return `undefined`.
952950

953951
### `asyncLocalStorage.enterWith(store)`
954952
<!-- YAML
@@ -1001,90 +999,23 @@ added: REPLACEME
1001999
* `callback` {Function}
10021000
* `...args` {any}
10031001

1004-
Calling `asyncLocalStorage.run(callback)` will create a new asynchronous
1005-
context. Within the callback function and the asynchronous operations from
1006-
the callback, `asyncLocalStorage.getStore()` will return the object or
1007-
the primitive value passed into the `store` argument (known as "the store").
1008-
This store will be persistent through the following asynchronous calls.
1009-
1010-
The callback will be ran asynchronously. Optionally, arguments can be passed
1011-
to the function. They will be passed to the callback function.
1012-
1013-
If an error is thrown by the callback function, it will not be caught by
1014-
a `try/catch` block as the callback is ran in a new asynchronous resource.
1015-
Also, the stacktrace will be impacted by the asynchronous call.
1016-
1017-
Example:
1018-
1019-
```js
1020-
const store = { id: 1 };
1021-
asyncLocalStorage.run(store, () => {
1022-
asyncLocalStorage.getStore(); // Returns the store object
1023-
someAsyncOperation(() => {
1024-
asyncLocalStorage.getStore(); // Returns the same object
1025-
});
1026-
});
1027-
asyncLocalStorage.getStore(); // Returns undefined
1028-
```
1029-
1030-
### `asyncLocalStorage.exit(callback[, ...args])`
1031-
<!-- YAML
1032-
added: REPLACEME
1033-
-->
1034-
1035-
* `callback` {Function}
1036-
* `...args` {any}
1037-
1038-
Calling `asyncLocalStorage.exit(callback)` will create a new asynchronous
1039-
context.
1040-
Within the callback function and the asynchronous operations from the callback,
1041-
`asyncLocalStorage.getStore()` will return `undefined`.
1042-
1043-
The callback will be ran asynchronously. Optionally, arguments can be passed
1044-
to the function. They will be passed to the callback function.
1045-
1046-
If an error is thrown by the callback function, it will not be caught by
1047-
a `try/catch` block as the callback is ran in a new asynchronous resource.
1048-
Also, the stacktrace will be impacted by the asynchronous call.
1049-
1050-
Example:
1051-
1052-
```js
1053-
asyncLocalStorage.run('store value', () => {
1054-
asyncLocalStorage.getStore(); // Returns 'store value'
1055-
asyncLocalStorage.exit(() => {
1056-
asyncLocalStorage.getStore(); // Returns undefined
1057-
});
1058-
asyncLocalStorage.getStore(); // Returns 'store value'
1059-
});
1060-
```
1061-
1062-
### `asyncLocalStorage.runSyncAndReturn(store, callback[, ...args])`
1063-
<!-- YAML
1064-
added: REPLACEME
1065-
-->
1066-
1067-
* `store` {any}
1068-
* `callback` {Function}
1069-
* `...args` {any}
1070-
10711002
This methods runs a function synchronously within a context and return its
10721003
return value. The store is not accessible outside of the callback function or
10731004
the asynchronous operations created within the callback.
10741005

10751006
Optionally, arguments can be passed to the function. They will be passed to
10761007
the callback function.
10771008

1078-
If the callback function throws an error, it will be thrown by
1079-
`runSyncAndReturn` too. The stacktrace will not be impacted by this call and
1080-
the context will be exited.
1009+
If the callback function throws an error, it will be thrown by `run` too.
1010+
The stacktrace will not be impacted by this call and the context will
1011+
be exited.
10811012

10821013
Example:
10831014

10841015
```js
10851016
const store = { id: 2 };
10861017
try {
1087-
asyncLocalStorage.runSyncAndReturn(store, () => {
1018+
asyncLocalStorage.run(store, () => {
10881019
asyncLocalStorage.getStore(); // Returns the store object
10891020
throw new Error();
10901021
});
@@ -1094,7 +1025,7 @@ try {
10941025
}
10951026
```
10961027

1097-
### `asyncLocalStorage.exitSyncAndReturn(callback[, ...args])`
1028+
### `asyncLocalStorage.exit(callback[, ...args])`
10981029
<!-- YAML
10991030
added: REPLACEME
11001031
-->
@@ -1109,17 +1040,17 @@ the asynchronous operations created within the callback.
11091040
Optionally, arguments can be passed to the function. They will be passed to
11101041
the callback function.
11111042

1112-
If the callback function throws an error, it will be thrown by
1113-
`exitSyncAndReturn` too. The stacktrace will not be impacted by this call and
1043+
If the callback function throws an error, it will be thrown by `exit` too.
1044+
The stacktrace will not be impacted by this call and
11141045
the context will be re-entered.
11151046

11161047
Example:
11171048

11181049
```js
1119-
// Within a call to run or runSyncAndReturn
1050+
// Within a call to run
11201051
try {
11211052
asyncLocalStorage.getStore(); // Returns the store object or value
1122-
asyncLocalStorage.exitSyncAndReturn(() => {
1053+
asyncLocalStorage.exit(() => {
11231054
asyncLocalStorage.getStore(); // Returns undefined
11241055
throw new Error();
11251056
});
@@ -1129,68 +1060,23 @@ try {
11291060
}
11301061
```
11311062

1132-
### Choosing between `run` and `runSyncAndReturn`
1133-
1134-
#### When to choose `run`
1135-
1136-
`run` is asynchronous. It is called with a callback function that
1137-
runs within a new asynchronous call. This is the most explicit behavior as
1138-
everything that is executed within the callback of `run` (including further
1139-
asynchronous operations) will have access to the store.
1140-
1141-
If an instance of `AsyncLocalStorage` is used for error management (for
1142-
instance, with `process.setUncaughtExceptionCaptureCallback`), only
1143-
exceptions thrown in the scope of the callback function will be associated
1144-
with the context.
1145-
1146-
This method is the safest as it provides strong scoping and consistent
1147-
behavior.
1148-
1149-
It cannot be promisified using `util.promisify`. If needed, the `Promise`
1150-
constructor can be used:
1151-
1152-
```js
1153-
const store = new Map(); // initialize the store
1154-
new Promise((resolve, reject) => {
1155-
asyncLocalStorage.run(store, () => {
1156-
someFunction((err, result) => {
1157-
if (err) {
1158-
return reject(err);
1159-
}
1160-
return resolve(result);
1161-
});
1162-
});
1163-
});
1164-
```
1165-
1166-
#### When to choose `runSyncAndReturn`
1167-
1168-
`runSyncAndReturn` is synchronous. The callback function will be executed
1169-
synchronously and its return value will be returned by `runSyncAndReturn`.
1170-
The store will only be accessible from within the callback
1171-
function and the asynchronous operations created within this scope.
1172-
If the callback throws an error, `runSyncAndReturn` will throw it and it will
1173-
not be associated with the context.
1174-
1175-
This method provides good scoping while being synchronous.
1176-
1177-
#### Usage with `async/await`
1063+
### Usage with `async/await`
11781064

11791065
If, within an async function, only one `await` call is to run within a context,
11801066
the following pattern should be used:
11811067

11821068
```js
11831069
async function fn() {
1184-
await asyncLocalStorage.runSyncAndReturn(new Map(), () => {
1070+
await asyncLocalStorage.run(new Map(), () => {
11851071
asyncLocalStorage.getStore().set('key', value);
11861072
return foo(); // The return value of foo will be awaited
11871073
});
11881074
}
11891075
```
11901076

11911077
In this example, the store is only available in the callback function and the
1192-
functions called by `foo`. Outside of `runSyncAndReturn`, calling `getStore`
1193-
will return `undefined`.
1078+
functions called by `foo`. Outside of `run`, calling `getStore` will return
1079+
`undefined`.
11941080

11951081
[`after` callback]: #async_hooks_after_asyncid
11961082
[`before` callback]: #async_hooks_before_asyncid

lib/async_hooks.js

+2-18
Original file line numberDiff line numberDiff line change
@@ -255,15 +255,15 @@ class AsyncLocalStorage {
255255
resource[this.kResourceStore] = store;
256256
}
257257

258-
runSyncAndReturn(store, callback, ...args) {
258+
run(store, callback, ...args) {
259259
const resource = new AsyncResource('AsyncLocalStorage');
260260
return resource.runInAsyncScope(() => {
261261
this.enterWith(store);
262262
return callback(...args);
263263
});
264264
}
265265

266-
exitSyncAndReturn(callback, ...args) {
266+
exit(callback, ...args) {
267267
if (!this.enabled) {
268268
return callback(...args);
269269
}
@@ -281,22 +281,6 @@ class AsyncLocalStorage {
281281
return resource[this.kResourceStore];
282282
}
283283
}
284-
285-
run(store, callback, ...args) {
286-
process.nextTick(() => {
287-
this.enterWith(store);
288-
return callback(...args);
289-
});
290-
}
291-
292-
exit(callback, ...args) {
293-
if (!this.enabled) {
294-
return process.nextTick(callback, ...args);
295-
}
296-
this.enabled = false;
297-
process.nextTick(callback, ...args);
298-
this.enabled = true;
299-
}
300284
}
301285

302286
// Placing all exports down here because the exported classes won't export

test/async-hooks/test-async-local-storage-args.js

+1-8
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,8 @@ const { AsyncLocalStorage } = require('async_hooks');
66
const asyncLocalStorage = new AsyncLocalStorage();
77

88
asyncLocalStorage.run({}, (runArg) => {
9-
assert.strictEqual(runArg, 1);
10-
asyncLocalStorage.exit((exitArg) => {
11-
assert.strictEqual(exitArg, 2);
12-
}, 2);
13-
}, 1);
14-
15-
asyncLocalStorage.runSyncAndReturn({}, (runArg) => {
169
assert.strictEqual(runArg, 'foo');
17-
asyncLocalStorage.exitSyncAndReturn((exitArg) => {
10+
asyncLocalStorage.exit((exitArg) => {
1811
assert.strictEqual(exitArg, 'bar');
1912
}, 'bar');
2013
}, 'foo');

test/async-hooks/test-async-local-storage-async-await.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ async function test() {
1212
}
1313

1414
async function main() {
15-
await asyncLocalStorage.runSyncAndReturn(new Map(), test);
15+
await asyncLocalStorage.run(new Map(), test);
1616
assert.strictEqual(asyncLocalStorage.getStore(), undefined);
1717
}
1818

test/async-hooks/test-async-local-storage-async-functions.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ async function testAwait() {
1616
await foo();
1717
assert.notStrictEqual(asyncLocalStorage.getStore(), undefined);
1818
assert.strictEqual(asyncLocalStorage.getStore().get('key'), 'value');
19-
await asyncLocalStorage.exitSyncAndReturn(testOut);
19+
await asyncLocalStorage.exit(testOut);
2020
}
2121

2222
asyncLocalStorage.run(new Map(), () => {

test/async-hooks/test-async-local-storage-enable-disable.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const { AsyncLocalStorage } = require('async_hooks');
55

66
const asyncLocalStorage = new AsyncLocalStorage();
77

8-
asyncLocalStorage.runSyncAndReturn(new Map(), () => {
8+
asyncLocalStorage.run(new Map(), () => {
99
asyncLocalStorage.getStore().set('foo', 'bar');
1010
process.nextTick(() => {
1111
assert.strictEqual(asyncLocalStorage.getStore().get('foo'), 'bar');
@@ -24,7 +24,7 @@ asyncLocalStorage.runSyncAndReturn(new Map(), () => {
2424

2525
process.nextTick(() => {
2626
assert.strictEqual(asyncLocalStorage.getStore(), undefined);
27-
asyncLocalStorage.runSyncAndReturn(new Map(), () => {
27+
asyncLocalStorage.run(new Map(), () => {
2828
assert.notStrictEqual(asyncLocalStorage.getStore(), undefined);
2929
});
3030
});

test/async-hooks/test-async-local-storage-errors-async.js

-26
This file was deleted.

test/async-hooks/test-async-local-storage-errors-sync-ret.js test/async-hooks/test-async-local-storage-errors.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ process.setUncaughtExceptionCaptureCallback((err) => {
1414
});
1515

1616
try {
17-
asyncLocalStorage.runSyncAndReturn(new Map(), () => {
17+
asyncLocalStorage.run(new Map(), () => {
1818
const store = asyncLocalStorage.getStore();
1919
store.set('hello', 'node');
2020
setTimeout(() => {

test/async-hooks/test-async-local-storage-gcable.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const onGC = require('../common/ongc');
1010

1111
let asyncLocalStorage = new AsyncLocalStorage();
1212

13-
asyncLocalStorage.runSyncAndReturn({}, () => {
13+
asyncLocalStorage.run({}, () => {
1414
asyncLocalStorage.disable();
1515

1616
onGC(asyncLocalStorage, { ongc: common.mustCall() });

test/async-hooks/test-async-local-storage-misc-stores.js

+3-12
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,11 @@ const { AsyncLocalStorage } = require('async_hooks');
55

66
const asyncLocalStorage = new AsyncLocalStorage();
77

8-
asyncLocalStorage.run(42, () => {
9-
assert.strictEqual(asyncLocalStorage.getStore(), 42);
8+
asyncLocalStorage.run('hello node', () => {
9+
assert.strictEqual(asyncLocalStorage.getStore(), 'hello node');
1010
});
1111

12-
const runStore = { foo: 'bar' };
12+
const runStore = { hello: 'node' };
1313
asyncLocalStorage.run(runStore, () => {
1414
assert.strictEqual(asyncLocalStorage.getStore(), runStore);
1515
});
16-
17-
asyncLocalStorage.runSyncAndReturn('hello node', () => {
18-
assert.strictEqual(asyncLocalStorage.getStore(), 'hello node');
19-
});
20-
21-
const runSyncStore = { hello: 'node' };
22-
asyncLocalStorage.runSyncAndReturn(runSyncStore, () => {
23-
assert.strictEqual(asyncLocalStorage.getStore(), runSyncStore);
24-
});

0 commit comments

Comments
 (0)