diff --git a/lib/realtime/tenants.ex b/lib/realtime/tenants.ex index 1e6560222..36c647f85 100644 --- a/lib/realtime/tenants.ex +++ b/lib/realtime/tenants.ex @@ -278,7 +278,7 @@ defmodule Realtime.Tenants do :notify_private_alpha :private_only """ - @spec update_management(String.t(), map()) :: {:ok, Tenant.t()} | {:error, term()} + @spec get_tenant_by_external_id(String.t()) :: Tenant.t() | nil def update_management(tenant_id, attrs) do tenant_id |> Cache.get_tenant_by_external_id() diff --git a/lib/realtime/tenants/connect/start_counters.ex b/lib/realtime/tenants/connect/start_counters.ex index e057bbca4..7b5ac797e 100644 --- a/lib/realtime/tenants/connect/start_counters.ex +++ b/lib/realtime/tenants/connect/start_counters.ex @@ -13,14 +13,16 @@ defmodule Realtime.Tenants.Connect.StartCounters do @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 + with tenant when not is_nil(tenant) <- Cache.get_tenant_by_external_id(tenant_id), + :ok <- start_joins_per_second_counter(tenant), + :ok <- start_max_events_counter(tenant), + :ok <- start_db_events_counter(tenant) do + {:ok, acc} + else + nil -> {:error, "Tenant not found"} + {:error, reason} -> {:error, reason} end - - {:ok, acc} end def start_joins_per_second_counter(tenant) do @@ -28,14 +30,21 @@ defmodule Realtime.Tenants.Connect.StartCounters do 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} - } - ) + res = + RateCounter.new(id, + idle_shutdown: :infinity, + telemetry: %{ + event_name: [:channel, :joins], + measurements: %{limit: max_joins_per_second}, + metadata: %{tenant: tenant} + } + ) + + case res do + {:ok, _} -> :ok + {:error, {:already_started, _}} -> :ok + {:error, reason} -> {:error, reason} + end end def start_max_events_counter(tenant) do @@ -45,27 +54,41 @@ defmodule Realtime.Tenants.Connect.StartCounters do GenCounter.new(key) - RateCounter.new(key, - idle_shutdown: :infinity, - telemetry: %{ - event_name: [:channel, :events], - measurements: %{limit: max_events_per_second}, - metadata: %{tenant: tenant} - } - ) + res = + RateCounter.new(key, + idle_shutdown: :infinity, + telemetry: %{ + event_name: [:channel, :events], + measurements: %{limit: max_events_per_second}, + metadata: %{tenant: tenant} + } + ) + + case res do + {:ok, _} -> :ok + {:error, {:already_started, _}} -> :ok + {:error, reason} -> {:error, reason} + end 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} - } - ) + res = + RateCounter.new(key, + idle_shutdown: :infinity, + telemetry: %{ + event_name: [:channel, :db_events], + measurements: %{}, + metadata: %{tenant: tenant} + } + ) + + case res do + {:ok, _} -> :ok + {:error, {:already_started, _}} -> :ok + {:error, reason} -> {:error, reason} + end end end diff --git a/lib/realtime_web/controllers/tenant_controller.ex b/lib/realtime_web/controllers/tenant_controller.ex index 334d15801..90deb2d80 100644 --- a/lib/realtime_web/controllers/tenant_controller.ex +++ b/lib/realtime_web/controllers/tenant_controller.ex @@ -288,7 +288,7 @@ defmodule RealtimeWeb.TenantController do Logger.metadata(external_id: tenant_id, project: tenant_id) case Tenants.update_management(tenant_id, attrs) do - {:ok, %Tenant{} = tenant} -> + %Tenant{} = tenant -> render(conn, "show.json", tenant: tenant) {:error, :tenant_not_found} -> diff --git a/lib/realtime_web/router.ex b/lib/realtime_web/router.ex index ae0094d26..da165e265 100644 --- a/lib/realtime_web/router.ex +++ b/lib/realtime_web/router.ex @@ -90,9 +90,9 @@ defmodule RealtimeWeb.Router do pipe_through(:api) resources("/tenants", TenantController, param: "tenant_id", except: [:edit, :new]) - patch("/tenants/:tenant_id", TenantController, :patch) post("/tenants/:tenant_id/reload", TenantController, :reload) get("/tenants/:tenant_id/health", TenantController, :health) + patch("/tenants/:tenant_id/management", TenantController, :patch) end scope "/api", RealtimeWeb do diff --git a/lib/realtime_web/views/tenant_view.ex b/lib/realtime_web/views/tenant_view.ex index 4f151b507..bb0e5f299 100644 --- a/lib/realtime_web/views/tenant_view.ex +++ b/lib/realtime_web/views/tenant_view.ex @@ -24,7 +24,8 @@ defmodule RealtimeWeb.TenantView do max_events_per_second: tenant.max_events_per_second, max_joins_per_second: tenant.max_joins_per_second, inserted_at: tenant.inserted_at, - extensions: tenant.extensions + extensions: tenant.extensions, + private_only: tenant.private_only } end end diff --git a/mix.exs b/mix.exs index d43a18ed9..9bbd3d14a 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule Realtime.MixProject do def project do [ app: :realtime, - version: "2.33.21", + version: "2.33.22", elixir: "~> 1.16.0", elixirc_paths: elixirc_paths(Mix.env()), start_permanent: Mix.env() == :prod, diff --git a/test/realtime/tenants/authorization_test.exs b/test/realtime/tenants/authorization_test.exs index 98f5ab36b..1288852a1 100644 --- a/test/realtime/tenants/authorization_test.exs +++ b/test/realtime/tenants/authorization_test.exs @@ -150,6 +150,8 @@ defmodule Realtime.Tenants.AuthorizationTest do role: claims.role }) + Realtime.Tenants.Connect.CreatePartitions.run(%{db_conn_pid: db_conn}) + on_exit(fn -> Process.exit(db_conn, :normal) end) %{ diff --git a/test/realtime_web/controllers/tenant_controller_test.exs b/test/realtime_web/controllers/tenant_controller_test.exs index 09da9a527..267fbc621 100644 --- a/test/realtime_web/controllers/tenant_controller_test.exs +++ b/test/realtime_web/controllers/tenant_controller_test.exs @@ -300,15 +300,20 @@ defmodule RealtimeWeb.TenantControllerTest do "private_only" => true } - conn = patch(conn, Routes.tenant_path(conn, :patch, tenant.external_id, tenant: attrs)) + conn = patch(conn, Routes.tenant_path(conn, :patch, tenant.external_id), attrs) data = json_response(conn, 200)["data"] + assert data["max_concurrent_users"] == 300 + assert data["max_channels_per_client"] == 150 + assert data["max_events_per_second"] == 250 + assert data["max_joins_per_second"] == 50 + assert data["private_only"] == true - tenant = Tenants.Cache.get_tenant_by_external_id(tenant.external_id) + tenant = Tenants.get_tenant_by_external_id(tenant.external_id) assert tenant.max_concurrent_users == 300 assert tenant.max_channels_per_client == 150 assert tenant.max_events_per_second == 250 assert tenant.max_joins_per_second == 50 - assert tenant.private_only == false + assert tenant.private_only == true end end end