From cfa9a1c331c0f4912107434b185d3f9157044638 Mon Sep 17 00:00:00 2001 From: Arjun Satarkar Date: Sun, 28 Jul 2024 19:58:49 +0530 Subject: Discord activity: add per-instance room limit We send all rooms for that instance to the client every few, seconds, so we shouldn't let the number grow without bound. --- lib/mediasync/http_errors.ex | 2 +- lib/mediasync/room.ex | 53 +++++++++++++++++++++++++++++++------------- lib/mediasync/router.ex | 32 +++++++++++++++----------- 3 files changed, 58 insertions(+), 29 deletions(-) diff --git a/lib/mediasync/http_errors.ex b/lib/mediasync/http_errors.ex index 5df85fd..30e3b58 100644 --- a/lib/mediasync/http_errors.ex +++ b/lib/mediasync/http_errors.ex @@ -99,7 +99,7 @@ defmodule Mediasync.HTTPErrors do conn |> put_json_content_type() - |> send_resp(400, Jason.encode!(error)) + |> send_resp(400, Jason.encode!(error, pretty: true)) end @bad_gateway Jason.encode!(%{"error" => "badGateway"}, pretty: true) diff --git a/lib/mediasync/room.ex b/lib/mediasync/room.ex index 6386893..f518220 100644 --- a/lib/mediasync/room.ex +++ b/lib/mediasync/room.ex @@ -51,12 +51,12 @@ defmodule Mediasync.Room do _ -> state end - Tuple.append( - GenServer.start_link(__MODULE__, state, - name: {:via, Registry, {Mediasync.RoomRegistry, state.room_id}} - ), - state.room_id - ) + case GenServer.start_link(__MODULE__, state, + name: {:via, Registry, {Mediasync.RoomRegistry, state.room_id}} + ) do + {:ok, pid} -> {:ok, pid, state.room_id} + {:error, reason} -> {:error, reason} + end end @spec get_video_info(GenServer.server()) :: Mediasync.Room.VideoInfo.t() @@ -93,22 +93,45 @@ defmodule Mediasync.Room do end @inactive_check_wait_milliseconds 10 * 1000 + @discord_activity_instance_rooms_max 20 @impl true @spec init(Mediasync.Room.State.t()) :: {:ok, Mediasync.Room.State.t()} def init(state = %Mediasync.Room.State{}) do - if state.discord_instance_id do - Registry.register(Mediasync.DiscordActivityInstanceRegistry, state.discord_instance_id, %{ - host_username: state.host_username, - room_id: state.room_id - }) - end + discord_activity_ok? = + if state.discord_instance_id do + instance_room_count = + Registry.count_match( + Mediasync.DiscordActivityInstanceRegistry, + state.discord_instance_id, + :_ + ) + + if instance_room_count < @discord_activity_instance_rooms_max do + Registry.register( + Mediasync.DiscordActivityInstanceRegistry, + state.discord_instance_id, + %{ + host_username: state.host_username, + room_id: state.room_id + } + ) + + true + else + false + end + end - Process.send_after(self(), :check_if_active, @inactive_check_wait_milliseconds) + if discord_activity_ok? != false do + Process.send_after(self(), :check_if_active, @inactive_check_wait_milliseconds) - Logger.info("Created room #{state.room_id}") + Logger.info("Created room #{state.room_id}") - {:ok, state} + {:ok, state} + else + {:stop, :discord_activity_instance_max_rooms_reached} + end end @impl true diff --git a/lib/mediasync/router.ex b/lib/mediasync/router.ex index c60ca8a..2a80882 100644 --- a/lib/mediasync/router.ex +++ b/lib/mediasync/router.ex @@ -85,19 +85,25 @@ defmodule Mediasync.Router do {"", nil, nil} end - {:ok, _pid, room_id} = - DynamicSupervisor.start_child( - Mediasync.RoomSupervisor, - {Mediasync.Room, - %Mediasync.Room.State{ - video_info: video_info, - host_user_token_hash: get_user_token_hash!(conn), - host_username: host_username, - discord_instance_id: instance_id - }} - ) - - redirect(conn, status: 303, location: "/room/#{room_id}#{suffix}") + case DynamicSupervisor.start_child( + Mediasync.RoomSupervisor, + {Mediasync.Room, + %Mediasync.Room.State{ + video_info: video_info, + host_user_token_hash: get_user_token_hash!(conn), + host_username: host_username, + discord_instance_id: instance_id + }} + ) do + {:ok, _pid, room_id} -> + redirect(conn, status: 303, location: "/room/#{room_id}#{suffix}") + + {:error, :discord_activity_instance_max_rooms_reached} -> + Mediasync.HTTPErrors.send_bad_request( + conn, + message: "Cannot host more rooms in this activity instance." + ) + end end end -- cgit v1.2.3-57-g22cb