iT邦幫忙

2024 iThome 鐵人賽

DAY 15
0

要把 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

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 元。

可以看到在關閉之後,他又立刻重開了


上一篇
14 GenServer 生命循環
系列文
Elixir 多工 : Processes 與 OTP15
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言