![](/img/trans.png)
[英]Is it necessary to check whether pid is alive before using it when it passing as paremeter from handle_call?
[英]Is it necessary to add try do ...catch for every 'handle_call' function?
在erlang
中,如果没有 try catch, handle_call
中的错误 function 会导致 GenServer 崩溃。 当它崩溃时,由于大量的崩溃和重启日志,很难找到问题所在。
我的问题是为什么这么多的 handle_call 还没有try catch
语句? 有什么考虑?
以下代码来自Nx项目stream.ex
文件,仅供学习。
@impl true
def handle_call(:recv, from, {output, waiting, acc, fun}) do
case :queue.out(output) do
{:empty, output} ->
{:noreply, {output, :queue.in(from, waiting), acc, fun}}
{{:value, data}, output} ->
{:reply, {:ok, data}, {output, waiting, acc, fun}}
end
end
@impl true
def handle_call(:done, _from, {output, waiting, acc, fun}) do
if :queue.is_empty(output) do
for from <- :queue.to_list(waiting) do
GenServer.reply(from, :done)
end
{:stop, :normal, {:ok, acc}, {output, waiting, acc, fun}}
else
{:reply, :recv_pending, {output, waiting, acc, fun}}
end
end
在 Elixir 中,使用try
并不常见,大多数时候您实际上是想让它崩溃,而不是阻止它。 处理崩溃是监督树的工作,而不是恢复崩溃过程。 这篇文章应该有所帮助。
我认为Joe Armstrong 的论文(2003 年)的这段摘录也很有趣,它解释了 Erlang 错误处理和“让它崩溃”背后的哲学:
- 进程是错误封装的单位 [...]
- 流程做他们应该做的事情或尽快失败
- 远程进程可以检测到失败和失败的原因
- 进程不共享 state,但通过消息传递进行通信
另外,我认为您在这里混淆了catch
和rescue
: catch
意味着获取由throw
传递的值,而rescue
可以从意外错误中恢复。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.