Skip to content

Conversation

timfish
Copy link
Collaborator

@timfish timfish commented Sep 24, 2025

This PR retains the original polled state feature so that we still support debug images and session termination on older versions of Node.

For Node.js v24 (and v22 with --experimental-async-context-frame flag) this PR adds support for fetching state from an AsyncLocalStorage instance from the native side. This allows us to fetch the current scopes from the Open Telemetry context object.

import { AsyncLocalStorage } from 'node:async_hooks';
import { Worker } from 'node:worker_threads';
import { registerThread } from '@sentry-internal/node-native-stacktrace';
import { longWork } from './long-work.js';

const asyncLocalStorage = new AsyncLocalStorage();
const storageKey = Symbol.for('sentry_scopes');

registerThread({ asyncLocalStorage, storageKey });

function withTraceId(traceId, fn) {
  return asyncLocalStorage.run({
    // Open Telemetry stores contexts on an object keyed by a symbol
    [storageKey]: { traceId },
  }, fn);
}

const watchdog = new Worker('./test/watchdog.js');

for (let i = 0; i < 10; i++) {
  withTraceId(`trace-${i}`, () => {
    if (i === 5) {
      longWork();
    }
  });
}

Results in the following output:

{
  "0": {
    "frames": [
      {
        "function": "from",
        "filename": "node:buffer",
        "lineno": 304,
        "colno": 28
      },
      {
        "function": "pbkdf2Sync",
        "filename": "node:internal/crypto/pbkdf2",
        "lineno": 79,
        "colno": 17
      },
      {
        "function": "longWork",
        "filename": "/Users/tim/Documents/Repos/node-native-stacktrace/test/long-work.js",
        "lineno": 6,
        "colno": 25
      },
      {
        "function": "?",
        "filename": "file:///Users/tim/Documents/Repos/node-native-stacktrace/test/async-storage.mjs",
        "lineno": 22,
        "colno": 7
      },
    ],
    "asyncState": {
      "traceId": "trace-5"
    }
  }
}

@timfish timfish force-pushed the timfish/feat/thread-state-global-function branch from bd16bcd to b642be1 Compare September 26, 2025 10:32
@timfish timfish marked this pull request as ready for review September 26, 2025 10:56
@timfish timfish force-pushed the timfish/feat/thread-state-global-function branch 2 times, most recently from 80402df to 1ee6ed1 Compare September 28, 2025 17:08
@timfish timfish changed the title feat: Capture thread state by calling global function feat: Capture thread state from AsyncLocalStorage store Sep 28, 2025
@timfish timfish force-pushed the timfish/feat/thread-state-global-function branch 2 times, most recently from e623ef6 to 936d588 Compare October 8, 2025 12:42
@timfish timfish marked this pull request as draft October 8, 2025 13:22
@timfish timfish requested a review from Copilot October 8, 2025 13:25
Copilot

This comment was marked as outdated.

@timfish timfish force-pushed the timfish/feat/thread-state-global-function branch from 1bd5e78 to 9046e07 Compare October 9, 2025 09:17
@timfish timfish requested a review from Copilot October 9, 2025 10:29
Copilot

This comment was marked as outdated.

@timfish timfish force-pushed the timfish/feat/thread-state-global-function branch 5 times, most recently from a8fd7b7 to 63a93d1 Compare October 9, 2025 12:42
@timfish timfish force-pushed the timfish/feat/thread-state-global-function branch from 63a93d1 to 1eccc68 Compare October 9, 2025 12:51
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.

1 participant