Skip to content

Commit 466f169

Browse files
authored
Merge pull request #4427 from esl/mnesia-wait-for-tables-noisy
Print mnesia:wait_for_tables progress
2 parents 91cdfa1 + 01ec22e commit 466f169

File tree

3 files changed

+78
-6
lines changed

3 files changed

+78
-6
lines changed

src/mongoose_internal_databases.erl

+29-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
-export([probe/2]).
88

99
%% For tests
10-
-export([instrumentation/0]).
11-
-ignore_xref([instrumentation/0]).
10+
-export([instrumentation/0, wait_for_mnesia/0]).
11+
-ignore_xref([instrumentation/0, wait_for_mnesia/0]).
12+
13+
-include("mongoose_logger.hrl").
1214

1315
-type db() :: mnesia | cets.
1416

@@ -28,11 +30,35 @@ init(mnesia, #{}) ->
2830
ok
2931
end,
3032
application:start(mnesia, permanent),
31-
mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity),
33+
wait_for_mnesia(),
3234
mongoose_node_num_mnesia:init();
3335
init(cets, #{}) ->
3436
ok.
3537

38+
wait_for_mnesia() ->
39+
wait_for_tables_loop(mnesia:system_info(local_tables), 10000, 0).
40+
41+
%% Sometimes mnesia:wait_for_tables/2 could hang on startup.
42+
%% This function logs which tables are not ready and their status.
43+
wait_for_tables_loop(Tables, Interval, Total) ->
44+
case mnesia:wait_for_tables(Tables, Interval) of
45+
ok ->
46+
ok;
47+
{timeout, WaitingTables} ->
48+
?LOG_WARNING(#{what => mnesia_wait_for_tables_progress,
49+
waiting_for_tables => WaitingTables,
50+
waiting_time => Total + Interval}),
51+
[log_detailed_table_info(Tab) || Tab <- WaitingTables],
52+
wait_for_tables_loop(WaitingTables, Interval, Total + Interval);
53+
{error, Reason} ->
54+
error({mnesia_wait_for_tables_failed, Reason})
55+
end.
56+
57+
log_detailed_table_info(Tab) ->
58+
?LOG_WARNING(#{what => log_detailed_table_info,
59+
table => Tab,
60+
details => mnesia:table_info(Tab, all)}).
61+
3662
-spec instrumentation() -> [mongoose_instrument:spec()].
3763
instrumentation() ->
3864
lists:flatmap(fun instrumentation/1, maps:keys(mongoose_config:get_opt(internal_databases))).

test/common/mongoose_helper.erl

+5-3
Original file line numberDiff line numberDiff line change
@@ -351,18 +351,20 @@ inject_module(Module) ->
351351
inject_module(Module, ReloadIfAlreadyLoaded) ->
352352
inject_module(mim(), Module, ReloadIfAlreadyLoaded).
353353

354-
-spec inject_module(Node :: atom(),
354+
-spec inject_module(Node :: distributed_helper:rpc_spec(),
355355
Module :: module(),
356356
ReloadIfAlreadyLoaded :: no_reload | reload) ->
357357
ok | already_loaded.
358-
inject_module(Node, Module, no_reload) ->
358+
inject_module(#{node := NodeAtom} = _Node, _, _) when NodeAtom =:= node() ->
359+
already_loaded;
360+
inject_module(#{} = Node, Module, no_reload) ->
359361
case successful_rpc(Node, code, is_loaded, [Module]) of
360362
false ->
361363
inject_module(Node, Module, reload);
362364
_ ->
363365
already_loaded
364366
end;
365-
inject_module(Node, Module, reload) ->
367+
inject_module(#{} = Node, Module, reload) ->
366368
{Mod, Bin, File} = code:get_object_code(Module),
367369
successful_rpc(Node, code, load_binary, [Mod, File, Bin]).
368370

test/mnesia_db_SUITE.erl

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
-module(mnesia_db_SUITE).
2+
-compile([export_all, nowarn_export_all]).
3+
4+
-include_lib("eunit/include/eunit.hrl").
5+
6+
local() ->
7+
#{node => node()}.
8+
9+
all() ->
10+
[mnesia_wait_for_tables].
11+
12+
init_per_suite(Config) ->
13+
Config.
14+
15+
end_per_suite(_Config) ->
16+
ok.
17+
18+
init_per_testcase(_, C) ->
19+
mock_mnesia(),
20+
logger_ct_backend:start(local()),
21+
C.
22+
23+
end_per_testcase(_, _) ->
24+
meck:unload(),
25+
logger_ct_backend:stop(local()).
26+
27+
mock_mnesia() ->
28+
meck:new(mnesia, []),
29+
meck:expect(mnesia, system_info, fun(local_tables) -> [test_table_fast, test_table_slow] end),
30+
meck:expect(mnesia, table_info, fun(_, _) -> [] end),
31+
meck:expect(mnesia, wait_for_tables, fun(Tables, _Interval) ->
32+
case meck:num_calls(mnesia, wait_for_tables, '_') > 5 of
33+
true -> ok;
34+
false -> {timeout, Tables -- [test_table_fast]}
35+
end
36+
end),
37+
ok.
38+
39+
mnesia_wait_for_tables(_Config) ->
40+
logger_ct_backend:capture(warning, local()),
41+
mongoose_internal_databases:wait_for_mnesia(),
42+
logger_ct_backend:stop_capture(local()),
43+
FilterFun = fun(_, Msg) -> re:run(Msg, "what: mnesia_wait_for_tables_progress") /= nomatch end,
44+
6 = length(logger_ct_backend:recv(FilterFun)).

0 commit comments

Comments
 (0)