All files / lib/internal inspector_async_hook.js

81.57% Statements 62/76
87.5% Branches 14/16
85.71% Functions 6/7
81.57% Lines 62/76

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77143x 143x 143x 143x 143x 143x 143x 143x 143x 3x 3x 3x 3x 3x 3x 3x 10x 10x 10x 10x 10x 10x 10x 3x 3x 3x 3x 3x 9x 9x 7x 3x 3x 3x 13x 13x 11x 3x 3x 3x 4x 4x 4x 3x 3x 3x 3x 3x 143x 4x 4x 4x                     4x 4x 4x 4x 143x         143x 143x 143x 143x 143x  
'use strict';
 
let hook;
let config;
 
const {
  SafeSet,
} = primordials;
 
function lazyHookCreation() {
  const inspector = internalBinding('inspector');
  const { createHook } = require('async_hooks');
  config = internalBinding('config');
 
  hook = createHook({
    init(asyncId, type, triggerAsyncId, resource) {
    // It's difficult to tell which tasks will be recurring and which won't,
    // therefore we mark all tasks as recurring. Based on the discussion
    // in https://github.com/nodejs/node/pull/13870#discussion_r124515293,
    // this should be fine as long as we call asyncTaskCanceled() too.
      const recurring = true;
      if (type === 'PROMISE')
        this.promiseIds.add(asyncId);
      else
        inspector.asyncTaskScheduled(type, asyncId, recurring);
    },
 
    before(asyncId) {
      if (this.promiseIds.has(asyncId))
        return;
      inspector.asyncTaskStarted(asyncId);
    },
 
    after(asyncId) {
      if (this.promiseIds.has(asyncId))
        return;
      inspector.asyncTaskFinished(asyncId);
    },
 
    destroy(asyncId) {
      if (this.promiseIds.has(asyncId))
        return this.promiseIds.delete(asyncId);
      inspector.asyncTaskCanceled(asyncId);
    },
  });
 
  hook.promiseIds = new SafeSet();
}
 
function enable() {
  if (hook === undefined) lazyHookCreation();
  if (config.bits < 64) {
    // V8 Inspector stores task ids as (void*) pointers.
    // async_hooks store ids as 64bit numbers.
    // As a result, we cannot reliably translate async_hook ids to V8 async_task
    // ids on 32bit platforms.
    process.emitWarning(
      'Warning: Async stack traces in debugger are not available ' +
      `on ${config.bits}bit platforms. The feature is disabled.`,
      {
        code: 'INSPECTOR_ASYNC_STACK_TRACES_NOT_AVAILABLE',
      });
  } else {
    hook.enable();
  }
}
 
function disable() {
  if (hook === undefined) lazyHookCreation();
  hook.disable();
}
 
module.exports = {
  enable,
  disable
};