我正在构建一个简单的 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)->
    #options{port = 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#options{port = Port};
        _Else ->
          case Head of
            "framed" ->
              Opts#options{server_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 是我问题的根源。我在几乎相同的状态下运行该程序并且它正在工作,然后突然开始出现此错误。我回滚了大部分更改,但它并没有停止。我还尝试重新启动,以防后台进程出现问题。

有帮助吗?

解决方案

你正在使用 application:start, ,它期望您的模块遵守 application 行为。

那是:它会打电话 foo:start/2, ,告诉您您的应用程序正在启动。预计您会回来 {ok, Pid}. 。这记录在“应用程序”中 章节 OTP 设计原则。

然而,你的 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 并完成它。它将继续在后台运行。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top