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

PeerConnection.close() Method is Blocking the Event Loop #326

Closed
mertushka opened this issue Jan 26, 2025 · 6 comments · Fixed by #327
Closed

PeerConnection.close() Method is Blocking the Event Loop #326

mertushka opened this issue Jan 26, 2025 · 6 comments · Fixed by #327

Comments

@mertushka
Copy link
Contributor

Describe the Bug

In certain cases, the PeerConnection.close() polyfill seems to block the event loop. Profiling has shown that the PeerConnection.close() method sometimes takes ~1 second to execute instead of the usual few milliseconds.

Additionally, the datachannel.readyState does not always correctly reflect its real state. This inconsistency can lead to issues such as attempting to send messages on a data channel that appears open but is not actually open. Check the additional context for more insight.

To Reproduce

Steps to reproduce the issue:

  1. Open a WebRTC connection.
  2. Trigger a PeerConnection.close() call.
  3. Observe that the event loop may be blocked, even for ~1 second.
  4. Check the datachannel.readyState before and after the .close() call to confirm state inconsistencies.

Expected Behavior

  • The PeerConnection.close() polyfill should clean up the connection asynchronously and avoid blocking the event loop.
  • The datachannel.readyState should accurately reflect the real state of the data channel.

Device Information

  • Node.js Version: 20.x LTS

Additional Context

See: mertushka/haxball.js#44

@mertushka
Copy link
Contributor Author

close(): void {
this.#closeRequested = true;
this.#dataChannel.close();
}

Fix

I was able to fix the issue by updating the close() method in the RTCDataChannel polyfill to use setImmediate. Specifically, I wrapped the this.#dataChannel.close() call in a setImmediate function like this:

close(): void {
    setImmediate(() => {
        this.#closeRequested = true;
        this.#dataChannel.close();
    });
}

This change ensures that the close() operation is executed asynchronously, preventing it from blocking the event loop. After applying this fix, the blocking caused by PeerConnection.close() are no longer occurring.

@murat-dogan Let me know if this is an ideal solution so i can make a PR.

@mertushka mertushka changed the title PeerConnection.close() Method Blocking the Event Loop PeerConnection.close() Method is Blocking the Event Loop Jan 27, 2025
@murat-dogan
Copy link
Owner

Hello @mertushka and thank you for sharing the solution.
The solution seems reasonable.

The only point is, can we keep that part out of setImmediate;
this.#closeRequested = true;

What do you think?

@mertushka
Copy link
Contributor Author

@murat-dogan Done with the #327 PR.

@mertushka
Copy link
Contributor Author

@murat-dogan Can you release the new version about this? This is considered as a major bug and i must have the fix on my module ASAP. Thanks in advance.

@murat-dogan
Copy link
Owner

https://github.com/murat-dogan/node-datachannel/releases/tag/v0.25.0

Has been released.

@mertushka
Copy link
Contributor Author

@murat-dogan This issue should be reopened as <DataChannel>.readyState still does not accurately reflect its actual state.

Relevant issue: mertushka/haxball.js#49

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 a pull request may close this issue.

2 participants