Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read node_id from discovery_nodes table in RDBMS #4042

Merged
merged 25 commits into from
Jun 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
bd40df4
Add node_id for discovery_nodes table
arcusfelis Jun 21, 2023
5bbe39a
Start Mnesia based on config
arcusfelis Jun 21, 2023
33c8487
Use mongoose_start_node_id in ejabberd_local
arcusfelis Jun 21, 2023
7ba1f5e
Start CETS after outgoing pools
arcusfelis Jun 21, 2023
58fd64a
Implement mongoose_start_node_id
arcusfelis Jun 21, 2023
fd76743
Make mnesia an included application
arcusfelis Jun 21, 2023
f69dfda
Still start mnesia in pgsql_cets preset
arcusfelis Jun 21, 2023
e1b7ad2
Add mongoose_node_num instead of ejabberd_node_id
arcusfelis Jun 21, 2023
372b8fd
Fix xref for mongoose_start_node_id
arcusfelis Jun 21, 2023
506a7a4
Fix updated_timestamp column name
arcusfelis Jun 22, 2023
8167380
Fix cets_disco_SUITE:rdbms_backend backend
arcusfelis Jun 22, 2023
e3fd670
Ensure ejabberd_sup is started in mongoose_cleanup_SUITE
arcusfelis Jun 22, 2023
393ff75
Fix mnesia starting in small tests
arcusfelis Jun 22, 2023
22a8c88
Fix mssql schema
arcusfelis Jun 22, 2023
57456d8
Add test for mongoose_cets_discovery_rdbms:next_free_num
arcusfelis Jun 22, 2023
1f8bea8
Deregister node ids in mongoose_start_node_id when node is down
arcusfelis Jun 22, 2023
4bff87e
Add a comment why mnesia:stop() is inside the start function
arcusfelis Jun 23, 2023
1b25b2b
Improve coverage in cets_disco
arcusfelis Jun 23, 2023
171fa01
Add start_node_id_SUITE
arcusfelis Jun 23, 2023
8978847
Imrove mongoose_cets_discovery_rdbms debugging info
arcusfelis Jun 23, 2023
2b9d616
Use lookup_opt to check if mnesia is disabled
arcusfelis Jun 28, 2023
b6a1dde
Start mnesia permanently
arcusfelis Jun 28, 2023
a9ab441
Fix typo
arcusfelis Jun 29, 2023
80077e2
Moved mongoose_node_num:set_node_num away from try..catch
arcusfelis Jun 29, 2023
b83dc98
Fix shadowed variable NodeBin
arcusfelis Jun 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions big_tests/default.spec
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
{suites, "tests", local_iq_SUITE}.
{suites, "tests", tcp_listener_SUITE}.
{suites, "tests", cets_disco_SUITE}.
{suites, "tests", start_node_id_SUITE}.

{config, ["test.config"]}.
{logdir, "ct_report"}.
Expand Down
1 change: 1 addition & 0 deletions big_tests/dynamic_domains.spec
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@
{suites, "tests", local_iq_SUITE}.
{suites, "tests", tcp_listener_SUITE}.
{suites, "tests", cets_disco_SUITE}.
{suites, "tests", start_node_id_SUITE}.

{config, ["dynamic_domains.config", "test.config"]}.

