-module(cabal_sup).
-behaviour(supervisor).
-export([start_link/1, stop/1, get_peer_pid/1]).
-export([init/1]).
start_link(Args) ->
case supervisor:start_link(?MODULE, {phase1, Args}) of
{ok, SupPid} ->
TransportSupPid = get_child_pid(SupPid, cabal_transport_sup),
StoragePath = proplists:get_value(storage, Args),
PeerServerSpec = #{
id => peer_server,
start =>
{cabal, start_link, [
[
{transport_sup, TransportSupPid},
{storage, StoragePath}
]
]},
restart => transient,
shutdown => 5000,
type => worker,
modules => [cabal]
},
{ok, PeerServerPid} = supervisor:start_child(SupPid, PeerServerSpec),
{ok, Db} = cabal:get_db(PeerServerPid),
PeerEventsSpec = #{
id => cabal_peer_events,
start =>
{cabal_peer_events, start_link, [
[
{db, Db},
{transport_sup, TransportSupPid},
{peer_server_pid, PeerServerPid}
]
]},
restart => transient,
shutdown => 5000,
type => worker,
modules => [cabal_peer_events]
},
{ok, PeerEventsPid} = supervisor:start_child(SupPid, PeerEventsSpec),
ok = cabal:update_peer_events_pid(PeerServerPid, PeerEventsPid),
{ok, SupPid};
Error ->
Error
end.
stop(SupPid) ->
MRef = erlang:monitor(process, SupPid),
unlink(SupPid),
exit(SupPid, shutdown),
receive
{'DOWN', MRef, process, SupPid, _Reason} ->
ok
end.
get_peer_pid(SupPid) ->
get_child_pid(SupPid, peer_server).
init({phase1, Args}) ->
SupFlags = #{
strategy => rest_for_one,
intensity => 5,
period => 10
},
[Host, WantPort] = proplists:get_value(listener, Args, ["0.0.0.0", 0]),
StoragePath = proplists:get_value(storage, Args),
TransportKp = cabal:create_or_load_transport_keypair(StoragePath),
TransportSupSpec = #{
id => cabal_transport_sup,
start =>
{cabal_transport_sup, start_link, [
[
{listen_addr, {Host, WantPort}},
{key_pair, TransportKp},
{event_handler, undefined}
]
]},
restart => permanent,
shutdown => infinity,
type => supervisor,
modules => [cabal_transport_sup]
},
{ok, {SupFlags, [TransportSupSpec]}}.
get_child_pid(SupPid, ChildId) ->
Children = supervisor:which_children(SupPid),
case lists:keyfind(ChildId, 1, Children) of
{ChildId, Pid, _, _} -> Pid;
false -> undefined
end.