当我尝试从 eshell 启动时,我的主管崩溃了?

2023-11-27

我对 OTP 很陌生,我正在尝试创建简单的示例来理解主管行为:

这是简单的增量服务器

-module( inc_serv ).
-behaviour( gen_server ).
-export( [ start/0, inc/1, stop/0 ] ).
-export( [ init/1, handle_call/3, terminate/2 ] ).

start() ->
        gen_server:start_link( { local, ?MODULE }, ?MODULE, no_args, [] ).

stop() ->
        gen_server:call( ?MODULE, stop ).

inc( Num ) ->
        gen_server:call( ?MODULE, { num, Num } ).

init( no_args ) ->
        io:format( "~p~n", [ "Increment server started :)" ] ),
        { ok, no_state }.

handle_call( { num, Num }, _From, no_state ) ->
        { reply, Num + 1, no_state };
handle_call( stop, _From, no_state ) ->
        { stop, normal, ok, no_state }.

terminate( Reason, no_state ) ->
        io:format( "~p~n", [ "Increment server stopped" ] ).

我想让它由这个模块监督:

-module( supervisor_inc ).
-behaviour( supervisor ).

-export( [ start/0 ] ).
-export( [ init/1 ] ).

start() ->
        supervisor:start_link( { local, ?MODULE }, ?MODULE, no_args ).

init( no_args ) ->
        process_flag( trap_exit, true ),
        Supervisor_Spec = { one_for_one, 1, 1 },
        IncServ_Spec = {
                inc_serv,
                { inc_serv, start, [] },
                permanent, 2000, worker, [ inc_serv ] },
        { ok, { Supervisor_Spec, [ IncServ_Spec ] } }.

之后我在 erlang shell 中执行了后续步骤:

1> 
1> c(inc_serv).
{ok,inc_serv}
2> 
2> c(supervisor_inc).
{ok,supervisor_inc}
3> 
3> supervisor_inc:start().
"Increment server started :)"
{ok,<0.43.0>}
4> 
4> inc_serv:inc( 7 ).
8
5> inc_serv:inc( 8 ).
9

之后我尝试了下一步(正如我预期的那样,我遇到了错误):

6> inc_serv:inc( bad_arg ).
"Increment server stopped"
"Increment server started :)"

=ERROR REPORT==== 23-Aug-2012::19:32:06 ===
** Generic server inc_serv terminating 
** Last message in was {num,bad_arg}
** When Server state == no_state
** Reason for termination == 
** {badarith,[{inc_serv,handle_call,3,[{file,"inc_serv.erl"},{line,22}]},
              {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,588}]},
              {proc_lib,init_p_do_apply,3,
                        [{file,"proc_lib.erl"},{line,227}]}]}

=ERROR REPORT==== 23-Aug-2012::19:32:06 ===
** Generic server supervisor_inc terminating 
** Last message in was {'EXIT',<0.31.0>,
                           {{{badarith,
                                 [{inc_serv,handle_call,3,
                                      [{file,"inc_serv.erl"},{line,22}]},
                                  {gen_server,handle_msg,5,
                                      [{file,"gen_server.erl"},{line,588}]},
                                  {proc_lib,init_p_do_apply,3,
                                      [{file,"proc_lib.erl"},{line,227}]}]},
                             {gen_server,call,[inc_serv,{num,bad_arg}]}},
                            [{gen_server,call,2,
                                 [{file,"gen_server.erl"},{line,180}]},
                             {erl_eval,do_apply,6,
                                 [{file,"erl_eval.erl"},{line,576}]},
                             {shell,exprs,7,[{file,"shell.erl"},{line,668}]},
                             {shell,eval_exprs,7,
                                 [{file,"shell.erl"},{line,623}]},
                             {shell,eval_loop,3,
                                 [{file,"shell.erl"},{line,608}]}]}}
** When Server state == {state,
                            {local,supervisor_inc},
                            one_for_one,
                            [{child,<0.48.0>,inc_serv,
                                 {inc_serv,start,[]},
                                 permanent,2000,worker,
                                 [inc_serv]}],
                            undefined,1,1,
                            [{1345,739526,107495}],
                            supervisor_inc,no_args}
