Skip to content

New checkpoint request protocol - #97

Open
LucDeCaf wants to merge 11 commits into
mainfrom
checkpoint-requests
Open

New checkpoint request protocol#97
LucDeCaf wants to merge 11 commits into
mainfrom
checkpoint-requests

Conversation

@LucDeCaf

@LucDeCaf LucDeCaf commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Implements the new Checkpoint Requests protocol for .NET, using the other SDKs as reference (mostly JS and Kotlin).

This PR also includes a internal refactor to the StreamingSyncImplementation class, which shifts it closer to the Kotlin SDK's implementation rather than JavaScript's.

Justification: While C# syntax looks a lot like JavaScript syntax, C#/.NET acts a lot more like Kotlin/Java internally. The new implementation takes better advantage of C#'s Task model and is generally cleaner/easier to reason about.

Note that this uses strings for the checkpoint request ID despite C# having a fast, native 64-bit integer type. This is mostly for consistency with other internal APIs and to avoid any accidental public API changes, but I'd like to use longs for IDs in v1.

AI Usage

I used Claude Code to assist with the StreamingSyncImplementation refactor and with porting tests/test utils from Kotlin/JS to C#. I reviewed the changes manually.

@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.

I wanted to leave a few early comments in case it helps. As far as the public API is concerned this looks good to me.

Comment thread PowerSync/PowerSync.Common/Client/Sync/Bucket/SqliteBucketStorage.cs Outdated

internal class CheckpointStateSignals
{
private CheckpointState _state = new CheckpointState.Pending();

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.

It looks like this might not be thread-safe. It's annoying that there is no MutableStateFlow-equivalent, but maybe the Mutex-based implementation from Swift could be easier to port?


public Task WaitForCheckpointRequestsReady(CancellationToken signal, bool wakeDownloadLoop = true)
{
var tcs = new TaskCompletionSource<bool>();

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.

The main reason for this layer of indication in JavaScript was that we otherwise can't cancel waiting for status updates.

ChannelReader does not have that issue, is it possible to structure this method like (pseudo-C#):

var reader = _stateBroadcaster.Subscribe(out var subscriberId);

try {
  if (HandleState(_state)) return;

  while (!HandleState(reader.WaitToReadAsync(signal))) {}
} finally {
  // ... also remove this from HandleState
  _stateBroadcaster.Unsubscribe(subscriberId);
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

For some reason I thought WaitToReadAsync(CancellationToken) wasn't available on netstandard2.0 (it is). Probably getting it confused with another cancellable Stream method.

Comment thread PowerSync/PowerSync.Common/Client/Sync/CheckpointRequest.cs
@LucDeCaf LucDeCaf added the Product Visibility Contains user-facing updates that may need to be documented and/or announced label Sep 2, 2026
…dard2.0 runtime features, use manual locking in CheckpointStateSignals
@LucDeCaf
LucDeCaf marked this pull request as ready for review September 3, 2026 09:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Product Visibility Contains user-facing updates that may need to be documented and/or announced

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants