Мониторинг gen_server - PullRequest
       12

Мониторинг gen_server

2 голосов
/ 19 марта 2012

Я пытался контролировать gen_server, используя erlang: monitor / 2. К сожалению, каждый раз, когда я пытаюсь это сделать, оболочка Эрланга заходит в бесконечный цикл.

Вот тестовая программа, которую я написал, чтобы проверить это.

-module(testmon).

-compile(export_all).

start() ->
    {ok,Proc} = gen_server:start(calc,[],[]),
    erlang:monitor(process,Proc),
    receive
        {'DOWN', Ref, process, Pid,  normal} -> 
            io:format("~p said that ~p died by natural causes~n",[Ref,Pid]);
        {'DOWN', Ref, process, Pid,  Reason} ->
            io:format("~p said that ~p died by unnatural causes~n~p",[Ref,Pid,Reason])
    end.

Когда я использую приведенный выше код для наблюдения за чем-то вроде этого spawn (fun () -> ok end) (путем изменения строк 6 и 7) на erlang: monitor (spawn (fun () -> ok end)) выше код работает как задумано.

Может кто-нибудь показать мне, что я делаю не так? Можно ли контролировать процесс gen_server только через супервизор?

Спасибо

1 Ответ

3 голосов
/ 20 апреля 2012

Это не бесконечный цикл (в Erlang вообще нет циклов), ваша оболочка просто блокирует в получает , пока gen_server по какой-то причине не умрет. Если вы хотите, чтобы shell немедленно возвращался, просто создайте дополнительный процесс для мониторинга. Это не обязательно должен быть gen_supervisor, ваш код в отдельном процессе должен работать так, как задумано.

Это может выглядеть примерно так:

-module(testmon).

-compile(export_all).

start() ->
    {ok,Proc} = gen_server:start(calc,[],[]),
    spawn(?MODULE, monitor, [Proc]).

monitor(Proc) ->
    erlang:monitor(process,Proc),
    receive
        {'DOWN', Ref, process, Pid,  normal} -> 
            io:format("~p said that ~p died by natural causes~n",[Ref,Pid]);
        {'DOWN', Ref, process, Pid,  Reason} ->
            io:format("~p said that ~p died by unnatural causes~n~p",[Ref,Pid,Reason])
    end.
...