Skip to content

Commit

Permalink
Partially revert delegate optimisation
Browse files Browse the repository at this point in the history
That was done in PR #3865.

The changes introduced in #3865 can cause message arrival ordering guarantees
between two logical erlang process (sending messages via delegate) to
be violated as a message sent to a single destination can overtake a prior
message sent as part of a fan-out. This is due to the fact that the fan-out
take a different route via the delegate process than the direct delivery that
bypasses it.

This commit only reverses it for the `invoke_no_result/2|3` API and leaves the
optimisation in for the synchronous `invoke/` API. This means that the message
send ordering you expect between erlang processes still can be violated when
mixing invoke and invoke_no_result invocations. As far as I can see there are
no places where the code relies on this and there are uses of invoke (mgmt db)
that very well could benefit from avoiding the additional copying.

(cherry picked from commit 8804434)
  • Loading branch information
kjnilsson authored and mergify[bot] committed Oct 17, 2022
1 parent ca4a23f commit 6c613b8
Showing 1 changed file with 0 additions and 9 deletions.
9 changes: 0 additions & 9 deletions deps/rabbit_common/src/delegate.erl
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,6 @@ demonitor(Ref) when is_reference(Ref) ->
demonitor({Name, Pid}) ->
gen_server2:cast(Name, {demonitor, self(), Pid}).

invoke_no_result(Pid, FunOrMFA = {gen_server2, _F, _A}) when is_pid(Pid) ->
_ = safe_invoke(Pid, FunOrMFA), %% we don't care about any error
ok;
invoke_no_result(Pid, FunOrMFA) when is_pid(Pid) andalso node(Pid) =:= node() ->
%% Optimization, avoids calling invoke_no_result/3.
%%
Expand All @@ -192,9 +189,6 @@ invoke_no_result(Pid, FunOrMFA) when is_pid(Pid) ->
ok;
invoke_no_result([], _FunOrMFA) -> %% optimisation
ok;
invoke_no_result([Pid], FunOrMFA = {gen_server2, _F, _A}) when is_pid(Pid) -> %% optimisation
_ = safe_invoke(Pid, FunOrMFA), %% must not die
ok;
invoke_no_result([Pid], FunOrMFA) when node(Pid) =:= node() -> %% optimisation
_ = safe_invoke(Pid, FunOrMFA), %% must not die
ok;
Expand All @@ -204,9 +198,6 @@ invoke_no_result([Pid], FunOrMFA) ->
{invoke, FunOrMFA,
maps:from_list([{RemoteNode, [Pid]}])}),
ok;
invoke_no_result(Pids, FunOrMFA = {gen_server2, _F, _A}) when is_list(Pids) ->
{LocalCallPids, Grouped} = group_local_call_pids_by_node(Pids),
invoke_no_result(Pids, FunOrMFA, LocalCallPids, Grouped);
invoke_no_result(Pids, FunOrMFA) when is_list(Pids) ->
{LocalPids, Grouped} = group_pids_by_node(Pids),
invoke_no_result(Pids, FunOrMFA, LocalPids, Grouped).
Expand Down

0 comments on commit 6c613b8

Please sign in to comment.