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/07/19 21:00:45 UTC

(couchdb) branch cleanup-rexi created (now 7771aa65e)

This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a change to branch cleanup-rexi
in repository https://gitbox.apache.org/repos/asf/couchdb.git


      at 7771aa65e Cleanup deprecated and unused functionality in rexi

This branch includes the following new commits:

     new 7771aa65e Cleanup deprecated and unused functionality in rexi

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(couchdb) 01/01: Cleanup deprecated and unused functionality in rexi

Posted by va...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch cleanup-rexi
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 7771aa65ede179151cc2150c2b4df4d329b71345
Author: Nick Vatamaniuc <va...@gmail.com>
AuthorDate: Fri Jul 19 16:45:43 2024 -0400

    Cleanup deprecated and unused functionality in rexi
    
    Continuing the cleanup started in #5143
    
    The `server_per_node` setting had been defaulted to `true` for the last 6
    years. Default it to `true` always. However, keep the `rexi_server` around for
    longer so that mixed cluster upgrades continue working.
    
    The `kill_all` optimization has been enabled since 3.3.3. We can remove any
    calls to rexi:kill/1 and replace with rexi:kill_all/1 leaving the server
    handling of `{kill, ...}` messages in for longer to allow mixed cluster
    upgrades from older nodes.
    
    `async_server_call` code is not used anywhere, so that's also cleaned up.
    
    [1] https://github.com/apache/couchdb/pull/1627
---
 rel/overlay/etc/default.ini       |  1 -
 src/docs/src/config/cluster.rst   |  8 -----
 src/fabric/src/fabric_streams.erl |  1 +
 src/fabric/src/fabric_view.erl    |  2 +-
 src/rexi/src/rexi.erl             | 65 ++++++---------------------------------
 src/rexi/src/rexi_server.erl      |  3 ++
 src/rexi/src/rexi_sup.erl         |  3 ++
 src/rexi/src/rexi_utils.erl       |  7 +----
 8 files changed, 19 insertions(+), 71 deletions(-)

diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini
index cb0a3f4e5..8053f1bdd 100644
--- a/rel/overlay/etc/default.ini
+++ b/rel/overlay/etc/default.ini
@@ -391,7 +391,6 @@ hash_algorithms = sha256, sha
 
 ;[rexi]
 ;buffer_count = 2000
-;server_per_node = true
 ;stream_limit = 5
 ;shard_split_timeout_msec = 600000
 ;shard_split_topoff_batch_size = 500
diff --git a/src/docs/src/config/cluster.rst b/src/docs/src/config/cluster.rst
index 72959829c..1742188bf 100644
--- a/src/docs/src/config/cluster.rst
+++ b/src/docs/src/config/cluster.rst
@@ -111,14 +111,6 @@ RPC Performance Tuning
     This flag determines how many messages will be buffered before the local
     server starts dropping messages. Default value is ``2000``.
 
-    .. config:option:: server_per_node :: Enable or disable one local `gen_server` \
-        process per node
-
-    By default, rexi will spawn one local gen_server process for each node in
-    the cluster. Disabling this flag will cause CouchDB to use a single process
-    for all RPC communication, which is not recommended in high throughput
-    deployments.
-
     .. config:option:: stream_limit :: Number of send messages without waiting \
         for acknowledgement from the coordinator
 
diff --git a/src/fabric/src/fabric_streams.erl b/src/fabric/src/fabric_streams.erl
index 20ee98fd2..75d52627a 100644
--- a/src/fabric/src/fabric_streams.erl
+++ b/src/fabric/src/fabric_streams.erl
@@ -142,6 +142,7 @@ handle_stream_start(rexi_STREAM_INIT, {Worker, From}, St) ->
                 {stop, Ready1} ->
                     % Have a full ring of workers. But don't ack the worker
                     % yet so they don't start sending us rows until we're ready
