有一种方法:在
:load
cast
,返回结果
long_process
作为新的国家。然后添加
call
它只返回当前状态(命名为
:get
下面)。由于genserver按消息发送的顺序顺序处理消息,因此
:获取
呼叫将被阻止,直到上一个
:加载
已经完成。
defmodule DistanceMatrix do
use GenServer
def start(id) do
GenServer.start(__MODULE__, id)
end
def load(pid) do
GenServer.cast(pid, {:load})
pid
end
def await(pid), do: GenServer.call(pid, :get)
def init(id), do: {:ok, id}
def handle_call(:get, _, state), do: {:reply, state, state}
def handle_cast({:load}, _state) do
{:noreply, long_process()}
end
def long_process do
:timer.sleep(2000)
%{result: "Process result.."}
end
end
1..10
|> Enum.map(fn id ->
{:ok, pid} = DistanceMatrix.start(id)
pid
end)
|> Enum.map(&DistanceMatrix.load/1)
|> Enum.map(&DistanceMatrix.await/1)
|> Enum.map(fn result ->
IO.inspect(result)
end)
输出:
%{result: "Process result.."}
%{result: "Process result.."}
%{result: "Process result.."}
%{result: "Process result.."}
%{result: "Process result.."}
%{result: "Process result.."}
%{result: "Process result.."}
%{result: "Process result.."}
%{result: "Process result.."}
%{result: "Process result.."}
正如预期的那样,这个程序需要2秒多一点的时间。