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

Feature: Add a bridge for SharedWorker to pool multiple tabs into a single connection #403

Open
2 tasks done
LucyEgan opened this issue Mar 25, 2025 · 8 comments
Open
2 tasks done

Comments

@LucyEgan
Copy link

LucyEgan commented Mar 25, 2025

Is your feature request related to a problem?

Having another connection type of SharedWebWorker that the developer can pick if they want/support Shared Workers
https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker.

For example a site with 3 live queries on the page(eg, account, config, notifications)

  • Opening 10 tabs of that site would result in 10 websocket connections, 30 live queries for effectively the same data

Describe the solution

Add SharedWebWorker possibly shared+wss:// or a option of useSharedWorker: true, preferably the second.
Which would open a SharedWorker for the contents of the shared web worker as a extra file or dataURI web worker.

Instead of directly opening/communicating on the WebSocket, it would work via the shared worker, where it would handle the connection for all the tabs connected to it.

Alternative methods

Adding support manually to wrap the client rather than the transport

SurrealDB version

2.3.0+20250321

JavaScript SDK version

1.2.1

Contact Details

[email protected]

Is there an existing issue for this?

  • I have searched the existing issues

Code of Conduct

  • I agree to follow this project's Code of Conduct
@nickchomey
Copy link

The problem with Shared Workers is that android chromium (50% of web users) doesn't support it.

The best solution is to use the broadcast channels and web locks apis to create a "leader" tab that interfaces with the db, and sends/receives to the other tabs as needed. It can be done in main threads or web workers.

Rxdb does this well - https://github.com/pubkey/rxdb/blob/master/src/plugins/leader-election/index.ts

(rxdb also has tons of other vastly better mechanisms, performance, etc than surreal)

@LucyEgan
Copy link
Author

I would say use the web standard first, and if support is needed outside of that then the developer can polyfil it for non supporting browsers(https://github.com/okikio/sharedworker), that way you wont be stuck with the bulkier worse off version long term, one day you can drop it with 0 side effects.

This feature is more leaning towards desktop anyway since nearly all users will sit with 1 tab open on mobile, and at worst any background tabs on mobile are going to deactivate when you start using others.

@nickchomey
Copy link

nickchomey commented Mar 25, 2025

Everything I just mentioned is web standards.

https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API
https://developer.mozilla.org/en-US/docs/Web/API/Web_Locks_API

You can also inspect the code I linked to in order to see how it works and confirm this. Its very simple

Here's a good, related discussion on all of this for wasm sqlite.

rhashimoto/wa-sqlite#81

As well as in the polyfill you linked to - okikio/sharedworker#1 - at the end of the thread, someone said they solved it quite simply with web locks.

@LucyEgan
Copy link
Author

I'm aware of the web standards to create it but it seems like extra overhead compared to something designed for it.
The main issue I see for that approach is with a single tab controlling it is on reload/tab closure causing the connection/live queries to be restarted.

Another option that might be worth exploring is a service worker to get further support, but the same outcome is desired with this.

A single WebSocket across open tabs that shares connection/auth/live queries that can survive tab closures/reloading

@nickchomey
Copy link

nickchomey commented Mar 26, 2025

I'm aware of the web standards

But you said "use web standards first"...

Shared workers are obviously the ideal tool for the job. The problem is, again, that they aren't available to 50% of web users. That doesn't seem like something an sdk should build upon when a reasonable proxy/polyfill can easily be made with other web standards - as shown in great details by the links that I shared.

A service worker is absolutely not appropriate for the task - their life cycle is short-lived and inconsistent, and I think even tab-specific as well. They are also missing various capabilities available to the main thread and dedicated workers.

@nickchomey
Copy link

nickchomey commented Mar 26, 2025

I'm aware of the web standards

But you said "use web standards first"...

Shared workers are obviously the ideal tool for the job. The problem is, again, that they aren't available to 50% of web users. That doesn't seem like something an sdk should build upon when a reasonable proxy/polyfill can easily be made with other web standards - as shown in great details by the links that I shared.

I see little problem/difference with connections being restarted upon tab closure - even with a sharedworker, a websocket connection will close on its own for a variety of common reasons.

Perhaps a solution would be to develop both a shared worker and a leader elected web worker module, and users can import them as-needed. Or have the shared worker as default and make the leader elected polyfill easily imported when needed.

A service worker is absolutely not appropriate for the task - their life cycle is short-lived and inconsistent, and I think even tab-specific as well. They are also missing various capabilities available to the main thread and dedicated workers.

@LucyEgan
Copy link
Author

For the 50% number, I agree 50% of mobile it wouldn't be supported for, but firstly this feature doesn't really apply to mobile, at best tablet which is why android chrome probably decided to never add it. Of that 50% of mobile that's out of a 60-70% of people that use mobile to start with.

Yes a connection will close the same as it does in a normal page, but instead of reconnecting 10 separate connections, it would be 1.

From what I've seen of a service worker its alive for the full required lifetime of all connected tabs that have/are/will be requiring it, and for a short time after, and will also be available before the first tab exists. WebSockets and cross tab communication are available. Because of these things I mention it as a possibility.

As for having both options, yeh that's totally a possibly to add this support for the 35% of mobile users that wont benefit from it, but as a separate thing, since that wont give the desired effect this is to address.

As I've not experimented with the options yet, feel free to send over your experiments you have used to rule those options out.

@nickchomey
Copy link

nickchomey commented Mar 26, 2025

For the 50% number, I agree 50% of mobile it wouldn't be supported for, but firstly this feature doesn't really apply to mobile, at best tablet which is why android chrome probably decided to never add it. Of that 50% of mobile that's out of a 60-70% of people that use mobile to start with.

No, it's 50% (or more!) of total web usage - most people don't have a computer, and most use Android. https://caniuse.com/sharedworkers

And I regularly have multiple tabs open for the same site on my phone. If they're making an automatic connection in the background, then they need to have a pooled connection

Yes a connection will close the same as it does in a normal page, but instead of reconnecting 10 separate connections, it would be 1.

A leader elected tab/web worker would only make one connection.

From what I've seen of a service worker its alive for the full required lifetime of all connected tabs that have/are/will be requiring it, and for a short time after, and will also be available before the first tab exists. WebSockets and cross tab communication are available. Because of these things I mention it as a possibility.

This is all completely wrong.

As for having both options, yeh that's totally a possibly to add this support for the 35% of mobile users that wont benefit from it, but as a separate thing, since that wont give the desired effect this is to address.

Again, it's 50% of all web users.

As I've not experimented with the options yet, feel free to send over your experiments you have used to rule those options out.

I've literally sent very detailed links and libraries...

Friend, I've noticed that you're very active and passionate about surrealdb and have contributed lots of bug reports, PRs etc. It's much appreciated. But it's very unbecoming how you've been communicating here - all sorts of incorrect or baseless claims, a general disregard for the world's mobile users, seemingly being offended by my well-cited attempts to help provide context to make this request successful, and ignoring all of those citations in which people have already explored this topic deeply

I hope you'll review those links and take a more constructive approach going forward towards finding the right solution here

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

No branches or pull requests

2 participants