Expand Down
3 changes: 2 additions & 1 deletion big_tests/test.config
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,8 @@
{stream_management_backend, cets},
{auth_method, "rdbms"},
{internal_databases, "[internal_databases.cets]
cluster_name = \"{{cluster_name}}\""},
cluster_name = \"{{cluster_name}}\"
[internal_databases.mnesia]"}, %% We still using mnesia for modules that are not converted to use CETS
{outgoing_pools, "[outgoing_pools.redis.global_distrib]
scope = \"global\"
workers = 10
Expand Down
8 changes: 6 additions & 2 deletions big_tests/tests/cets_disco_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,9 @@ rdbms_backend(_Config) ->
State1 = rpc(mim(), mongoose_cets_discovery_rdbms, init, [Opts1]),
rpc(mim(), mongoose_cets_discovery_rdbms, get_nodes, [State1]),
State2 = rpc(mim(), mongoose_cets_discovery_rdbms, init, [Opts2]),
{{ok, Nodes}, _} = rpc(mim(), mongoose_cets_discovery_rdbms, get_nodes, [State2]),
[test1, test2] = lists:sort(Nodes).
{{ok, Nodes}, State2_2} = rpc(mim(), mongoose_cets_discovery_rdbms, get_nodes, [State2]),
%% "test2" node can see "test1"
true = lists:member(test1, Nodes),
{{ok, _}, State2_3} = rpc(mim(), mongoose_cets_discovery_rdbms, get_nodes, [State2_2]),
%% Check that we follow the right code branch
#{last_query_info := #{already_registered := true}} = State2_3.
55 changes: 55 additions & 0 deletions big_tests/tests/start_node_id_SUITE.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
-module(start_node_id_SUITE).
-compile([export_all, nowarn_export_all]).

-import(distributed_helper, [mim/0, rpc/4]).
-include_lib("common_test/include/ct.hrl").

%%--------------------------------------------------------------------
%% Suite configuration
%%--------------------------------------------------------------------

all() ->
[{group, all}].

groups() ->
[{all, [], cases()}].

cases() ->
[cleaning_works].

suite() ->
escalus:suite().

%%--------------------------------------------------------------------
%% Init & teardown
%%--------------------------------------------------------------------
init_per_suite(Config) ->
escalus:init_per_suite(Config).

end_per_suite(Config) ->
escalus:end_per_suite(Config).

init_per_group(_, Config) ->
Config.

end_per_group(_, Config) ->
Config.

init_per_testcase(CaseName, Config) ->
escalus:init_per_testcase(CaseName, Config).

end_per_testcase(CaseName, Config) ->
escalus:end_per_testcase(CaseName, Config).

%%--------------------------------------------------------------------
%% Test cases
%%--------------------------------------------------------------------

cleaning_works(Config) ->
Id = <<"someid139455">>,
Pid = spawn_link(fun() -> receive stop -> ok end end),
ok = rpc(mim(), mongoose_start_node_id, register_on_remote_node_rpc, [node(), Id, Pid]),
GetF = fun() -> rpc(mim(), mongoose_start_node_id, node_id_to_name, [Id]) end,
mongoose_helper:wait_until(GetF, {ok, node()}),
Pid ! stop,
mongoose_helper:wait_until(GetF, {error, unknown_id}).
2 changes: 2 additions & 0 deletions priv/mssql2012.sql
Original file line number Diff line number Diff line change
Expand Up @@ -757,5 +757,7 @@ CREATE TABLE discovery_nodes (
node_name varchar(250),
cluster_name varchar(250),
updated_timestamp BIGINT NOT NULL, -- in microseconds
node_num INT NOT NULL,
PRIMARY KEY (cluster_name, node_name)
);
CREATE UNIQUE INDEX i_discovery_nodes_node_num ON discovery_nodes(cluster_name, node_num);
2 changes: 2 additions & 0 deletions priv/mysql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -549,5 +549,7 @@ CREATE TABLE discovery_nodes (
node_name varchar(250),
cluster_name varchar(250),
updated_timestamp BIGINT NOT NULL, -- in microseconds
node_num INT UNSIGNED NOT NULL,
PRIMARY KEY (cluster_name, node_name)
);
CREATE UNIQUE INDEX i_discovery_nodes_node_num USING BTREE ON discovery_nodes(cluster_name, node_num);
2 changes: 2 additions & 0 deletions priv/pg.sql
Original file line number Diff line number Diff line change
Expand Up @@ -509,5 +509,7 @@ CREATE TABLE discovery_nodes (
node_name varchar(250),
cluster_name varchar(250),
updated_timestamp BIGINT NOT NULL, -- in microseconds
node_num INT NOT NULL,
PRIMARY KEY (cluster_name, node_name)
);
CREATE UNIQUE INDEX i_discovery_nodes_node_num ON discovery_nodes USING BTREE(cluster_name, node_num);
40 changes: 32 additions & 8 deletions src/ejabberd_app.erl
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,30 @@
%%%

start(normal, _Args) ->
try
do_start()
catch Class:Reason:StackTrace ->
%% Log a stacktrace because while proc_lib:crash_report/4 would report a crash reason,
%% it would not report the stacktrace
?LOG_CRITICAL(#{what => app_failed_to_start,
class => Class, reason => Reason, stacktrace => StackTrace}),
erlang:raise(Class, Reason, StackTrace)
end;
start(_, _) ->
{error, badarg}.

