Skip to content

Don't block disconnect on pending checkpoint requests - #491

Merged
simolus3 merged 1 commit into
powersync-ja:mainfrom
RaphaelFakhri:fix-request-checkpoint-disconnect
Oct 22, 2026
Merged

simolus3 merged 1 commit into
powersync-ja:mainfrom
RaphaelFakhri:fix-request-checkpoint-disconnect

Conversation

@RaphaelFakhri

Copy link
Copy Markdown
Contributor

Closes #483.

ConnectionManager.requestCheckpoint() held syncConnectMutex while waiting for the service to respond, and StreamingSyncImplementation.requestCheckpoint() ran the request under an AbortController that nothing aborted. If the service accepted the request but never answered, disconnect(), disconnectAndClear() and close() waited on the mutex until the service came back.

This implements the first suggested fix from the issue:

  • ConnectionManager.requestCheckpoint() only holds syncConnectMutex to read the active sync client, and awaits the request after releasing it.
  • StreamingSyncImplementation.requestCheckpoint() ties the request to the abort controller of the active sync iteration. Disconnecting aborts both the wait for the checkpoint seed and the sync/checkpoint-request call. The pending requestCheckpoint() fails with the existing CheckpointRequestException ("sync client is disconnected").

The API additions from the issue (an abortTrigger on requestCheckpoint() and an abort signal for postCheckpointRequest) are left for a separate change.

Testing

The new test disconnect aborts pending requests in test/sync/in_memory_sync_test.dart stalls the mock sync/checkpoint-request handler, calls requestCheckpoint(), and expects disconnect() to complete within 5 seconds and the request to fail with disconnected. It fails on main with TimeoutException and passes with this change (JSON and BSON variants).

dart test -p vm passes, except for upload_test.dart, which is flaky on main as well. dart format and dart analyze --fatal-infos --fatal-warnings are clean.

@simolus3 simolus3 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the checkpoint request is tied to the current abort signal, I feel comfortable with the sync client being used outside of the mutex.

Thanks for the contribution 👍

@simolus3
simolus3 merged commit 4eed9aa into powersync-ja:main Oct 22, 2026
6 checks passed
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.

requestCheckpoint() can't be aborted and holds syncConnectMutex, so disconnect(), disconnectAndClear() and close() hang while the service stalls

2 participants