fix endpoint_sup

This commit is contained in:
anlicheng 2026-05-11 18:22:52 +08:00
parent 4d77369ab1
commit 0b066e4bb0
7 changed files with 125 additions and 125 deletions

View File

@ -2,8 +2,8 @@
[{description, "Endpoint OTP application"}, [{description, "Endpoint OTP application"},
{vsn, "0.1.0"}, {vsn, "0.1.0"},
{registered, [ {registered, [
endpoint_sup_sup,
endpoint_sup, endpoint_sup,
endpoint_adapter_sup,
endpoint_subscription, endpoint_subscription,
endpoint_log endpoint_log
]}, ]},

View File

@ -0,0 +1,88 @@
%%%-------------------------------------------------------------------
%% @doc endpoint top level supervisor.
%% @end
%%%-------------------------------------------------------------------
-module(endpoint_adapter_sup).
-behaviour(supervisor).
-include("endpoint.hrl").
-export([start_link/0]).
-export([ensured_endpoint_started/1, delete_endpoint/1]).
-export([init/1]).
-define(SERVER, ?MODULE).
start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
%% sup_flags() = #{strategy => strategy(), % optional
%% intensity => non_neg_integer(), % optional
%% period => pos_integer()} % optional
%% child_spec() = #{id => child_id(), % mandatory
%% start => mfargs(), % mandatory
%% restart => restart(), % optional
%% shutdown => shutdown(), % optional
%% type => worker(), % optional
%% modules => modules()} % optional
init([]) ->
SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600},
Endpoints = iot_api_client:get_all_endpoints(),
ChildSpecs = lists:filtermap(fun(EndpointInfo) ->
case endpoint:endpoint_record(EndpointInfo) of
error ->
false;
{ok, Endpoint} ->
case endpoint:is_support(endpoint:get_protocol(Endpoint)) of
true ->
{true, child_spec(Endpoint)};
false ->
false
end
end
end, Endpoints),
{ok, {SupFlags, ChildSpecs}}.
-spec ensured_endpoint_started(Endpoint :: #endpoint{}) -> {ok, Pid :: pid()} | {error, Reason :: any()}.
ensured_endpoint_started(Endpoint = #endpoint{}) ->
case supervisor:start_child(?MODULE, child_spec(Endpoint)) of
{ok, Pid} when is_pid(Pid) ->
{ok, Pid};
{error, {'already_started', Pid}} when is_pid(Pid) ->
{ok, Pid};
{error, Error} ->
{error, Error}
end.
-spec delete_endpoint(Id :: integer()) -> ok | {error, Reason :: any()}.
delete_endpoint(Id) when is_integer(Id) ->
Name = endpoint:get_name(Id),
case supervisor:terminate_child(?MODULE, Name) of
ok ->
delete_endpoint_child(Name);
{error, not_found} ->
delete_endpoint_child(Name);
{error, Reason} ->
{error, Reason}
end.
delete_endpoint_child(Name) ->
case supervisor:delete_child(?MODULE, Name) of
ok ->
ok;
{error, not_found} ->
ok;
{error, Reason} ->
{error, Reason}
end.
child_spec(Endpoint = #endpoint{id = Id}) ->
Name = endpoint:get_name(Id),
#{id => Name,
start => {endpoint, start_link, [Endpoint]},
restart => permanent,
shutdown => 2000,
type => worker,
modules => ['endpoint']}.

View File

@ -9,7 +9,7 @@
-export([start/2, stop/1]). -export([start/2, stop/1]).
start(_StartType, _StartArgs) -> start(_StartType, _StartArgs) ->
endpoint_sup_sup:start_link(). endpoint_sup:start_link().
stop(_State) -> stop(_State) ->
ok. ok.

View File

@ -9,8 +9,6 @@
-include("endpoint.hrl"). -include("endpoint.hrl").
-export([start_link/0]). -export([start_link/0]).
-export([ensured_endpoint_started/1, delete_endpoint/1]).
-export([init/1]). -export([init/1]).
-define(SERVER, ?MODULE). -define(SERVER, ?MODULE).
@ -28,61 +26,33 @@ start_link() ->
%% type => worker(), % optional %% type => worker(), % optional
%% modules => modules()} % optional %% modules => modules()} % optional
init([]) -> init([]) ->
SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600}, SupFlags = #{strategy => one_for_all, intensity => 1000, period => 3600},
Endpoints = iot_api_client:get_all_endpoints(), ChildSpecs = [
ChildSpecs = lists:filtermap(fun(EndpointInfo) -> #{
case endpoint:endpoint_record(EndpointInfo) of id => endpoint_log,
error -> start => {'endpoint_log', start_link, []},
false; restart => permanent,
{ok, Endpoint} -> shutdown => 2000,
case endpoint:is_support(endpoint:get_protocol(Endpoint)) of type => worker,
true -> modules => ['endpoint_log']
{true, child_spec(Endpoint)}; },
false ->
false #{
end id => endpoint_subscription,
end start => {'endpoint_subscription', start_link, []},
end, Endpoints), restart => permanent,
shutdown => 2000,
type => worker,
modules => ['endpoint_subscription']
},
#{
id => 'endpoint_adapter_sup',
start => {'endpoint_adapter_sup', start_link, []},
restart => permanent,
shutdown => 2000,
type => supervisor,
modules => ['endpoint_adapter_sup']
}
],
{ok, {SupFlags, ChildSpecs}}. {ok, {SupFlags, ChildSpecs}}.
-spec ensured_endpoint_started(Endpoint :: #endpoint{}) -> {ok, Pid :: pid()} | {error, Reason :: any()}.
ensured_endpoint_started(Endpoint = #endpoint{}) ->
case supervisor:start_child(?MODULE, child_spec(Endpoint)) of
{ok, Pid} when is_pid(Pid) ->
{ok, Pid};
{error, {'already_started', Pid}} when is_pid(Pid) ->
{ok, Pid};
{error, Error} ->
{error, Error}
end.
-spec delete_endpoint(Id :: integer()) -> ok | {error, Reason :: any()}.
delete_endpoint(Id) when is_integer(Id) ->
Name = endpoint:get_name(Id),
case supervisor:terminate_child(?MODULE, Name) of
ok ->
delete_endpoint_child(Name);
{error, not_found} ->
delete_endpoint_child(Name);
{error, Reason} ->
{error, Reason}
end.
delete_endpoint_child(Name) ->
case supervisor:delete_child(?MODULE, Name) of
ok ->
ok;
{error, not_found} ->
ok;
{error, Reason} ->
{error, Reason}
end.
child_spec(Endpoint = #endpoint{id = Id}) ->
Name = endpoint:get_name(Id),
#{id => Name,
start => {endpoint, start_link, [Endpoint]},
restart => permanent,
shutdown => 2000,
type => worker,
modules => ['endpoint']}.

View File

@ -1,58 +0,0 @@
%%%-------------------------------------------------------------------
%% @doc endpoint top level supervisor.
%% @end
%%%-------------------------------------------------------------------
-module(endpoint_sup_sup).
-behaviour(supervisor).
-include("endpoint.hrl").
-export([start_link/0]).
-export([init/1]).
-define(SERVER, ?MODULE).
start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
%% sup_flags() = #{strategy => strategy(), % optional
%% intensity => non_neg_integer(), % optional
%% period => pos_integer()} % optional
%% child_spec() = #{id => child_id(), % mandatory
%% start => mfargs(), % mandatory
%% restart => restart(), % optional
%% shutdown => shutdown(), % optional
%% type => worker(), % optional
%% modules => modules()} % optional
init([]) ->
SupFlags = #{strategy => one_for_all, intensity => 1000, period => 3600},
ChildSpecs = [
#{
id => endpoint_log,
start => {'endpoint_log', start_link, []},
restart => permanent,
shutdown => 2000,
type => worker,
modules => ['endpoint_log']
},
#{
id => endpoint_subscription,
start => {'endpoint_subscription', start_link, []},
restart => permanent,
shutdown => 2000,
type => worker,
modules => ['endpoint_subscription']
},
#{
id => 'endpoint_sup',
start => {'endpoint_sup', start_link, []},
restart => permanent,
shutdown => 2000,
type => supervisor,
modules => ['endpoint_sup']
}
],
{ok, {SupFlags, ChildSpecs}}.

