Skip to content

Conversation

@kevin-dp
Copy link
Contributor

@kevin-dp kevin-dp commented Jul 3, 2025

This PR addresses the issue raised in #2546 (comment). The crux of the issue is that messages might be processed several times if the SSE connection breaks after processing a message but before receiving the up-to-date message. This is because we only advance the offset when processing the up-to-date message, hence, we would fetch again at the old offset and receive some messages that we already processed.

The fix is easy: we batch SSE messages until we receive up-to-date and only process the messages at that point. The hard part was to write a unit test that reproduces this scenario. After a bit of trial and error i managed to do that by creating a custom fetch wrapper that proxies the SSE response but filters out the first up-to-date message and then forces a refresh of the shapestream at that point.

kevin-dp added 3 commits June 30, 2025 16:32
…pe stream if the SSE connection breaks after processing messages and before receiving the up-to-date message.
@codecov
Copy link

codecov bot commented Jul 3, 2025

Codecov Report

Attention: Patch coverage is 93.75000% with 1 line in your changes missing coverage. Please review.

Project coverage is 79.21%. Comparing base (f6e9eba) to head (7682c12).
Report is 10 commits behind head on main.

✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
packages/typescript-client/src/helpers.ts 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2869      +/-   ##
==========================================
+ Coverage   77.79%   79.21%   +1.41%     
==========================================
  Files         157      157              
  Lines        7495     7523      +28     
  Branches      284      284              
==========================================
+ Hits         5831     5959     +128     
+ Misses       1662     1562     -100     
  Partials        2        2              
Flag Coverage Δ
elixir 78.08% <ø> (+1.24%) ⬆️
elixir-client 73.57% <ø> (ø)
packages/experimental 88.95% <ø> (ø)
packages/react-hooks 86.30% <ø> (ø)
packages/typescript-client 93.15% <93.75%> (+3.78%) ⬆️
packages/y-electric 55.12% <ø> (ø)
postgres-140000 78.28% <ø> (+1.47%) ⬆️
postgres-150000 78.32% <ø> (+1.42%) ⬆️
postgres-170000 78.30% <ø> (+1.37%) ⬆️
sync-service 78.67% <ø> (+1.40%) ⬆️
typescript 85.39% <93.75%> (+2.34%) ⬆️
unit-tests 79.21% <93.75%> (+1.41%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@samwillis samwillis left a comment

Choose a reason for hiding this comment

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

This is great. Thanks @kevin-dp


As an aside I don't like the existing getOffset method that constructs one from the LSN and a _0 suffix. The offset being constructed from an LSN is a backend implementation detail we should not depend on. I think we had this in my original POC as a work around, but we really should replace this by adding the actual offset on the up-to-date message, at least in SSE mode.

cc @KyleAMathews @balegas

edit: filed a bug #2870

@kevin-dp kevin-dp merged commit 7be2fd3 into main Jul 3, 2025
53 of 55 checks passed
@kevin-dp kevin-dp deleted the kevin/sse-buffer-messages branch July 3, 2025 10:09
3dyuval pushed a commit to 3dyuval/electric that referenced this pull request Aug 23, 2025
This PR addresses the issue raised in
electric-sql#2546 (comment).
The crux of the issue is that messages might be processed several times
if the SSE connection breaks after processing a message but before
receiving the up-to-date message. This is because we only advance the
offset when processing the up-to-date message, hence, we would fetch
again at the old offset and receive some messages that we already
processed.

The fix is easy: we batch SSE messages until we receive up-to-date and
only process the messages at that point. The hard part was to write a
unit test that reproduces this scenario. After a bit of trial and error
i managed to do that by creating a custom fetch wrapper that proxies the
SSE response but filters out the first up-to-date message and then
forces a refresh of the shapestream at that point.
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.

3 participants