** Reason for termination == 
** {{{badarith,[{inc_serv,handle_call,3,[{file,"inc_serv.erl"},{line,22}]},
                {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,588}]},
                {proc_lib,init_p_do_apply,3,
                          [{file,"proc_lib.erl"},{line,227}]}]},
     {gen_server,call,[inc_serv,{num,bad_arg}]}},
    [{gen_server,call,2,[{file,"gen_server.erl"},{line,180}]},
     {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,576}]},
     {shell,exprs,7,[{file,"shell.erl"},{line,668}]},
     {shell,eval_exprs,7,[{file,"shell.erl"},{line,623}]},
     {shell,eval_loop,3,[{file,"shell.erl"},{line,608}]}]}
** exception exit: {{badarith,[{inc_serv,handle_call,3,
                                         [{file,"inc_serv.erl"},{line,22}]},
                               {gen_server,handle_msg,5,
                                           [{file,"gen_server.erl"},{line,588}]},
                               {proc_lib,init_p_do_apply,3,
                                         [{file,"proc_lib.erl"},{line,227}]}]},
                    {gen_server,call,[inc_serv,{num,bad_arg}]}}
     in function  gen_server:call/2 (gen_server.erl, line 180)

在此之后我预计 - 我的主管会重新启动inc_serv。但它没有:

7> inc_serv:inc( 8 ).      
** exception exit: {noproc,{gen_server,call,[inc_serv,{num,8}]}}
     in function  gen_server:call/2 (gen_server.erl, line 180)

你能帮我理解发生了什么吗?我应该如何重写我的主管,使其能够重新启动inc_serv

Thanks


这实际上是一种竞争条件。

您可能知道,Erlang shell 本身是一个普通的 Erlang 进程。当您从 shell 启动主管时,主管将链接到 shell(因为您使用supervisor:start_link/3).

当您调用 gen_server 进程时,该进程崩溃(并由主管正确地重新启动,正如您可以通过后续命令看到的)"Increment server started :)"输出)。

However,同时,您拨打gen_server:call/2将导致相同的崩溃(在调用过程中 gen_server 崩溃将通过gen_server:call/2功能)。然后,这会导致 shell 进程崩溃,该进程链接到您的主管,而该进程又会因相同的原因而崩溃(badarith).

基本上,在你的 shell 进程忠实地重新启动你的 gen_server 之后,你的主管会被你的 shell 进程背刺。就像这样:

       +---------(6)exit----------+    +---------(5)restart---------+
       |                          |    |                            |
       |                          v    |                            v
     Shell ---(1)start_link---> supervisor ---(2)start_link---> gen_server
     |  ^                         ^    |                         ^  |   ^
     |  |                         |    |                         |  |   |
     |  |                         |    +---------(7)exit---------+  |   |
     |  |                         |                                 |   |
     |  +-------------------------+--------------(4)exit------------+   |
     |                                                                  |
     +---------------------------(3)call--------------------------------+

您可以通过调用来避免这种情况catch inc_serv:inc(bad_arg).在你的外壳中:

90> inc_serv:inc(7).        
8
91> catch inc_serv:inc(bad_arg).
"Increment server stopped"

=ERROR REPORT==== 23-Aug-2012::22:10:02 ===
** Generic server inc_serv terminating 
** Last message in was {num,bad_arg}
** When Server state == no_state
** Reason for termination == 
** {badarith,[{inc_serv,handle_call,3,[{file,"inc_serv.erl"},{line,20}]},
              {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,588}]},
              {proc_lib,init_p_do_apply,3,
                        [{file,"proc_lib.erl"},{line,227}]}]}
"Increment server started :)"
{'EXIT',{{badarith,[{inc_serv,handle_call,3,
                              [{file,"inc_serv.erl"},{line,20}]},
                    {gen_server,handle_msg,5,
                              [{file,"gen_server.erl"},{line,588}]},
                    {proc_lib,init_p_do_apply,3,
                              [{file,"proc_lib.erl"},{line,227}]}]},
                    {gen_server,call,[inc_serv,{num,bad_arg}]}}}
