Skip to content

feat(browser): Add debugId sync APIs between web worker and main thread #16981

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

Merged
merged 10 commits into from
Jul 17, 2025

Conversation

Lms24
Copy link
Member

@Lms24 Lms24 commented Jul 14, 2025

This PR adds two Browser SDK APIs to let the main thread know about debugIds of worker files:

  • webWorkerIntegration({worker}) to be used in the main thread
  • registerWebWorker(self) to be used in the web worker

The communication between workers and main thread is established between both APIs and they have to be used both for the sync to work correctly. Another limitation around this approach is that users must set up webWorkerInegration before they register their own message listeners. This ensures that the message from registerWebWorker is not propagated to user-created message listeners. We'll document this thoroughly in docs and I already added a section about this in the JSDoc.

Because of the strict co-dependence of both APIs, I decided to add them in one PR (also makes testing easier).

Usage

// main.js
Sentry.init({...})

const worker = new MyWorker(...);

Sentry.addIntegration(Sentry.webWorkerIntegration({ worker }));

worker.addEventListener('message', e => {...});
// worker.js
Sentry.registerWebWorker({ self });

self.postMessage(...);

Multiple Workers

Multiple workers are also supported:

// main.js
Sentry.init({...})

const worker = new MyWorker(...);
const worker2 = new MyWorker2(...);

Sentry.addIntegration(Sentry.webWorkerIntegration({ worker: [worker, worker2] }));

worker.addEventListener('message', e => {...});

A worker can also be passed to the integration after it was initialized. This is helpful if workers are initialized lazily or at different times:

// main.js
Sentry.init({...})

const worker = new MyWorker(...);

const webWorkerIntegration = Sentry.webWorkerIntegration({ worker });

Sentry.addIntegration(webWorkerIntegration);

worker.addEventListener('message', e => {...});

// sometime later

const lazyWorker = new MyLazyWorker(...);
webWorkerIntegration.addWorker(lazyWorker);
lazyWorker.addEventListener('message', e => {...});

I decided to keep both APIs very general around web workers because I think there could be other use cases in which we can sync data by using the worker's message channels. This should be as easy as listening for other messages.

also added

  • unit tests for the two APIs
  • integration test testing the webWorkerIntegration
  • e2e test demonstrating correct usage of both APIs together

closes #16975
closes #16976

