gpt4 book ai didi

elixir - 如何在 GenServer 中获得有关异步失败的通知?

转载 作者:行者123 更新时间:2023-12-04 16:06:11 37 4
gpt4 key购买 nike

在elixir GenServer中,有sync和async方法,handle_casthandle_call。在异步情况下,如果该方法失败,我如何获得通知?

方法失败意味着在handle_call 方法中,我需要定义一些逻辑来查询/写入数据库。如果数据库操作失败,我需要将此失败通知调用者。在异步方法中,我该怎么做?

最佳答案

因此,鼓励您“让它死去”的评论通常是正确的。惯用的 Erlang 和 Elixir 呼吁“快速失败”,并让主管重启任何崩溃的组件。

也就是说,有时崩溃是不合适的;通常是在您知道可能会出现负面结果时。标准库中的许多 API 通过返回结果元组来处理此问题,即 {:ok, result}{:error, reason} 并使其由调用代码负责崩溃或尝试其他方法。

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

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

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

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

关于elixir - 如何在 GenServer 中获得有关异步失败的通知?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48727296/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com