要把 Bank 加入 Supervisor 底下比較方便的方式是讓我們的 Bank GenServer 開始時註冊在一個名字底下,通常可以直接使用 Module 名稱 (使用 __MODULE__
就可以直接指定目前 module,直接給 Bank
也可以,但之後如果要移動比較方便)
在目前的 start_link 裡加上 name: __MODULE__
def start_link(init_balance) do
IO.puts("啟動中")
GenServer.start_link(__MODULE__, init_balance, name: __MODULE__)
end
Supervisor.start_link
接著使用 Supervisor 來啟動他
Supervisor.start_link([{Bank, 100}], strategy: :one_for_one)
Supervisor.start_link
的第一個變數是這個 supervisor 的 children list,目前只有一個,可以直接給註冊的名字( Bank
) 或是註冊名與起始值組成的 tuple,我們使用後者( {Bank, 100}
)
strategy 選項可以讓我們決定要如何監督底下的 children,目前使用的 :one_for_one
效果為:如果其中一個 child 結束了,重新啟動他。另外還有 :one_for_all
:其中一個 child 結束,全部的 children 會被重新啟動,以及 :rest_for_one
:結束的 child 以及比他晚啟動的都會被重新啟動。
來把 process 關閉看看會不會重新啟動
使用 Process.whereis/1
來找出已註冊 process 的 pid
再用 Process.exit/2
來將它關閉
iex(2)> Supervisor.start_link([{Bank, 100}], strategy: :one_for_one)
啟動中
開戶存了 100 元。
{:ok, #PID<0.114.0>}
時間到了,該算利息了
時間到了,該算利息了
iex(3)> pid = Process.whereis(Bank)
#PID<0.115.0>
iex(4)> Process.exit(pid, :exit)
啟動中
true
開戶存了 100 元。
可以看到在關閉之後,他又立刻重開了