Skip to content

Fire join notifications for new groups during initial sync#16

Merged
twinn merged 2 commits intomainfrom
fix/sync-join-notifications
Apr 13, 2026
Merged

Fire join notifications for new groups during initial sync#16
twinn merged 2 commits intomainfrom
fix/sync-join-notifications

Conversation

@twinn
Copy link
Copy Markdown
Owner

@twinn twinn commented Apr 13, 2026

Summary

Fixes sync paths to fire monitor notifications for membership changes that arrive via the initial :sync exchange or re-sync after reconnection.

Previously, sync_groups and sync_one_group silently updated ETS without notifying monitor subscribers. This meant processes using PgRegistry.monitor/2 were not informed of members that registered on a peer before the local scope discovered that peer.

The suppression was based on a misunderstanding about ambiguity in diffing entries during re-sync. Since each entry carries a unique {pid, tag} pair, joins and leaves can be unambiguously identified.

Changes

  • sync_groups: fire :join notifications for new groups from a peer (the {nil, _} branch — entirely new group, no diff ambiguity)
  • sync_one_group: diff entries by {pid, tag}, fire :join for new entries and :leave for removed entries

Motivation

Discovered while integrating PgRegistry into PartitionedEts for cluster membership with per-node metadata. When a new node joins and registers a table, existing nodes receive the entry via :sync (not via the {:join, ...} broadcast, which races with the discover/sync exchange). Without this fix, existing nodes never receive the :join monitor event and never run handoff for the new node.

Test plan

  • mix format --check-formatted
  • mix credo --strict — no issues
  • 13 doctests + 151 tests, 0 failures
  • 4 new cluster tests:
    • Monitor receives :join for entries arriving via initial sync
    • Monitor receives :join when a late-joining peer has pre-existing entries
    • sync_one_group fires :join when a known peer adds entries to an existing group
    • Existing tests unchanged and passing

When a new peer syncs its entries for the first time, groups that
have no previous remote entries are unambiguous joins. Fire :join
notifications for these so monitor subscribers are notified of all
cluster members, not just those that register after the initial
sync exchange completes.

The existing sync_one_group path (re-sync of known groups) still
skips notifications due to the multi-join ambiguity documented in
the code.
@twinn twinn force-pushed the fix/sync-join-notifications branch from 070fb0c to bb97cf9 Compare April 13, 2026 16:21
Previously, sync_groups and sync_one_group silently updated ETS
without firing monitor notifications. This meant subscribers were
not notified of membership changes that arrived via the initial
sync exchange or via re-sync after a netsplit.

The suppression was based on a misunderstanding about ambiguity in
diffing entries. Since each entry has a unique {pid, tag} pair,
joins and leaves can be unambiguously identified during sync.

Changes:
- sync_groups: fire :join for new groups from a peer
- sync_one_group: fire :join/:leave by diffing {pid, tag} sets
- Bump version to 0.4.1
@twinn twinn force-pushed the fix/sync-join-notifications branch from bb97cf9 to 104914f Compare April 13, 2026 16:31
@twinn twinn merged commit 53db153 into main Apr 13, 2026
3 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.

1 participant