HomePhabricator
Diffusion Comm dd05e9d5fb55

[web] Introduce useWebLock

Description

[web] Introduce useWebLock

Summary:
ENG-6667 : Implement "primary" tab lock

We want to only have a singular tunnelbroker connection across all tabs on web. One way to achieve this is to use the WebLockAPI. The useWebLock hook exposes a nicer interface to it. It returns lock status and releaseLock function. When the status is equal to 'should-release' the caller is expected to run cleanup (e.g. disconnecting from the tunnelbroker) and call releaseLock.

Only the foreground tabs will try and acquire a lock. After a tab is backgrounded it should release the lock if it has one.

Some information about the web lock api:

  • It allows to request a lock with a specific name
  • The lock can be held only "in one place"/"one call to the request method" across all tabs of the same origin
    • If we make sure to only call it once in the app, we can get the required locking behaviour between tabs
    • (this is assuming the exclusive mode, which is the default)
  • If the lock is already taken, the request call goes into a queue, and will wait until the lock is released
    • Request in queue can be aborted with an AbortSignall
  • Call to request returns a promise and expects an async callback as an argument. When it acquired the lock it calls the provided callback. The promise returned by the request call resolves when the the promise returned from the callback resolves.
  • Locks are released automatically after the tab is closed

Additionally our version of flow doesn't type the LockManager (this was also the case for e.g. service worker and shared worker types) so I had to do it myself.

Test Plan:
Add this code:

const { lockStatus, releaseLock } = useWebLock('lock');
React.useEffect(() => {
   document.title = lockStatus;

   if(lockStatus === 'should-release') {
     // Add some delay to simulate closing the tunnelbroker socket
     setTimeout(releaseLock, 1000);
   }
 }, [lockStatus]);

Try switching between different tabs quickly, try displaying two tabs at the same time. Check that at all times the only tab holding the lock is one of the tabs in the foreground (except for the 1s delay before call to releaseLock). Check that if no tab is selected the lock is released.

Reviewers: kamil, inka, bartek

Reviewed By: kamil

Subscribers: ashoat, tomek

Differential Revision: https://phab.comm.dev/D11113

Details

Provenance
Michal Gniadek <michal.gniadek@swmansion.com>Authored on Feb 19 2024, 6:55 AM
Reviewer
kamil
Differential Revision
D11113: [web] Introduce useWebLock
Parents
rCOMM025145fc8b16: Revert "[native] Temporary changes for staff release"
Branches
Unknown
Tags
Unknown

Event Timeline

Michal Gniadek <michal.gniadek@swmansion.com> committed rCOMMdd05e9d5fb55: [web] Introduce useWebLock (authored by Michal Gniadek <michal.gniadek@swmansion.com>).Mar 4 2024, 7:13 AM