fix(sync-service): drop duplicate relation messages before routing#4560
fix(sync-service): drop duplicate relation messages before routing#4560robacourt wants to merge 3 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4560 +/- ##
===========================================
- Coverage 70.96% 58.08% -12.88%
===========================================
Files 83 369 +286
Lines 9856 40459 +30603
Branches 3124 11469 +8345
===========================================
+ Hits 6994 23500 +16506
- Misses 2844 16885 +14041
- Partials 18 74 +56
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
✅ Deploy Preview for electric-next ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Claude Code ReviewSummaryIncremental review (iteration 2). Since the first pass, two commits — What's Working Well
Issues FoundCritical (Must Fix)None. The iteration-1 critical issue is resolved. Important (Should Fix)None. Suggestions (Nice to Have)
|
|
Note This review was generated by Claude on request by @alco. Dropping 1. Retry after
2. Restart with the early-persisted tracker (not fixed by addressing #1 alone)
The stale shapes (select-all shape with old column count, shape on a renamed table, …) are never terminated and keep serving the wrong schema until the next actual schema change. Previously this exact sequence self-healed via the per-shape recheck. Fix Commit the tracker — both in-memory and persisted — only after case Partitions.handle_relation(state.partitions, updated_rel) do
{:ok, partitions} ->
state = %{state | partitions: partitions}
with {:ok, state} <- publish_relation(state, updated_rel, relation_status) do
:ok =
PersistentReplicationState.set_tracked_relations(
tracker_state,
state.persistent_replication_data_opts
)
{:ok, %{state | tracked_relations: tracker_state}}
end
{:error, :connection_not_available} ->
{{:error, :connection_not_available}, state}
endThis makes the failure direction safe: a crash after publish but before persist means the relation re-classifies as Tests Both windows are currently uncovered, and they're exactly where this PR changes recovery semantics:
(For the record: the steady-state optimization itself is sound. Info that's missing from relation messages entirely — nullability etc. — was never detectable by the shape recheck anyway; that's handled by |
141952c to
b96a3a9
Compare
|
Addressed the tracker-ordering review feedback in b96a3a9. Changes:
Reran:
|
Relation messages can be emitted by Postgres when tables autoanalyze and autovacuum. Previously we checked all shapes to see if the Relation message affected them, which scales O(n) with the number of shapes (taking approx 25ms with 20K shapes). This PR checks to see if the Relation message has actually changed, and only checks the shapes if it has, saving that expensive operation.
Summary