通过Genserver的强制转换方法合并API的响应

时间:2018-04-20 20:23:09

标签: api elixir otp

我试图通过Genserver的cast方法异步调用一个API 10次。有人可以指导我如何收集10 API的响应并合并到一个元组列表中吗?

defmodule DataMonitor.RuleReceiver do
  use GenServer

  require Logger

  alias DataMonitor.{
    ProcessRuleSet
  }

  def init(state) do
    {:ok, state}
  end

  def start_link do
    GenServer.start_link(__MODULE__, [])
  end

  def process_rule_set(receiver_pid, {rule_set, company_id, auth_headers}) do
    GenServer.cast(receiver_pid, {rule_set, company_id, auth_headers})
  end

  def handle_cast({rule_set, company_id, auth_headers}, state) do
    result = ProcessRuleSet.process_rule_set(rule_set, company_id, auth_headers)
    {:noreply, state}
  end

end

发件人/来电者模块

defmodule DataMonitor.RuleSender do
    def perform() do
      Enum.each(rule_sets, fn rule_set ->
        {:ok, pid} = RuleReceiver.start_link()
        RuleReceiver.process_rule_set(pid, {rule_set, company_id, auth_headers})
      end)
    end
end

1 个答案:

答案 0 :(得分:2)

  

尽管GenServer.cast/2 [...]我如何收集回复

你本身不能。转换请求是异步的,并返回无响应。从cast收集数据的唯一方法是引入商店(如Agentets或其他),并直接存储{{1 }}秒。这个解决方案有一个明显的缺点:它的工作流程将不确定,人们可能不会假设所有10个响应都在任何时候处理和存储。也就是说,cast在某些情况下甚至可能会丢失和未经处理,您也没有机会得到通知。我从来没有见过这样的案子,但它被认为是合法的。

因此,在这种特殊情况下,您可能只需使用GenServer.call/2代替cast,并使用Enum.map/2直接在迭代中收集回复:

cast

结果你将有10个元组def perform() do Enum.map(rule_sets, fn rule_set -> {:ok, pid} = RuleReceiver.start_link() {pid, RuleReceiver.process_rule_set_call(...)} end) end 。我不确定在这里创建10个{pid, response}的原因是什么,为什么不使用命名的GenServer来打扰GenServer s,但这显然超出了范围