Skip to content

Commit

Permalink
async_hooks: move lookupResourceWithStorage() into executionAsyncReso…
Browse files Browse the repository at this point in the history
…urce()

Signed-off-by: Darshan Sen <darshan.sen@postman.com>
  • Loading branch information
RaisinTen committed Nov 7, 2021
1 parent 12abaf7 commit 9d8b234
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 62 deletions.
63 changes: 4 additions & 59 deletions lib/async_hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,65 +252,10 @@ class AsyncResource {
}
}

let _tls_wrap;

function lazyLoadTlsWrap() {
_tls_wrap ??= require('_tls_wrap');
}

let dgram;

function lazyLoadDgram() {
dgram ??= require('dgram');
}

let internal_dgram;

function lazyLoadInternalDgram() {
internal_dgram ??= require('internal/dgram');
}

let net;

function lazyLoadNet() {
net ??= require('net');
}

function lookupResourceWithStorage() {
// When a TCP/UDP object is created, its owner_symbol is uninitialized, so
// calling executionAsyncResource() would return the TCP/UDP object itself.
// So the store is initially saved on the TCP/UDP object. Later on, when the
// Socket/TLSSocket object is created, the TCP/UDP object is wrapped by the
// Socket/TLSSocket object in the _handle property and the owner_symbol of the
// TCP/UDP object is set to the corresponding Socket/TLSSocket object. So
// calling executionAsyncResource() now would return the Socket/TLSSocket
// object, which does not contain the storage that was saved initially. Hence,
// in the case of a Socket/TLSSocket object, we must use the underlying
// TCP/UDP object, if available, for storage.

lazyLoadDgram();
lazyLoadInternalDgram();
lazyLoadNet();
lazyLoadTlsWrap();

let resource = executionAsyncResource();

if ((resource instanceof net.Socket ||
resource instanceof _tls_wrap.TLSSocket) &&
resource._handle != null) {
resource = resource._handle;
} else if (resource instanceof dgram.Socket &&
resource[internal_dgram.kStateSymbol].handle != null) {
resource = resource[internal_dgram.kStateSymbol].handle;
}

return resource;
}

const storageList = [];
const storageHook = createHook({
init(asyncId, type, triggerAsyncId, resource) {
const currentResource = lookupResourceWithStorage();
const currentResource = executionAsyncResource();
// Value of currentResource is always a non null object
for (let i = 0; i < storageList.length; ++i) {
storageList[i]._propagate(resource, currentResource);
Expand Down Expand Up @@ -354,7 +299,7 @@ class AsyncLocalStorage {

enterWith(store) {
this._enable();
const resource = lookupResourceWithStorage();
const resource = executionAsyncResource();
resource[this.kResourceStore] = store;
}

Expand All @@ -366,7 +311,7 @@ class AsyncLocalStorage {

this._enable();

const resource = lookupResourceWithStorage();
const resource = executionAsyncResource();
const oldStore = resource[this.kResourceStore];

resource[this.kResourceStore] = store;
Expand All @@ -392,7 +337,7 @@ class AsyncLocalStorage {

getStore() {
if (this.enabled) {
const resource = lookupResourceWithStorage();
const resource = executionAsyncResource();
return resource[this.kResourceStore];
}
}
Expand Down
54 changes: 51 additions & 3 deletions lib/internal/async_hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,30 @@ setCallbackTrampoline(callbackTrampoline);

const topLevelResource = {};

let _tls_wrap;

function lazyLoadTlsWrap() {
_tls_wrap ??= require('_tls_wrap');
}

let dgram;

function lazyLoadDgram() {
dgram ??= require('dgram');
}

let internal_dgram;

function lazyLoadInternalDgram() {
internal_dgram ??= require('internal/dgram');
}

let net;

function lazyLoadNet() {
net ??= require('net');
}

function executionAsyncResource() {
// Indicate to the native layer that this function is likely to be used,
// in which case it will inform JS about the current async resource via
Expand All @@ -149,9 +173,33 @@ function executionAsyncResource() {

const index = async_hook_fields[kStackLength] - 1;
if (index === -1) return topLevelResource;
const resource = execution_async_resources[index] ||
executionAsyncResource_(index);
return lookupPublicResource(resource);
let resource = execution_async_resources[index] ||
executionAsyncResource_(index);
resource = lookupPublicResource(resource);

// When a TCP/UDP object is created, its owner_symbol is uninitialized, so the
// store is saved on the TCP/UDP object. Later on, when the Socket/TLSSocket
// object is created, the TCP/UDP object is wrapped by the Socket/TLSSocket
// object in the handle and the owner_symbol of the TCP/UDP object is set to
// the corresponding Socket/TLSSocket object. Hence, in the case of a
// Socket/TLSSocket object, we must use the underlying TCP/UDP object, if
// available, for storage.

lazyLoadDgram();
lazyLoadInternalDgram();
lazyLoadNet();
lazyLoadTlsWrap();

if ((resource instanceof net.Socket ||
resource instanceof _tls_wrap.TLSSocket) &&
resource._handle != null) {
resource = resource._handle;
} else if (resource instanceof dgram.Socket &&
resource[internal_dgram.kStateSymbol].handle != null) {
resource = resource[internal_dgram.kStateSymbol].handle;
}

return resource;
}

function inspectExceptionValue(e) {
Expand Down

0 comments on commit 9d8b234

Please sign in to comment.