Skip to content

Upgrade pg_registry from 0.2.2 to 0.4#1

Merged
twinn merged 10 commits intomainfrom
upgrade-pg-registry-0.4
Apr 10, 2026
Merged

Upgrade pg_registry from 0.2.2 to 0.4#1
twinn merged 10 commits intomainfrom
upgrade-pg-registry-0.4

Conversation

@twinn
Copy link
Copy Markdown
Owner

@twinn twinn commented Apr 10, 2026

Summary

  • Upgrades pg_registry dependency from ~> 0.2.2 to ~> 0.4
  • Replaces Erlang :pg scope with a PgRegistry-managed :stagehand scope
  • Producers and cron now register explicitly via PgRegistry.register/3 in init instead of :via tuples
  • Producers use local Registry names for consumer subscription addressing
  • Replaces :pg.monitor/2 with PgRegistry.monitor/2 for cluster join/leave events
  • Replaces removed get_members/2 with lookup/2 (extracts pids from [{pid, value}])

Test plan

  • mix test — 82 tests, 0 failures

twinn added 10 commits April 10, 2026 12:14
PgRegistry 0.3+ replaced the Erlang :pg backend with a self-contained
Elixir port. This migrates stagehand off the old API:

- Replace :pg scope with a PgRegistry :stagehand scope
- Use PgRegistry.register/3 in init instead of :via tuples for cluster
  group membership (producers and cron)
- Use local Registry names for producer addressing (consumer subscription)
- Replace :pg.monitor with PgRegistry.monitor/2 for join/leave events
- Replace get_members/2 with lookup/2 (returns [{pid, value}])
- Update tests for new API shapes
Follow the Elixir convention of module-style atoms for named processes
(e.g. MyApp.Registry, MyApp.PubSub).
- Replace manual leader election in Cron with Highlander, which
  ensures a single cron process runs cluster-wide via :global
- Remove cron's PgRegistry dependency entirely
- Register cron in the local Registry for addressability
- Rename PgRegistry scope from Stagehand.PgRegistry to
  Stagehand.ProducerRegistry since it is now only used for
  producer cluster discovery
Move PgRegistry scope startup from Stagehand.Supervisor (with
idempotent case/match) to a proper Application module. The scope
is now started once when the :stagehand application boots.
Producers are discovered cluster-wide via PgRegistry and addressed by
pid (consumer subscribes via self(), router uses producers_for_queue).
The local Registry name was unused. Producer still accepts an optional
name: for direct unit tests.
Cron doesn't need a local name — it's a Highlander singleton found
through :global. Test helper walks the Highlander supervision tree
to find the cron pid.
Rendezvous (HRW) hashing needs only the member list and a key —
no separate ring structure to build and maintain. The implementation
is a single Enum.max_by over :erlang.phash2({node, key}).

Removes the libring dependency.
A pid's internal representation differs between the local node
(where it shows as <0.N.C>) and remote nodes (where the first
element is a node-specific identifier). Hashing on node(pid)
ensures all nodes in the cluster compute the same winner for a
given key.
@twinn twinn merged commit 973e2ce into main Apr 10, 2026
1 check 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