Elixir:通过某些操作重新启动 GenServer
Elixir: restart GenServer with certain action
假设我有 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
但我不确定如何实现这个
我记得这在 Dave Thomas 的书中有描述。这个想法是有另一个进程来保存状态的副本。这个过程有一个工作:跟踪状态的变化。这应该可以防止它崩溃(如果原始进程将状态更改通知观察者,则意味着它在应用更改时没有崩溃)。
然后,当原始进程崩溃并重新启动时,它可以从备份进程中获取以前的状态(它应该从主管那里获取该进程的 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
假设我有 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
但我不确定如何实现这个
我记得这在 Dave Thomas 的书中有描述。这个想法是有另一个进程来保存状态的副本。这个过程有一个工作:跟踪状态的变化。这应该可以防止它崩溃(如果原始进程将状态更改通知观察者,则意味着它在应用更改时没有崩溃)。
然后,当原始进程崩溃并重新启动时,它可以从备份进程中获取以前的状态(它应该从主管那里获取该进程的 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