如何从Elixir GenServer处理程序中调用其他函数?

Tho*_*ser 1 erlang function elixir erlang-otp gen-server

我有一个实现单个项目功能的GenServer,例如:

def handle_call({:sync, id}, _from, state) do
    ## update data
    {:reply, data, sync}
end
Run Code Online (Sandbox Code Playgroud)

现在我想为多个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
Run Code Online (Sandbox Code Playgroud)

然而,这并不能告诉我该过程试图调用自己.

我认为这必然是由于阻塞性质call.如果我castsync_all版本中使用,则会发生相同的情况.

所以我的问题是:如何GenServer从一个handle_call或一个handle_cast函数中调用其他任务?

mic*_*ala 7

在这种情况下,您通常会将共同逻辑提取到单独的函数中:

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
Run Code Online (Sandbox Code Playgroud)