2014-07-29 4 views
0

Я создаю простое приложение erlang и очень новое для окружающей среды, поэтому у меня возникли проблемы с пониманием некоторых ошибок, которые я получаю. Я не уверен, что корень моей проблемы здесь, так что если есть что-то важно, что я не публикуйте, пожалуйста, дайте мне знать:Почему приложение 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 - корень моей проблемы. Я запускал программу в почти идентичном состоянии, и он работал, и внезапно начал получать эту ошибку. Я отбросил большинство изменений, и это не остановилось. Я также попытался перезагрузить, если это проблема с фоновым процессом.

+0

Разве это не ... интересный ... период времени после того, как был дан правильный ответ на этот вопрос? –

ответ

5

Вы используете application:start, который ожидает, что ваш модуль будет придерживаться поведения application.

То есть: он позвонит foo:start/2, чтобы сообщить, что ваше приложение запускается. Ожидается, что вы вернетесь {ok, Pid}. Это описано в «Приложениях» 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 и сделайте это. Он будет продолжать работать в фоновом режиме.

+0

Я искал ожидаемый результат старта, но не смог его найти, спасибо (я просмотрел книгу, которую я здесь, и не упоминал об этом, и я прочитал этот пример, но сделал вывод: «Ожидается, что вернуть pid верхнего супервизора «означает просто вернуть pid). Также я вырезал большую часть кода для примера, который я опубликовал, поведение делает больше, чем кажется здесь. Спасибо за разъяснения. –

Смежные вопросы