File size: 3,022 Bytes
894656d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
%%%-------------------------------------------------------------------
%%% @doc HK-CORE :: root supervisor.
%%%
%%% Implements the `<otp_architecture>' hierarchy exactly:
%%%
%%%   hyperkitty_sup
%%%     +-- hk_event_sup       (started first: everything else can publish immediately)
%%%     +-- hk_messaging_sup
%%%     +-- hk_browser_sup
%%%     +-- hk_agent_sup
%%%     +-- hk_search_sup
%%%     +-- hk_api_sup         (started after every plane it exposes)
%%%     +-- hk_frontend_sup
%%%
%%% `rest_for_one': if an earlier-listed subsystem crashes, every
%%% subsystem *after* it in this list is restarted too, because they
%%% may depend on it (e.g. `hk_api_sup' talks to all of `hk_browser_sup',
%%% `hk_agent_sup', `hk_search_sup', `hk_messaging_sup', and
%%% `hk_event_sup'; if `hk_event_sup' restarts, callers that publish
%%% events don't get an error, but every listener that had subscribed
%%% to the old `hk_event_bus' has silently lost that subscription and
%%% must resubscribe -- `hk_api_sup' restarting alongside it forces
%%% every open WebSocket to reconnect and pick that back up, rather
%%% than leaving the frontend silently stale). Subsystems listed
%%% *before* the one that crashed are left running, so a browser
%%% crash never disturbs messaging or the event log, and an agent
%%% crash never disturbs the browser plane.
%%%
%%% `intensity'/`period' are a modest bump over OTP's typical default
%%% (3/5) to 8/10. The real defense against a mid-tree supervisor's
%%% *nested* children not having released their registered names yet
%%% (see `hk_sup_util' -- every registered-name `start_link/0' in
%%% this application waits for the old holder to actually die and
%%% retries once, rather than surfacing that transient race as a
%%% start error) lives in `hk_sup_util:start_link_retry/1', not in
%%% this number; this headroom just tolerates the occasional
%%% legitimate extra restart without weakening the check's real
%%% purpose of catching a genuinely crash-looping child.
%%% @end
%%%-------------------------------------------------------------------
-module(hyperkitty_sup).
-behaviour(supervisor).

-export([start_link/0]).
-export([init/1]).

-define(SERVER, ?MODULE).

start_link() ->
    supervisor:start_link({local, ?SERVER}, ?MODULE, []).

init([]) ->
    SupFlags = #{strategy => rest_for_one, intensity => 8, period => 10},
    ChildSpecs = [
        sup_child(hk_event_sup),
        sup_child(hk_messaging_sup),
        sup_child(hk_browser_sup),
        sup_child(hk_agent_sup),
        sup_child(hk_search_sup),
        worker_child(hk_health),
        sup_child(hk_api_sup),
        sup_child(hk_frontend_sup)
    ],
    {ok, {SupFlags, ChildSpecs}}.

%%% internal

sup_child(Mod) ->
    #{id => Mod, start => {Mod, start_link, []}, restart => permanent,
      shutdown => infinity, type => supervisor, modules => [Mod]}.

worker_child(Mod) ->
    #{id => Mod, start => {Mod, start_link, []}, restart => permanent,
      shutdown => 5000, type => worker, modules => [Mod]}.