+                    % BUG!
                     {stop, St#stream_acc{workers = [], ready = Ready1}}
             end
     end;
diff --git a/src/fabric/src/fabric_view.erl b/src/fabric/src/fabric_view.erl
index 677f1d5ae..33a59db88 100644
--- a/src/fabric/src/fabric_view.erl
+++ b/src/fabric/src/fabric_view.erl
@@ -132,7 +132,7 @@ filter_exact_copies(#shard{range = Range0} = Shard0, Shards, Cb) ->
     ).
 
 stop_worker(#shard{ref = Ref, node = Node}) ->
-    rexi:kill(Node, Ref).
+    rexi:kill_all([{Node, Ref}]).
 
 maybe_send_row(#collector{limit = 0} = State) ->
     #collector{counters = Counters, user_acc = AccIn, callback = Callback} = State,
diff --git a/src/rexi/src/rexi.erl b/src/rexi/src/rexi.erl
index 9cc33d786..868d48c49 100644
--- a/src/rexi/src/rexi.erl
+++ b/src/rexi/src/rexi.erl
@@ -12,9 +12,8 @@
 
 -module(rexi).
 
--export([cast/2, cast/3, cast/4, kill/2, kill_all/1]).
+-export([cast/2, cast/3, cast/4, kill_all/1]).
 -export([reply/1]).
--export([async_server_call/2, async_server_call/3]).
 -export([stream_start/1, stream_cancel/1]).
 -export([stream_ack/1]).
 -export([stream2/1, stream_last/1, stream_last/2]).
@@ -56,63 +55,19 @@ cast(Node, Caller, MFA, Options) ->
             cast(Node, Caller, MFA)
     end.
 
-%% @doc Sends an async kill signal to the remote process associated with Ref.
-%% No rexi_EXIT message will be sent.
--spec kill(node(), reference()) -> ok.
-kill(Node, Ref) ->
-    rexi_utils:send(rexi_utils:server_pid(Node), cast_msg({kill, Ref})),
-    ok.
-
 %% @doc Sends an async kill signal to the remote processes associated with Refs.
 %% No rexi_EXIT message will be sent.
 -spec kill_all([{node(), reference()}]) -> ok.
 kill_all(NodeRefs) when is_list(NodeRefs) ->
-    %% use_kill_all is available since version 3.0. When performing a rolling
-    %% cluster upgrade from 2.x, set this value to false, then revert it back
-    %% to default (true) after all nodes have been upgraded.
-    case config:get_boolean("rexi", "use_kill_all", true) of
-        true ->
-            PerNodeMap = lists:foldl(
-                fun({Node, Ref}, Acc) ->
-                    maps:update_with(
-                        Node,
-                        fun(Refs) ->
-                            [Ref | Refs]
-                        end,
-                        [Ref],
-                        Acc
-                    )
-                end,
-                #{},
-                NodeRefs
-            ),
-            maps:map(
-                fun(Node, Refs) ->
-                    ServerPid = rexi_utils:server_pid(Node),
-                    rexi_utils:send(ServerPid, cast_msg({kill_all, Refs}))
-                end,
-                PerNodeMap
-            );
-        false ->
-            lists:foreach(fun({Node, Ref}) -> kill(Node, Ref) end, NodeRefs)
-    end,
-    ok.
-
-%% @equiv async_server_call(Server, self(), Request)
--spec async_server_call(pid() | {atom(), node()}, any()) -> reference().
-async_server_call(Server, Request) ->
-    async_server_call(Server, self(), Request).
-
-%% @doc Sends a properly formatted gen_server:call Request to the Server and
-%% returns the reference which the Server will include in its reply.  The
-%% function acts more like cast() than call() in that the server process
-%% is not monitored.  Clients who want to know if the server is alive should
-%% monitor it themselves before calling this function.
--spec async_server_call(pid() | {atom(), node()}, pid(), any()) -> reference().
-async_server_call(Server, Caller, Request) ->
-    Ref = make_ref(),
-    rexi_utils:send(Server, {'$gen_call', {Caller, Ref}, Request}),
-    Ref.
+    % #{N1 => [Ref1, Ref2], N2 => [Ref3], ...}
+    PerNodeMap = maps:groups_from_list(fun({Node, _}) -> Node end, NodeRefs),
+    maps:foreach(
+        fun(Node, Refs) ->
+            ServerPid = rexi_utils:server_pid(Node),
+            rexi_utils:send(ServerPid, cast_msg({kill_all, Refs}))
+        end,
+        PerNodeMap
+    ).
 
 %% @doc convenience function to reply to the original rexi Caller.
 -spec reply(any()) -> any().
diff --git a/src/rexi/src/rexi_server.erl b/src/rexi/src/rexi_server.erl
index 676a15d52..eb130c8c8 100644
--- a/src/rexi/src/rexi_server.erl
+++ b/src/rexi/src/rexi_server.erl
@@ -79,6 +79,9 @@ handle_cast({doit, {ClientPid, ClientRef} = From, Nonce, MFA}, State) ->
     },
     {noreply, add_job(Job, State)};
 handle_cast({kill, FromRef}, St) ->
+    % TODO: Compatibility clause. This is left to handle mixed cluster
+    % upgrades. Old nodes may still send {kill, Ref} message from rexi:kill.
+    % Remove in the future in > 3.4 version.
     kill_worker(FromRef, St),
     {noreply, St};
 handle_cast({kill_all, FromRefs}, St) ->
diff --git a/src/rexi/src/rexi_sup.erl b/src/rexi/src/rexi_sup.erl
index 3bea0ed15..739ed44bd 100644
--- a/src/rexi/src/rexi_sup.erl
+++ b/src/rexi/src/rexi_sup.erl
@@ -22,6 +22,9 @@ start_link(Args) ->
 init([]) ->
     {ok,
         {{rest_for_one, 3, 10}, [
+            % TODO: Compatibility clause rexi_server. This was used by
+            % server_per_node=false mode once After 3.4+ releases, this can be
+            % removed.
             {
                 rexi_server,
                 {rexi_server, start_link, [rexi_server]},
diff --git a/src/rexi/src/rexi_utils.erl b/src/rexi/src/rexi_utils.erl
index 7e7518e67..146d0238a 100644
--- a/src/rexi/src/rexi_utils.erl
+++ b/src/rexi/src/rexi_utils.erl
@@ -16,12 +16,7 @@
 
 %% @doc Return a rexi_server id for the given node.
 server_id(Node) ->
-    case config:get_boolean("rexi", "server_per_node", true) of
-        true ->
-            list_to_atom("rexi_server_" ++ atom_to_list(Node));
-        _ ->
-            rexi_server
-    end.
+    list_to_atom("rexi_server_" ++ atom_to_list(Node)).
 
 %% @doc Return a {server_id(node()), Node} Pid name for the given Node.
 server_pid(Node) ->