GenServer 正常关闭

2024-04-30

我使用 GenServer 编写了一个 Elixir 应用程序,该应用程序在启动时启动外部应用程序,然后将其关闭,并在退出时进行其他清理。我在中添加了启动功能init/1 https://hexdocs.pm/elixir/GenServer.html#c:init/1回调和清理代码在terminate/2 https://hexdocs.pm/elixir/GenServer.html#c:terminate/2打回来。

The init当 GenServer 启动时,代码工作正常,并且terminate方法也被调用时:stop信号是手动发送的,但是如果 IEx 中出现意外关闭和中断(例如按 Ctrl+C),则不会调用终止代码。


目前,我已经浏览了大量的论坛主题、博客文章和文档,包括:

  • 入门:基因服务器 http://elixir-lang.org/getting-started/mix-otp/genserver.html
  • Elixir-Lang-Talk:退出 iex -S mix 时正常关闭 GenServer https://groups.google.com/forum/#!msg/elixir-lang-talk/d2z2lZnoa6w/0FX4tg0fCAAJ
  • Elixir-Lang-Talk:停止 Genserver 与 Process.exit https://groups.google.com/forum/#!topic/elixir-lang-talk/vxOtIXdqiWw

From Elixir 文档 - GenServers https://hexdocs.pm/elixir/GenServer.html#c:terminate/2:

If the GenServer收到退出信号(即不是:normal) 任何进程在不捕获退出时都会突然退出 出于同样的原因,所以不打电话terminate/2。请注意,一个 过程确实NOTtrap默认退出并发送退出信号 当链接的进程退出或其节点断开连接时。

因此不能保证terminate/2当一个GenServer退出。出于这些原因,我们通常建议重要的 清理规则发生在单独的进程中,或者通过使用 监控或通过链接本身。

但我完全不知道如何得到:init.stop, linked 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 http://elixir-lang.org/docs/stable/elixir/GenServer.html#c:terminate/2.

如前所述,如果您想礼貌地关闭系统,您应该调用:init.stop,这将递归地关闭监督树,导致terminate要调用的回调。

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

如果您无条件地想要在 BEAM 终止时执行某些操作,则需要从另一个操作系统进程中检测到这一点。我不确定您的确切用例是什么,但假设您对此有一些强烈的需求,那么在同一台(或另一台)机器上运行另一个 BEAM 节点可以在这里工作。然后,您可以让一个节点上的一个进程监视另一节点上的另一个进程,这样即使 BEAM 被残酷杀死,您也可以做出反应。

但是,如果您不需要无条件运行一些清理逻辑,您的生活会更简单,因此请考虑中的代码是否terminate是必须的,或者更确切地说,是锦上添花的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GenServer 正常关闭 的相关文章

