Skip to content

Shared webworker example - #1004

Open
krzysiek4321 wants to merge 2 commits into
trunk-rs:mainfrom
krzysiek4321:shared_workers
Open

krzysiek4321 wants to merge 2 commits into
trunk-rs:mainfrom
krzysiek4321:shared_workers

Conversation

@krzysiek4321

@krzysiek4321 krzysiek4321 commented Jul 19, 2025 •

Copy link
Copy Markdown

Added a simple SharedWorker example based on webworker-module example. It demonstrates using both set_on<event> and addEventListener interfaces.

As of this moment this example has a problem to be fixed where the first page which creates a shared worker does not reach the onconnect handler, so it will not receive messages from worker nor be able to post messages to unless it creates a new SharedWorker object which will this time reach already initialized SharedWorkerGlobalScope's onconnect.
See worker processing model

You can easily see this by inspecting worker's log in browser's devtools and opening the served example in new tabs.
See Using_web_workers#debugging_worker_threads

Added a simple SharedWorker example based on webworker-module example.
It demonstrates using both set_on<event> and addEventListener
interfaces.

As of this moment this example has a problem to be fixed where
the first page which creates a shared worker does not reach the
onconnect handler, so it will not receive messages from worker nor be
able to post messages to unless it creates a new SharedWorker object
which will this time reach already initialized
SharedWorkerGlobalScope's onconnect.
@ctron

ctron commented Jul 21, 2025

Copy link
Copy Markdown
Collaborator

Cool. Could you add this to the CI as well please:

example:
- cargo-manifest
- cdylib
- hooks
- initializer
- leptos
- no-rust
- proxy
- seed
- target-path
- vanilla
- webworker
- webworker-gloo
- webworker-module
- wasm_threads
- yew
- yew-tailwindcss
- yew-tls

@krzysiek4321

Copy link
Copy Markdown
Author

Cool. Could you add this to the CI as well please:

@ctron Done.
Do you wish to wait with merging until wasm-bindgen resolves shared worker loading issue?

@krzysiek4321

Copy link
Copy Markdown
Author

I've found a workaround for the issue.
It's to create such a loader shim:

import init from './worker.js';

let initialized = false;

async function initial_handler(e) {
	if (initialized)
		return;

	removeEventListener(self, initial_handler); // all following events will be handled by wasm handler
	await init();
	// necessary because dispatchEvent reaches initial_handler despite removeEventListener
	initialized = true;
	// send the first event into proper handler
	// I've tried to use useTimeout to remove initialized flag, but no good
	self.dispatchEvent(e);
};

self.addEventListener("connect", initial_handler);

Initial handler get's invoked twice, but the initialization block is invoked only once.

@ctron What do you think about this approach?

@ctron

ctron commented Aug 12, 2025

Copy link
Copy Markdown
Collaborator

Sorry, I'm not quite following.

@niclashoyer

Copy link
Copy Markdown

@krzysiek4321 I can confirm that your loader works as expected.

@ctron the initialization of shared workers seems to be different from dedicated workers. It is not clear to me if this is a problem with wasm-bindgen (as reported in wasm-bindgen/wasm-bindgen#4536) or fails somewhere else, because of race conditions while loading wasm modules.

The alternative loader shim provided by @krzysiek4321 works around the issue by deferring await init() to the connect event.

Replacing the default worker loader shim generated by trunk with the alternative shim seems to work right away. So one option would be to add a data-shared-loader-shim or something like that, to add this alternative shim to the generated worker code.

This branch has not been deployed

No deployments
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.

3 participants