View File

@ -36,7 +36,7 @@ handle_request("POST", "/endpoint/start", _, #{<<"id">> := Id}) when is_integer(
{ok, EndpointInfo} -> {ok, EndpointInfo} ->
case endpoint:endpoint_record(EndpointInfo) of case endpoint:endpoint_record(EndpointInfo) of
{ok, Endpoint = #endpoint{title = Title}} -> {ok, Endpoint = #endpoint{title = Title}} ->
case endpoint_sup:ensured_endpoint_started(Endpoint) of case endpoint_adapter_sup:ensured_endpoint_started(Endpoint) of
{ok, Pid} when is_pid(Pid) -> {ok, Pid} when is_pid(Pid) ->
{ok, 200, iot_util:json_data(<<"success">>)}; {ok, 200, iot_util:json_data(<<"success">>)};
{error, Reason} -> {error, Reason} ->
@ -53,7 +53,7 @@ handle_request("POST", "/endpoint/stop", _, #{<<"id">> := Id}) when is_integer(I
undefined -> undefined ->
{ok, 200, iot_util:json_error(404, <<"endpoint not found">>)}; {ok, 200, iot_util:json_error(404, <<"endpoint not found">>)};
{ok, _} -> {ok, _} ->
case endpoint_sup:delete_endpoint(Id) of case endpoint_adapter_sup:delete_endpoint(Id) of
ok -> ok ->
{ok, 200, iot_util:json_data(<<"success">>)}; {ok, 200, iot_util:json_data(<<"success">>)};
{error, Reason} -> {error, Reason} ->
@ -71,7 +71,7 @@ handle_request("POST", "/endpoint/restart", _, #{<<"id">> := Id}) when is_intege
{ok, Endpoint = #endpoint{title = Title}} -> {ok, Endpoint = #endpoint{title = Title}} ->
case endpoint:get_pid(Id) of case endpoint:get_pid(Id) of
undefined -> undefined ->
case endpoint_sup:ensured_endpoint_started(Endpoint) of case endpoint_adapter_sup:ensured_endpoint_started(Endpoint) of
{ok, Pid} when is_pid(Pid) -> {ok, Pid} when is_pid(Pid) ->
{ok, 200, iot_util:json_data(<<"success">>)}; {ok, 200, iot_util:json_data(<<"success">>)};
{error, Reason} -> {error, Reason} ->
@ -79,9 +79,9 @@ handle_request("POST", "/endpoint/restart", _, #{<<"id">> := Id}) when is_intege
{ok, 200, iot_util:json_error(404, <<"restart endpoint error">>)} {ok, 200, iot_util:json_error(404, <<"restart endpoint error">>)}
end; end;
Pid when is_pid(Pid) -> Pid when is_pid(Pid) ->
case endpoint_sup:delete_endpoint(Id) of case endpoint_adapter_sup:delete_endpoint(Id) of
ok -> ok ->
case endpoint_sup:ensured_endpoint_started(Endpoint) of case endpoint_adapter_sup:ensured_endpoint_started(Endpoint) of
{ok, Pid0} when is_pid(Pid0) -> {ok, Pid0} when is_pid(Pid0) ->
{ok, 200, iot_util:json_data(<<"success">>)}; {ok, 200, iot_util:json_data(<<"success">>)};
{error, Reason} -> {error, Reason} ->

View File

@ -1,4 +1,4 @@
{erl_opts, [debug_info, {i, "include"}]}. {erl_opts, [debug_info, {i, "apps/iot/include"}, {i, "apps/endpoint/include"}]}.
{project_app_dirs, ["apps/*"]}. {project_app_dirs, ["apps/*"]}.