私が作成したプロセスのスーパーバイザーを作成しようとしています。私はこれをしばらくの間調査しましたが役に立たなかったので、誰かが助けてくれることを願っています.
これは課題用であるため、使用しなければならないインターフェースに特定の制限があるため、リストを使用した例や、Erlang サイトのより精巧な OTP の例も知っていますが、これらは適切ではありません。問題を示すために、アプリケーションから抜粋した例を提供しました。
通常の理由で終了した任意のワーカーを再起動しようとしています。ワーカー プロセスは次のとおりです。
-module(my_mod).
-export([start/1, init/1]).
start(Pid)->
{ok, spawn_link(?MODULE, init, [Pid])}.
init(Pid) ->
register(Pid, self()),
io:format("Started ~p~n",[Pid]),
loop().
loop() ->
receive stop -> exit(byebye) end.
スーパーバイザーでは、ワーカーを追跡して再起動するために ETS タブを使用しています。スーパーバイザーは次のようになります。
-module(my_sup).
-export([start_link/0, init/1, add_item/1, remove_item/1]).
start_link() ->
spawn(?MODULE, init, [self()]).
init(Pid) ->
process_flag(trap_exit, true),
register(?MODULE, Pid),
ets:new(?MODULE, [set, named_table, public]),
loop().
add_item(Pid) ->
ets:insert(?MODULE, {Pid}),
my_mod:start(Pid),
{ok, Pid}.
remove_item(Pid) ->
ets:delete(?MODULE, [Pid]).
loop() ->
io:format("Looping ~n"),
receive
{'EXIT', Pid, _Reason} ->
remove_item(Pid),
add_item(Pid)
end.
だから私はここで何かをしていると思います.my_modはスーパーバイザにリンクされているので、終了シグナルが通知されます.スーパーバイザはtrap_exitを設定して、スーパーバイザがシグナルを処理する機会を得る必要があります. しかし、** 例外 exit: stop がスローされるだけで、なぜそうなのかわかりませんか?
私のテストケースは次のとおりです。
1> c(my_sup), c(my_mod), my_sup:start_link().
Looping
<0.42.0>
2> my_sup:add_item(a).
Started a
{ok,a}
3> a ! stop .
** exception exit: byebye
誰かが私を正しい方向に向けることができますか?