Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 如何在GenServer中获取异步失败的通知?_Elixir_Gen Server - Fatal编程技术网

Elixir 如何在GenServer中获取异步失败的通知?

Elixir 如何在GenServer中获取异步失败的通知?,elixir,gen-server,Elixir,Gen Server,在elixirGenServer中,有同步和异步方法、handle\u cast和handle\u call。在异步情况下,如果方法失败,我如何获得通知 方法失败意味着在handle\u调用方法中,我需要定义一些逻辑来查询/写入数据库。如果数据库操作失败,我需要通知调用方此失败。在异步方法中,我如何才能做到这一点呢?因此,鼓励您“任其自然”的评论通常是正确的。惯用的Erlang和Elixir要求“快速失败”,并允许主管重新启动崩溃的组件 也就是说,有时撞车是不合适的;通常情况下,当你知道负面结果

在elixir
GenServer
中,有同步和异步方法、
handle\u cast
handle\u call
。在异步情况下,如果方法失败,我如何获得通知


方法失败意味着在
handle\u调用
方法中,我需要定义一些逻辑来查询/写入数据库。如果数据库操作失败,我需要通知调用方此失败。在异步方法中,我如何才能做到这一点呢?

因此,鼓励您“任其自然”的评论通常是正确的。惯用的Erlang和Elixir要求“快速失败”,并允许主管重新启动崩溃的组件

也就是说,有时撞车是不合适的;通常情况下,当你知道负面结果可能发生时。标准库中的许多API通过返回结果元组来处理此问题,即
{:ok,result}
{:error,reason}
,并使调用代码负责崩溃或尝试其他操作

在您的用例中,我认为您应该使用数据从进程调用数据库写/查询代码,而不使用异步方法,首先修复数据库性能。如果这确实是一个长期运行的查询,并且优化数据库不是正确的答案,那么您的下一个最佳选择是
任务
模块(),它是Elixir标准库的一部分-它为异步任务执行提供了内置功能

我知道人们不回答你的问题是多么令人沮丧,所以我会回答;但请注意,这几乎肯定不是解决原始问题的正确方法

关键的细节是将调用进程的pid传递给工作进程,以便它可以稍后发送结果消息:

defmodule CastBackExampleWorker do
  use GenServer
  # ...
  def do_operation(args) do
    caller = self()
    ref = make_ref()
    # Pass the caller's pid to the GenServer so that it can message back later
    GenServer.cast(__MODULE__, {:do_operation, caller, ref, args})
    # hand back a unique ref for this request
    ref
  end

  # ...

  def handle_cast({:do_operation, caller, ref, args}, state) do
    case execute_operation(args) do
      {:ok, result} -> send(caller, {__MODULE__, ref, {:ok, result}})
      {:error, reason} -> send(caller, {__MODULE__, ref, {:error, reason}})
    end
    {:noreply, state}
  end
end

defmodule CastBackExampleClient do
  use GenServer
  # ...
  def handle_call(:my_real_work, _from, state) do
    # ignoring the ref, but we could stick it into our state for later...
    _ref = CastBackExampleWorker.do_operation([])
    {:reply, :ok, state}
  end

  def handle_info({CastBackExampleWorker, _ref, outcome}, state) do
    # Do something with the outcome here
    {:noreply, state}  
  end
end

有没有办法检查该流程的PID?也许这是一个解决办法。我不太清楚你所说的“当方法失败时”是什么意思。您是否正在考虑导致整个GenServer崩溃的故障情况?恐怕你需要更具体一点。@PawełDawczak谢谢,我已经更新了我的问题。让它消失吧。DB故障是导致死亡的合理原因。如何在异步函数中捕获此故障?