8000 fix: `nodeIntegrationInWorker` not working in AudioWorklet by codebytere · Pull Request #47244 · electron/electron · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

fix: nodeIntegrationInWorker not working in AudioWorklet #47244

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

codebytere
Copy link
Member

Description of Change

Closes #41263
Refs CL:5270028

With Chromium's new AudioWo 8000 rklet thread pooling system in CL:5270028, threads are reused for multiple AudioWorklet contexts. This breaks nodeIntegrationInWorker functionality for the 4th+ AudioWorklet instances due to incorrect thread-local observer management.

This causes subsequent contexts on reused threads to fail Node.js environment setup, breaking nodeIntegrationInWorker functionality for the 4th+ AudioWorklet instances. When an observer exists on a reused thread, it incorrectly skipped Node.js setup for new contexts.

Tested with https://gist.github.com/5a8ab93852ccb201057a9f3e813af47b

Checklist

Release Notes

Notes: Fixed an issue where nodeIntegrationInWorker didn't always work in AudioWorklet

@codebytere codebytere requested review from ckerr and deepak1556 May 23, 2025 10:06
@codebytere codebytere added semver/patch backwards-compatible bug fixes target/35-x-y PR should also be added to the "35-x-y" branch. target/36-x-y PR should also be added to the "36-x-y" branch. target/37-x-y PR should also be added to the "37-x-y" branch. labels May 23, 2025
@electron-cation electron-cation bot added the new-pr 🌱 PR opened recently label May 23, 2025
@deepak1556
Copy link
Member

If multiple worklet contexts share the same thread which was also the case before https://chromium-review.googlesource.com/c/chromium/src/+/5270028 , previously we would bail early before associating the Node environment to the new worker context and now node::Environment::GetCurrent(context) would still be false for new contexts sharing the same thread so we just end up reinitializing the Node environment in the same thread. Both of these produce will lead to incorrect results, we would need a refactor in the NodeBindings logic to do the following,

  1. Assign an Environment to a give v8::Context with https://github.com/nodejs/node/blob/d96d57d5a7cf3a897a81ed9b89d5e883803b2492/src/env.h#L685-L688
  2. Run the process init script for that context
  3. Unassign the Environment when the v8::Context is destroyed

Copy link
Member
@deepak1556 deepak1556 left a comment

Choose a reason for hiding this comment

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

Blocking the change since it is incomplete in its current state. For ex:

In the test case, update the renderer code to

const workletPath = './worklet.js';

async function createContextAndLoadWorklet(channel = false, path = workletPath) {
    const audioCtx = new AudioContext();
    await audioCtx.audioWorklet.addModule(path);
    if (channel) {
        const node = new AudioWorkletNode(audioCtx, "audio-worklet");
        node.port.onmessage = (e) => {
            console.log(e.data);
            node.port.postMessage("pong");
        }
        node.connect(audioCtx.destination);
    }
    await audioCtx.close();
}

createContextAndLoadWorklet()
.then(() => { return createContextAndLoadWorklet(); })
.then(() => { return createContextAndLoadWorklet(); })
.then(() => { return createContextAndLoadWorklet(); })
.then(() => { return createContextAndLoadWorklet(true); })
.then(() => { return createContextAndLoadWorklet(); })

and worklet code to

// Empty
console.log('worklet globalThis', globalThis, 'Is require a function?', typeof require === 'function');

const { setInterval } = require('node:timers');

class AudioWorklet extends AudioWorkletProcessor {
    constructor() {
        super();
        setInterval(() => {
            this.port.postMessage("ping");
        }, 1000);
        this.port.onmessage = (e) => console.log(e.data);
    }

    process() {
        return true;
    }
}

registerProcessor('audio-worklet', AudioWorklet);

the creation of the 6th worklet which shares the same thread will cause the node integration to be reinitialized and will break the ping-pong loop.

@electron-cation electron-cation bot removed the new-pr 🌱 PR opened recently label May 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver/patch backwards-compatible bug fixes target/35-x-y PR should also be added to the "35-x-y" branch. target/36-x-y PR should also be added to the "36-x-y" branch. target/37-x-y PR should also be added to the "37-x-y" branch.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: [AudioWorklet] value of globalThis differs between first and second calls to the worklet.
4 participants
0