上章說到咱們要引入syn https://github.com/ostinelli/syn/html
看過文檔,它並無直接提供{via, Module, Name} 相關的方法。咱們須要封裝一下。git
Name暫時能夠用id,若是有須要再調整github
之後有回調需求的話,恰好也能夠作在那個模塊裏。app
在player_server_manager項目裏增長{:syn, "1.4.0"} 運行命令獲取依賴socket
修改application 方法,增長依賴分佈式
def application do [applications: [:logger, :syn], mod: {PlayerServerManager, []}] end
而後在項目裏增長PlayerRegistry模塊測試
defmodule PlayerRegistry do def register_name(name, pid) when is_pid(pid) do case :syn.register(name, pid) do :ok -> :yes _ -> :no end end def unregister_name(name) do :syn.unregister(name) :ok end def whereis_name(name) do :syn.find_by_key(name) end def send(name, msg) do case whereis_name(name) do :undefined -> exit({:badarg, {name, msg}}) pid -> Kernel.send pid, msg pid end end end
參照:global 模塊實現。spa
修改PlayerServer.start_link 以下rest
def via_tuple(id), do: {:via, PlayerRegistry, id} def start_link(player) do GenServer.start_link(__MODULE__, %{player: player, socket: nil}, name: via_tuple(player.base_info.id)) end
PlayerServerManager.start 修改,增長syn的初始化,code
def start(_type, _args) do import Supervisor.Spec, warn: false :syn.init() children = [ # Define workers and child supervisors to be supervised worker(PlayerServer, [], restart: :temporary), ] # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html # for other strategies and supported options opts = [strategy: :simple_one_for_one, name: PlayerServerManager.Supervisor] Supervisor.start_link(children, opts) end
PlayerServerManagerTest增長測試代碼
test "player_registry", %{player: player} do assert {:ok, pid} = PlayerServerManager.start_player_server(player) assert PlayerServer.gem(PlayerServer.via_tuple(player.base_info.id)) == 0 end
測試成功,ok。目前看起來還好。分佈式的註冊以及衝突處理留待之後再作測試了。
寫到這,發現via_tuple要能接受player和id2種參數更好,方便點。