Erlang gen_server实现

时间:2014-03-24 07:11:30

标签: erlang gen-server

在下面的代码中,为什么模块prime_server没有加载?

-module(prime_server).

-behaviour(gen_server).

-export([new_prime/1, start_link/0]).

%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

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

new_prime(N) ->
    %% 20000 is a timeout (ms)
    gen_server:call(?MODULE, {prime, N}, 20000).

init([]) ->
    %% Note we must set trap_exit = true if we
    %% want terminate/2 to be called when the application
    %% is stopped

    process_flag(trap_exit, true),

    io:format("~p starting~n" ,[?MODULE]),
    {ok, 0}.

handle_call({prime, K}, _From, N) ->
    {reply, make_new_prime(K), N+1}.


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

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

terminate(_Reason, _N) ->
    io:format("~p stopping~n" ,[?MODULE]),
    ok.

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

make_new_prime(K) ->
    if
        K > 100 ->
            alarm_handler:set_alarm(tooHot),
            N = lib_primes:make_prime(K),
            alarm_handler:clear_alarm(tooHot),
            N;
        true ->
            lib_primes:make_prime(K)
    end.

输出:

$ erl -boot start_sasl

1>c(prime_server).
{ok,prime_server}
2>c(my_alarm_handler).
my_alarm_handler.erl:2: Warning: undefined callback function code_change/3 (behaviour 'gen_event')
my_alarm_handler.erl:19: Warning: variable 'Reply' is unused
{ok,my_alarm_handler}
3> {ok, Pid} = prime_server:start_link().
prime_server starting
{ok, <0.73.0>}
4> prime_server:new_prime(6).
prime_server stopping
=ERROR REPORT==== 24-Mar-2014::10:59:39 ===
** Generic server prime_server terminating
** Last message in was {prime,6}
** When Server state == 0
** Reason for termination ==
** {'module could not be loaded',
       [{lib_primes,make_prime,[6],[]},
        {prime_server,handle_call,3,[{file,"prime_server.erl"},{line,21}]},
        {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,585}]},
        {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,239}]}]}

=CRASH REPORT==== 24-Mar-2014::10:59:39 ===
  crasher:
    initial call: prime_server:init/1
    pid: <0.73.0>
    registered_name: prime_server
    exception exit: {undef,
                        [{lib_primes,make_prime,[6],[]},
                         {prime_server,handle_call,3,
                             [{file,"prime_server.erl"},{line,21}]},
                         {gen_server,handle_msg,5,
                             [{file,"gen_server.erl"},{line,585}]},
                         {proc_lib,init_p_do_apply,3,
                             [{file,"proc_lib.erl"},{line,239}]}]}
      in function  gen_server:terminate/6 (gen_server.erl, line 744)
    ancestors: [<0.71.0>]
    messages: []
    links: [<0.71.0>]
    dictionary: []
    trap_exit: true
    status: running
    heap_size: 610
    stack_size: 27
    reductions: 181
  neighbours:
    neighbour: [{pid,<0.71.0>},
                  {registered_name,[]},
                  {initial_call,{erlang,apply,2}},
                  {current_function,{gen,do_call,4}},
                  {ancestors,[]},
                  {messages,[]},
                  {links,[<0.27.0>,<0.73.0>]},
                  {dictionary,[]},
                  {trap_exit,false},
                  {status,waiting},
                  {heap_size,610},
                  {stack_size,36},
                  {reductions,1303}]
** exception exit: undef
     in function  lib_primes:make_prime/1
        called as lib_primes:make_prime(6)
     in call from prime_server:handle_call/3 (prime_server.erl, line 21)
     in call from gen_server:handle_msg/5 (gen_server.erl, line 585)
     in call from proc_lib:init_p_do_apply/3 (proc_lib.erl, line 239)
9> gen_server:call(prime_server, 6).
** exception exit: {noproc,{gen_server,call,[prime_server,6]}}
     in function  gen_server:call/2 (gen_server.erl, line 180)
10> gen_server:call(prime_server, new_prime,  6).
** exception exit: {noproc,{gen_server,call,[prime_server,new_prime,6]}}
     in function  gen_server:call/3 (gen_server.erl, line 188)
11> gen_server:call(prime_server, new_prime(5), []).
** exception error: undefined shell command new_prime/1
12> gen_server:call(prime_server, {prime, 4},  []).
** exception exit: {{function_clause,
                        [{gen,call,
                             [prime_server,'$gen_call',{prime,4},[]],
                             [{file,"gen.erl"},{line,147}]},
                         {gen_server,call,3,
                             [{file,"gen_server.erl"},{line,184}]},
                         {erl_eval,do_apply,6,
                             [{file,"erl_eval.erl"},{line,573}]},
                         {shell,exprs,7,[{file,"shell.erl"},{line,674}]},
                         {shell,eval_exprs,7,[{file,"shell.erl"},{line,629}]},
                         {shell,eval_loop,3,[{file,"shell.erl"},{line,614}]}]},
                    {gen_server,call,[prime_server,{prime,4},[]]}}

1 个答案:

答案 0 :(得分:3)

{&#39;模块无法加载&#39;,

[{lib_primes,make_prime,[6],[]},

{prime_server,handle_call,3,[{file,"prime_server.erl"},{line,21}]},

{gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,585}]},

{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,239}]}]}

从日志中,您使用此模块lib_primes,您是否拥有此文件lib_primes.erl

我认为您应首先编译并加载此模块lib_primes