92> inc_serv:inc(7).            
8
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当我尝试从 eshell 启动时,我的主管崩溃了? 的相关文章

  • Erlang 可以使用哪些分布式进程注册表?

    我想为 Erlang 编译一个相当完整的分布式进程注册表库列表 此类库需要支持基本操作 例如register name Pid Name and whereis name Name 并且理想情况下registered names 0 名称不
  • 在 Erlang 中编写和编译自定义行为

    我试图在 Erlang 中编写并编译自定义行为 我找不到任何关于如何编译此行为的明确文档 module bla export start link 0 behaviour info 1 behaviour info callbacks gt
  • Erlang 中的 begin...end 有何用途?

    我刚刚踩了一个begin end在 Erlang 的文档中 here http www erlang org doc reference manual expressions html id79819 但它没有给出一些例子来说明它是如何有用
  • 何时“让它崩溃”以及何时捍卫 Erlang 中的代码?

    因此 带着 让它崩溃 的口号 Erlang 代码意味着能够抵御残酷的世界事件 例如意外拔出插头 硬件故障和不稳定的网络连接 另一方面 有防御性编程 https en wikipedia org wiki Defensive programm
  • 在 Erlang 中如何将元组对列表转换为记录?

    假设我有这个 record my record foo bar baz Keyvalpairs foo val1 bar val2 baz val3 Foorecord my record foo val1 bar val2 baz val
  • Mnesia 返回 {aborted, no_transaction}

    我有一个名为 Mnesia 的表person 使用以下记录定义 record person id firstname lastname phone 该表包含以下值 12 alen dumas 97888888 13 franco mocci
  • 选择用于实现分布式消息传递算法的编程语言

    基本上 我想实现以下算法并分析使用这些算法构建的系统在不同条件下的行为 八卦协议 多个paxos 一致的散列 我的兴趣在于这些算法 我基本上是在寻找一种编程语言 可以让我快速编写这些算法并深入理解这些算法 我应该选择哪种语言 Java Sc
  • 如何在 erlang 中格式化包含整数的平面字符串?

    在erlang中 我想格式化一个包含整数的字符串 并且我希望结果被展平 但我明白了 io lib format sdfsdf B 12312 115 100 102 115 100 102 32 12312 我可以使用下面的代码获得所需的结
  • Erlang 记忆的简单示例

    假设您有一个简单的函数 对于较大的值来说 它的成本可能会相当高 fact 0 gt 1 fact N gt N fact N 1 在哪里可以找到使用缓存 或记忆 函数值的简单示例dets 任何其他方便记忆的方法都将受到高度赞赏 根据您的情况
  • 在 Erlang 中确定传入 TCP/IP 连接的 IP 地址和端口

    我想获取传入 TCP IP 连接的 IP 地址和端口号 很遗憾gen tcp s accept and recv函数只返回一个套接字 而gen udp s recv函数还返回地址信息 有没有一种简单的方法来收集属于 Erlang 中套接字的
  • Erlang编译器错误

    我有以下代码 loop Data gt receive Key Value gt Key Value Data Key gt member Key Data 14 loop Data stop gt io format server sto
  • 有什么方法可以将 ActionScript 3 中的常规字符串转换为 Latin-1 字符代码的 ByteArray?

    我在将字符串转换为 UTF 16 编码字符的 byteArray 时没有问题 但我尝试与之通信的应用程序 用 Erlang 编写 仅理解 Latin 1 编码 有什么方法可以从 Actionscript 3 中的字符串生成充满 Latin
  • `ejabberdctl start` 导致“内核 pid 终止”错误 - 我该怎么办?

    我用谷歌搜索了三个小时但没有结果 我有一个 ejabberd 安装 但不是使用 apt 安装的 它是从源代码安装的 其中没有名为 ejabberd 的程序 启动和停止 一切都是通过 ejabberdctl 进行的 它完美地运行了一个月 突然
  • Erlang中如何维护状态?

    我见过人们使用口述 命令 记录用于维护我读过的许多博客中的状态 我发现这是一个非常重要的概念 一般来说 我理解维护状态和递归的含义 但是当涉及到 Erlang 时 我对它的处理方式有点模糊 有什么帮助吗 维护状态的最简单方法是使用gen s
  • Erlang 生成问题

    我在 erlang 中遇到了 spawn 问题 似乎进程在一段时间后就死掉了 这是简单的代码 module simple export server 1 client 1 owner 1 spawn n 2 start 1 main 1 s
  • RabbitMQ 失败,错误:无法连接到节点rabbit@TPAJ05421843:nodedown

    在 Windows 7 Enterprise 计算机上 我全新安装了 Erlang 17 4 和 RabbitMQ 3 4 3 x64 安装成功且顺利 我还没有尝试创建我的第一个队列或交换器 但我已经看到了麻烦 这个问题类似于另一个SO帖子
  • 与共享数据相比,消息传递的性能损失

    最近有很多关于不使用锁和使用 Erlang 等消息传递方法的讨论 或者关于使用不可变的数据结构 例如函数式编程与 C Java 中的比较 但我关心的是以下几点 AFAIK Erlang 不保证消息传递 消息可能会丢失 如果还要担心消息丢失
  • 使用字符串将 Erlang 映射编码为 JSON 以便通过 Javascript 进行解析?

    我正在尝试使用 Erlang 地图 例如 breakfast gt leftovers 并编码为 JSON 映射 例如 我尝试使用 jiffy 转换列表 email protected cdn cgi l email protection
  • 停止 Erlang 守护进程

    除了跑步 killall 9 beam smp 当我知道 Erlang 节点的情况时 如何以编程方式杀死它 sname 如果我不希望心跳监视器重新启动该进程 如何确保上述问题的任何答案也会终止心跳 有没有一个不错的指南来将 Erlang 部
  • Erlang get_tcp:recv数据长度

    I user gen tcp recv Socket 0 用于数据接收 但我只能接收1次1418字节 我怎样才能收到发送的数据量 in gen tcp recv Socket 0 您正在询问内核 给我接收缓冲区中现在可用的所有数据 不过 内