do_start() ->
mongoose_fips:notify(),
write_pid_file(),
update_status_file(starting),
db_init(),
application:start(cache_tab),

mongoose_graphql:init(),
translate:start(),
ejabberd_node_id:start(),
ejabberd_commands:init(),
mongoose_graphql_commands:start(),
mongoose_config:start(),
db_init(),
mongoose_router:start(),
mongoose_logs:set_global_loglevel(mongoose_config:get_opt(loglevel)),
mongoose_deprecations:start(),
Expand All @@ -72,9 +84,7 @@ start(normal, _Args) ->
ejabberd_admin:start(),
update_status_file(started),
?LOG_NOTICE(#{what => mongooseim_node_started, version => ?MONGOOSE_VERSION, node => node()}),
Sup;
start(_, _) ->
{error, badarg}.
Sup.

%% @doc Prepare the application for termination.
%% This function is called when an application is about to be stopped,
Expand All @@ -97,6 +107,9 @@ stop(_State) ->
?LOG_NOTICE(#{what => mongooseim_node_stopped, version => ?MONGOOSE_VERSION, node => node()}),
delete_pid_file(),
update_status_file(stopped),
%% We cannot stop other applications inside of the stop callback
%% (because we would deadlock the application controller process).
%% That is why we call mnesia:stop() inside of db_init_mnesia() instead.
%%ejabberd_debug:stop(),
ok.

Expand All @@ -105,14 +118,25 @@ stop(_State) ->
%%% Internal functions
%%%
db_init() ->
case mongoose_config:lookup_opt([internal_databases, mnesia]) of
{ok, _} ->
db_init_mnesia(),
mongoose_node_num_mnesia:init();
{error, _} ->
ok
end.

db_init_mnesia() ->
%% Mnesia should not be running at this point, unless it is started by tests.
%% Ensure Mnesia is stopped
mnesia:stop(),
case mnesia:system_info(extra_db_nodes) of
[] ->
application:stop(mnesia),
mnesia:create_schema([node()]),
application:start(mnesia, permanent);
mnesia:create_schema([node()]);
_ ->
ok
end,
application:start(mnesia, permanent),
mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).

-spec broadcast_c2s_shutdown_listeners() -> ok.
Expand Down
10 changes: 4 additions & 6 deletions src/ejabberd_local.erl
Original file line number Diff line number Diff line change
Expand Up @@ -423,23 +423,21 @@ do_unregister_host(Host) ->

make_iq_id() ->
%% Attach NodeId, so we know to which node to forward the response
{ok, NodeId} = ejabberd_node_id:node_id(),
BinNodeId = mongoose_start_node_id:node_id(),
Rand = mongoose_bin:gen_from_crypto(),
<<(integer_to_binary(NodeId))/binary, "_", Rand/binary>>.
<<BinNodeId/binary, "_", Rand/binary>>.

%% Parses ID, made by make_iq_id function
-spec parse_iq_id(ID :: binary()) ->
local_node | {remote_node, node()}
| {error, {unknown_node_id, term()} | bad_iq_format}.
parse_iq_id(ID) ->
{ok, NodeId} = ejabberd_node_id:node_id(),
BinNodeId = integer_to_binary(NodeId),
BinNodeId = mongoose_start_node_id:node_id(),
case binary:split(ID, <<"_">>) of
[BinNodeId, _Rest] ->
local_node;
[OtherBinNodeId, _Rest] ->
OtherNodeId = binary_to_integer(OtherBinNodeId),
case ejabberd_node_id:node_id_to_name(OtherNodeId) of
case mongoose_start_node_id:node_id_to_name(OtherBinNodeId) of
{ok, NodeName} ->
{remote_node, NodeName};
{error, Reason} ->
Expand Down
70 changes: 0 additions & 70 deletions src/ejabberd_node_id.erl

This file was deleted.

13 changes: 9 additions & 4 deletions src/ejabberd_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -152,22 +152,27 @@ init([]) ->
PG =
{pg,
{pg, start_link, [mim_scope]},
permanent, infinity, supervisor, [pg]},
permanent, infinity, worker, [pg]},
StartIdServer =
{mongoose_start_node_id,
{mongoose_start_node_id, start_link, []},
permanent, infinity, worker, [mongoose_start_node_id]},
{ok, {{one_for_one, 10, 1},
cets_specs() ++
[PG,
[StartIdServer,
PG,
Hooks,
Cleaner,
SMBackendSupervisor,
Router,
OutgoingPoolsSupervisor
] ++ cets_specs() ++ [
S2S,
Local,
ReceiverSupervisor,
C2SSupervisor,
S2SInSupervisor,
S2SOutSupervisor,
ServiceSupervisor,
OutgoingPoolsSupervisor,
IQSupervisor,
Listener,
MucIQ,
Expand Down
2 changes: 1 addition & 1 deletion src/mam/mod_mam_muc.erl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
%%%
%%% <ul>
%%% <li>date (using `timestamp()');</li>
%%% <li>node number (using {@link ejabberd_node_id}).</li>
%%% <li>node number (using {@link mongoose_node_num}).</li>
%%% </ul>
%%% @end
%%%-------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion src/mam/mod_mam_pm.erl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
%%%
%%% <ul>
%%% <li>date (using `timestamp()');</li>
%%% <li>node number (using {@link ejabberd_node_id}).</li>
%%% <li>node number (using {@link mongoose_node_num}).</li>
%%% </ul>
%%% @end
%%%-------------------------------------------------------------------
Expand Down
14 changes: 7 additions & 7 deletions src/mam/mod_mam_utils.erl
Original file line number Diff line number Diff line change
Expand Up @@ -179,27 +179,27 @@ get_or_generate_mam_id(Acc) ->

-spec generate_message_id(integer()) -> integer().
generate_message_id(CandidateStamp) ->
{ok, NodeId} = ejabberd_node_id:node_id(),
NodeNum = mongoose_node_num:node_num(),
UniqueStamp = mongoose_mam_id:next_unique(CandidateStamp),
encode_compact_uuid(UniqueStamp, NodeId).
encode_compact_uuid(UniqueStamp, NodeNum).

%% @doc Create a message ID (UID).
%%
%% It removes a leading 0 from 64-bit binary representation.
%% It puts node id as a last byte.
%% The maximum date, that can be encoded is `{{4253, 5, 31}, {22, 20, 37}}'.
-spec encode_compact_uuid(integer(), integer()) -> integer().
encode_compact_uuid(Microseconds, NodeId)
when is_integer(Microseconds), is_integer(NodeId) ->
(Microseconds bsl 8) + NodeId.
encode_compact_uuid(Microseconds, NodeNum)
when is_integer(Microseconds), is_integer(NodeNum) ->
(Microseconds bsl 8) + NodeNum.


%% @doc Extract date and node id from a message id.
-spec decode_compact_uuid(integer()) -> {integer(), byte()}.
decode_compact_uuid(Id) ->
Microseconds = Id bsr 8,
NodeId = Id band 255,
{Microseconds, NodeId}.
NodeNum = Id band 255,
{Microseconds, NodeNum}.


%% @doc Encode a message ID to pass it to the user.
Expand Down
Loading