The initial solution I was thinking of is:
- Store content hash (of .wasm file) in worker memory.
- Each time a new tab is opened compare content hashes.
- On difference kill the worker and initialize again to fetch a new bundle.
- Reload old tabs.
A couple of issues with this:
- There is no easy way to terminate a worker. Terminate does not work for Shared Workers, close only clear task queue, and does not cause re-fetching worker script.
- We can close all tabs, leave only the newest one, and refresh - this doesn't make any sense.
- We can refresh all tabs at once - this is very hard to implement because it must be done simultaneously. There is a risk of race condition, when with multiple tabs first already finished refreshing when the latest has not started yet.
That being said, I am proposing a simpler and safer solution:
- We create a worker, which name is associated with the web version - when we open a new tab with the new version we will create new Shared worker with the newest bundle (which is in sync with main thread and .wasm file).
- We broadcast (supported by all browsers) current version to other tabs.
- When we receive the version we compare it, if it's different this tab is old, we refresh it - download the newest web app version, and connect to the new worker.
- After all tabs are reloaded, the old worker dies (there is no connection to it).
- When we open a new tab with the new version, old tabs are in the background so it should be safe because the worker should not be performing anything on DB.