为啥我的 Erlang 应用程序崩溃了?
Posted
技术标签:
【中文标题】为啥我的 Erlang 应用程序崩溃了?【英文标题】:Why is my Erlang application crashing?为什么我的 Erlang 应用程序崩溃了? 【发布时间】:2014-09-20 12:28:21 【问题描述】:我正在构建一个简单的 erlang 应用程序,并且对环境非常陌生,所以我无法理解我遇到的一些错误。我不确定我的问题的根源是什么,所以如果我没有发布任何相关的内容,请告诉我:
我正在运行的模块的来源:
-module(basilisk_server).
-author("Oak").
-export([start_link/2,start/0,start/1,start/2, stop/1]).
-behaviour(application).
-record(options,
port = 6890,
server_opts = []
).
-define(LocalIP,"192.168.64.128").
start()->
start([]).
start(Args)->
#optionsport = Port, server_opts = ServerOpts = parse_args(Args),
spawn(
fun() ->
start_link(Port, ServerOpts),
receive after infinity -> ok end
end)
.
start(_StartType, Args) ->
start(Args).
parse_args(Args) -> parse_args(Args, #options).
parse_args([], Opts) -> Opts;
parse_args([Head | Rest], Opts) ->
NewOpts =
case catch list_to_integer(Head) of
Port when is_integer(Port) ->
Opts#optionsport = Port;
_Else ->
case Head of
"framed" ->
Opts#optionsserver_opts = [framed, true | Opts#options.server_opts];
"" ->
Opts;
_Else ->
erlang:error(bad_arg, Head)
end
end,
parse_args(Rest, NewOpts)
.
stop(_State) ->
ok.
start_link(Port, ServerOpts) ->
io:format("Starting server on port ~p with args: ~p~n",[Port,ServerOpts]),
Services =
[
"AuthenticationService",authenticationService_thrift,
"UserRegistrationService",userRegistrationService_thrift
]
,
ok, _ = thrift_socket_server:start([
ip, ?LocalIP,
port, Port,
name, ?MODULE,
service, Services,
handler,[
"error_handler", thrift_error_handler,
"AuthenticationService",authentication_service,
"UserRegistrationService",user_registration_service
],
socket_opts, [recv_timeout, infinity]
]++
ServerOpts).
我运行application:start(basilisk_server).
并按以下顺序获取这些消息:
error,bad_return,basilisk_server,start,[normal,[]],
<0.38.0>
=INFO REPORT==== 29-Jul-2014::03:11:06 ===
application: basilisk_server
exited: bad_return,basilisk_server,start,[normal,[]],<0.38.0>
type: temporary
=ERROR REPORT==== 29-Jul-2014::03:11:06 ===
Error in process <0.38.0> with exit value: terminated,[io,format,
[<0.36.0>,"Starting server on port ~p with args: ~p~n",[6890,[]]],[],
basilisk_server,start_link,2,[file,"src/basilisk_server.erl",line,55],
basilisk_server,'-start/1-fun-0-',2,[file,"src/basilisk_serve...
我遇到的主要问题是确定错误的实际来源。我的印象是io:format
是短时间内的问题,但我相信这是一个“红鲱鱼”,而 bad_result 是我问题的根源。我以几乎相同的状态运行程序并且它正在运行,但突然开始出现此错误。我回滚了大部分更改,但它并没有停止。我还尝试重新启动,以防后台进程出现问题。
【问题讨论】:
在给出有效答案以否决这个问题后,这不是一个......有趣的......时间长度吗? 【参考方案1】:您正在使用application:start
,它希望您的模块遵守application
行为。
也就是说:它会调用foo:start/2
,告诉你你的应用程序正在启动。您应该返回ok, Pid
。这记录在 OTP 设计原则的“应用程序”chapter 中。
但是,您的 start
函数会立即调用 spawn
,并使用其结果。由于spawn
返回Pid
,而不是ok, Pid
,application:start
抱怨预期结果不匹配。
这就是你看到bad_return
的原因:
error,bad_return,basilisk_server,start,[normal,[]],
<0.38.0>
这告诉你你有一个error
,类型为bad_return
。它发生在调用basilisk_server:start(normal, [])
时,它的返回值为<0.38.0>
(一个pid)。
哦,另一个错误是因为你使用了start_link
,这意味着你的两个进程是链接的。当一个人死了,另一个人就会被杀死。这就是您通过terminated
看到的内容。在这种情况下,它恰好在io:format
的中间被杀死;它可能会在其他运行中被杀死之前更进一步。
此外,假设应用程序启动一个根主管(这就是返回的 pid 的用途)。
此时,您不需要application
行为。事实上,我根本不相信您需要大部分代码。只需致电thrift_socket_server:start
即可完成。它将继续在后台运行。
【讨论】:
我正在寻找 start 的预期结果但找不到它,谢谢(我翻阅了我这里的书,它没有提到它,我读了那个例子但推断“预计返回最高主管的pid”意味着简单地返回一个pid)。此外,我删除了我发布的示例的大部分代码,行为比这里看起来的要多。感谢您的澄清。以上是关于为啥我的 Erlang 应用程序崩溃了?的主要内容,如果未能解决你的问题,请参考以下文章