Skip to content

Conversation

@trentm
Copy link
Member

@trentm trentm commented Jun 24, 2022

Implement a run-context manager using AsyncLocalStorage. Newer versions
of node (>=14.5, >=12.19) should benefit from significant better perf
compared to AsyncHooksRunContextManager, esp. for promise-heavy apps.

See the many async_hooks-related improvements in:
https://nodejs.org/en/blog/release/v14.5.0/
https://nodejs.org/en/blog/release/v12.19.0/

Refs: #2745

Implement a run-context manager using AsyncLocalStorage. Newer versions
of node (>=14.5, >=12.19) should benefit from significant better perf
compared to AsyncHooksRunContextManager, esp. for promise-heavy apps.

See the many async_hooks-related improvements in:
    https://nodejs.org/en/blog/release/v14.5.0/
    https://nodejs.org/en/blog/release/v12.19.0/
@trentm trentm self-assigned this Jun 24, 2022
@github-actions github-actions bot added the agent-nodejs Make available for APM Agents project planning. label Jun 24, 2022
@ghost
Copy link

ghost commented Jun 24, 2022

💚 Build Succeeded

the below badges are clickable and redirect to their specific view in the CI or DOCS
Pipeline View Test View Changes Artifacts preview preview

Expand to view the summary

Build stats

  • Start Time: 2022-07-07T19:43:47.957+0000

  • Duration: 25 min 56 sec

Test stats 🧪

Test Results
Failed 0
Passed 257312
Skipped 0
Total 257312

🤖 GitHub comments

To re-run your PR in the CI, just comment with:

  • /test : Re-trigger the build.

  • run module tests for <modules> : Run TAV tests for one or more modules, where <modules> can be either a comma separated list of modules (e.g. memcached,redis) or the string literal ALL to test all modules

  • run benchmark tests : Run the benchmark test only.

  • run elasticsearch-ci/docs : Re-trigger the docs validation. (use unformatted text in the comment!)

@trentm trentm marked this pull request as ready for review July 5, 2022 21:23
@trentm trentm requested a review from astorm July 5, 2022 21:23
@trentm
Copy link
Member Author

trentm commented Jul 5, 2022

@astorm Some review notes that might help. The initial work for this was to 3 files, but that become 27 files after config, docs, and test changes.

Review notes

There are a few parts to this change that can mostly be reviewed separately:

  • The implementation of the new contextManager=asynclocalstorage|asynchooks|patch config var that deprecates the asyncHooks=true|false config var. This part is all in:

    • lib/config.js
    • test/config.test.js
    • lib/instrumentation/index.js - The selection of the appropriate RunContextManager based on contextManager.
    • docs/configuration.asciidoc
  • The conversion of Jenkins CI to use ELASTIC_APM_CONTEXT_MANAGER rather than ELASTIC_APM_ASYNC_HOOKS.

    • .ci/...
  • The addition of the AsyncLocalStorageRunContextManager class. The class hierarchy is:

    AbstractRunContextManager
        BasicRunContextManager (used for the non-async_hooks tracking)
            AsyncHooksRunContextManager
        AsyncLocalStorageRunContextManager
    

    The implementation of .root() was moved from Basic... up to Abstract...
    so that AsyncLocalStorage... could use it without using other unneeded
    parts of Basic....

    • lib/instrumentation/run-context/AbstractRunContextManager.js
    • lib/instrumentation/run-context/BasicRunContextManager.js

    Then the implementation of AsyncLocalStorage... is very similar to OTel's
    AsyncLocalStorageContextManager.ts.

    • lib/instrumentation/run-context/AsyncLocalStorageContextManager.js
  • The conversion of the test suite to use conf.contextManager rather than conf.asyncHooks:

    • test/... (except "test/config.test.js")

Copy link
Contributor

@astorm astorm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good and an AsyncLocalStorage option is a welcome change (especially with the potential perf. improvements for Kibana). The class hierarchy makes sense and the configuration looks like it will correctly honor the asyncHooks:false for folks upgrading.

I don't have a lot of insight on the changes to the CI and what context managers are/aren't tested -- so if you have anything you're nervous about there you should probably get a second opinion but I don't have any objections to committing those changes.

agent supports a limited tracking mechanism (named "patch") that monkey-patches
much of the core Node.js API to attempt to follow asynchronous calls. The
"patch" mechanism is limited in usage and coverage (for example, it cannot
track `async/await` usage), is not recommended, and may be deprecated and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd +1 deprecating patch now to give us/users a long run way in it going away forever.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@astorm I've done so in commit 8af9716. Does that commit look reasonable to you?

} else {
// Select the appropriate run-context manager.
const confContextManager = this._agent._conf.contextManager
if (confContextManager === config.CONTEXT_MANAGER_PATCH) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Appears to preserve a user's desires when asyncHooks: false is set to false with no other configuration -- so we should be good here from a backwards compatibility point of view) (i.e uses the basic run context manager)

// A basic manager for run context. It handles a stack of run contexts, but does
// no automatic tracking (via async_hooks or otherwise). In combination with
// "patch-async.js" it does an adequate job of context tracking for much of the
// "patch-async.js" it does a limited job of context tracking for much of the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥 🔥 🔥 🔥

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent-nodejs Make available for APM Agents project planning.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants