Elixir:通过某些操作重启GenServer

时间:2017-03-21 10:34:15

标签: erlang elixir otp

我们说我有GenServer个实例:

defmodule MyModule do
  use GenServer

  def init(_) do
   {:ok, %{}}
  end

#...
end

我希望MyModule受到监督,但是当它崩溃时,在崩溃前以状态重新启动之前做一些事情:

defmodule MyModule do
  use GenServer

  def init(_) do
   {:ok, %{}}
  end

 def init(:restart, previous_state) do
   some_func(previous_state)
   {:ok, previous_state}
 end

#...
end

但我不确定如何实现这个

1 个答案:

答案 0 :(得分:1)

我记得戴夫托马斯的书中描述过这一点。我们的想法是让另一个过程保留国家的复制品。此过程有一项任务:跟踪对状态的更改。这应该可以防止它崩溃(如果原始进程通知观察者状态更改,则表示它在应用更改时没有崩溃)。

然后,当原始进程崩溃并重新启动时,它只能从备份进程中获取先前的状态(它应该从主管获取该进程的PID)。

def start_link(backup_pid) do
   GenServer.start_link(__MODULE__, backup_pid)
end  

def init(backup_pid) do
  state = Backup.get_state(backup_pid)
  {:ok, state}
end

def terminate(_reason, state) do
  Backup.save_state(state)
end