Packages
ra
0.9.2
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.erl
%% @hidden
-module(ra_server_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]);
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),
% can it be made generic without already knowing the config state?
ra_log:read_config(Dir)
end.
-spec stop_server(RaNodeId :: ra_server_id()) -> ok | {error, term()}.
stop_server({RaName, Node}) ->
Pid = rpc:call(Node, ra_directory,
where_is, [RaName]),
supervisor:terminate_child({?MODULE, Node}, Pid);
stop_server(RaName) ->
% local node
case ra_directory:where_is(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 ->
?INFO("Deleting node ~p and it's data.~n", [NodeId]),
rpc:call(Node, ?MODULE, delete_server_rpc, [Name]);
{error, _} = Err -> Err
end.
delete_server_rpc(RaName) ->
%% TODO: better handle and report errors
UId = ra_directory:uid_of(RaName),
Dir = ra_env:server_data_dir(UId),
ok = ra_log_segment_writer:release_segments(
ra_log_segment_writer, UId),
supervisor:terminate_child(?MODULE, UId),
% TODO: move into separate retrying process
try ra_lib:recursive_delete(Dir) of
ok -> ok
catch
_:_ = Err ->
?WARN("delete_server/2 failed to delete directory ~s~n"
"Error: ~p~n", [Dir, Err])
end,
ra_directory:unregister_name(UId),
ok.
remove_all() ->
[begin
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,
intensity => 10,
period => 5},
ChildSpec = #{id => undefined,
type => worker,
% needs to be transient as may shut itself down by returning
% {stop, normal, State}
restart => transient,
start => {ra_server_proc, start_link, []}},
{ok, {SupFlags, [ChildSpec]}}.