随机推荐

  • 位字节顺序如何影响 C 中的按位移位和文件 IO?

    Let L and B是两台机器 L订购它的bits从最低有效位 最低有效位 到 MSB 最高有效位 同时B命令 从 MSB 到 LSB 或者 换句话说 L使用 Little Endian 而B使用大尾数法bit 不要与字节排序相混淆 问题
  • 关闭实体框架 CTP5 中的对象缓存

    我无法弄清楚 CTP 5 中实体框架代码优先的内容 它正在缓存对象 但我不希望它这样做 例如 我加载一个加载对象的页面 使用 ASP NET MVC 站点 然后我去更改数据库 我重新加载页面 但更改没有反映出来 如果我终止该网站并重新运行它
  • iOS:键盘出现时禁用 UITableView 动画

    每个人都想在键盘弹出时移动 UITableView 但我正在寻找一种方法来禁用键盘弹出时光标的自动动画 当键盘弹出并导致 UITableView 滚动到光标 以避免阻塞它 时 我遇到了奇怪的抽动 颠簸 不稳定的滚动行为 我的每个 UITab
  • PHP 捕获 SimpleXMLElement 解析错误 [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 我有一个脚本可以解析一些 XML adf 内容 有时我
  • 如何在 Play 框架 2.0 (Java) 中重定向到外部 URL

    通过使用控制器中的redirect 方法似乎可以重定向到内部URL public static Result index return redirect routes Application tasks 但是我想重定向到控制器中的外部 UR
  • 在 Ubuntu OpenJDK 7 上启用密码

    我编写了以下 Java 程序来转储 JVM 中启用的密码 import java security KeyStore import javax net ssl KeyManagerFactory import javax net ssl S
  • const 引用必须在构造函数基类/成员初始值设定项列表中初始化

    我试图阻止对我正在编写的类的默认构造函数的访问 我希望其他人使用的构造函数需要对另一个对象的 const 引用 我已将默认构造函数设为私有 以防止其他人使用它 我收到默认构造函数的编译器错误 因为 const 引用成员变量未正确初始化 我该
  • 除 ffmpeg x264 之外的 H264 编码器

    我正在开发的 iPhone 应用程序会在特定的用户定义的时间间隔内连续捕获图像 我正在寻找一种将这些图像组合成 H264 编码视频的方法 我在 Google 上做了一些研究 看起来我必须在 iPhone 上使用 ffmpeg mencode
  • LINQ to SQL:多列左连接

    首先 我搜索了 google SO 检查了一些示例 但我没有设法编写正确的 linq 表达式 这就是我的工作 sql 查询的样子 select from Places p left join VoteLog v on p Id v Plac
  • 为什么我的应用服务的 Kudu 网站显示 503 服务不可用

    我在将容器部署到 Azure 中的应用程序服务时遇到问题 在发布管道中 我看到以下错误 调试 放置 https iagadsca01 cac app salesforcedownstream 01 iagadsca01 cac app sa
  • 在没有实际 Excel 的情况下使用 Microsoft.Office.Interop.Excel?

    我在用着Microsoft Office Interop Excel在 VB Net 中 以便将 xls 文件导出为 pdf 文件 这是我能找到的唯一方法 无需依赖在运行的计算机上安装第三方软件或使用昂贵的 Visual Studio 附加
  • Eclipse 声音池加载错误

    我正在尝试使用 Eclipse 开发一个 Android 图书馆管理软件 到目前为止 我的应用程序运行良好 在 Eclipse 模拟器中 但我遇到了一些困扰我的错误 尽管对功能没有明显影响 如果有人可以指导我 我将非常感激 错误 1 每当我
  • Ruby 中的循环位右移运算

    Ruby 中有右旋转位吗 或者请问我该怎么做 Thanks 一些事实 Ruby 有运算符 lt lt and gt gt 移位 但没有内置旋转运算符 你必须伪造它 Ruby s Fixnum类自动升级为Bignum当该值超过机器字大小时 这
  • 为什么我不能将 asp.net mvc 4 项目设置为 x64

    我有一个 VS2012 解决方案 可以简化如下 一个 asp net mvc 4 Web 应用程序 一个中间 C 类库项目和一个用于计算等的最终 C 库项目 该 Web 应用程序当前没有对其他项目的引用 并且在构建时配置为 任何 CPU 最
  • Angular 2 同级组件之间的通信

    我试图遵循这个答案 但它太令人困惑了Angular 2 兄弟组件之间的事件捕获 我想调用一个方法子组件 1当点击某物时子组件 2 子组件 2 发出一个名为 trackClick 的事件 父组件 div div
  • 如何使用 KSOAP2 从 Android 调用 PHP Web 服务?

    有人可以建议 如何使用 KSOAP2 从 Android 调用 PHP Web 服务吗 现在提供示例代码 您自己尝试一下 private final String SOAP ACTION urn abc login private fina
  • oData 查询中如何处理特殊字符?

    oData 中以下查询中的 符号是如何处理的 vendordataservice svc vDataMapper SourceMapVendor filter startswith ParentName AT T top 7 skip 0
  • UIScrollView 触摸开始

    所以我想做的就是当用户触摸 UIScrollView 时播放声音 UIScrollViewDelegate有scrollViewWillBeginDragging 方法 但它只在touchMoved时被调用 我希望它在 touchBegan
  • 创建不同长度的分类变量的汇总表

    在 SPSS 中 使用 自定义表 创建分类变量的汇总表相当容易 我怎样才能在 R 中做到这一点 通用和可扩展的解决方案是首选 并且使用的解决方案 Plyr 和 或 Reshape2 软件包 因为我正在尝试学习这些 示例数据 mtcars 在
  • 当我尝试从 eshell 启动时,我的主管崩溃了?

    我对 OTP 很陌生 我正在尝试创建简单的示例来理解主管行为 这是简单的增量服务器 module inc serv behaviour gen server export start 0 inc 1 stop 0 export init 1