2016-05-05 7 views
0

bekomme ich folgende Fehlermeldung, wenn ich versuche, mein Programm durch Shell auszuführen erlang.mk verwenden.Gen Server Error noproc

=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) 
([email protected])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 

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, []} 
]}. 

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}). 

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. 

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). 

Also im Grunde habe ich zwei Fragen an die Fehler im Zusammenhang, der hier geworfen wird:

  1. Ist dieser Fehler geworfen, weil mein gen_server starten nicht in der Lage ist?

  2. Die Linie in rad_config-file:consult/1 entspricht, möchte ich von fragen, woher kommt diese Funktion die Datei wie im Parameter abruft, die ich geführt habe, um es config/rad.cfg aber alle .erl Dateien gespeichert sind in src Ordner ist. Und diese beiden Ordner src und config sind auf der gleichen Verzeichnisebene. So ist der Parameter, die ich file:consult/1 bestanden haben, ist es richtig? Obwohl ich versucht habe, den Parameter als ../config/rad.cfg auch zu übergeben. Ich bekomme immer noch den gleichen Fehler.

Bitte helfen Sie mir. Ich bin new-Erlang und ich versuche, diesen Fehler schon seit geraumer Zeit zu lösen. BTW, ich benutze Erlang 17.5.

Antwort

3

Zunächst scheint es so, als ob Sie rad_app.erl Ihren rad_config Server noch nicht gestartet haben. so, wenn Sie erhält auf diese Zeile:

Port = rad_config:lookup(port) 

Sie rufen tatsächlich:

lookup(Tag) -> 
    gen_server:call(?SERVER, {lookup, Tag}). 

Und die gen_server nicht gestartet, so dass Sie einen noproc Fehler.

Darüber hinaus können Sie, selbst wenn der Server bereits gestartet wurde, keine gen_server:call für sich selbst erstellen. Der beste Weg, um einen Fall zu behandeln, die Sie selbst ein Ereignis senden wollen, ist ein neues Verfahren spawn mit zu öffnen und aus dem Innern des erzeugten Prozess den Anruf zu tätigen.

Sie soll mehr über gen_server und OTP lesen.