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),

Reply via email to