electric-sql / electric-sql/pglite
OnLeaderChange triggers two times in a row
- Dominant language
- TypeScript
- Stars
- 16k
- Forks
- 442
- Avg merge
- 20h 19m
- Merged PRs (30d)
- 7
Description
I’m building on the Linearlite demo to wire up Electric sync with PGlite.
When the browser-tab leader changes, sync dies with: Leader changed, pending operation in indeterminate state (LeaderChangedError)
Repro steps on https://linearlite.examples.electric-sql.com/
1. Open the demo twice → two tabs (Tab A, Tab B)
2. Tab A becomes the initial leader.
3. Refresh Tab A.
4. Tab B is elected leader, with these logs in the console:
```
Leader changed, isLeader: true
Leader changed, isLeader: true
Uncaught (in promise) Ore: Leader changed, pending operation in indeterminate state
```
From my understanding, onLeaderChange is started two times.
The first time sync is started, which runs this query: pg.query('SELECT 1 FROM issue LIMIT 1').
The second onLeaderChange kills running queries by throwing LeaderChangedError: https://github.com/electric-sql/pglite/blob/665389967336c8f29636077e9a6de77365b14d6d/packages/pglite/src/worker/index.ts#L239
Why does onLeaderChange fire twice ? Is there a way to prevent that ?
To prevent the error, I added a sleep for 100ms to be sure onLeaderChange has correctly been triggered two times before proceeding with sync:
```ts
export async function startSync(pg: PGliteWithExtensions, options?: SyncOptions) {
// It seems that when leader changes, leader change is triggered 2 times in a row
// The running queries in pg are canceled with a reject, which stops the sync
// For now, we are waiting for 100ms to avoid this
// error: "Leader changed, pending operation in indeterminate state"
await new Promise((resolve) => setTimeout(resolve, 100))
const syncResult = await startSyncToDatabase(pg, options)
return syncResult
}
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.