Skip to content

Commit 51a380e

Browse files
committed
Fix enabling cets without RDBMS
1 parent e5d5bdd commit 51a380e

File tree

1 file changed

+64
-56
lines changed

1 file changed

+64
-56
lines changed

src/mongoose_cluster_id.erl

Lines changed: 64 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,42 @@
22

33
-include("mongoose.hrl").
44

5-
-export([
6-
start/0,
7-
get_cached_cluster_id/0,
8-
get_backend_cluster_id/0
9-
]).
5+
-export([start/0, get_cached_cluster_id/0]).
106

117
% For testing purposes only
12-
-export([clean_table/0, clean_cache/0]).
8+
-export([clean_table/0, clean_cache/0, get_backend_cluster_id/0]).
139

1410
-ignore_xref([clean_table/0, clean_cache/0, get_backend_cluster_id/0]).
1511

1612
-record(mongoose_cluster_id, {key :: atom(), value :: cluster_id()}).
1713
-type cluster_id() :: binary().
1814
-type maybe_cluster_id() :: {ok, cluster_id()} | {error, any()}.
19-
-type mongoose_backend() :: rdbms
20-
| mnesia
21-
| cets.
15+
-type persistent_backend() :: rdbms | {error, none}.
16+
-type volatile_backend() :: mnesia | cets.
2217

