-
Notifications
You must be signed in to change notification settings - Fork 28
/
ns_server_sup.erl
150 lines (118 loc) · 5.28 KB
/
ns_server_sup.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
%% @author Northscale <info@northscale.com>
%% @copyright 2010 NorthScale, Inc.
%%
%% 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 the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-module(ns_server_sup).
-behaviour(supervisor).
-export([start_link/0]).
-export([init/1, pull_plug/1]).
start_link() ->
application:start(os_mon),
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init([]) ->
pre_start(),
{ok, {{one_for_one,
misc:get_env_default(max_r, 3),
misc:get_env_default(max_t, 10)},
get_child_specs()}}.
pre_start() ->
misc:make_pidfile(),
misc:ping_jointo().
get_child_specs() ->
good_children() ++ bad_children().
%% Children that needn't be restarted when we pull the plug. These
%% cannot crash or hang if Mnesia is down, but they can depend on it
%% for proper operation unless they will cause other good children to
%% crash without it.
good_children() ->
[{ns_config_sup, {ns_config_sup, start_link, []},
permanent, infinity, supervisor,
[ns_config_sup]},
%% ns_log starts after ns_config because it needs the config to
%% find where to persist the logs
{ns_log, {ns_log, start_link, []},
permanent, 10, worker, [ns_log]},
{ns_log_events, {gen_event, start_link, [{local, ns_log_events}]},
permanent, 10, worker, dynamic},
{ns_mail_sup, {ns_mail_sup, start_link, []},
permanent, infinity, supervisor, [ns_mail_sup]},
{ns_node_disco_sup, {ns_node_disco_sup, start_link, []},
permanent, infinity, supervisor,
[ns_node_disco_sup]},
{ns_heart, {ns_heart, start_link, []},
permanent, 10, worker, [ns_heart]},
{ns_doctor, {ns_doctor, start_link, []},
permanent, 10, worker, [ns_doctor]},
{menelaus, {menelaus_app, start_subapp, []},
permanent, infinity, supervisor,
[menelaus_app]},
{ns_port_sup, {ns_port_sup, start_link, []},
permanent, 10, worker,
[ns_port_sup]},
{ns_tick_event, {gen_event, start_link, [{local, ns_tick_event}]},
permanent, 10, worker, dynamic},
{ns_stats_event, {gen_event, start_link, [{local, ns_stats_event}]},
permanent, 10, worker, dynamic},
{ns_good_bucket_worker, {work_queue, start_link, [ns_good_bucket_worker]},
permanent, 10, worker, [work_queue]},
{ns_good_bucket_sup, {ns_bucket_sup, start_link,
[ns_good_bucket_sup, fun good_bucket_children/1, ns_good_bucket_worker]},
permanent, infinity, supervisor, [ns_bucket_sup]},
{ns_orchestrator, {ns_orchestrator, start_link, []},
permanent, 20, worker, [ns_orchestrator]}
].
%% Children that get restarted if we pull the plug. These can depend
%% on Mnesia.
bad_children() ->
[{ns_mnesia, {ns_mnesia, start_link, []},
permanent, 5000, worker, [ns_mnesia]},
{ns_bad_bucket_worker, {work_queue, start_link, [ns_bad_bucket_worker]},
permanent, 10, worker, [work_queue]},
{ns_bad_bucket_sup, {ns_bucket_sup, start_link,
[ns_bad_bucket_sup, fun bad_bucket_children/1, ns_bad_bucket_worker]},
permanent, infinity, supervisor, [ns_bucket_sup]},
{ns_moxi_sup, {ns_moxi_sup, start_link, []},
permanent, infinity, supervisor,
[ns_moxi_sup]},
{ns_tick, {ns_tick, start_link, []},
permanent, 10, worker, [ns_tick]}].
%% beware that if it's called from one of restarted childs it won't
%% work. This can be allowed with further work here.
pull_plug(Fun) ->
GoodChildren = [Id || {Id, _, _, _, _, _} <- good_children()],
BadChildren = [Id || {Id, _, _, _, _, _} <- bad_children()],
error_logger:info_msg("~p plug pulled. Killing ~p, keeping ~p~n",
[?MODULE, BadChildren, GoodChildren]),
lists:foreach(fun(C) -> ok = supervisor:terminate_child(?MODULE, C) end,
lists:reverse(BadChildren)),
Fun(),
lists:foreach(fun(C) ->
R = supervisor:restart_child(?MODULE, C),
error_logger:info_msg("Restarting ~p: ~p~n", [C, R])
end,
BadChildren).
bad_bucket_children(Bucket) ->
[{{stats_collector, Bucket}, {stats_collector, start_link, [Bucket]},
permanent, 10, worker, [stats_collector]},
{{stats_archiver, Bucket}, {stats_archiver, start_link, [Bucket]},
permanent, 10, worker, [stats_archiver]},
{{stats_reader, Bucket}, {stats_reader, start_link, [Bucket]},
permanent, 10, worker, [stats_reader]}].
good_bucket_children(Bucket) ->
%% Start ns_memcached last so we know the bucket's good once it's available
[{{ns_vbm_sup, Bucket}, {ns_vbm_sup, start_link, [Bucket]},
permanent, 1000, worker, [ns_vbm_sup]},
{{ns_memcached, Bucket}, {ns_memcached, start_link, [Bucket]},
%% ns_memcached waits for the bucket to sync to disk before exiting
permanent, 86400000, worker, [ns_memcached]}].