Gen 服务器错误 noproc

Abh*_*ran 1 erlang gen-server

当我尝试使用 .shell 通过 shell 运行我的程序时,出现以下错误erlang.mk

=INFO REPORT==== 5-May-2016::05:47:57 ===
application: rad
exited: {bad_return,
            {{rad_app,start,[normal,[]]},
             {'EXIT',
                 {noproc,{gen_server,call,[rad_config,{lookup,port}]}}}}}
type: permanent
Eshell V6.4  (abort with ^G)
(rad@127.0.0.1)1> {"Kernel pid terminated",application_controller,"{application_start_failure,rad,{bad_return,{{rad_app,start,[normal,[]]},{'EXIT',{noproc,{gen_server,call,[rad_config,{lookup,port}]}}}}}}"}
Kernel pid terminated (application_controller) ({application_start_failure,rad,{bad_return,{{rad_app,start,[normal,[]]},{'EXIT',{noproc,{gen_server,call,[radheart: Thu May  5 05:47:58 2016: _coErlang is crashing .. (waiting for crash dump file)nf
ig,{lookup,porheart: Thu May  5 05:47:58 2016: tWould reboot. Terminating.}
]}}}}}})
make: *** [run] Error 1
Run Code Online (Sandbox Code Playgroud)

rad.app.src

{application, rad,
[
{description, "Awesome server written in Erlang"},
{vsn, "0.0.1"},
{registered, [rad_sup, rad_config]},
{modules, []},
{applications, [
  kernel,
  stdlib,
  cowboy
]},
{mod, {rad_app, []}},
{env, []}
]}.
Run Code Online (Sandbox Code Playgroud)

rad_config.erl

-module(rad_config).
-behaviour(gen_server).

%% API
-export([start_link/0]).

%% Gen Server Callbacks
-export([init/1 , handle_call/3 , handle_cast/2 , handle_info/2 , terminate/2 , code_change/3]).
-export([lookup/1]).

-define(SERVER, ?MODULE).
-record(state, {conf}).

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

init([]) ->
    {ok, Conf} = file:consult("config/rad.cfg"),
    {ok, #state{conf = Conf}}.

handle_call({lookup, Tag} , _From , State) ->
    Reply = case lists:keyfind(Tag, 1, State#state.conf) of
            {Tag, Value} ->
                Value;
                    false ->
                        {error, noinstance}
        end,
    {reply, Reply, State};

handle_call(_Request, _From, State) ->
    Reply = ok,
    {reply, Reply, State}.

handle_cast(_Msg , State) ->
    {noreply, State}.

handle_info(_Info , State) ->
    {noreply, State}.

terminate(Reason , _State) ->
    io:format("~n Server shutdown. Reason: ~s.~n", [Reason]),
    ok.

code_change(_OldVsn , State , _Extra) ->
    {ok, State}.

lookup(Tag) ->
    gen_server:call(?SERVER, {lookup, Tag}).
Run Code Online (Sandbox Code Playgroud)

rad_app.erl

-module(rad_app).
-behaviour(application).

-export([start/2]).
-export([stop/1]).

%%  First we need to define and compile the dispatch list, a list of routes
%%  that Cowboy will use to map requests to handler modules. Then we tell
%%  Cowboy to listen for connections.
start(_Type, _Args) ->
    Port = rad_config:lookup(port),

    Dispatch = cowboy_router:compile([
    {'_', [{"/", route_handler, []}]}
      ]),
    {ok, _} = cowboy:start_http(rad_http_listener, 100,
    [{port, Port}], [{env, [{dispatch, Dispatch}]}]),

    %% Start the supervisor
    rad_sup:start_link().

stop(_State) ->
    ok.
Run Code Online (Sandbox Code Playgroud)

rad_sup.erl

-module(rad_sup).
-behaviour(supervisor).

%% API
-export([start_link/0]).
%% Supervisor callbacks
-export([init/1, shutdown/0]).

-define(SERVER, ?MODULE).

%% Helper macro for declaring children of supervisor
-define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5000, Type, [I]}).

%%         ===================================================================
%% API functions
%% ===================================================================

start_link() ->
    supervisor:start_link({local, ?SERVER}, ?MODULE, []).

%% ===================================================================
%% Supervisor callbacks
%% ===================================================================

init([]) ->
    RestartStrategy = simple_one_for_one,
    MaxRestarts = 10,
    MaxSecondsBwRestarts = 5,

    SupFlag = {RestartStrategy, MaxRestarts, MaxSecondsBwRestarts},

    Processes = [?CHILD(rad_config, worker)],
    {ok, {SupFlag, Processes}}.

%% Supervisor can be shutdown by calling exit(SupPid,shutdown)
%% or, if it's linked to its parent, by parent calling exit/1.
shutdown() ->
    exit(whereis(?MODULE), shutdown).
Run Code Online (Sandbox Code Playgroud)

所以基本上我有两个与这里抛出的错误相关的问题:

  1. 这个错误是因为我的gen_server无法启动而引发的吗?

  2. rad_config对应于 的行file:consult/1,我想问这个函数从哪里获取文件,就像我传递给它的参数一样config/rad.cfg,但所有.erl文件都存储在src文件夹中。这两个文件夹src和 都config位于同一目录级别。那么,我传递给 的参数file:consult/1是否正确?尽管我也尝试过传递参数../config/rad.cfg。我仍然遇到同样的错误。

请帮帮我。我已经new尝试Erlang解决这个错误很长一段时间了。顺便说一句,我使用Erlang 17.5.

A. *_*rid 5

首先,当您运行时,rad_app.erl您的rad_config服务器似乎尚未启动。所以当你到达这一行时:

Port = rad_config:lookup(port)
Run Code Online (Sandbox Code Playgroud)

您实际上是在调用:

lookup(Tag) ->
    gen_server:call(?SERVER, {lookup, Tag}).
Run Code Online (Sandbox Code Playgroud)

并且gen_server尚未启动,因此您会收到noproc错误。

除此之外,即使服务器已经启动,您也无法gen_server:call自己创建一个。处理您想要向自己发送事件的情况的最佳方法是使用打开一个新进程spawn并从生成的进程内部进行调用。

您应该阅读更多关于gen_serverOTP 的内容。