You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2024/10/30 00:53:43 UTC
(couchdb) 01/01: Allow online js_engine reconfiguration
This is an automated email from the ASF dual-hosted git repository.
vatamane pushed a commit to branch dynamic-quick-reconf
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit dcd8f00fd4ad1d9e400ff10031490c7db0f62cba
Author: Nick Vatamaniuc <va...@gmail.com>
AuthorDate: Tue Oct 29 20:50:53 2024 -0400
Allow online js_engine reconfiguration
This should make it possible to toggle between engines without having to
restart the node.
We already had a config listener so make sure it also sets up the js_engine
bits, as well.
Add a test to demonstrate it works both when setting a non-default value and
reverting back to the default value.
---
src/couch/src/couch_proc_manager.erl | 19 ++++++---
src/couch_quickjs/test/couch_quickjs_tests.erl | 53 +++++++++++++++++++++++++-
2 files changed, 64 insertions(+), 8 deletions(-)
diff --git a/src/couch/src/couch_proc_manager.erl b/src/couch/src/couch_proc_manager.erl
index 885a438f7..81739bf09 100644
--- a/src/couch/src/couch_proc_manager.erl
+++ b/src/couch/src/couch_proc_manager.erl
@@ -139,11 +139,7 @@ init([]) ->
% Lang -> number of procs spawn for that lang
ets:new(?COUNTERS, [named_table]),
- ets:insert(?SERVERS, get_servers_from_env("COUCHDB_QUERY_SERVER_")),
- ets:insert(?SERVERS, get_servers_from_env("COUCHDB_NATIVE_QUERY_SERVER_")),
- ets:insert(?SERVERS, [{"QUERY", {mango_native_proc, start_link, []}}]),
- maybe_configure_erlang_native_servers(),
- configure_js_engine(couch_server:get_js_engine()),
+ ok = configure_language_servers(),
{ok, #state{
config = get_proc_config(),
@@ -221,7 +217,7 @@ handle_cast(reload_config, State) ->
hard_limit = get_hard_limit(),
soft_limit = get_soft_limit()
},
- maybe_configure_erlang_native_servers(),
+ ok = configure_language_servers(),
lists:foreach(
fun({Lang, _}) ->
ok = flush_waiters(NewState, Lang)
@@ -290,6 +286,9 @@ handle_config_change("native_query_servers", _, _, _, _) ->
handle_config_change("query_server_config", _, _, _, _) ->
gen_server:cast(?MODULE, reload_config),
{ok, undefined};
+handle_config_change("couchdb", "js_engine", _, _, _) ->
+ gen_server:cast(?MODULE, reload_config),
+ {ok, undefined};
handle_config_change(_, _, _, _, _) ->
{ok, undefined}.
@@ -512,6 +511,14 @@ get_servers_from_env(Spec) ->
os:getenv()
).
+configure_language_servers() ->
+ ets:insert(?SERVERS, get_servers_from_env("COUCHDB_QUERY_SERVER_")),
+ ets:insert(?SERVERS, get_servers_from_env("COUCHDB_NATIVE_QUERY_SERVER_")),
+ ets:insert(?SERVERS, [{"QUERY", {mango_native_proc, start_link, []}}]),
+ maybe_configure_erlang_native_servers(),
+ configure_js_engine(couch_server:get_js_engine()),
+ ok.
+
get_query_server(LangStr) ->
case ets:lookup(?SERVERS, string:to_upper(LangStr)) of
[{_, Command}] -> Command;
diff --git a/src/couch_quickjs/test/couch_quickjs_tests.erl b/src/couch_quickjs/test/couch_quickjs_tests.erl
index b1089e3e5..44af444cd 100644
--- a/src/couch_quickjs/test/couch_quickjs_tests.erl
+++ b/src/couch_quickjs/test/couch_quickjs_tests.erl
@@ -18,7 +18,9 @@ setup() ->
test_util:start_couch().
teardown(Ctx) ->
- config:delete("quickjs", "memory_limit_bytes", _Persist = false),
+ Persist = false,
+ config:delete("quickjs", "memory_limit_bytes", Persist),
+ config:delete("couchdb", "js_engine", Persist),
test_util:stop_couch(Ctx).
quickjs_test_() ->
@@ -30,7 +32,8 @@ quickjs_test_() ->
?TDEF_FE(t_get_mainjs_cmd),
?TDEF_FE(t_get_coffee_cmd),
?TDEF_FE(t_can_configure_memory_limit),
- ?TDEF_FE(t_bad_memory_limit)
+ ?TDEF_FE(t_bad_memory_limit),
+ ?TDEF_FE(t_couch_jsengine_config_triggers_proc_server_reload)
]
}.
@@ -60,9 +63,55 @@ t_bad_memory_limit(_) ->
?assertEqual(ExpectCmd, string:find(Cmd, ExpectCmd)),
?assertEqual(1, os_cmd(Cmd ++ " -V")).
+t_couch_jsengine_config_triggers_proc_server_reload(_) ->
+ case couch_server:with_spidermonkey() of
+ false ->
+ % Spidermonkey is not in the build at all, skip the test
+ ok;
+ true ->
+ OldVal = get_proc_manager_default_js(),
+ % In the test, set the engine to whatever is not the default
+ Toggle =
+ case couch_server:get_js_engine() of
+ <<"quickjs">> -> "spidermonkey";
+ <<"spidermonkey">> -> "quickjs"
+ end,
+
+ config:set("couchdb", "js_engine", Toggle, false),
+ % couch_server:get_js_engine/0 should be visible immediately
+ ?assertEqual(list_to_binary(Toggle), couch_server:get_js_engine()),
+
+ wait_until_proc_manager_updates(OldVal),
+ ?assertNotEqual(OldVal, get_proc_manager_default_js()),
+ NewVal = get_proc_manager_default_js(),
+
+ % Toggle back to the original default (test config:delete/3)
+ config:delete("couchdb", "js_engine", false),
+ wait_until_proc_manager_updates(NewVal),
+ ?assertNotEqual(NewVal, get_proc_manager_default_js()),
+ % We should be back to the original default
+ ?assertEqual(OldVal, get_proc_manager_default_js())
+ end.
+
os_cmd(Cmd) ->
Opts = [stream, {line, 4096}, binary, exit_status, hide],
Port = open_port({spawn, Cmd}, Opts),
receive
{Port, {exit_status, Status}} -> Status
end.
+
+wait_until_proc_manager_updates(OldVal) ->
+ WaitFun = fun() ->
+ case get_proc_manager_default_js() of
+ OldVal -> wait;
+ _ -> ok
+ end
+ end,
+ case test_util:wait(WaitFun, 5000) of
+ timeout -> error(timeout);
+ _ -> ok
+ end.
+
+get_proc_manager_default_js() ->
+ [{"JAVASCRIPT", Val}] = ets:lookup(couch_proc_manager_servers, "JAVASCRIPT"),
+ Val.