我的 GenServer 中有以下功能:
def add_event(param1, param2) do
Enum.each(:pg2.get_members("some_group"), fn pid -> GenServer.cast(pid, {:new_event, param1, param2}) end)
end
def handle_cast({:new_event, param1, param2}, state) do
#do something
{:noreply, state}
end
我的想法是,每当调用 add_event
时,我想将此请求传递给其他节点中组的所有成员。我的问题是,直接在公共(public) api 内进行转换是个好主意还是在 handle_cast
回调内进行转换更好
最佳答案
在 Process
中进行调度(而不是在客户端 api 中),意味着这些优点和缺点:
优点:
- 真正的异步行为:由于分派(dispatch)是在服务器端的
进程
内进行的,因此您不会在分派(dispatch)完成后等待,因为GenServer
继续工作。 - 主管:您可以使用 Supervisor监督调度员。
- 在调度程序中保持状态,例如指示:最常调用的
pid
、什么类型的事件
使用比较频繁,在调度中添加一些逻辑..
缺点:
- 您创建了两个
handle_cast
而不是一个:一个用于调度,另一个用于实际执行工作。更多行代码 -> 你会失去可读性 - 您的一些进程将专门用于调度,另一些进程将专门用于完成这项工作..但所有这些进程都将来自同一个 genserver。 您有一个
GenServer
用于两种进程 - 专门用于分派(dispatch)作业的进程可能不需要维护状态。
- 您不能根据流程类型使用不同的主管策略..因为它们来自相同的
GenServer
如果我必须选择:我会在“客户端 api”端进行调度,因为它是一个更简单的模式。如果我需要维护 GenServer
的 call
和 cast
的状态,我会创建第二个专用于该状态的状态。
关于Elixir GenServer 转换到其他节点的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52363985/