Erlang остановить gen_server

У меня есть gen_server:

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

Теперь я хочу написать функцию, чтобы остановить этот ген-сервер. У меня есть:

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

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

Я запускаю это:

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

Но:

stop(player).
ok

это работа.

Как запустить gen_server по имени и остановить по имени?

Спасибо.


person 0xAX    schedule 20.04.2011    source источник


Ответы (2)


Во-первых: вы всегда должны использовать одно и то же имя для обращения к процессу, "foo" и foo разные, поэтому начните со строгого соглашения об именах.

Во-вторых: при использовании глобально зарегистрированных процессов вам также необходимо использовать {global, Name} для адресации процессов.

На мой взгляд, вам также следует преобразовать функцию stop для использования gen_server:call, которая заблокирует и позволит вам вернуть значение из gen_server. Пример:

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

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

Это вернет shutdown_ok вызывающей стороне.

При этом модуль global довольно ограничен, а альтернативы, такие как gproc, обеспечивают гораздо лучшее распространение.

person knutin    schedule 20.04.2011
comment
gen_server имеет для этого специальную функцию stop/1, stop/3 erlang.org/ doc/man/gen_server.html#stop-1 - person Alexander Shavelev; 20.05.2016

У меня нет документов передо мной, но я предполагаю, что вам нужно обернуть имя пользователя в глобальный кортеж в приведении gen_server.

person Lukas    schedule 20.04.2011