Erlang stop gen_server

2019-05-21 08:31发布

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.

2条回答
走好不送
2楼-- · 2019-05-21 09:17

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.

查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-05-21 09:24

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.

查看更多
登录 后发表回答