这取决于。如果你只是每个节点启动一个GenServer
过程中,你可以这样调用它:
@doc """
If you want to call the server only from the current module.
"""
def local_call(message) do
GenServer.call(__MODULE__, message)
end
或
@doc """
If you want to call the server from another node on the network.
"""
def remote_call(message, server \\ nil) do
server = if server == nil, do: node(), else: server
GenServer.call({__MODULE__, server}, message)
end
如果从同一模块的几个过程,你需要额外的标识(例如,如果你有一个主管策略:simple_one_for_one
按需生成GenServer
)。
类似的东西我会建议使用:
:gproc
命名过程。
:ets
如果您需要额外信息来识别您的流程。
:gproc
很棒,它可以与GenServer
一起使用。您通常使用atom作为注册名称来命名您的进程。 :gproc
允许你用一个任意的名字命名你的进程,例如一个元组。
比方说,在我的函数调用中,我有一个像{:id, id :: term}
这样的服务器的复杂标识符,例如id
可以是一个字符串。我可以开始我的GenServer
,如:
defmodule MyServer do
use GenServer
def start_link(id) do
name = {:n, :l, {:id, id}}
GenServer.start_link(__MODULE__, %{}, name: {:via, :gproc, name})
end
(...)
end
而且比原子不同的东西看看我的过程,就像我之前说的,例如一个字符串。所以,如果我启动我的服务器,如:
MyServer.start_link("My Random Hash")
而且我有这样一个功能:
def f(id, message) do
improved_call(id, message)
end
defp improved_call(id, message, timeout \\ 5000) do
name = {:n, :l, {:id, id}}
case :gproc.where(name) do
undefined -> :error
pid -> GenServer.call(pid, message, timeout)
end
你可以用它来调用类似的过程:
MyServer.f("My Random Hash", {:message, "Hello"})
如果您的命名过程更复杂的是,您可以使用:ets
来存储更复杂的状态。
如果你想使用:gproc
你可以把它添加到您的mix.exs
文件,如:
(...)
defp deps do
[{:gproc, github: "uwiger/gproc"}]
end
(...)
在一个侧面说明,永远,永远调用从handle_call/3
内GenServer.call/3
。它会超时并在您的其他GenServer.call
上执行DOS。 handle_call/3
当时处理一条消息。
就像Onorio所说,你可以使用GenServer.call(self,request)。看看: http://elixir-lang.org/getting-started/processes.html 或小药剂和OTP指南,如果你想深入了解进程和OTP平台。 –
@Onorio为什么它不是一个好主意? – user3790827
@ user3790827我没有说这不是一个好主意。我说我不确定这是最好的方式。由于你的问题几乎没有背景,所以很难说。 –