像Player进程那样增长TableServer表明桌子进程git
增长TableSupervisor监控TableServer。使用同一个Registry,所以名字也改为LocalRegistry了。数据结构
所以Registry的启动代码,以及原来PlayerServer的register_name要作稍微修改。ide
固然你也可使用2个不一样的Registry,但恐怕就要增长一个RegstrySupervisor 去start_child了,函数
又或者手动启动2个(更加不建议)。测试
新的game_server.exspa
defmodule GameServer do use Application def start(_type, _args) do children = [ {Registry, keys: :unique, name: LocalRegistry}, PlayerSupervisor, TableSupervisor ] Supervisor.start_link(children, strategy: :one_for_one) end end
PlayerServer 的register_name 应该按table_server 那样修改,这样清晰,而且也不会冲突。rest
defmodule TableServer do use GenServer, restart: :temporary, start: {__MODULE__, :start_link, []} def start_link(table) do GenServer.start_link(__MODULE__, table, name: register_name(table)) end def init(table) do {:ok, table} end def register_name(%{} = table), do: register_name(table |> SimpleTable.get_id) def register_name(id), do: {:via, Registry, {LocalRegistry, {Table, id}}} def exist?(table) do key = {Table, table |> SimpleTable.get_id} case Registry.lookup(LocalRegistry, key) do [{_pid, _}] -> true [] -> false end end end
新增了exist? 判断函数,之后会有用吧。code
原则上当玩家建立了一个牌局后,没解散以前不容许再建立(固然你能够改,我只是简化了)server
table_supervisor 测试blog
defmodule TableSupervisorTest do use ExUnit.Case doctest PlayerSupervisor setup do Application.stop(GameServer) Application.start(GameServer) %{} end test "测试TableSupervisor启动TableServer" do table1 = SimpleTable.init |> SimpleTable.set_id(1) table2 = SimpleTable.init |> SimpleTable.set_id(2) assert {:ok, _p1} = TableSupervisor.start_table(table1) assert {:ok, _p2} = TableSupervisor.start_table(table2) assert TableServer.exist?(table1) assert TableServer.exist?(table2) end end
改为使用exist? 了
player_supervisor_test.exs 也照着修改。
编译测试ok。
代码变迁参看git吧。
下回咱们由玩家建立牌局,一步步展开吧。
XXXX,想了下 上句话不对,建立那些跟玩法也没有关系,先放着,直接起牌局玩才对。
XXXXX,上句好像也不对,本质上server进程只是转调用数据结构的操做,所以牌局玩法彻底能够是数据结构的操做先。
因此下回咱们直接操做数据,进行牌局。