Skip to content

Instantly share code, notes, and snippets.

@andrewhao
Last active July 1, 2025 06:55
Show Gist options
  • Select an option

  • Save andrewhao/c90f3d12cc92c0356f7d2d7173289071 to your computer and use it in GitHub Desktop.

Select an option

Save andrewhao/c90f3d12cc92c0356f7d2d7173289071 to your computer and use it in GitHub Desktop.

Revisions

  1. andrewhao revised this gist Jan 11, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion player_supervised.ex
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@ defmodule Player do
    # Insert this start_link/2 method, which intercepts the extra `[]`
    # argument from the Supervisor and molds it back to correct form.
    def start_link([], {player_name, game_id}) do
    start_link(player_name, game_id)
    start_link({player_name, game_id})
    end

    def start_link({player_name, game_id}) do
  2. andrewhao revised this gist Jan 11, 2018. 4 changed files with 38 additions and 3 deletions.
    2 changes: 1 addition & 1 deletion game.ex
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,7 @@ defmodule Game do

    def handle_call({:add_player, player_name}, _from, %{game_id: game_id} = state) do
    # Uh oh, we started this process but it's not under supervision!
    start_status = Player.start_link(player_name, game_id)
    start_status = Player.start_link({player_name, game_id})
    {:reply, start_status, state}
    end
    end
    2 changes: 1 addition & 1 deletion player.ex
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,7 @@ defmodule Player do
    {:ok, %{name: player_name, game_id: game_id}}
    end

    def start_link(player_name, game_id) do
    def start_link({player_name, game_id}) do
    GenServer.start_link(
    __MODULE__,
    {player_name, game_id},
    35 changes: 35 additions & 0 deletions player_dynamic_supervisor.ex
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,35 @@
    defmodule PlayerDynamicSupervisor do
    use DynamicSupervisor

    def start_link(_arg) do
    DynamicSupervisor.start_link(__MODULE__, :ok, name: __MODULE__)
    end

    def init(:ok) do
    DynamicSupervisor.init(strategy: :one_for_one)
    end

    # Start a Player process and add it to supervision
    def add_player(player_name, game_id) do
    # Note that start_child now directly takes in a child_spec.
    child_spec = {Player, {player_name, game_id}}
    # Equivalent to:
    # child_spec = Player.child_spec({player_name, game_id})
    DynamicSupervisor.start_child(__MODULE__, child_spec)
    end

    # Terminate a Player process and remove it from supervision
    def remove_player(player_pid) do
    DynamicSupervisor.terminate_child(__MODULE__, player_pid)
    end

    # Nice utility method to check which processes are under supervision
    def children do
    DynamicSupervisor.which_children(__MODULE__)
    end

    # Nice utility method to check which processes are under supervision
    def count_children do
    DynamicSupervisor.count_children(__MODULE__)
    end
    end
    2 changes: 1 addition & 1 deletion player_supervised.ex
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,7 @@ defmodule Player do
    start_link(player_name, game_id)
    end

    def start_link(player_name, game_id) do
    def start_link({player_name, game_id}) do
    # Original implementation...
    end

  3. andrewhao revised this gist Jan 11, 2018. 1 changed file with 0 additions and 8 deletions.
    8 changes: 0 additions & 8 deletions game.ex
    Original file line number Diff line number Diff line change
    @@ -13,14 +13,6 @@ defmodule Game do
    GenServer.call(pid, {:add_player, player_name})
    end

    def get(pid) do
    GenServer.call(pid, :get)
    end

    def handle_call(:get, _from, state) do
    {:reply, {:ok, state}, state}
    end

    def handle_call({:add_player, player_name}, _from, %{game_id: game_id} = state) do
    # Uh oh, we started this process but it's not under supervision!
    start_status = Player.start_link(player_name, game_id)
  4. andrewhao revised this gist Jan 11, 2018. 2 changed files with 10 additions and 25 deletions.
    23 changes: 1 addition & 22 deletions game_supervised.ex
    Original file line number Diff line number Diff line change
    @@ -1,26 +1,5 @@
    defmodule SupervisedGame do
    use GenServer

    def init(game_id) do
    {:ok, %{game_id: game_id}}
    end

    def start_link(game_id) do
    GenServer.start_link(__MODULE__, game_id, name: {:global, "game:#{game_id}"})
    end

    def add_player(pid, player_name) do
    GenServer.call(pid, {:add_player, player_name})
    end

    def get(pid) do
    GenServer.call(pid, :get)
    end

    def handle_call(:get, _from, state) do
    {:reply, {:ok, state}, state}
    end

    # ...
    def handle_call({:add_player, player_name}, _from, %{game_id: game_id} = state) do
    # Now we replace this with supervised management
    start_status = PlayerSupervisor.add_player(player_name, game_id)
    12 changes: 9 additions & 3 deletions player_supervisor.ex
    Original file line number Diff line number Diff line change
    @@ -10,8 +10,9 @@ defmodule PlayerSupervisor do
    end

    # Start a Player process and add it to supervision
    def add_player(player_pid) do
    Supervisor.start_child(__MODULE__, player_pid)
    def add_player(player_name, game_id) do
    # Note that the second arg to start_child/2 must be an Enumerable
    Supervisor.start_child(__MODULE__, [{player_name, game_id}])
    end

    # Terminate a Player process and remove it from supervision
    @@ -20,7 +21,12 @@ defmodule PlayerSupervisor do
    end

    # Nice utility method to check which processes are under supervision
    def child_pids do
    def children do
    Supervisor.which_children(__MODULE__)
    end

    # Nice utility method to check which processes are under supervision
    def count_children do
    Supervisor.count_children(__MODULE__)
    end
    end
  5. andrewhao created this gist Jan 11, 2018.
    29 changes: 29 additions & 0 deletions game.ex
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,29 @@
    defmodule Game do
    use GenServer

    def init(game_id) do
    {:ok, %{game_id: game_id}}
    end

    def start_link(game_id) do
    GenServer.start_link(__MODULE__, game_id, name: {:global, "game:#{game_id}"})
    end

    def add_player(pid, player_name) do
    GenServer.call(pid, {:add_player, player_name})
    end

    def get(pid) do
    GenServer.call(pid, :get)
    end

    def handle_call(:get, _from, state) do
    {:reply, {:ok, state}, state}
    end

    def handle_call({:add_player, player_name}, _from, %{game_id: game_id} = state) do
    # Uh oh, we started this process but it's not under supervision!
    start_status = Player.start_link(player_name, game_id)
    {:reply, start_status, state}
    end
    end
    29 changes: 29 additions & 0 deletions game_supervised.ex
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,29 @@
    defmodule SupervisedGame do
    use GenServer

    def init(game_id) do
    {:ok, %{game_id: game_id}}
    end

    def start_link(game_id) do
    GenServer.start_link(__MODULE__, game_id, name: {:global, "game:#{game_id}"})
    end

    def add_player(pid, player_name) do
    GenServer.call(pid, {:add_player, player_name})
    end

    def get(pid) do
    GenServer.call(pid, :get)
    end

    def handle_call(:get, _from, state) do
    {:reply, {:ok, state}, state}
    end

    def handle_call({:add_player, player_name}, _from, %{game_id: game_id} = state) do
    # Now we replace this with supervised management
    start_status = PlayerSupervisor.add_player(player_name, game_id)
    {:reply, start_status, state}
    end
    end
    23 changes: 23 additions & 0 deletions player.ex
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,23 @@
    defmodule Player do
    use GenServer

    def init({player_name, game_id}) do
    {:ok, %{name: player_name, game_id: game_id}}
    end

    def start_link(player_name, game_id) do
    GenServer.start_link(
    __MODULE__,
    {player_name, game_id},
    name: {:global, "player:#{player_name}"}
    )
    end

    def get(pid) do
    GenServer.call(pid, :get)
    end

    def handle_call(:get, _from, state) do
    {:reply, {:ok, state}, state}
    end
    end
    15 changes: 15 additions & 0 deletions player_supervised.ex
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,15 @@
    defmodule Player do
    # ...

    # Insert this start_link/2 method, which intercepts the extra `[]`
    # argument from the Supervisor and molds it back to correct form.
    def start_link([], {player_name, game_id}) do
    start_link(player_name, game_id)
    end

    def start_link(player_name, game_id) do
    # Original implementation...
    end

    # ...
    end
    26 changes: 26 additions & 0 deletions player_supervisor.ex
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,26 @@
    defmodule PlayerSupervisor do
    use Supervisor

    def start_link([]) do
    Supervisor.start_link(__MODULE__, :ok, name: __MODULE__)
    end

    def init(:ok) do
    Supervisor.init([Player], strategy: :simple_one_for_one)
    end

    # Start a Player process and add it to supervision
    def add_player(player_pid) do
    Supervisor.start_child(__MODULE__, player_pid)
    end

    # Terminate a Player process and remove it from supervision
    def remove_player(player_pid) do
    Supervisor.terminate_child(__MODULE__, player_pid)
    end

    # Nice utility method to check which processes are under supervision
    def child_pids do
    Supervisor.which_children(__MODULE__)
    end
    end