Какое поведение 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()]).
Я никогда не компилировал выше, но это должно дать вам идею.