2318
-spec start() -> maybe_cluster_id().
2419
start() ->
2520
%% Consider rewriting this logic, so it does not block the starting process.
2621
%% Currently, we have to do an SQL query each time we restart MongooseIM
2722
%% application in the tests.
2823
init_cache(),
29-
Backend = which_backend_available(),
30-
IntBackend = which_volatile_backend_available(),
31-
maybe_prepare_queries(Backend),
24+
PersistentBackend = which_persistent_backend_enabled(),
25+
VolatileBackend = which_volatile_backend_available(),
26+
maybe_prepare_queries(PersistentBackend),
3227
cets_long:run_tracked(#{task => wait_for_any_backend,
33-
backend => Backend, volatile_backend => IntBackend},
34-
fun() -> wait_for_any_backend(Backend, IntBackend) end),
35-
CachedRes = get_cached_cluster_id(IntBackend),
36-
BackendRes = get_backend_cluster_id(),
28+
backend => PersistentBackend, volatile_backend => VolatileBackend},
29+
fun() -> wait_for_any_backend(PersistentBackend, VolatileBackend) end),
30+
CachedRes = get_cached_cluster_id(VolatileBackend),
31+
BackendRes = get_backend_cluster_id(PersistentBackend),
3732
case {CachedRes, BackendRes} of
3833
{{ok, ID}, {ok, ID}} ->
3934
{ok, ID};
4035
{{ok, ID}, {error, _}} ->
41-
set_new_cluster_id(ID, Backend);
36+
persist_cluster_id(ID, PersistentBackend);
4237
{{error, _}, {ok, ID}} ->
43-
set_new_cluster_id(ID, IntBackend);
38+
cache_cluster_id(ID, VolatileBackend);
4439
{{error, _}, {error, _}} ->
45-
make_and_set_new_cluster_id();
40+
make_and_set_new_cluster_id(PersistentBackend, VolatileBackend);
4641
{{ok, CachedID}, {ok, BackendID}} ->
4742
?LOG_ERROR(#{what => cluster_id_setup_conflict,
4843
text => <<"Mnesia and Backend have different cluster IDs">>,
@@ -53,12 +48,14 @@ start() ->
5348

5449
%% If RDBMS is available before CETS - it is enough for us to continue
5550
%% the starting procedure
56-
wait_for_any_backend(Backend, IntBackend) ->
51+
wait_for_any_backend(PersistentBackend, VolatileBackend) ->
5752
Alias = erlang:alias([reply]),
58-
Pids = lists:append([wait_for_backend_promise(B, Alias) || B <- lists:sort([Backend, IntBackend])]),
53+
Pids = lists:append([wait_for_backend_promise(B, Alias)
54+
|| B <- lists:sort([PersistentBackend, VolatileBackend])]),
5955
wait_for_first_reply(Alias),
6056
%% Interrupt other waiting calls to reduce the logging noise
6157
[erlang:exit(Pid, shutdown) || Pid <- Pids],
58+
clear_pending_replies(Alias),
6259
ok.
6360

6461
wait_for_first_reply(Alias) ->
@@ -67,9 +64,13 @@ wait_for_first_reply(Alias) ->
6764
ok
6865
end.
6966

70-
wait_for_backend_promise(mnesia, Alias) ->
71-
Alias ! {ready, Alias},
72-
[];
67+
clear_pending_replies(Alias) ->
68+
receive
69+
{ready, Alias} -> clear_pending_replies(Alias)
70+
after
71+
0 -> ok
72+
end.
73+
7374
wait_for_backend_promise(cets, Alias) ->
7475
[spawn(fun() ->
7576
%% We have to do it, because we want to read from across the cluster
@@ -81,7 +82,10 @@ wait_for_backend_promise(rdbms, Alias) ->
8182
[spawn(fun() ->
8283
cets_long:run_tracked(#{task => wait_for_rdbms}, fun() -> wait_for_rdbms() end),
8384
Alias ! {ready, Alias}
84-
end)].
85+
end)];
86+
wait_for_backend_promise(_, Alias) ->
87+
Alias ! {ready, Alias},
88+
[].
8589

8690
wait_for_rdbms() ->
8791
case get_backend_cluster_id(rdbms) of
@@ -121,16 +125,14 @@ get_cached_cluster_id(cets) ->
121125
%% ====================================================================
122126
-spec get_backend_cluster_id() -> maybe_cluster_id().
123127
get_backend_cluster_id() ->
124-
get_backend_cluster_id(which_backend_available()).
125-
126-
-spec set_new_cluster_id(cluster_id()) -> maybe_cluster_id().
127-
set_new_cluster_id(ID) ->
128-
set_new_cluster_id(ID, which_backend_available()).
128+
get_backend_cluster_id(which_persistent_backend_enabled()).
129129

130-
-spec make_and_set_new_cluster_id() -> maybe_cluster_id().
131-
make_and_set_new_cluster_id() ->
132-
NewID = make_cluster_id(),
133-
set_new_cluster_id(NewID).
130+
-spec make_and_set_new_cluster_id(persistent_backend(), volatile_backend()) ->
131+
maybe_cluster_id().
132+
make_and_set_new_cluster_id(PersistentBackend, VolatileBackend) ->
133+
NewID = make_cluster_id(PersistentBackend),
134+
persist_cluster_id(NewID, PersistentBackend),
135+
cache_cluster_id(NewID, VolatileBackend).
134136

135137
%% ====================================================================
136138
%% Internal functions
@@ -149,31 +151,36 @@ init_cache(cets) ->
149151
cets:start(cets_cluster_id, #{}),
150152
cets_discovery:add_table(mongoose_cets_discovery, cets_cluster_id).
151153

152-
-spec maybe_prepare_queries(mongoose_backend()) -> ok.
153-
maybe_prepare_queries(mnesia) -> ok;
154+
-spec maybe_prepare_queries(persistent_backend()) -> any().
154155
maybe_prepare_queries(rdbms) ->
155156
mongoose_rdbms:prepare(cluster_insert_new, mongoose_cluster_id, [v],
156157
<<"INSERT INTO mongoose_cluster_id(k,v) VALUES ('cluster_id', ?)">>),
157158
mongoose_rdbms:prepare(cluster_select, mongoose_cluster_id, [],
158-
<<"SELECT v FROM mongoose_cluster_id WHERE k='cluster_id'">>),
159+
<<"SELECT v FROM mongoose_cluster_id WHERE k='cluster_id'">>);
160+
maybe_prepare_queries(_) ->
159161
ok.
160162

161163
-spec execute_cluster_insert_new(binary()) -> mongoose_rdbms:query_result().
162164
execute_cluster_insert_new(ID) ->
163165
mongoose_rdbms:execute_successfully(global, cluster_insert_new, [ID]).
164166

165-
-spec make_cluster_id() -> cluster_id().
166-
make_cluster_id() ->
167-
uuid:uuid_to_string(uuid:get_v4(), binary_standard).
167+
%% If there's no persistent backend, cluster IDs will be recreated on every cluster restart,
168+
%% hence prefix them as ephemeral to re-classify them later.
169+
-spec make_cluster_id(persistent_backend()) -> cluster_id().
170+
make_cluster_id(rdbms) ->
171+
uuid:uuid_to_string(uuid:get_v4(), binary_standard);
172+
make_cluster_id({error, none}) ->
173+
<<"ephemeral-", (uuid:uuid_to_string(uuid:get_v4(), binary_standard))/binary>>.
168174

169-
%% Which backend is enabled
170-
-spec which_backend_available() -> mongoose_backend().
171-
which_backend_available() ->
175+
%% Which persistent backend is enabled
176+
-spec which_persistent_backend_enabled() -> persistent_backend().
177+
which_persistent_backend_enabled() ->
172178
case mongoose_wpool:get_pool_settings(rdbms, global, default) of
173-
undefined -> which_volatile_backend_available();
179+
undefined -> {error, none};
174180
_ -> rdbms
175181
end.
176182

183+
-spec which_volatile_backend_available() -> volatile_backend().
177184
which_volatile_backend_available() ->
178185
case mongoose_config:get_opt(internal_databases) of
179186
#{cets := _} ->
@@ -182,11 +189,10 @@ which_volatile_backend_available() ->
182189
mnesia
183190
end.
184191

185-
-spec set_new_cluster_id(cluster_id(), mongoose_backend()) -> ok | {error, any()}.
186-
set_new_cluster_id(ID, rdbms) ->
192+
-spec persist_cluster_id(cluster_id(), persistent_backend()) -> maybe_cluster_id().
193+
persist_cluster_id(ID, rdbms) ->
187194
try execute_cluster_insert_new(ID) of
188195
{updated, 1} ->
189-
set_new_cluster_id(ID, which_volatile_backend_available()),
190196
{ok, ID}
191197
catch
192198
Class:Reason:Stacktrace ->
@@ -196,20 +202,24 @@ set_new_cluster_id(ID, rdbms) ->
196202
class => Class, reason => Reason, stacktrace => Stacktrace}),
197203
{error, {Class, Reason}}
198204
end;
199-
set_new_cluster_id(ID, mnesia) ->
205+
persist_cluster_id(ID, {error, none}) ->
206+
{ok, ID}.
207+
208+
-spec cache_cluster_id(cluster_id(), volatile_backend()) -> maybe_cluster_id().
209+
cache_cluster_id(ID, mnesia) ->
200210
T = fun() -> mnesia:write(#mongoose_cluster_id{key = cluster_id, value = ID}) end,
201211
case mnesia:transaction(T) of
202212
{atomic, ok} ->
203213
{ok, ID};
204214
{aborted, Reason} ->
205215
{error, Reason}
206216
end;
207-
set_new_cluster_id(ID, cets) ->
217+
cache_cluster_id(ID, cets) ->
208218
cets:insert_serial(cets_cluster_id, {cluster_id, ID}),
209219
{ok, ID}.
210220

211221
%% Get cluster ID
212-
-spec get_backend_cluster_id(mongoose_backend()) -> maybe_cluster_id().
222+
-spec get_backend_cluster_id(persistent_backend()) -> maybe_cluster_id().
213223
get_backend_cluster_id(rdbms) ->
214224
try mongoose_rdbms:execute_successfully(global, cluster_select, []) of
215225
{selected, [{ID}]} -> {ok, ID};
@@ -221,15 +231,13 @@ get_backend_cluster_id(rdbms) ->
221231
class => Class, reason => Reason, stacktrace => Stacktrace}),
222232
{error, {Class, Reason}}
223233
end;
224-
get_backend_cluster_id(mnesia) ->
225-
get_cached_cluster_id(mnesia);
226-
get_backend_cluster_id(cets) ->
227-
get_cached_cluster_id(cets).
234+
get_backend_cluster_id({error, none}) ->
235+
{error, no_value_in_backend}.
228236

229237
clean_table() ->
230-
clean_table(which_backend_available()).
238+
clean_table(which_persistent_backend_enabled()).
231239

232-
-spec clean_table(mongoose_backend()) -> ok | {error, any()}.
240+
-spec clean_table(persistent_backend()) -> ok | {error, any()}.
233241
clean_table(rdbms) ->
234242
SQLQuery = [<<"TRUNCATE TABLE mongoose_cluster_id;">>],
235243
try mongoose_rdbms:sql_query(global, SQLQuery) of

0 commit comments

Comments
 (0)