我的电脑上有两个节点(
foo@my-pc
和bar@my-pc
)。bar
节点中有一个简单的生成服务器:
defmodule Bar.Server do
use ExActor.GenServer, export: :bar_server
defstart start_link, do: initial_state(0)
defcall get, state: state, do: reply(state)
defcast(set(num), state: state, do: new_state(state + num))
end
Genserver 已启动并运行 所以当我跑步时:
GenServer.call(:bar_server, :get)
它完美地工作了。
我通过在 foo
foo
中运行将
bar
连接到
Node.connect :'bar@my-pc'
foo
将熟悉:aa
中的genserverbar
,GenServer.call(:bar_server, :get)
我明白:
(EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
我假设我错过了一些东西。但可以弄清楚是什么。
假设您只想在两个节点之间运行 GenServer 的单个实例,则需要将 GenServer 显式注册为全局:
use ExActor.GenServer, export: {:global, :bar_server}
要与此进程通信,请使用相同的名称:
GenServer.call({:global, :bar_server}, :get)
除了
:global
之外,还有一些其他选项可以跨节点注册 GenServer 名称。有关详细信息,请参阅 GenServer 文档的名称注册部分。
您注册一个进程以使其成为单例:使其可用作唯一实例。
如果你给它命名为“name: processname”,那么你就不能在该节点上注册另一个同名的进程。
如果您需要多个进程,那么您可以使用主管来获取该进程的子进程,使用它并要求主管在完成后终止子进程。
此设计模式将帮助您通过主管管理子进程,以防子进程崩溃。
我还是个新手,所以我不确定它是否会起作用,但我认为你应该简单地从 foo 的 bar 上生成一个执行 GenServer.call() 的进程。由于它是在 bar 上执行的,因此它会找到 GenServer 并能够执行调用,然后将回复返回给 foo。 我的答案基于此链接:https://hexdocs.pm/elixir/1.16/distributed-tasks.html
所以只需在 foo@my-pc 上运行:
Node.spawn_link(:"foo@my-pc", fn -> GenServer.call(:bar_server, :get) end)