diff options
author | Nick Vatamaniuc <vatamane@apache.org> | 2019-11-21 13:03:36 -0500 |
---|---|---|
committer | Nick Vatamaniuc <nickva@users.noreply.github.com> | 2019-11-21 13:48:38 -0500 |
commit | 5e47f501c1b756e56a1b57b852e0c1715cf16e1a (patch) | |
tree | 8482d23d0fa4d665e71b7ecb6c95d0ba3ba61825 | |
parent | 4680884b1d232d1f3159d1222b63e4e30bfffc25 (diff) | |
download | couchdb-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.erl | 4 | ||||
-rw-r--r-- | src/chttpd/src/chttpd_sup.erl | 16 | ||||
-rw-r--r-- | src/couch_views/src/couch_views_app.erl | 4 | ||||
-rw-r--r-- | src/couch_views/src/couch_views_sup.erl | 32 | ||||
-rw-r--r-- | src/fabric/src/fabric2_node_types.erl | 52 | ||||
-rw-r--r-- | src/fabric/test/fabric2_node_types_tests.erl | 73 |
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)). |