Skip to content

Commit 8126950

Browse files
committed
rabbit_mnesia: Make some functions backward-compatible
... with older RabbitMQ versions which don't know about Khepri. [Why] When an older node wants to join a cluster, it calls `node_info/0` and `cluster_status_from_mnesia/0` directly using RPC calls. If it does that against a node already using Khepri, t will get an error telling it that Mnesia is not running. The error is reported to the end user, making it difficult to understand the problem: both nodes are simply incompatible. It's better to leave the final decision to the Feature flags subsystem, but for that, `rabbit_mnesia` on the newer Khepri-based node still needs to return something the older version can accept. [How] `cluster_status_from_mnesia/0` and `node_info/0` are modified to verify if Khepri is enabled and if it is, return a value based on Khepri's status as if it was from Mnesia. This will let the remote older node to continue all its checks and eventually refuse to join because the Feature flags subsystem will indicate they are incompatible.
1 parent 297981e commit 8126950

File tree

1 file changed

+34
-2
lines changed

1 file changed

+34
-2
lines changed

deps/rabbit/src/rabbit_mnesia.erl

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,24 @@ cluster_nodes(WhichNodes) -> cluster_status(WhichNodes).
407407
cluster_status_from_mnesia() ->
408408
case is_running() of
409409
false ->
410-
{error, mnesia_not_running};
410+
case rabbit_khepri:get_feature_state() of
411+
enabled ->
412+
%% To keep this API compatible with older remote nodes who
413+
%% don't know about Khepri, we take the cluster status
414+
%% from `rabbit_khepri' and reformat the return value to
415+
%% ressemble the node from this module.
416+
%%
417+
%% Both nodes won't be compatible, but let's leave that
418+
%% decision to the Feature flags subsystem.
419+
case rabbit_khepri:cluster_status_from_khepri() of
420+
{ok, {All, Running}} ->
421+
{ok, {All, All, Running}};
422+
{error, _} = Error ->
423+
Error
424+
end;
425+
_ ->
426+
{error, mnesia_not_running}
427+
end;
411428
true ->
412429
%% If the tables are not present, it means that
413430
%% `init_db/3' hasn't been run yet. In other words, either
@@ -475,8 +492,23 @@ members() ->
475492
end.
476493

477494
node_info() ->
495+
%% Once Khepri is enabled, the Mnesia protocol is irrelevant obviously.
496+
%%
497+
%% That said, older remote nodes who don't known about Khepri will request
498+
%% this information anyway as part of calling `node_info/0'. Here, we
499+
%% simply return `unsupported' as the Mnesia protocol. Older versions of
500+
%% RabbitMQ will skip the protocol negotiation and use other ways.
501+
%%
502+
%% The goal is mostly to let older nodes which check Mnesia before feature
503+
%% flags to reach the feature flags check. This one will correctly
504+
%% indicate that they are incompatible. That's why we return `unsupported'
505+
%% here, even if we could return the actual Mnesia protocol.
506+
MnesiaProtocol = case rabbit_khepri:get_feature_state() of
507+
enabled -> unsupported;
508+
_ -> mnesia:system_info(protocol_version)
509+
end,
478510
{rabbit_misc:otp_release(), rabbit_misc:version(),
479-
mnesia:system_info(protocol_version),
511+
MnesiaProtocol,
480512
cluster_status_from_mnesia()}.
481513

482514
-spec node_type() -> rabbit_db_cluster:node_type().

0 commit comments

Comments
 (0)