Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async Context Manager #183

Merged
merged 9 commits into from
Jun 22, 2021
Merged

Async Context Manager #183

merged 9 commits into from
Jun 22, 2021

Conversation

t2t2
Copy link
Contributor

@t2t2 t2t2 commented Jun 14, 2021

Adds custom context manager that keeps parent through common async operations (eg. setTimeout, setImmediate (IE), Promise.then, ...). Patched targets are based on what's used in react (v17, newer) and vue (v2, v3), but should pretty much cover most of the things users do.

APMI-1716

Using todolist example (react)

Current version:

image

image
image

Separate traceid for /items which happens after rerender caused by processing response of /login

With these changes:

image

image

Both requests are in same traceid

Populates span parent through most async usages that are important,
allowing linking them to user interactions or custom parents made by
the developer
@t2t2 t2t2 requested a review from mhennoch as a code owner June 14, 2021 15:12
<button type="button" id="btn1">Button</button>

<script>
// Based on react/scheduler's implementation of nextTick
Copy link
Contributor

Choose a reason for hiding this comment

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

Right, but also a small test using actual React would be good. Also, we could use a rough initial documentation for the use cases it covers.

Copy link
Contributor

Choose a reason for hiding this comment

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

There is an issue in jira to have framework tests

<button type="button" id="btn1">Button</button>

<script>
// Based on vue's implementation of nextTick
Copy link
Contributor

Choose a reason for hiding this comment

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

Again, a tiny test case based on Vue.

<button type="button" id="btn1">Button</button>

<script>
btn1.addEventListener('click', function () {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we merge all Promise context management tests into one? For example have one button per scenario. Then in a test you can execute clicks one by one - it will run faster.

btn1.addEventListener('click', function () {
setTimeout(function () {
SplunkRum.provider.getTracer('default').startSpan('context-child').end();
}, 1);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we. add a second button, with longer timeout? IIRC you exclude timeouts longer than 34 ms.

// eslint-disable-next-line @typescript-eslint/no-this-alias
const manager = this;

wrapNatively(XMLHttpRequest.prototype, 'addEventListener', original =>
Copy link
Contributor

Choose a reason for hiding this comment

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

but doesn't this belong in the XHR instrumentation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would rather keep everything related to async trace connecting in one place (also made it way easier to config)

let wrapped = wrappedListeners.get(args[1] as EventListener);

if (!wrapped) {
wrapped = manager.bind(args[1] as EventListener, manager.active());
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe it's intentional but I want to make sure, should we take the context which was active when .addEventListener() was called or the one active when XHR was created?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Taking parent context as of registration is intentional, based on these thought processes in node side:

open-telemetry/opentelemetry-js#1479
open-telemetry/opentelemetry-js#2037

src/index.ts Outdated Show resolved Hide resolved
CHANGELOG.md Outdated Show resolved Hide resolved
Firefox possibly runs timeouts (macrotask) before message event listeners (should be microtask)? At least seems like it in a few test runs
@t2t2 t2t2 merged commit 929e38b into main Jun 22, 2021
@t2t2 t2t2 deleted the async-context-manager branch June 22, 2021 10:36
sfishel-splunk pushed a commit to sfishel-splunk/splunk-otel-js-web that referenced this pull request Jun 22, 2022
Populates span parent through most async usages that are important,
allowing linking them to user interactions or custom parents made by
the developer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants