Erlang stop gen_server

北战南征 提交于 2019-12-10 11:25:52

问题


I have gen_server:

start(UserName) ->
    case gen_server:start({global, UserName}, player, [], []) of
    {ok, _} ->
        io:format("Player: " ++ UserName ++ " started");
    {error, Error} ->
        Error
    end
    ...

Now i want to write function to stop this gen server. I have:

stop(UserName) ->
    gen_server:cast(UserName, stop).

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

I run it:

start("shk").
Player: shk startedok
stop(shk).
ok
start("shk").
{already_started,<0.268.0>}

But:

stop(player).
ok

is work.

How can i run gen_server by name and stop by name?

Thank you.


回答1:


First: You must always use the same name to address a process, "foo" and foo are different, so start by having a strict naming convention.

Second: When using globally registered processes, you also need to use {global, Name} for addressing processes.

In my opinion you should also convert the stop function to use gen_server:call, which will block and let you return a value from the gen_server. An example:

stop(Name) ->
    gen_server:call({global, Name}, stop).

handle_call(stop, _From, State) ->
    {stop, normal, shutdown_ok, State}

This would return shutdown_ok to the caller.

With this said, the global module is rather limited and alternatives like gproc provides much better distribution.




回答2:


I don't have the docs infront of me, but my guess would be that you need to wrap the username in a global tuple within the gen_server cast.



来源:https://stackoverflow.com/questions/5726481/erlang-stop-gen-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!