Erlang gen_server如何在另一个节点上启动gen_server?

时间:2012-09-12 17:38:06

标签: erlang nodes distributed otp gen-server

我有一个Erlang应用程序,它需要一点资源,以便留在一个节点上。我正在使gen_servers从一个进程转移到另一个进程 - 事实证明它相对容易。我处于最后一个障碍:获取创建这些gen_servers的工厂进程以在远程节点而不是本地节点上生成它们。 start_link的默认行为显然只在本地启动,但我没有看到任何改变它的选项。

似乎我必须要有创造力的解决方案,并希望看看是否有人已经实现了这样的事情并取得了成功。 IOW,推荐的解决方案是什么?

修改

我正在查看通过调用触发的调用链:

gen_server:start_link(?Module, Args, [])

gen_server:START_LINK / 3:

start_link(Mod, Args, Options) ->
    gen:start(?MODULE, link, Mod, Args, Options).

根:启动/ 5:

start(GenMod, LinkP, Mod, Args, Options) ->
    do_spawn(GenMod, LinkP, Mod, Args, Options).

创:do_spawn / 5:

do_spawn(GenMod, link, Mod, Args, Options) ->
    Time = timeout(Options),
    proc_lib:start_link(?MODULE, init_it,
                        [GenMod, self(), self(), Mod, Args, Options], 
                        Time,
                        spawn_opts(Options));

proc_lib:START_LINK / 5:

start_link(M,F,A,Timeout,SpawnOpts) when is_atom(M), is_atom(F), is_list(A) ->
    Pid = ?MODULE:spawn_opt(M, F, A, ensure_link(SpawnOpts)),
    sync_wait(Pid, Timeout).

最终让我们感兴趣的是。有一个匹配的spawn_opt / 4:

spawn_opt(M, F, A, Opts) when is_atom(M), is_atom(F), is_list(A) ->
    ...
    ...

但是,有一个对我有用的东西:

spawn_opt(Node, M, F, A, Opts) when is_atom(M), is_atom(F), is_list(A) ->
    ...
    ...

令我难以置信的是,这并没有暴露出来。我意识到一个粗心的程序员可能会尝试gen_server:start_link一个正好在火星上运行的erlang节点的进程,阻止这个半小时的调用,但当然,这是程序员的了望。我真的坚持修改OTP或编写某种特殊的解决方案吗?

2 个答案:

答案 0 :(得分:5)

我们不直接start_link远程节点上的服务器。为了获得良好的程序结构和简单性,我们在远程节点上启动一个单独的应用程序,并将远程进程的创建委托给在远程应用程序中运行的某个进程。

由于链接到流程主要是为了监督或监控,我们更喜欢与本地主管而不是远程流程进行链接。如果您需要任何远程流程的活动状态,我建议erlang:monitorerlang:demonitor

典型的分布式设置:

Node1
+---------------+                          Node2
| App1          |                          +---------------+
|   Supervisor1 |  Proc Creation Request   | App2          |
|     Processes | -----------------------> |   Supervisor2 |
|     ......    |                          |      |
|     ......    |                          |      | Create Children
|     ......    |       Monitor            |      V
|     ......    | -----------------------> |     Processes |
+---------------+                          |     ......    |
                                           +---------------+

答案 1 :(得分:1)

也许rpc模块可以帮助您。特别是函数async_call