我們可以把 process 註冊在 Registry 裡,並用名稱去查詢,解決了 process 重啟後 pid 更換,或是需要動態產生名字但是又要避免動態生成 atom 的問題。
更改 NiceBank application.ex
裡的 start 函式,讓 application 啟動時自動開啟 Registry 而不是先前的產生一個 Bank GenServer
開啟時啟動一個叫 NiceBank.Registry
的 Registry
def start(_type, _args) do
children = [
{Registry, keys: :unique, name: NiceBank.Registry}
]
opts = [strategy: :one_for_one, name: NiceBank.Supervisor]
Supervisor.start_link(children, opts)
end
再把 Bank
模組的 start_link 的 name 選項改用 {:via, Registry, {NiceBank.Registry, name}}
另外再加一個 name 變數讓我們設定
def start_link(name, init_balance) do
IO.puts("啟動以 #{name} 註冊的戶頭。")
GenServer.start_link(__MODULE__, init_balance,
name: {:via, Registry, {NiceBank.Registry, name}}
)
end
用 iex -S mix
執行看看
iex(1)> NiceBank.Bank.start_link("Jack", 1000)
啟動以 Jack 註冊的戶頭。
開戶存了 1000 元。
{:ok, #PID<0.161.0>}
而且可以使用來Registry.lookup/2
得到該 process
iex(2)> Registry.lookup(NiceBank.Registry, "Jack")
[{#PID<0.161.0>, nil}]
但這樣子原本的監督鏈就沒了
下一邊我們要搭配使用 DynamicSupervisor