0

私はこの構造を持つスーパーバイザーツリーを構築しようとしています:

1 つのルート スーパーバイザ -> 3 つの「レベル」スーパーバイザ -> 各レベル スーパーバイザにはイニシャライザ スーパーバイザがあります -> X 個のワーカー (例のために現在は 1 つだけ)

しかし、何らかの理由で、第 2 レベルのスーパーバイザーを開始すると、ツリー全体が終了します。1 つのルート -> 1 つのレベル -> 1 つの init -> 1 つのワーカー (または複数のワーカー) のみを開始する場合は問題ありませんが、さらに追加しようとするとすぐにツリーが終了するスーパバイザ。

-module(otp_supervisor).
-behavior(supervisor).

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

start_cell(root) ->
    supervisor:start_link({local, root}, ?MODULE, [root]);
start_cell({Type, Role}) ->
    supervisor:start_link({local, Type}, ?MODULE, [{Type, Role}]).

init([root]) -> 
    init_root(one_for_one, 3, 60);
init([{level, Param}]) -> 
    init_level(one_for_one, 3, 60, {member, Param});
init([{member, Param}]) -> 
    init_member(one_for_one, 3, 60, Param).

init_root(RestartStrategy, MaxRestart, MaxTime) ->
    io:format("~p ~s: Spawning...~n", [self(), root_supervisor]),
    {ok, {
        {RestartStrategy, MaxRestart, MaxTime},
        [
            {olevel,
                {otp_supervisor, start_cell, [{level, overseer}]},
                permanent, 1000, supervisor, [otp_supervisor]
            },
            {slevel,
                {otp_supervisor, start_cell, [{level, supervisor}]},
              permanent, 1000, supervisor, [otp_supervisor]
            },
            {wlevel,
                {otp_supervisor, start_cell, [{level, worker}]},
                permanent, 1000, supervisor, [otp_supervisor]
            }
        ]
        }
    }.

init_level(RestartStrategy, MaxRestart, MaxTime, {member, overseer}) ->
    io:format("~p ~s: Spawning...~n", [self(), overseer_level_supervisor]),
    {ok, {
        {RestartStrategy, MaxRestart, MaxTime},
        [
            {oinit,
                {otp_supervisor, start_cell, [{member, overseer}]},
                permanent, 1000, supervisor, [otp_supervisor]}
        ]
        }
    };
init_level(RestartStrategy, MaxRestart, MaxTime, {member, supervisor}) ->
    io:format("~p ~s: Spawning...~n", [self(), supervisor_level_supervisor]),
    {ok, {
        {RestartStrategy, MaxRestart, MaxTime},
        [
            {sinit,
                {otp_supervisor, start_cell, [{member, supervisor}]},
                permanent, 1000, supervisor, [otp_supervisor]}
        ]
        }
    };
init_level(RestartStrategy, MaxRestart, MaxTime, {member, worker}) ->
    io:format("~p ~s: Spawning...~n", [self(), worker_level_supervisor]),
    {ok, {
        {RestartStrategy, MaxRestart, MaxTime},
        [
            {winit,
                {otp_supervisor, start_cell, [{member, worker}]},
                permanent, 1000, supervisor, [otp_supervisor]}
        ]
        }
    }.

init_member(RestartStrategy, MaxRestart, MaxTime, overseer) ->
    io:format("~p ~s: Spawning...~n", [self(), init_overseer]),
    {ok, {
        {RestartStrategy, MaxRestart, MaxTime},
        [
            {ol_core,
                {aux_datasocket, start, [ol_overseer1]},
                permanent, 1000, worker, [aux_datasocket]
            }
        ]
        }
    };
init_member(RestartStrategy, MaxRestart, MaxTime, supervisor) ->
    io:format("~p ~s: Spawning...~n", [self(), init_supervisor]),
    {ok, {
        {RestartStrategy, MaxRestart, MaxTime},
        [
            {sl_core,
                {aux_datasocket, start, [sl_overseer1]},
                permanent, 1000, worker, [aux_datasocket]
            }
        ]
        }
    };
init_member(RestartStrategy, MaxRestart, MaxTime, worker) ->
    io:format("~p ~s: Spawning...~n", [self(), init_worker]),
    {ok, {
        {RestartStrategy, MaxRestart, MaxTime},
        [
            {wl_core,
                {aux_datasocket, start, [wl_overseer1]},
                permanent, 1000, worker, [aux_datasocket]
            }
        ]
        }
    }.

aux_datasocket モジュールは非常に単純な gen_server であり、それ自体で完全に正常に動作するため (現在 gen_server を起動するだけなので)、エラーがそのモジュールにあるわけではないと確信しています。

4

1 に答える 1

1

推測:{local, Type}登録ポイントで同じスーパーバイザーの複数の登録を行っています。これをデバッグする方法は、実行rel -boot start_saslしてからクラッシュ/進行レポートを探し、何が問題なのかを突き止めることです。多重度の問題は、これが間違っていることを示唆しています。

もう 1 つの重要な点は、これをシェルから実行すると、ツリーがシェルにリンクされることです。そのため、エラーが原因でシェルを強制終了した場合、poof もスーパーバイザー ツリーに移動します。リンクされたネットワークの外に移動する必要があります。

Pid = spawn(fun() -> {ok, _} = supervisor_tree_start(), receive stop -> ok end end),
...
Pid ! stop.
于 2012-11-28T14:01:53.440 に答える