Erlang:聊天服务器在启动时崩溃

Erlang: Chat server crashing on startup

我得到了一组程序应该通过的测试,并且所有本地测试在我的服务器上工作得很好,当我尝试 运行 服务器崩溃的远程测试时。

崩溃信息如下:

=ERROR REPORT==== 23-Jul-2015::23:59:17 === Error in process <0.39.0> on
node 'nodeS@127.0.0.1' with exit value: 
{undef,[{genserver,start,[server, {server_st,[],[]},#Fun<server.loop.2>],[]}]}

我的启动函数如下所示:

loop(St, {From, Nick, connection_wanted}) ->
    case lists:keymember(Nick, 2, St#server_st.users) of
        false -> {ok, St#server_st{users = St#server_st.users ++ [{From, Nick}]}};
        true -> {{user_already_connected, St}, St}
    end;

与记录"server_st"定义为:

-record(server_st, {users = [], channels = []}).

最后的genserver start&loop函数是:

start(Name, State, F) ->
Pid = spawn(fun() -> loop(State, F) end),
register(Name, Pid),
Pid.

loop(State, F) ->
receive
{request, From, Ref, Data} ->
    case catch(F(State, Data)) of
    {'EXIT', Reason} ->
        From!{exit, Ref, Reason},
        loop(State, F);
    {R, NewState} ->
        From!{result, Ref, R},
        loop(NewState, F)
    end;
{update, From, Ref, NewF} ->
    From ! {ok, Ref},
    loop(State, NewF);
stop ->
    true
end.

那么genserver的功能我是不允许更改的。如果需要,我也可以 post 整个测试套件。

编辑 深入研究测试用例,我不确定是否真的是导致问题的服务器,我的远程连接功能如下所示:

loop(St, {connect, {_Server, _Machine}}) ->
ServerPID = {list_to_atom(_Server), list_to_atom(_Machine)},
case genserver:request(ServerPID, {self(), St#cl_st.nick, connection_wanted}) of
    ok -> {ok, St#cl_st{connected_to = ServerPID}};
    _ -> {{error, user_already_connected, "A user with the nick " ++ St#cl_st.nick ++ "is already connected to" ++ _Server}, St}
end;

编辑 2 在测试套件中找到导致错误的特定行:

-define(HOST, '127.0.0.1').

new_client(Nick, GUIName) ->
ClientName = test_client:find_unique_name("client_"),
ClientAtom = list_to_atom(ClientName),

% Row below is causing the error
Result = slave:start(?HOST, ClientAtom),

assert_ok("start client node "++ClientName, element(1,Result)),
ClientNode = element(2,Result),

InitState = client:initial_state(Nick, GUIName),
Result2 = spawn(ClientNode, genserver, start, [ClientAtom, InitState, fun client:loop/2]),
assert("client startup "++ClientName, is_pid(Result2)),

{Nick, ClientAtom, ClientNode}.

您的函数 genserver:start/3 很可能未导出,或者模块 genserver 在调用它的 运行 代码所在的节点不可用。

已解决,在客户端与其他用户通信的完全不相关的部分。仍然使用 whereis 命令从程序的旧版本中定位其他用户。