syn_sup.erl 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. %% ==========================================================================================================
  2. %% Syn - A global Process Registry and Process Group manager.
  3. %%
  4. %% The MIT License (MIT)
  5. %%
  6. %% Copyright (c) 2015-2022 Roberto Ostinelli <roberto@ostinelli.net> and Neato Robotics, Inc.
  7. %%
  8. %% Permission is hereby granted, free of charge, to any person obtaining a copy
  9. %% of this software and associated documentation files (the "Software"), to deal
  10. %% in the Software without restriction, including without limitation the rights
  11. %% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. %% copies of the Software, and to permit persons to whom the Software is
  13. %% furnished to do so, subject to the following conditions:
  14. %%
  15. %% The above copyright notice and this permission notice shall be included in
  16. %% all copies or substantial portions of the Software.
  17. %%
  18. %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. %% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. %% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. %% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. %% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. %% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. %% THE SOFTWARE.
  25. %% ==========================================================================================================
  26. %% @private
  27. -module(syn_sup).
  28. -behaviour(supervisor).
  29. %% API
  30. -export([start_link/0]).
  31. -export([node_scopes/0, add_node_to_scope/1]).
  32. %% supervisor callbacks
  33. -export([init/1]).
  34. %% includes
  35. -include("syn.hrl").
  36. %% ===================================================================
  37. %% API
  38. %% ===================================================================
  39. -spec start_link() -> {ok, pid()} | {already_started, pid()} | shutdown.
  40. start_link() ->
  41. supervisor:start_link({local, ?MODULE}, ?MODULE, []).
  42. -spec node_scopes() -> [atom()].
  43. node_scopes() ->
  44. application:get_env(syn, scopes, []).
  45. -spec add_node_to_scope(Scope :: atom()) -> ok.
  46. add_node_to_scope(Scope) when is_atom(Scope) ->
  47. error_logger:info_msg("SYN[~s] Adding node to scope <~s>", [node(), Scope]),
  48. Scopes0 = node_scopes(),
  49. case lists:member(Scope, Scopes0) of
  50. true ->
  51. %% nothing to do
  52. ok;
  53. false ->
  54. %% add scope
  55. Scopes = [Scope | Scopes0],
  56. %% save to ENV (failsafe if sup is restarted)
  57. application:set_env(syn, scopes, Scopes),
  58. %% start child
  59. supervisor:start_child(?MODULE, child_spec(Scope)),
  60. ok
  61. end.
  62. %% ===================================================================
  63. %% Callbacks
  64. %% ===================================================================
  65. -spec init([]) ->
  66. {ok, {{supervisor:strategy(), non_neg_integer(), pos_integer()}, [supervisor:child_spec()]}}.
  67. init([]) ->
  68. %% backbone
  69. BackboneChildSpec = #{
  70. id => syn_backbone,
  71. start => {syn_backbone, start_link, []},
  72. type => worker,
  73. shutdown => 10000,
  74. restart => permanent,
  75. modules => [syn_backbone]
  76. },
  77. %% build children
  78. Children = [BackboneChildSpec] ++
  79. %% add scopes sup
  80. lists:foldl(fun(Scope, Acc) ->
  81. %% add to specs
  82. [child_spec(Scope) | Acc]
  83. end, [], node_scopes()),
  84. %% return
  85. {ok, {{one_for_one, 10, 10}, Children}}.
  86. %% ===================================================================
  87. %% Internals
  88. %% ===================================================================
  89. -spec child_spec(Scope :: atom()) -> supervisor:child_spec().
  90. child_spec(Scope) ->
  91. #{
  92. id => {syn_scope_sup, Scope},
  93. start => {syn_scope_sup, start_link, [Scope]},
  94. type => supervisor,
  95. shutdown => 10000,
  96. restart => permanent,
  97. modules => [syn_scope_sup]
  98. }.