随机推荐

  • 切换 git 分支时如何处理 vim 缓冲区?

    因此 我在 vim 缓冲区中打开了大量文件 并且正在使用 git 处理功能分支 突然 我意识到我需要恢复到主分支来进行快速修复 提交后 我将 vim 会话保持打开状态并切换回 master 分支 但是 当我尝试从缓冲区加载我需要的文件时 我
  • 没有要加载的文件——readline(加载错误)

    当我想执行 Rails 3 控制台时 它会抛出以下错误 script rails c usr local rvm rubies ruby 1 9 2 p318 lib ruby 1 9 1 irb completion rb 9 in re
  • 将 css 应用到区域地图

    我创建了一个非常大的地图 其中包含许多多边形区域 每个多边形区域超过 20 个坐标 用于地图内的区域 但是 您无法将 css 添加到 AREA 标记 因为我被告知它不是可见元素 我想要做的是 当用户将鼠标悬停在地图上的某个区域上时 我希望通
  • Java线程池大小(执行器)

    我有一个有 3 个线程的应用程序 我将其切换为由 ScheduledExecutorService 管理 创建此实例时 您必须指定线程池大小 但这是什么 这是否意味着如果我计划运行 3 个任务 我应该为每个任务创建一个大小为 3 的线程池
  • 控制器中的模拟服务器

    我的控制器中有以下行 string lTempPath Path Combine Server MapPath Temp lRandomFileName 问题是服务器不是虚拟的 只能通过 getter 进行访问 I get a 该方法或操作
  • 枚举类型的命名空间 - 最佳实践

    通常 需要同时使用多种枚举类型 有时 人们会发生名字冲突 我想到了两种解决方案 使用命名空间 或使用 更大的 枚举元素名称 尽管如此 命名空间解决方案有两种可能的实现 带有嵌套枚举的虚拟类 或完整的命名空间 我正在寻找所有三种方法的优缺点
  • Haskell 有反向模式自动微分的工作实现吗?

    我见过的 Haskell 中最相关的实现是前向模式http hackage haskell org packages archive fad 1 0 doc html Numeric FAD html http hackage haskel
  • Django 组和权限。扩展组以拥有 FK?

    我正在开发一种产品 允许不同的学校在线管理他们的内容 其中一部分涉及设置我自己编写的基于角色的访问控制逻辑 本质上 每所学校都有自己的一组角色 这些角色拥有自己的一组权限 该软件的用户在任何给定时间都可能属于多个具有不同角色的学校 由于各种
  • 我应该在哪里放置 axis2.xml 以便由带有肥皂客户端的 jar 读取?

    我在 jar 文件中有一个 java 控制台应用程序 它通过调用肥皂服务axis2 http axis apache org axis2 java core 我在用这个博客 http www nandana org 2008 08 want
  • 如何从 C# (ASP.NET) 中的函数返回多个值?

    我有一个页面 其中包含一些产品和用户输入数字的文本字段 我首先使用 JavaScript 来计算总成本 根据他们输入的用户数量 他们会获得不同的费率 如下面的代码所示 当用户在文本字段中键入或粘贴数字时 将调用CalculateCost 函
  • 为什么 NHibernate 在选择时删除然后插入复合元素?

    有人可以向我解释一下关于 NHibernate 如何处理复合元素的这个小谜团吗 我的课程看起来像这样 public class Blog public virtual int Id get private set public virtua
  • IllegalStateException:无法从cursorWindow读取第0行,第-1列

    IllegalStateException 无法从cursorWindow读取第0行 第 1列 我是 Android 新手 我查看了 smiller 问题确实解决了我的问题 请帮忙提前致谢 这是我的代码 function to add da
  • 当我从 Android 设备中选择下一步时,在填写表单时,它会跳过任何下拉菜单

    我有一个由输入文本框 下拉菜单和提交按钮组成的网络表单 当我在 Android 手机上使用我的网站 chrome 浏览器 或 Android 设备上的任何浏览器 时 我使用手机键盘上的 next 导航到下一个字段 我的表单上的字段顺序 名字
  • 带有存根列表的 Pandas Wide_to_long

    我目前有以下数据框 1 1 1 2 1 3 1 4 1 5 2 1 9 5 10 1 10 2 10 3 10 4 10 5 0 0 049400 0 063812 0 097736 0 077222 0 112779 0 201620 0
  • gofabric8> 无法解压缩 /Users/apple/.fabric8/bin/oc.zip zip:不是有效的 zip

    我正在尝试为微服务设置环境 我正在使用 Fabric8 来做到这一点 我在用着mvn fabric8 cluster start Dfabric8 cluster kind openshift命令 执行时出现以下错误 INFO gofabr
  • 使用 jQuery 加载脚本时保持范围

    假设我有一个包含以下内容的文件 test js var test something 然后我有一个主要脚本需要加载 test js 以获取测试变量 显然这有效 ajax dataType script cache true url test
  • 一个或多个参数值无效:键 xyz 的类型不匹配预期:S 实际:M

    我的 AWS Lambda 根据以下答案调用 DynamoDB https stackoverflow com a 33649402 495455 https stackoverflow com a 33649402 495455 我收到错
  • NSString 中的子字符串 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我在用NSString我想获取它的一个子字符串 其中包含字符串的前 20 个字符 我怎样才能做到这一点 您可以使用substringT
  • Glassfish Eclipse 插件与 jdk 8

    我正在尝试使用 glassfish eclipse plugin 启动 glassfish 4 不幸的是 它似乎无法识别我刚刚安装的 JDK 8 Release候选版本 完成 按钮保持禁用状态 如果我选择 java 7 jdk 完成按钮将启
  • GenServer 正常关闭

    我使用 GenServer 编写了一个 Elixir 应用程序 该应用程序在启动时启动外部应用程序 然后将其关闭 并在退出时进行其他清理 我在中添加了启动功能init 1 https hexdocs pm elixir GenServer