diff options
Diffstat (limited to 'src/couch_epi/src/couch_epi_sup.erl')
-rw-r--r-- | src/couch_epi/src/couch_epi_sup.erl | 163 |
1 files changed, 0 insertions, 163 deletions
diff --git a/src/couch_epi/src/couch_epi_sup.erl b/src/couch_epi/src/couch_epi_sup.erl deleted file mode 100644 index aca423a7d..000000000 --- a/src/couch_epi/src/couch_epi_sup.erl +++ /dev/null @@ -1,163 +0,0 @@ -% 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(couch_epi_sup). - -%% -------------------- -%% Important assumption -%% ==================== -%% Keeper and codechange_monitor childspecs rely on undocumented behaviour. -%% According to supervisor docs: -%% ...if the child process is a supervisor, gen_server, or gen_fsm, this -%% should be a list with one element [Module]. -%% However it is perfectly fine to have more than one module in the list. -%% Modules property is used to determine if process is suspendable. -%% Only suspendable processes are hot code upgraded, others are killed. -%% The check looks like `lists:member(Module, Modules)` -%% The assumption is that it is indeed underdocumented fact and not -%% an implementation detail. - --behaviour(supervisor). - --include("couch_epi.hrl"). - -%% API --export([start_link/0]). --export([plugin_childspecs/2]). - -%% Supervisor callbacks --export([init/1]). - -%% For testing --export([ - plugin_childspecs/3 -]). - -%% Helper macro for declaring children of supervisor --define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5000, Type, [I]}). - -%% =================================================================== -%% API functions -%% =================================================================== - -start_link() -> - supervisor:start_link({local, ?MODULE}, ?MODULE, []). - -plugin_childspecs(Plugin, Children) -> - Plugins = application:get_env(couch_epi, plugins, []), - plugin_childspecs(Plugin, Plugins, Children). - -%% =================================================================== -%% Supervisor callbacks -%% =================================================================== - -init([]) -> - {ok, {{one_for_one, 5, 10}, keepers()}}. - -%% ------------------------------------------------------------------ -%% Internal Function Definitions -%% ------------------------------------------------------------------ - -keepers() -> - Plugins = application:get_env(couch_epi, plugins, []), - Definitions = couch_epi_plugin:grouped_definitions(Plugins), - Children = keeper_childspecs(Definitions), - remove_duplicates(Children). - -plugin_childspecs(Plugin, Plugins, Children) -> - Definitions = couch_epi_plugin:grouped_definitions([Plugin]), - ExtraChildren = couch_epi_plugin:plugin_processes(Plugin, Plugins), - merge(ExtraChildren, Children) ++ childspecs(Definitions). - -childspecs(Definitions) -> - lists:map( - fun({{Kind, Key}, Defs}) -> - CodeGen = couch_epi_plugin:codegen(Kind), - Handle = CodeGen:get_handle(Key), - Modules = lists:append([modules(Spec) || {_App, Spec} <- Defs]), - Name = service_name(Key) ++ "|" ++ atom_to_list(Kind), - code_monitor(Name, [Handle], [Handle | Modules]) - end, - Definitions - ). - -%% ------------------------------------------------------------------ -%% Helper Function Definitions -%% ------------------------------------------------------------------ - -remove_duplicates(Definitions) -> - lists:ukeysort(1, Definitions). - -keeper_childspecs(Definitions) -> - lists:map( - fun({{Kind, Key}, _Specs}) -> - Name = service_name(Key) ++ "|keeper", - CodeGen = couch_epi_plugin:codegen(Kind), - Handle = CodeGen:get_handle(Key), - keeper(Name, [provider_kind(Kind), Key, CodeGen], [Handle]) - end, - Definitions - ). - -keeper(Name, Args, Modules) -> - { - "couch_epi|" ++ Name, - {couch_epi_module_keeper, start_link, Args}, - permanent, - 5000, - worker, - Modules - }. - -code_monitor(Name, Args, Modules0) -> - Modules = [couch_epi_codechange_monitor | Modules0], - { - "couch_epi_codechange_monitor|" ++ Name, - {couch_epi_codechange_monitor, start_link, Args}, - permanent, - 5000, - worker, - Modules - }. - -provider_kind(services) -> providers; -provider_kind(data_subscriptions) -> data_providers; -provider_kind(Kind) -> Kind. - -service_name({ServiceId, Key}) -> - atom_to_list(ServiceId) ++ ":" ++ atom_to_list(Key); -service_name(ServiceId) -> - atom_to_list(ServiceId). - -modules(#couch_epi_spec{kind = providers, value = Module}) -> - [Module]; -modules(#couch_epi_spec{kind = services, value = Module}) -> - [Module]; -modules(#couch_epi_spec{kind = data_providers, value = Value}) -> - case Value of - {static_module, Module} -> [Module]; - {callback_module, Module} -> [Module]; - _ -> [] - end; -modules(#couch_epi_spec{kind = data_subscriptions, behaviour = Module}) -> - [Module]. - -merge([], Children) -> - Children; -merge([{Id, _, _, _, _, _} = Spec | Rest], Children) -> - merge(Rest, lists:keystore(Id, 1, Children, Spec)); -merge([#{id := Id} = Spec | Rest], Children) -> - Replace = fun - (#{id := I}) when I == Id -> Spec; - (E) -> E - end, - merge(Rest, lists:map(Replace, Children)). |