Start a supervised rexi_governor per node
This generalizes rexi_server_mon to start per-node versions of a server
specified by a child module.
BugzID: 23717
BugzID: 23718
diff --git a/src/rexi_server_mon.erl b/src/rexi_server_mon.erl
index 756ab95..205ef4a 100644
--- a/src/rexi_server_mon.erl
+++ b/src/rexi_server_mon.erl
@@ -1,4 +1,4 @@
-% Copyright 2010 Cloudant
+% Copyright 2010-2013 Cloudant
%
% Licensed under the Apache License, Version 2.0 (the "License"); you may not
% use this file except in compliance with the License. You may obtain a copy of
@@ -18,7 +18,7 @@
-export([
- start_link/0,
+ start_link/1,
status/0
]).
@@ -33,35 +33,34 @@
]).
--define(SUP_MODULE, rexi_server_sup).
--define(CHILD_MODULE, rexi_server).
-define(INTERVAL, 60000).
-start_link() ->
- gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
+start_link(ChildMod) ->
+ Name = list_to_atom(lists:concat([ChildMod, "_mon"])),
+ gen_server:start_link({local, Name}, ?MODULE, ChildMod, []).
status() ->
gen_server:call(?MODULE, status).
-init([]) ->
+init(ChildMod) ->
net_kernel:monitor_nodes(true),
erlang:send_after(?INTERVAL, self(), check_nodes),
- {ok, nil}.
+ {ok, ChildMod}.
terminate(_Reason, _St) ->
ok.
-handle_call(status, _From, St) ->
- case missing_servers() of
+handle_call(status, _From, ChildMod) ->
+ case missing_servers(ChildMod) of
[] ->
- {reply, ok, St};
+ {reply, ok, ChildMod};
Missing ->
- {reply, {waiting, length(Missing)}, St}
+ {reply, {waiting, length(Missing)}, ChildMod}
end;
handle_call(Msg, _From, St) ->
@@ -74,52 +73,58 @@
{noreply, St}.
-handle_info({nodeup, _}, St) ->
- start_rexi_servers(),
- {noreply, St};
+handle_info({nodeup, _}, ChildMod) ->
+ start_servers(ChildMod),
+ {noreply, ChildMod};
handle_info({nodedown, _}, St) ->
{noreply, St};
-handle_info(check_nodes, St) ->
- start_rexi_servers(),
+handle_info(check_nodes, ChildMod) ->
+ start_servers(ChildMod),
erlang:send_after(?INTERVAL, self(), check_nodes),
- {noreply, St};
+ {noreply, ChildMod};
handle_info(Msg, St) ->
twig:log(notice, "~s ignored_info ~w", [?MODULE, Msg]),
{noreply, St}.
+code_change(_OldVsn, nil, _Extra) ->
+ {ok, rexi_server};
code_change(_OldVsn, St, _Extra) ->
{ok, St}.
-start_rexi_servers() ->
+start_servers(ChildMod) ->
lists:foreach(fun(Id) ->
- {ok, _} = start_rexi_server(Id)
- end, missing_servers()).
+ {ok, _} = start_server(ChildMod, Id)
+ end, missing_servers(ChildMod)).
-missing_servers() ->
- ServerIds = [list_to_atom("rexi_server_" ++ atom_to_list(Node))
+missing_servers(ChildMod) ->
+ ServerIds = [list_to_atom(lists:concat([ChildMod, "_", Node]))
|| Node <- [node() | nodes()]],
- ChildIds = [Id || {Id, _, _, _} <- supervisor:which_children(?SUP_MODULE)],
+ SupModule = sup_module(ChildMod),
+ ChildIds = [Id || {Id, _, _, _} <- supervisor:which_children(SupModule)],
ServerIds -- ChildIds.
-start_rexi_server(ChildId) ->
+start_server(ChildMod, ChildId) ->
ChildSpec = {
ChildId,
- {rexi_server, start_link, [ChildId]},
+ {ChildMod, start_link, [ChildId]},
permanent,
brutal_kill,
worker,
- [?CHILD_MODULE]
+ [ChildMod]
},
- case supervisor:start_child(?SUP_MODULE, ChildSpec) of
+ case supervisor:start_child(sup_module(ChildMod), ChildSpec) of
{ok, Pid} ->
{ok, Pid};
Else ->
erlang:error(Else)
end.
+
+sup_module(ChildMod) ->
+ list_to_atom(lists:concat([ChildMod, "_sup"])).
diff --git a/src/rexi_server_sup.erl b/src/rexi_server_sup.erl
index 97b5b9e..29c6ad6 100644
--- a/src/rexi_server_sup.erl
+++ b/src/rexi_server_sup.erl
@@ -18,11 +18,11 @@
-export([init/1]).
--export([start_link/0]).
+-export([start_link/1]).
-start_link() ->
- supervisor:start_link({local, ?MODULE}, ?MODULE, []).
+start_link(Name) ->
+ supervisor:start_link({local, Name}, ?MODULE, []).
init([]) ->
diff --git a/src/rexi_sup.erl b/src/rexi_sup.erl
index 1c13eea..8ee116f 100644
--- a/src/rexi_sup.erl
+++ b/src/rexi_sup.erl
@@ -39,7 +39,7 @@
},
{
rexi_server_sup,
- {rexi_server_sup, start_link, []},
+ {rexi_server_sup, start_link, [rexi_server_sup]},
permanent,
100,
supervisor,
@@ -47,7 +47,23 @@
},
{
rexi_server_mon,
- {rexi_server_mon, start_link, []},
+ {rexi_server_mon, start_link, [rexi_server]},
+ permanent,
+ 100,
+ worker,
+ [rexi_server_mon]
+ },
+ {
+ rexi_governor_sup,
+ {rexi_server_sup, start_link, [rexi_governor_sup]},
+ permanent,
+ 100,
+ supervisor,
+ [rexi_server_sup]
+ },
+ {
+ rexi_governor_mon,
+ {rexi_server_mon, start_link, [rexi_governor]},
permanent,
100,
worker,