【问题标题】:Handling the cleanup of the gen_server state处理 gen_server 状态的清理
【发布时间】:2011-07-04 09:30:54
【问题描述】:

我有一个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 试图在工人和主管之间正确传播错误时,我们必须正确处理。

【问题讨论】:

    标签: erlang erlang-otp


    【解决方案1】:

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

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

    我会考虑三个选项:

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

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

    仔细考虑为什么要清理,以及当进程崩溃时是否真的必须这样做(毕竟这是一个错误)。小心不要做太多防御性编程。

    【讨论】:

    • 如果我错了,请纠正我,但即使 gen_server 没有陷阱退出,AFAIK terminate/2 也会被调用。当你的父母崩溃时,需要捕获它们。
    • 我跑了一些测试,terminate/2gen_server崩溃时被调用,那么在什么情况下terminate/2没有被调用?
    • 当你得到另一个进程的退出信号时。
    • 我认为下面的讨论表明它需要成为一个社区 wiki。不幸的是,当涉及到这类事情时,OTP 行为有点棘手和模糊。如果您发现有问题或遗漏,请编辑帖子!
    • @Ricardo:严格来说,terminate/2 在您的父级崩溃时不会被调用(如果没有陷阱退出是不可能的)。例外可能是主管,它存在陷阱并且可以优雅地终止他们的孩子(我不确定他们是否这样做)。 terminate/2gen_server 本身崩溃时调用,因为可以在不使用trap_exit 的情况下捕获在同一进程中生成的退出。
    【解决方案2】:

    这是非常新鲜和相关的 When does terminate/2 get called in a gen_server?

    【讨论】:

      猜你喜欢
      • 2018-08-02
      • 1970-01-01
      • 2020-04-03
      • 1970-01-01
      • 1970-01-01
      • 2021-10-25
      • 2011-09-23
      • 2016-08-19
      • 2022-06-21
      相关资源
      最近更新 更多