-
-
Notifications
You must be signed in to change notification settings - Fork 317
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Adds plug like logic to Connect (#1174)
Add Plug like logic to Connect so we can pipe operations of the Connect operation to ensure we guarantee full operation of all features Co-authored-by: Wojtek Mach <[email protected]>
- Loading branch information
1 parent
c1b39dd
commit 75d2aea
Showing
14 changed files
with
323 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
defmodule Realtime.Tenants.Connect.CheckConnection do | ||
@moduledoc """ | ||
Check tenant database connection. | ||
""" | ||
alias Realtime.Database | ||
alias Realtime.Tenants.Cache | ||
|
||
@application_name "realtime_connect" | ||
@behaviour Realtime.Tenants.Connect.Piper | ||
|
||
@impl true | ||
def run(acc) do | ||
%{tenant_id: tenant_id} = acc | ||
tenant = Cache.get_tenant_by_external_id(tenant_id) | ||
|
||
case Database.check_tenant_connection(tenant, @application_name) do | ||
{:ok, conn} -> | ||
{:ok, %{acc | db_conn_pid: conn, db_conn_reference: Process.monitor(conn)}} | ||
|
||
{:error, error} -> | ||
{:error, error} | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
defmodule Realtime.Tenants.Connect.GetTenant do | ||
@moduledoc """ | ||
Get tenant database connection. | ||
""" | ||
|
||
alias Realtime.Api.Tenant | ||
alias Realtime.Tenants | ||
@behaviour Realtime.Tenants.Connect.Piper | ||
|
||
@impl Realtime.Tenants.Connect.Piper | ||
def run(acc) do | ||
%{tenant_id: tenant_id} = acc | ||
|
||
case Tenants.Cache.get_tenant_by_external_id(tenant_id) do | ||
%Tenant{} -> {:ok, acc} | ||
_ -> {:error, :tenant_not_found} | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
defmodule Realtime.Tenants.Connect.Migrations do | ||
@moduledoc """ | ||
Migrations for the Tenants.Connect process. | ||
""" | ||
@behaviour Realtime.Tenants.Connect.Piper | ||
alias Realtime.Tenants.Migrations | ||
alias Realtime.Tenants.Cache | ||
@impl true | ||
def run(acc) do | ||
%{tenant_id: tenant_id} = acc | ||
tenant = Cache.get_tenant_by_external_id(tenant_id) | ||
[%{settings: settings} | _] = tenant.extensions | ||
migrations = %Migrations{tenant_external_id: tenant.external_id, settings: settings} | ||
|
||
case Migrations.run_migrations(migrations) do | ||
:ok -> {:ok, acc} | ||
{:error, error} -> {:error, error} | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
defmodule Realtime.Tenants.Connect.Piper do | ||
@moduledoc """ | ||
Pipes different commands to execute specific actions during the connection process. | ||
""" | ||
@callback run(any()) :: {:ok, any()} | {:error, any()} | ||
|
||
def run(pipers, init) do | ||
Enum.reduce_while(pipers, {:ok, init}, fn piper, {:ok, acc} -> | ||
case piper.run(acc) do | ||
{:ok, result} -> | ||
{:cont, {:ok, result}} | ||
|
||
{:error, error} -> | ||
{:halt, {:error, error}} | ||
|
||
_e -> | ||
raise ArgumentError, "must return {:ok, _} or {:error, _}" | ||
end | ||
end) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
defmodule Realtime.Tenants.Connect.RegisterProcess do | ||
@moduledoc """ | ||
Registers the database process in :syn | ||
""" | ||
|
||
@behaviour Realtime.Tenants.Connect.Piper | ||
|
||
@impl true | ||
def run(acc) do | ||
%{tenant_id: tenant_id, db_conn_pid: conn} = acc | ||
|
||
case :syn.update_registry(Realtime.Tenants.Connect, tenant_id, fn _pid, meta -> | ||
%{meta | conn: conn} | ||
end) do | ||
{:ok, _} -> {:ok, acc} | ||
{:error, error} -> {:error, error} | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
defmodule Realtime.Tenants.Connect.StartCounters do | ||
@moduledoc """ | ||
Start tenant counters. | ||
""" | ||
|
||
alias Realtime.GenCounter | ||
alias Realtime.RateCounter | ||
alias Realtime.Tenants | ||
alias Realtime.Tenants.Cache | ||
|
||
@behaviour Realtime.Tenants.Connect.Piper | ||
|
||
@impl true | ||
def run(acc) do | ||
%{tenant_id: tenant_id} = acc | ||
tenant = Cache.get_tenant_by_external_id(tenant_id) | ||
|
||
with {:ok, _} <- start_joins_per_second_counter(tenant), | ||
{:ok, _} <- start_max_events_counter(tenant), | ||
{:ok, _} <- start_db_events_counter(tenant) do | ||
end | ||
|
||
{:ok, acc} | ||
end | ||
|
||
def start_joins_per_second_counter(tenant) do | ||
%{max_joins_per_second: max_joins_per_second} = tenant | ||
id = Tenants.joins_per_second_key(tenant) | ||
GenCounter.new(id) | ||
|
||
RateCounter.new(id, | ||
idle_shutdown: :infinity, | ||
telemetry: %{ | ||
event_name: [:channel, :joins], | ||
measurements: %{limit: max_joins_per_second}, | ||
metadata: %{tenant: tenant} | ||
} | ||
) | ||
end | ||
|
||
def start_max_events_counter(tenant) do | ||
%{max_events_per_second: max_events_per_second} = tenant | ||
|
||
key = Tenants.events_per_second_key(tenant) | ||
|
||
GenCounter.new(key) | ||
|
||
RateCounter.new(key, | ||
idle_shutdown: :infinity, | ||
telemetry: %{ | ||
event_name: [:channel, :events], | ||
measurements: %{limit: max_events_per_second}, | ||
metadata: %{tenant: tenant} | ||
} | ||
) | ||
end | ||
|
||
def start_db_events_counter(tenant) do | ||
key = Tenants.db_events_per_second_key(tenant) | ||
GenCounter.new(key) | ||
|
||
RateCounter.new(key, | ||
idle_shutdown: :infinity, | ||
telemetry: %{ | ||
event_name: [:channel, :db_events], | ||
measurements: %{}, | ||
metadata: %{tenant: tenant} | ||
} | ||
) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
defmodule Realtime.Tenants.Connect.StartReplication do | ||
@moduledoc """ | ||
Starts BroadcastChanges replication slot. | ||
""" | ||
|
||
@behaviour Realtime.Tenants.Connect.Piper | ||
alias Realtime.BroadcastChanges.Handler | ||
alias Realtime.Tenants.Cache | ||
@impl true | ||
def run(acc) do | ||
%{tenant_id: tenant_id} = acc | ||
tenant = Cache.get_tenant_by_external_id(tenant_id) | ||
|
||
if tenant.notify_private_alpha do | ||
opts = %Handler{tenant_id: tenant_id} | ||
supervisor_spec = Handler.supervisor_spec(tenant) | ||
|
||
child_spec = %{ | ||
id: Handler, | ||
start: {Handler, :start_link, [opts]}, | ||
restart: :transient, | ||
type: :worker | ||
} | ||
|
||
case DynamicSupervisor.start_child(supervisor_spec, child_spec) do | ||
{:ok, pid} -> {:ok, Map.put(acc, :broadcast_changes_pid, pid)} | ||
{:error, {:already_started, pid}} -> {:ok, Map.put(acc, :broadcast_changes_pid, pid)} | ||
error -> {:error, error} | ||
end | ||
else | ||
{:ok, acc} | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.