summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Vatamaniuc <vatamane@apache.org>2019-11-21 13:03:36 -0500
committerNick Vatamaniuc <nickva@users.noreply.github.com>2019-11-21 13:48:38 -0500
commit5e47f501c1b756e56a1b57b852e0c1715cf16e1a (patch)
tree8482d23d0fa4d665e71b7ecb6c95d0ba3ba61825
parent4680884b1d232d1f3159d1222b63e4e30bfffc25 (diff)
downloadcouchdb-5e47f501c1b756e56a1b57b852e0c1715cf16e1a.tar.gz
Implement node types
The implementation follows the RFC [1] [1]: https://github.com/apache/couchdb-documentation/blob/master/rfcs/013-node-types.md
-rw-r--r--src/chttpd/src/chttpd_app.erl4
-rw-r--r--src/chttpd/src/chttpd_sup.erl16
-rw-r--r--src/couch_views/src/couch_views_app.erl4
-rw-r--r--src/couch_views/src/couch_views_sup.erl32
-rw-r--r--src/fabric/src/fabric2_node_types.erl52
-rw-r--r--src/fabric/test/fabric2_node_types_tests.erl73
6 files changed, 163 insertions, 18 deletions
diff --git a/src/chttpd/src/chttpd_app.erl b/src/chttpd/src/chttpd_app.erl
index d7a5aef86..770b78ef9 100644
--- a/src/chttpd/src/chttpd_app.erl
+++ b/src/chttpd/src/chttpd_app.erl
@@ -14,8 +14,8 @@
-behaviour(application).
-export([start/2, stop/1]).
-start(_Type, StartArgs) ->
- chttpd_sup:start_link(StartArgs).
+start(_Type, _StartArgs) ->
+ chttpd_sup:start_link().
stop(_State) ->
ok.
diff --git a/src/chttpd/src/chttpd_sup.erl b/src/chttpd/src/chttpd_sup.erl
index d4bdb118c..8b51e6c40 100644
--- a/src/chttpd/src/chttpd_sup.erl
+++ b/src/chttpd/src/chttpd_sup.erl
@@ -18,17 +18,25 @@
-export([init/1]).
--export([start_link/1]).
+-export([start_link/0]).
-export([handle_config_change/5, handle_config_terminate/3]).
%% Helper macro for declaring children of supervisor
-define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 100, Type, [I]}).
-start_link(Args) ->
- supervisor:start_link({local,?MODULE}, ?MODULE, Args).
+start_link() ->
+ Arg = case fabric2_node_types:is_type(api_frontend) of
+ true -> normal;
+ false -> disabled
+ end,
+ supervisor:start_link({local,?MODULE}, ?MODULE, Arg).
-init([]) ->
+init(disabled) ->
+ couch_log:notice("~p : api_frontend disabled", [?MODULE]),
+ {ok, {{one_for_one, 3, 10}, []}};
+
+init(normal) ->
Children = [
{
config_listener_mon,
diff --git a/src/couch_views/src/couch_views_app.erl b/src/couch_views/src/couch_views_app.erl
index 5ede5ef85..7337d0580 100644
--- a/src/couch_views/src/couch_views_app.erl
+++ b/src/couch_views/src/couch_views_app.erl
@@ -23,8 +23,8 @@
]).
-start(_StartType, StartArgs) ->
- couch_views_sup:start_link(StartArgs).
+start(_StartType, _StartArgs) ->
+ couch_views_sup:start_link().
stop(_State) ->
diff --git a/src/couch_views/src/couch_views_sup.erl b/src/couch_views/src/couch_views_sup.erl
index 7650fdf14..7a72a1f33 100644
--- a/src/couch_views/src/couch_views_sup.erl
+++ b/src/couch_views/src/couch_views_sup.erl
@@ -18,7 +18,7 @@
-export([
- start_link/1
+ start_link/0
]).
@@ -27,20 +27,32 @@
]).
-start_link(Args) ->
- supervisor:start_link({local, ?MODULE}, ?MODULE, Args).
+start_link() ->
+ Arg = case fabric2_node_types:is_type(view_indexing) of
+ true -> normal;
+ false -> builds_disabled
+ end,
+ supervisor:start_link({local, ?MODULE}, ?MODULE, Arg).
-init([]) ->
- Flags = #{
- strategy => one_for_one,
- intensity => 1,
- period => 5
- },
+init(normal) ->
Children = [
#{
id => couch_views_server,
start => {couch_views_server, start_link, []}
}
],
- {ok, {Flags, Children}}.
+ {ok, {flags(), Children}};
+
+init(builds_disabled) ->
+ couch_log:notice("~p : view_indexing disabled", [?MODULE]),
+ couch_views_jobs:set_timeout(),
+ {ok, {flags(), []}}.
+
+
+flags() ->
+ #{
+ strategy => one_for_one,
+ intensity => 1,
+ period => 5
+ }.
diff --git a/src/fabric/src/fabric2_node_types.erl b/src/fabric/src/fabric2_node_types.erl
new file mode 100644
index 000000000..110f04d15
--- /dev/null
+++ b/src/fabric/src/fabric2_node_types.erl
@@ -0,0 +1,52 @@
+% 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(fabric2_node_types).
+
+
+-export([
+ is_type/1
+]).
+
+
+is_type(Type) when is_atom(Type) ->
+ case {from_os_env(Type), from_app_env(Type)} of
+ {V, _} when is_boolean(V) ->
+ V;
+ {undefined, V} when is_boolean(V) ->
+ V;
+ {undefined, undefined} ->
+ % When not defined anywhere assume `true`, that is by default a
+ % node will perform all the background tasks
+ true
+ end.
+
+
+from_os_env(Type) when is_atom(Type) ->
+ StrType = erlang:atom_to_list(Type),
+ StrTypeUpper = string:to_upper(StrType),
+ case os:getenv("COUCHDB_NODE_TYPE_" ++ StrTypeUpper) of
+ false ->
+ undefined;
+ Str when is_list(Str) ->
+ case string:to_lower(Str) of
+ "false" -> false;
+ _ -> true
+ end
+ end.
+
+
+from_app_env(Type) when is_atom(Type) ->
+ case application:get_env(fabric, node_types) of
+ undefined -> undefined;
+ {ok, Props} when is_list(Props) -> proplists:get_value(Type, Props)
+ end.
diff --git a/src/fabric/test/fabric2_node_types_tests.erl b/src/fabric/test/fabric2_node_types_tests.erl
new file mode 100644
index 000000000..ad400f98f
--- /dev/null
+++ b/src/fabric/test/fabric2_node_types_tests.erl
@@ -0,0 +1,73 @@
+% 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(fabric2_node_types_tests).
+
+
+-include_lib("eunit/include/eunit.hrl").
+
+
+-define(TDEF(A), {atom_to_list(A), fun A/0}).
+
+
+node_types_test_() ->
+ {
+ "Test node types",
+ foreach,
+ fun() ->
+ os:putenv("COUCHDB_NODE_TYPE_FOO", "false"),
+ os:putenv("COUCHDB_NODE_TYPE_BAZ", "true"),
+ os:putenv("COUCHDB_NODE_TYPE_ZIG", ""),
+ % erlfdb, rexi and mem3 are all dependent apps for fabric. We make
+ % sure to start them so when fabric is started during the test it
+ % already has its dependencies
+ test_util:start_couch([erlfdb, rexi, mem3, ctrace])
+ end,
+ fun(Ctx) ->
+ ok = application:stop(fabric),
+ test_util:stop_couch(Ctx),
+ application:unset_env(fabric, node_types),
+ os:unsetenv("COUCHDB_NODE_TYPE_FOO"),
+ os:unsetenv("COUCHDB_NODE_TYPE_BAZ"),
+ os:unsetenv("COUCHDB_NODE_TYPE_ZIG")
+ end,
+ [
+ ?TDEF(basics),
+ ?TDEF(os_env_priority)
+ ]
+ }.
+
+
+basics() ->
+ ok = application:start(fabric),
+
+ % default is true for new types
+ ?assert(fabric2_node_types:is_type(some_new_node_type)),
+
+ % defined in os env
+ ?assert(fabric2_node_types:is_type(baz)),
+ ?assert(not fabric2_node_types:is_type(foo)),
+ ?assert(fabric2_node_types:is_type(zig)),
+
+ % defined in app env
+ application:set_env(fabric, node_types, [{zag, true}, {bam, false}]),
+ ?assert(fabric2_node_types:is_type(zag)),
+ ?assert(not fabric2_node_types:is_type(bam)).
+
+
+os_env_priority() ->
+ ok = application:start(fabric),
+
+ % os env takes precedence
+ application:set_env(fabric, node_types, [{foo, true}, {baz, false}]),
+ ?assert(not fabric2_node_types:is_type(foo)),
+ ?assert(fabric2_node_types:is_type(baz)).