1. Prompt
Several same-origin tabs may refresh an IndexedDB cache and synchronize with the server at once. Design a coordinator that lets at most one context synchronize while others wait, skip, or recheck after release. Cover tab closure, network errors, and browsers without Web Locks.
2. Constraints and clarifications
- A lock name is shared across same-origin windows and workers.
- A lock protects only the asynchronous callback’s coordination scope; it is not a database transaction or server-side concurrency control.
- Synchronization may take time, so it needs cancellation, retries, and a version or result broadcast.
- Distinguish waiting for a lock, probing immediately, and abandoning a request.
3. Core approach
Call navigator.locks.request(name, options, callback) to request a named lock. The lock is released after the callback Promise settles, so the callback must contain the complete read, sync, and state-write flow. A default request queues; ifAvailable: true calls back with null when busy; signal can cancel a request that is still waiting.
The lock manager releases a lock when its owning context terminates, but correctness must not rely only on tab crash cleanup. Sync records should carry a version, lease, or idempotency key, and the server should still validate writes. Other tabs can learn a new version through BroadcastChannel or by rereading IndexedDB.
4. Reference implementation
const LOCK = "shared-cache-sync";
async function runSync(signal) {
return navigator.locks.request(LOCK, { signal }, async (lock) => {
if (!lock) return { status: "busy" };
const current = await readSyncVersion();
if (await isFresh(current)) return { status: "fresh" };
const result = await fetchAndWriteCache({ signal, baseVersion: current });
await publishVersion(result.version);
return { status: "updated", version: result.version };
});
}
async function trySyncWithoutWaiting() {
return navigator.locks.request(
LOCK,
{ ifAvailable: true },
(lock) => lock ? runOneSync() : { status: "busy" },
);
}5. Correctness and failure handling
The lock provides mutual exclusion among same-origin contexts for the named resource; it does not roll back a network request or database write. Reread the version before a conditional update. If the network fails, throw so the lock releases and a later request can retry. Do not store a “we own the lock” boolean outside the callback.
When an AbortSignal cancels a waiting request, callers should distinguish cancellation from business failure. For long waits, show that another tab is synchronizing or skip the work; after release, reread the version to avoid duplicate refreshes. A BroadcastChannel notification is an optimization; IndexedDB or the server remains authoritative.
6. Follow-ups and traps
- Web Locks coordinates same-origin contexts only; it cannot lock another site, a server process, or a database row.
ifAvailabledoes not queue. A busy request receivesnull, which is a normal outcome.steal: truebreaks existing queue semantics and should be limited to explicitly disposable work with version checks.- Without the API, BroadcastChannel plus IndexedDB can provide best-effort coordination, not the same mutual-exclusion guarantee; the server still needs deduplication.
7. Further reading
Compare Web Locks, IndexedDB transactions, Service Worker messages, and BroadcastChannel: locks provide cross-context exclusion, transactions provide single-database atomicity, and channels provide notification. Cross-device or cross-user exclusion belongs on server leases, idempotent APIs, or database constraints.
8. Interview scoring points
Can state the lock scope
The candidate should say that a named lock coordinates same-origin windows and workers, releases when the callback Promise settles, and cannot replace server or database concurrency control.
Can distinguish request modes
They should explain default queuing, immediate ifAvailable probing, and abandoning a wait with AbortSignal.
Can handle crashes and duplicates
They should use versions, idempotency keys, and conditional writes, explaining that tab crash cleanup does not roll back business writes.
Can give an honest fallback
They should provide a BroadcastChannel/IndexedDB best-effort path and state that mutual exclusion is weaker while server safeguards remain mandatory.