@Lms24 Lms24 self-assigned this Jul 14, 2025
@Lms24 Lms24 force-pushed the lms/feat-browser-web-worker-debugIds branch from ef4ba1a to 3acf7a8 Compare July 16, 2025 08:55
@@ -28,7 +28,7 @@ function fixPackageJson(cwd: string): void {

// 2. Fix volta extends
if (!packageJson.volta) {
throw new Error('No volta config found, please provide one!');
throw new Error("No volta config found, please add one to the test app's package.json!");
Copy link
Member Author

Choose a reason for hiding this comment

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

adjusted this message because I didn't realize the volta config needed to be added to the e2e test apps. Might be a me-problem but I think the message is now fool-proof :D

@Lms24 Lms24 marked this pull request as ready for review July 16, 2025 11:00
@Lms24 Lms24 requested review from timfish, mydea, a team and AbhiPrasad and removed request for a team July 16, 2025 11:01
cursor[bot]

This comment was marked as outdated.

Copy link
Collaborator

@timfish timfish left a comment

Choose a reason for hiding this comment

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

LGTM.

What happens if you have more than one worker and try and add them both? If you add the integration twice will it remove the one you added first?

@Lms24
Copy link
Member Author

Lms24 commented Jul 16, 2025

What happens if you have more than one worker and try and add them both? If you add the integration twice will it remove the one you added first?

Good point, thanks for raising! The first installed integration wins and the second instance wouldn't be added (=> setupOnce wouldn't be called and debugIds not added).

I think we have a couple of options:

  1. We can let the integration accept an array of workers instead. This assumes though that all workers are initialized at the same time. Which seems unlikely.
  2. We can add a method on the integration (webWorkerIntegration.addWorker(worker)), similarly to how the replay and feature flag integrations work. This increases complexity of the integration (or rather typing-wise) but still comes with the benefit that everything can be handled within one integration.
  3. We could also move away from making the main thread part an integration at all but just a regular function (e.g. Sentry.instrumentWorker()` or something similar). I wanted to go with the integration because it's a well-known pattern and seemed fitting. But maybe we should revisit.

I'm tentatively tending towards 2 but don't yet have a strong opinion. Any thoughts on this? Will also take it to the team to discuss shortly.

(set the PR to draft in the meantime)

@Lms24 Lms24 marked this pull request as draft July 16, 2025 12:48
@timfish
Copy link
Collaborator

timfish commented Jul 16, 2025

Another possibly more hacky solution is to set a different name for each instance of the Integration:

let count = 0;

export const webWorkerIntegration = defineIntegration(({ worker }: WebWorkerIntegrationOptions) => ({
  name: `${INTEGRATION_NAME}-${count++}`,
  setupOnce: () => {

Since this integration isn't default included users wont need to use the name to filter it out and because the name differs, multiples can be added?

@Lms24
Copy link
Member Author

Lms24 commented Jul 16, 2025

I went with options 1 and 2 combined. Decided to do it "properly" instead of the "hack" (though I liked the suggestion) to avoid the side effect it would introduce and to keep the integration name constant. Not sure why users would look up or remove the integration but let's keep the integration names predictable.

@Lms24 Lms24 marked this pull request as ready for review July 16, 2025 14:09
Copy link
Collaborator

@timfish timfish left a comment

Choose a reason for hiding this comment

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

Looks good!

@Lms24 Lms24 merged commit e8f2b2d into develop Jul 17, 2025
174 checks passed
@Lms24 Lms24 deleted the lms/feat-browser-web-worker-debugIds branch July 17, 2025 07:29
Lms24 added a commit to getsentry/sentry-docs that referenced this pull request Jul 22, 2025
#14395)

<!-- Use this checklist to make sure your PR is ready for merge. You may
delete any sections you don't need. -->

## DESCRIBE YOUR PR

closes getsentry/sentry-javascript#16977
closes getsentry/sentry-javascript#16974

This PR adds documentation for two new `WebWorker`-related APIs:
- `Sentry.webWorkerIntegration()`
- `Sentry.registerWebWorker()`

More details in
getsentry/sentry-javascript#16981

I also gave the entire web worker guide a facelift, removed some
unnecessary `notSupported` platforms and added an integration page for
the new integration. Also, the guide now includes a paragraph about
configuring Vite correctly for worker builds which was raised in
getsentry/sentry-javascript-bundler-plugins#755.


## IS YOUR CHANGE URGENT?  

Help us prioritize incoming PRs by letting us know when the change needs
to go live.
- [ ] Urgent deadline (GA date, etc.): <!-- ENTER DATE HERE -->
- [ ] Other deadline: <!-- ENTER DATE HERE -->
- [x] None: Not urgent, can wait up to 1 week+ (only to be merged after
9.40.0 was released)

## SLA

- Teamwork makes the dream work, so please add a reviewer to your PRs.
- Please give the docs team up to 1 week to review your PR unless you've
added an urgent due date to it.
Thanks in advance for your help!

## PRE-MERGE CHECKLIST

*Make sure you've checked the following before merging your changes:*

- [x] Checked Vercel preview for correctness, including links
- [x] PR was reviewed and approved by any necessary SMEs (subject matter
experts)
- [ ] PR was reviewed and approved by a member of the [Sentry docs
team](https://github.com/orgs/getsentry/teams/docs)

## LEGAL BOILERPLATE

<!-- Sentry employees and contractors can delete or ignore this section.
-->

Look, I get it. The entity doing business as "Sentry" was incorporated
in the State of Delaware in 2015 as Functional Software, Inc. and is
gonna need some rights from me in order to utilize my contributions in
this here PR. So here's the deal: I retain all rights, title and
interest in and to my contributions, and by keeping this boilerplate
intact I confirm that Sentry can use, modify, copy, and redistribute my
contributions, under Sentry's choice of terms.

## EXTRA RESOURCES

- [Sentry Docs contributor guide](https://docs.sentry.io/contributing/)

---------

Co-authored-by: Alex Krawiec <alex.krawiec@sentry.io>
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.

Add worker thread Sentry.registerWorker(self) API Add main thread webWorkerIntegration
3 participants