-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
In Node & edge environments, we use async local storage to ensure we have actual isolation for active spans. So the following code:
startSpan({ name: 'outer 1' }, async () => {
await waitForSeconds(2);
console.log(getActiveSpan());
});
startSpan({ name: 'outer 2' }, async () => {
await waitForSeconds(3);
console.log(getActiveSpan());
});Will actually work and log outer 1 and outer 2 correctly.
However, in browser (and theoretically any other environment where we don't have a custom Async Context Strategy (ACS)), this will not necessarily work as expected, because we cannot isolate the execution contexts, thus they may leak out into other parts of the code - so the above code may print out different spans, depending on what is globally active at the time.
This was always the case - also with the old performance APIs - but with the new APIs it is much easier to accidentally do this.
Previously, if you just did getActiveTransaction().startChild() or similar, stuff would work just fine - you had to actually go and do getCurrentScope().setSpan(span) to get potentially inconsistent behavior.
Since now startSpan (and startSpanManual) are the "default" APIs proposed for these things, I feel like maybe this will become a bigger problem in v8, and we should address this somehow.
Some options I see:
- We do nothing - this will basically work when passing a sync callback, and it may or may not work when passing async callbacks.
- In browser environment, we make
startSpanandstartSpanManualnot actually update the active span. This would mean that the only active spans would ever be ones that we create (? or we provide a separate API/option for that...?), so pageload/navigation spans... we'd need some story for manual page load etc. instrumentation though as well 🤔 - Or we could do 2 only if an async callback is provided, not if a sync callback is provided. But I guess this would only make things even more confusing...
Basically, I think it would be safer to say that in browser we don't have a nested span structure, but we only have a single active span (pageload, navigation, ...) and all other spans are children of that. That of course also has downsides, but to me less severe ones. But 🤷 there is no ideal solution here 😬