Function 如何从Elixir GenServer处理程序中调用其他函数?
我有一个GenServer,它实现单个项目的功能,例如:Function 如何从Elixir GenServer处理程序中调用其他函数?,function,erlang,elixir,otp,gen-server,Function,Erlang,Elixir,Otp,Gen Server,我有一个GenServer,它实现单个项目的功能,例如: def handle_call({:sync, id}, _from, state) do ## update data {:reply, data, sync} end 现在我想为多个ID处理此功能,例如: def handle_call({:sync_all, ids}, _from, state) do ## call sync for each id data = Enum.map(ids, fn
def handle_call({:sync, id}, _from, state) do
## update data
{:reply, data, sync}
end
现在我想为多个ID处理此功能,例如:
def handle_call({:sync_all, ids}, _from, state) do
## call sync for each id
data = Enum.map(ids, fn(id) ->
GenServer.call(self(), {:sync, id})
end)
## Further reduce down data to stats
{:reply, data, sync}
end
但是,如果告诉我进程试图调用自己,那么这是无效的
我认为这一定是由于调用的阻塞性质造成的。但是,如果在sync\u all
版本中使用cast
,也会发生同样的情况
所以我的问题是:如何从handle\u call
或handle\u cast
函数中调用其他GenServer
任务?在这种情况下,您通常会做的是将公共逻辑提取到一个单独的函数中:
def handle_call({:sync, id}, _from, state) do
{data, state} = do_sync(id, state)
{:reply, data, state}
end
def handle_call({:sync_all, ids}, _from, state) do
{data, state} = Enum.map_reduce(ids, state, &do_sync/2)
{:reply, data, state}
end
defp do_sync(id, state) do
# do something
{data, new_state}
end
在这种情况下,您通常会将通用逻辑提取到单独的函数:
def handle_call({:sync, id}, _from, state) do
{data, state} = do_sync(id, state)
{:reply, data, state}
end
def handle_call({:sync_all, ids}, _from, state) do
{data, state} = Enum.map_reduce(ids, state, &do_sync/2)
{:reply, data, state}
end
defp do_sync(id, state) do
# do something
{data, new_state}
end
对同一进程进行GenServer调用没有多大意义。一个进程一次处理一条消息。电话将等待应答。但是,在处理完当前消息之前,进程无法应答。您拥有的代码将在等待应答时超时,因为该进程永远不会处理当前消息,因此也永远不会处理随呼叫发送的消息
通常,可以使用强制转换和调用为其他进程定义一个接口,以便向该进程发送消息。您可以将实际数据转换建模为纯函数,然后根据需要从两个处理程序函数中的每一个调用这些函数。对同一进程进行GenServer调用没有多大意义。一个进程一次处理一条消息。电话将等待应答。但是,在处理完当前消息之前,进程无法应答。您拥有的代码将在等待应答时超时,因为该进程永远不会处理当前消息,因此也永远不会处理随呼叫发送的消息
通常,可以使用强制转换和调用为其他进程定义一个接口,以便向该进程发送消息。您可以将实际的数据转换建模为纯函数,然后根据需要从两个处理程序函数中的每一个调用这些函数。cast
应该在handle\u call
中工作。你能发布代码的版本吗?该版本可以做到这一点,但对你不起作用。cast
应该在handle\u call
中起作用。你能发布代码的版本吗?它可以做到这一点,但不适合你?