Какое поведение OTP я должен использовать для такого модуля?

У меня есть простой модуль erlang, и я хочу переписать его на основе принципов OTP. Но я не могу определить, какой шаблон выбрать мне.

Код модуля:

-module(main).

-export([start/0, loop/0]).

start() -> 
    Mypid = spawn(main, loop, []),
    register( main, Mypid).

loop() ->
    receive
        [Pid, getinfo] -> Pid! [self(), welcome],
            io:fwrite( "Got ~p.~n", [Pid] ),
            // spawn new process here
            loop();
        quit -> ok;
        X ->
            io:fwrite( "Got ~p.~n", [ X ] ),
            // spawn new process here
            loop()
    end.

1 ответ

Решение

gen_server было бы хорошо.

Пара вещей:

  • отправлять сообщения себе - это плохая практика
  • сообщения обычно являются кортежами, а не списками, потому что они не являются динамическими
  • несмотря на ваш комментарий, вы не создаете новый процесс. Call to loop/0 входит в тот же цикл.

Gen_server init будет содержать ваше начальное / 0 тело. API вызывает последовательность и передает ваши вызовы через gen_server для handle_calls. Чтобы вызвать новый процесс при вызове функции, добавьте функцию spawn в тело требуемого handle_call. Не используйте handle_info для обработки входящих сообщений - вместо отправки их вызовите API gen_server и "переведите" ваш вызов в gen_server:call или cast. например

start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

init(_) ->
    {ok, #state{}}

welcome(Arg) ->
   gen_server:cast(?MODULE, {welcome, Arg}).

handle_cast({welcome, Arg},_,State) ->
  io:format("gen_server PID: ~p~n", [self()]),
  spawn(?MODULE, some_fun, [Arg]),
  {noreply, State}

some_fun(Arg) ->
  io:format("Incoming arguments ~p to me: ~p~n",[Arg, self()]).

Я никогда не компилировал выше, но это должно дать вам идею.

Другие вопросы по тегам