1

編集:以下。

監視対象の gen_server がすぐにシャットダウンするのはなぜですか?

アプリケーションで必要なコマンド チェーンをより明確にするために、これらの組織名を付けます。最初に「assembly_line_worker」から開始し、後で「marketing_specialist」を監視ツリーに追加します...

ceo_supervisor.erl

-module(ceo_supervisor).
-behaviour(supervisor).

-export([start_link/1]).
-export([init/1]).

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

init([Args]) ->
     RestartStrategy = {one_for_one, 10, 60},
     ChildSpec= {assembly_line_worker_supervisor,
          {assembly_line_worker_supervisor, start_link, [Args]},
          permanent, infinity, supervisor, [assembly_line_worker_supervisor]},
     {ok, {RestartStrategy, [ChildSpec]}}.    

assembly_line_worker_supervisor.erl

-module(assembly_line_worker_supervisor).
-behaviour(supervisor).

-export([start_link/1]).
-export([init/1]). %% Internal

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

init([Args]) ->
    RestartStrategy = {one_for_one, 10, 60},
    ChildSpec = {assembly_line_worker, {assembly_line_worker, start_link, [Args]}, permanent,     
        infinity, worker, [assembly_line_worker]},
    {ok, {RestartStrategy, [ChildSpec]}}.

assembly_line_worker.erl

-module(assembly_line_worker).
...

init([State]) ->
   process_flag(trap_exit, true),
   {ok, State}.

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

handle_cast(...,State} ->
    io:format("We're getting this message.~n",[]),
    {noreply, State};
...

何が起きているかというと、アセンブリ ライン ワーカーは、ceo_supervisor:start_link(#innovative_ideas{}) コマンドが呼び出された直後に送信されるいくつかのメッセージを受信するなど、いくつかの作業を行ってからシャットダウンします。理由はありますか?コンソールへの io:format であるため、gen_server がいくつかのメッセージを受信して​​いることはわかっています。

ありがとう!


編集:私は erlsrv.exe を介して Windows でこれをホストしています。次のような関数を介してプログラムを起動すると、次のことがわかりました。

start() ->
    ceo_supervisor:start_link(#innovative_ideas{}),
    assembly_line_worker:ask_for_more_pay(), %% Prints out "I want more $$$" as expected,
    ok.

...この関数がすぐに終了すると、スーパーバイザー / gen_servers がシャットダウンします。これはすべて監督を介して元の呼び出しプロセスにリンクされているため、これが終了すると予想されます。

したがって、より良い質問は、すべての起動構成を行った後、スーパーバイザーが実行を継続できるようにするにはどうすればよいでしょうか? これらすべてをアプリケーションにラップする以外にオプションはありますか? (これは悪くない音ですが...)

掘り下げた質問をありがとう!私はそのようにして監督者についてもっと学びました。

バットマン

4

2 に答える 2

2

何が起こっているかについてより多くの情報を得るには、スーパーバイザを起動する前に sasl を起動します: application:start(sasl)。

これをデバッグする別の方法は、erlang シェルからワーカーを開始して、サーバーをクラッシュさせた一連のメッセージを送信することです。ところで: 2 レベルのスーパーバイザーが必要ですか?

于 2012-10-11T09:13:32.213 に答える
2

いくつかの即時のコメント:

ceo_supervisor:init/1スーパーバイザーの子仕様では、の代わりに宣言する必要がありtransientますpermanent

erl -boot start_sasl何か問題が発生したときにエラーログを取得し、クラッシャーのクラッシュレポートを取得できるように実行します。

これをシェルで実行して何かミスをすると、ツリーは強制的に殺されます。これは、シェルにリンクしていて、シェルがエラーでクラッシュするためです。だからあなたはあなたの木を引きずっています。次のようなものを試してください:

 Pid = spawn(fun() -> my_app:start() end).

だからあなたはそれを分割しました。に終了メッセージを送信して、アプリを強制終了できますPid

于 2012-10-13T11:23:00.183 に答える