[Fix] OPFS Sleeping Tabs Sync Deadlock #498
Draft
+64
−5
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Overview
We recently introduced OPFS VFS support for the PowerSync web SDK. Unlike IndexedDB-based VFS, which allows a single shared SQLite connection within a shared web worker across multiple tabs, OPFS requires each tab to have its own dedicated SQLite worker.
To manage concurrency, we use Navigator locks, ensuring exclusive access to SQLite connections. Table change notifications are propagated using a BroadcastChannel.
In multi-tab scenarios, a shared sync worker is responsible for syncing operations. This worker requires access to the SQLite database.
MessagePort
to the shared SQLite worker is passed to the sync worker, allowing direct DB access.MessagePort
to the last connected tab’s dedicated SQLite worker is passed to the sync worker. This connection is updated as tabs are opened and closed.The shared sync worker's DB connection is linked to a specific tab. If that tab is frozen or put to sleep (e.g., in Chrome’s Tab Freezing or Edge’s Sleeping Tabs), the connection becomes inaccessible, blocking SQLite queries in the sync worker.
Luckily browsers don't freeze or sleep tabs which are actively holding a web lock. This PR adds a hold on a web lock as soon as the connection is shared to the sync worker. In local testing this prevents tabs from being put to sleep.