Skip to content

fix(worker): register leader-now listener early to prevent race condition#890

Open
kaigritun wants to merge 1 commit intoelectric-sql:mainfrom
kaigritun:fix/worker-leader-race-condition
Open

fix(worker): register leader-now listener early to prevent race condition#890
kaigritun wants to merge 1 commit intoelectric-sql:mainfrom
kaigritun:fix/worker-leader-race-condition

Conversation

@kaigritun
Copy link

Summary

Fixes #850

Problem

There is a race condition in PGliteWorker leader election when the main thread is under heavy load (e.g., during React hydration or complex app initialization).

The leader-now message sent by the worker immediately after ready could be lost because the main thread was still blocked or had not yet attached the message event listener.

This resulted in isLeader remaining false indefinitely, even though the worker successfully acquired the lock and was acting as the leader.

Root Cause

The listener for leader-now was registered after several async operations:

  1. await acquireLock(tabCloseLockId) - yields the main thread
  2. BroadcastChannel setup
  3. Tab channel setup

During this time, the worker could send leader-now before the listener was in place.

Fix

Move the leader-now listener registration to immediately after workerReadyPromise resolves, before any async operations that could yield control.

This ensures the listener is in place before the worker has any chance to send the message.

Testing

  • The fix is logically sound: the listener must be registered before any await that could allow the worker to send the message
  • The original issue reporter provided detailed logs showing the race window was only ~0.4ms, which this fix closes by not having any async gap at all

…tion

Fixes electric-sql#850

The 'leader-now' message from the worker could be lost if the main thread
was still blocked (e.g., awaiting acquireLock) when the message arrived.
This happened because the listener was registered after several async
operations that could yield control.

By moving the listener registration to immediately after the worker
signals it's ready (and before any other async operations), we ensure
the message is never missed, regardless of main thread load.
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.

[BUG]: Race condition in PGliteWorker leader election: 'leader-now' message lost during initialization

1 participant