gpt4 book ai didi

elixir - 正常关闭GenServer

转载 作者:行者123 更新时间:2023-12-03 14:09:15 24 4
gpt4 key购买 nike

我用GenServer编写了一个Elixir应用程序,该应用程序在启动时启动外部应用程序,然后将其关闭,并在退出时进行其他清理。我在 init/1 回调中添加了启动功能,并在 terminate/2 回调中添加了清理代码。

在启动GenServer时,init代码可以正常工作,并且在手动发送terminate信号时也可以调用:stop方法,但是在IEx中意外关闭和中断(如按Ctrl + C的情况)时,可以使用,不调用终止代码。

目前,我已经浏览了许多论坛主题,博客文章和文档,其中包括:

  • Getting Started: GenServers
  • Elixir-Lang-Talk: Graceful shutdown of GenServer(s) on exiting iex -S mix
  • Elixir-Lang-Talk: Stopping Genserver vs Process.exit

  • From Elixir Docs - GenServers:

    If the GenServer receives an exit signal (that is not :normal) from any process when it is not trapping exits it will exit abruptly with the same reason and so not call terminate/2. Note that a process does NOT trap exits by default and an exit signal is sent when a linked process exits or its node is disconnected.

    Therefore it is not guaranteed that terminate/2 is called when a GenServer exits. For such reasons, we usually recommend important clean-up rules to happen in separated processes either by use of monitoring or by links themselves.



    但是我完全不知道如何获取 :init.stoplinked processes或其他任何东西来使用它(因为这是我第一次使用GenServers)。



    这是我的代码:

    defmodule MyAwesomeApp do
    use GenServer

    def start do
    GenServer.start_link(__MODULE__, nil)
    end

    def init(state) do
    # Do Bootup stuff

    IO.puts "Starting: #{inspect(state)}"
    {:ok, state}
    end

    def terminate(reason, state) do
    # Do Shutdown Stuff

    IO.puts "Going Down: #{inspect(state)}"
    :normal
    end
    end

    MyAwesomeApp.start

    最佳答案

    为了增加terminate回调被调用的机会,服务器进程应捕获导出。但是,即使这样,在某些情况下(例如,当该过程被残酷地杀死或当它自身崩溃时),也可能不会调用该回调。有关更多详细信息,请参见here

    如上所述,如果要礼貌地关闭系统,则应调用:init.stop,它将递归关闭监视树,从而导致terminate回调被调用。

    正如您所注意到的,无法从内部捕获突然的BEAM OS进程导出。这是一个自定义属性:BEAM进程突然终止,因此它无法运行任何代码(因为终止)。因此,如果BEAM被残酷地终止,则不会调用该回调。

    如果在BEAM死后无条件地想做某事,则需要从另一个OS进程中检测出来。我不确定您的确切用例是什么,但是假设您对此有强烈的需求,则可以在同一台(或另一台)计算机上运行另一个BEAM节点。然后,您可能在一个节点上有一个进程监视另一个节点上的另一个进程,因此即使BEAM被残酷地杀死,您也可以使用react。

    但是,如果您不需要无条件运行某些清理逻辑,您的生活将变得更加简单,因此请考虑terminate中的代码是必须的还是比较好的。

    关于elixir - 正常关闭GenServer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39756769/

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