Packages
ra
0.9.4
3.1.9
3.1.8
3.1.7
3.1.6
3.1.5
3.1.4
3.1.3
3.1.2
3.1.1
3.1.0
3.0.2
3.0.1
3.0.0
3.0.0-beta.1
2.17.3
2.17.2
2.17.1
2.17.0
2.16.13
2.16.12
2.16.11
2.16.10
2.16.9
2.16.8
2.16.7
2.16.6
2.16.5
2.16.4
2.16.3
2.16.2
2.16.1
2.16.0
2.16.0-pre.12
2.16.0-pre.11
2.16.0-pre.10
2.16.0-pre.9
2.16.0-pre.8
2.16.0-pre.7
2.16.0-pre.6
2.16.0-pre.5
2.16.0-pre.4
2.16.0-pre.3
2.16.0-pre.2
2.16.0-pre.1
2.15.4
2.15.3
2.15.2
2.15.1
2.15.0
2.14.0
2.13.6
2.13.5
2.13.4
2.13.3
2.13.2
2.13.1
2.13.0
2.13.0-pre.1
2.12.0
2.11.0
2.11.0-pre.1
2.10.2-pre.2
2.10.2-pre.1
2.10.1
2.10.0
2.10.0-pre.3
2.10.0-pre.2
2.10.0-pre.1
2.9.10-pre.1
2.9.1
2.9.1-pre.2
2.9.1-pre.1
2.9.0
2.8.0
retired
2.7.3
2.7.2
2.7.1
2.7.0
2.7.0-pre.3
2.7.0-pre.2
2.7.0-pre.1
2.6.3
2.6.2
2.6.1
2.6.0-pre.1
2.5.1
2.5.1-pre.1
2.5.0
2.4.9
2.4.8
2.4.7
2.4.6
2.4.5
2.4.4
2.4.3
2.4.2
retired
2.4.1
2.4.0
2.3.0
2.2.0
2.1.0
2.0.13
2.0.12
2.0.11
2.0.10
2.0.9
2.0.8
2.0.7
2.0.6
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.9.6
0.9.5
0.9.4
0.9.2
0.3.3
retired
0.3.2
retired
0.3.1
retired
Raft library
Current section
Files
Jump to
Current section
Files
src/ra_server_sup_sup.erl
%% @hidden
-module(ra_server_sup_sup).
-behaviour(supervisor).
%% API functions
-export([start_server/1,
restart_server/1,
stop_server/1,
delete_server/1,
remove_all/0,
start_link/0,
% for rpcs only
prepare_start_rpc/1,
prepare_restart_rpc/1,
delete_server_rpc/1]).
%% Supervisor callbacks
-export([init/1]).
-include("ra.hrl").
-spec start_server(ra_server:ra_server_config()) ->
supervisor:startchild_ret() | {error, not_new}.
start_server(#{id := NodeId,
uid := UId} = Config) ->
%% check that the node isn't already registered
Node = ra_lib:ra_server_id_node(NodeId),
case rpc:call(Node, ?MODULE, prepare_start_rpc, [UId]) of
ok ->
supervisor:start_child({?MODULE, Node}, [Config]);
Err ->
Err
end.
-spec restart_server(ra_server_id()) -> supervisor:startchild_ret().
restart_server({RaName, Node}) ->
case rpc:call(Node, ?MODULE, prepare_restart_rpc, [RaName]) of
{ok, Config} ->
supervisor:start_child({?MODULE, Node}, [Config]);
{error, _} = Err ->
Err;
Err ->
{error, Err}
end.
prepare_start_rpc(UId) ->
case ra_directory:name_of(UId) of
undefined ->
ok;
Name ->
case whereis(Name) of
undefined ->
{error, not_new};
Pid ->
{error, {already_started, Pid}}
end
end.
prepare_restart_rpc(RaName) ->
case ra_directory:uid_of(RaName) of
undefined ->
name_not_registered;
UId ->
Dir = ra_env:server_data_dir(UId),
case ra_directory:where_is(UId) of
Pid when is_pid(Pid) ->
case is_process_alive(Pid) of
true ->
{error, {already_started, Pid}};
false ->
ra_log:read_config(Dir)
end;
_ ->
% can it be made generic without already knowing the config state?
ra_log:read_config(Dir)
end
end.
-spec stop_server(RaNodeId :: ra_server_id()) -> ok | {error, term()}.
stop_server({RaName, Node}) ->
%% TODO: this could timeout
Pid = rpc:call(Node, ra_directory,
where_is_parent, [RaName]),
supervisor:terminate_child({?MODULE, Node}, Pid);
stop_server(RaName) ->
% local node
case ra_directory:where_is_parent(RaName) of
undefined -> ok;
Pid ->
supervisor:terminate_child(?MODULE, Pid)
end.
-spec delete_server(NodeId :: ra_server_id()) ->
ok | {error, term()}.
delete_server(NodeId) ->
Node = ra_lib:ra_server_id_node(NodeId),
Name = ra_lib:ra_server_id_to_local_name(NodeId),
case stop_server(NodeId) of
ok ->
rpc:call(Node, ?MODULE, delete_server_rpc, [Name]);
{error, _} = Err -> Err
end.
delete_server_rpc(RaName) ->
?INFO("Deleting server ~w and it's data directory.~n",
[RaName]),
%% TODO: better handle and report errors
UId = ra_directory:uid_of(RaName),
Pid = ra_directory:where_is(RaName),
ra_log_meta:delete(UId),
Dir = ra_env:server_data_dir(UId),
_ = supervisor:terminate_child(?MODULE, UId),
% TODO: move into separate retrying process
try ra_lib:recursive_delete(Dir) of
ok ->
_ = ra_directory:unregister_name(UId),
%% forcefully clean up ETS tables
catch ets:delete(ra_log_metrics, UId),
catch ets:delete(ra_log_snapshot_state, UId),
catch ets:delete(ra_metrics, RaName),
catch ets:delete(ra_state, RaName),
catch ets:delete(ra_open_file_metrics, Pid),
ok
catch
_:_ = Err ->
?WARN("delete_server/1 failed to delete directory ~s~n"
"Error: ~p~n", [Dir, Err])
end,
ok.
remove_all() ->
_ = [begin
?INFO("terminating child ~w~n", [Pid]),
supervisor:terminate_child(?MODULE, Pid)
end
|| {_, Pid, _, _} <- supervisor:which_children(?MODULE)],
ok.
-spec start_link() ->
{ok, pid()} | ignore | {error, term()}.
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init([]) ->
SupFlags = #{strategy => simple_one_for_one},
ChildSpec = #{id => undefined,
type => supervisor,
restart => temporary,
start => {ra_server_sup, start_link, []}},
{ok, {SupFlags, [ChildSpec]}}.