背景:
我想在erlang集群中启动一个全局唯一的gen_server进程。如果该进程停止或运行它的节点关闭,则应在其他节点上启动该进程。
该进程是监管器的一部分。问题是,在第二个节点上启动监管器失败,因为gen_server已经在第一个节点上进行全局注册了。
问题:
- 在gen_server的start_link函数内检查该进程是否已经进行全局注册并在这种情况下返回已运行进程的{ok,Pid},而不是启动新的gen_server实例,这样做可以吗?
- 如果使用上述方法,那么这样一来,一个进程将成为多个监管器的一部分,如果某个进程出现故障,则所有其他节点上的所有监管器都会尝试重新启动该进程。第一个监管器将创建一个新的gen_server进程,并且其他监管器将再次链接到该进程。
- 我是否应该在gen_server的start_link函数中使用
global:trans()
?
示例代码:
start_link() ->
global:trans({?MODULE, ?MODULE}, fun() ->
case gen_server:start_link({global, ?MODULE}, ?MODULE, [], []) of
{ok, Pid} ->
{ok, Pid};
{error, {already_started, Pid}} ->
link(Pid),
{ok, Pid};
Else -> Else
end
end).