gpt4 book ai didi

erlang - 处理 gen_server 状态的清理

转载 作者:行者123 更新时间:2023-12-02 02:09:46 25 4
gpt4 key购买 nike

我有一个正在运行的gen_server,每当它正常停止或意外崩溃时,它都必须清理其状态。清理工作主要是删除一些文件。

此时,当gen_server崩溃或正常停止时,清理工作在terminate/2中完成。

如果 gen_server 崩溃,是否有任何原因导致 terminate/2 不会被调用?

如果 gen_server 意外终止,监视 gen_server 的任何其他进程是否应该等待进行清理?

所以,代码是这样的:

terminate(normal, State) ->
% Invoked when the process stops
% Clean up the mess
terminate(Error, State) ->
% Invoked when the process crashes
% Clean up the mess
<小时/>

编辑:我在官方邮件列表中找到了这封电子邮件,其中讨论的是同一件事:

http://groups.google.com/group/erlang-programming/browse_thread/thread/9a1ba2d974775ce8

正如 Adam 在下面所说,如果我们想避免捕获 gen_server 中的存在,我们可以使用不同的方法。

但是如果我们捕获存在,terminate/2 似乎是进行清理的安全位置,因为它总是会被调用。此外,当 'EXIT' 被发送到 terminate/2handle_call/3 时,我们必须正确处理,试图在工作人员和工作人员之间正确传播错误。主管。

最佳答案

terminate/2gen_server 内部发生崩溃时被调用,即使它没有捕获退出,如果它收到“EXIT”,也不会被调用来自链接到它的其他进程,如果您需要清理,那么它应该捕获退出(使用 process_flag(trap_exit, true))。

这种行为有点不幸,因为它使得为 gen_server 进程编写可靠的关闭过程变得困难。另外,仅仅为了能够运行 terminate/2 而捕获退出也不是一个好习惯,因为您可能会捕获许多其他错误,从而使调试系统变得更加困难。

我会考虑三种选择:

  1. 在进程的下一个实例启动时处理剩余文件(例如,在 init/1 中)
  2. 陷阱退出,清理文件,然后以同样的原因再次崩溃
  3. 有一个监视 gen_server 的第三个进程,其唯一目的是清理文件

选项 1 可能是最好的选择,因为至少代码不会捕获退出并且您可以免费获得持久状态。由于上述原因,选项 2 不太好,它可以隐藏和掩盖其他错误。 3 很困惑,因为在 gen_server 再次启动之前清理过程可能尚未完成。

仔细考虑一下为什么要进行清理,以及是否真的必须在进程崩溃时进行清理(毕竟这是一个错误)。请小心,不要最终进行过多的防御性编程。

关于erlang - 处理 gen_server 状态的清理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5119107/

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