-
-
Notifications
You must be signed in to change notification settings - Fork 401
fix: scope postgres cdc syn registry #1594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -71,6 +71,7 @@ broadcast_pool_size = Env.get_integer("BROADCAST_POOL_SIZE", 10) | |
| pubsub_adapter = System.get_env("PUBSUB_ADAPTER", "gen_rpc") |> String.to_atom() | ||
| websocket_max_heap_size = div(Env.get_integer("WEBSOCKET_MAX_HEAP_SIZE", 50_000_000), :erlang.system_info(:wordsize)) | ||
| users_scope_shards = Env.get_integer("USERS_SCOPE_SHARDS", 5) | ||
| postgres_cdc_scope_shards = Env.get_integer("POSTGRES_CDC_SCOPE_SHARDS", 5) | ||
|
Comment on lines
73
to
+74
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you think we should document this as part of the README? |
||
| regional_broadcasting = Env.get_boolean("REGIONAL_BROADCASTING", false) | ||
|
|
||
| no_channel_timeout_in_ms = | ||
|
|
@@ -130,6 +131,7 @@ config :realtime, | |
| pubsub_adapter: pubsub_adapter, | ||
| broadcast_pool_size: broadcast_pool_size, | ||
| users_scope_shards: users_scope_shards, | ||
| postgres_cdc_scope_shards: postgres_cdc_scope_shards, | ||
| regional_broadcasting: regional_broadcasting | ||
|
|
||
| if config_env() != :test && run_janitor? do | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| defmodule Realtime.Syn.PostgresCdc do | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. :nitpick: Should this be scoped (no pun intended) like this
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I want to do something similar for Connect so probably will keep them all together so we can abstract more syn stuff |
||
| @moduledoc """ | ||
| Scope for the PostgresCdc module. | ||
| """ | ||
|
|
||
| @doc """ | ||
| Returns the scope for a given tenant id. | ||
| """ | ||
| @spec scope(String.t()) :: atom() | ||
| def scope(tenant_id) do | ||
| shards = Application.fetch_env!(:realtime, :postgres_cdc_scope_shards) | ||
| shard = :erlang.phash2(tenant_id, shards) | ||
| :"realtime_postgres_cdc_#{shard}" | ||
| end | ||
|
|
||
| def scopes() do | ||
| shards = Application.fetch_env!(:realtime, :postgres_cdc_scope_shards) | ||
| Enum.map(0..(shards - 1), fn shard -> :"realtime_postgres_cdc_#{shard}" end) | ||
| end | ||
|
|
||
| def syn_topic_prefix(), do: "realtime_postgres_cdc_" | ||
| def syn_topic(tenant_id), do: "#{syn_topic_prefix()}#{tenant_id}" | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,9 +3,9 @@ defmodule Realtime.SynHandler do | |
| Custom defined Syn's callbacks | ||
| """ | ||
| require Logger | ||
| alias Extensions.PostgresCdcRls | ||
| alias RealtimeWeb.Endpoint | ||
| alias Realtime.Syn.PostgresCdc | ||
| alias Realtime.Tenants.Connect | ||
| alias RealtimeWeb.Endpoint | ||
|
|
||
| @behaviour :syn_event_handler | ||
|
|
||
|
|
@@ -15,12 +15,17 @@ defmodule Realtime.SynHandler do | |
| Endpoint.local_broadcast(Connect.syn_topic(tenant_id), "ready", %{pid: pid, conn: conn}) | ||
| end | ||
|
|
||
| def on_registry_process_updated(PostgresCdcRls, tenant_id, _pid, meta, _reason) do | ||
| # Update that the CdCRls connection is ready | ||
| Endpoint.local_broadcast(PostgresCdcRls.syn_topic(tenant_id), "ready", meta) | ||
| end | ||
| def on_registry_process_updated(scope, tenant_id, _pid, meta, _reason) do | ||
| scope = Atom.to_string(scope) | ||
|
|
||
| def on_registry_process_updated(_scope, _name, _pid, _meta, _reason), do: :ok | ||
| case scope do | ||
| "realtime_postgres_cdc_" <> _ -> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. :nitpick: What if we keep this as part of the Syn module you created and not expose the prefix here? @postgres_cdc_scope_prefix Realtime.Syn.PostgresCdc.scope_prefix
case scope do
@postgres_cdc_scope_prefix <> _ ->
...
|
||
| Endpoint.local_broadcast(PostgresCdc.syn_topic(tenant_id), "ready", meta) | ||
|
|
||
| _ -> | ||
| :ok | ||
| end | ||
| end | ||
|
|
||
| @doc """ | ||
| When processes registered with :syn are unregistered, either manually or by stopping, this | ||
|
|
@@ -31,14 +36,20 @@ defmodule Realtime.SynHandler do | |
| We want to log conflict resolutions to know when more than one process on the cluster | ||
| was started, and subsequently stopped because :syn handled the conflict. | ||
| """ | ||
| @postgres_cdc_scope_prefix PostgresCdc.syn_topic_prefix() | ||
| @impl true | ||
| def on_process_unregistered(mod, name, pid, _meta, reason) do | ||
| if reason == :syn_conflict_resolution do | ||
| log("#{mod} terminated due to syn conflict resolution: #{inspect(name)} #{inspect(pid)}") | ||
| def on_process_unregistered(scope, name, pid, _meta, reason) do | ||
| case Atom.to_string(scope) do | ||
| @postgres_cdc_scope_prefix <> _ = scope -> | ||
| Endpoint.local_broadcast(PostgresCdc.syn_topic(name), scope <> "_down", %{pid: pid, reason: reason}) | ||
|
|
||
| _ -> | ||
| topic = topic(scope) | ||
| Endpoint.local_broadcast(topic <> ":" <> name, topic <> "_down", %{pid: pid, reason: reason}) | ||
| end | ||
|
|
||
| topic = topic(mod) | ||
| Endpoint.local_broadcast(topic <> ":" <> name, topic <> "_down", %{pid: pid, reason: reason}) | ||
| if reason == :syn_conflict_resolution, | ||
| do: log("#{scope} terminated due to syn conflict resolution: #{inspect(name)} #{inspect(pid)}") | ||
|
|
||
| :ok | ||
| end | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔 I think the description is wrong here