Почему мое приложение 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 является корнем моей проблемы.Я запустил программу в почти идентичном состоянии, и она работала, и вдруг начала появляться эта ошибка.Я откатил большинство изменений, и это не остановилось.Я также попробовал перезагрузку, на случай, если это была проблема с фоновым процессом.
Решение
Ты используешь 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>
(пид).
О, и еще одна ошибка связана с тем, что вы использовали start_link
, что означает, что ваши два процесса связаны.Когда один умрет, другой будет убит.Это то, что вы видите с помощью terminated
.В данном случае он был убит в середине io:format
;он может продвинуться дальше, прежде чем будет убит в других заездах.
Более того, предполагается, что приложение запускает супервизор root (именно для этого и предназначен возвращаемый pid).
На данном этапе вам не нужно application
поведение.На самом деле, я не уверен, что вам вообще нужна большая часть вашего кода.Просто позвони thrift_socket_server:start
и покончим с этим.Он будет продолжать работать в фоновом режиме.