This is an automated email from the ASF dual-hosted git repository. vatamane pushed a commit to branch call-reload-after-js-engine-switch-over in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit dd3246f5dee88632a7a67efc08e456d4dce1baec Author: Nick Vatamaniuc <[email protected]> AuthorDate: Fri Jan 31 11:53:59 2025 -0500 Kill all couchjs processes right after updating the engine setting Previously, we set the default JS engine dynamically, so that newly spawned processes would use the new setting. However, we didn't actively try to kill the old JS processes. Since a quiet cluster, without much concurrent indexing activity, could hang on to the same set of spawned processes for a while, it may take an indeterminate amount of time until the couchjs proceses actually switch to the new engine. To fix that let's force a `reload()` as well, which will immediately kill all the free (available) processes and then kill the acquired processes when the user is done with them and releases them back to the process manager. --- src/couch/src/couch_proc_manager.erl | 5 +++++ src/couch_quickjs/test/couch_quickjs_tests.erl | 31 +++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/couch/src/couch_proc_manager.erl b/src/couch/src/couch_proc_manager.erl index 73dbb17b1..e20fd9216 100644 --- a/src/couch/src/couch_proc_manager.erl +++ b/src/couch/src/couch_proc_manager.erl @@ -288,6 +288,11 @@ handle_config_change("query_server_config", _, _, _, _) -> {ok, undefined}; handle_config_change("couchdb", "js_engine", _, _, _) -> gen_server:cast(?MODULE, reload_config), + % Besides reloading the config to switch the engine for the new procs, run + % reload to kill all free and then released procs in the pool. This way we + % ensure all the procs will be recycled and using the new engine as soon as + % possible + spawn(fun() -> reload() end), {ok, undefined}; handle_config_change(_, _, _, _, _) -> {ok, undefined}. diff --git a/src/couch_quickjs/test/couch_quickjs_tests.erl b/src/couch_quickjs/test/couch_quickjs_tests.erl index 6126e64d6..56e62d9fc 100644 --- a/src/couch_quickjs/test/couch_quickjs_tests.erl +++ b/src/couch_quickjs/test/couch_quickjs_tests.erl @@ -78,14 +78,43 @@ t_couch_jsengine_config_triggers_proc_server_reload(_) -> <<"spidermonkey">> -> "quickjs" end, + % Get and return one proc to the pool, and get and keep another + % proc during the switch. Both should be eventually be killed. + + {ok, ProcKeep, _} = couch_proc_manager:get_proc(<<"javascript">>), + PidKeep = element(2, ProcKeep), + RefKeep = monitor(process, PidKeep), + ?assert(is_pid(PidKeep)), + + {ok, ProcFree, _} = couch_proc_manager:get_proc(<<"javascript">>), + PidFree = element(2, ProcFree), + RefFree = monitor(process, PidFree), + % Return it back so there is one free process in the pool + couch_proc_manager:ret_proc(ProcFree), + 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(), + % Wait for the returned process to die + receive + {'DOWN', RefFree, _, _, _} -> ok + end, + + % The one we kept should be alive, we don't want to discrupt + % checked-out processes while they are doing work + is_process_alive(PidKeep), + + % Return the one we kept and that one should die as well + couch_proc_manager:ret_proc(ProcKeep), + receive + {'DOWN', RefKeep, _, _, _} -> ok + end, + + 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),
