MSPF-561 Add live migration with shorter read-only mode (#137)

And also fix v4 init signal routing
This commit is contained in:
Andrey Fadeev 2020-07-07 17:26:56 +03:00 committed by GitHub
parent 4b32f86cab
commit 5bca6314ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 18 deletions

View File

@ -16,8 +16,9 @@
{dmt_api, [
{repository, dmt_api_repository_v5},
{migration, #{
timeout => 360,
limit => 20
timeout => 360,
limit => 20,
read_only_gap => 1000
}},
{ip, "::"},
{port, 8022},

View File

@ -8,7 +8,8 @@
-define(ID , <<"migration/v4_to_v5">>).
-define(DEFAULT_MIGRATION_SETTINGS, #{
timeout => 360, % lagre enought, that we can process butch of old events
limit => 20 % 2xBASE, maybe even less
limit => 20, % 2xBASE, maybe even less
read_only_gap => 1000 % make config read-only near of the migration end
}).
%% API
@ -74,7 +75,12 @@ commit(Version, Commit, Context) ->
true ->
dmt_api_repository_v5:commit(Version, Commit, Context);
false ->
{error, migration_in_progress}
case is_safe_to_commit(Version, Context) of
true ->
dmt_api_repository_v4:commit(Version, Commit, Context);
false ->
{error, migration_in_progress}
end
end.
%%
@ -82,14 +88,11 @@ commit(Version, Commit, Context) ->
-spec process_call(dmt_api_automaton_handler:call(), machine(), context()) ->
{dmt_api_automaton_handler:response(), dmt_api_automaton_handler:events()} | no_return().
process_call(
Call,
#mg_stateproc_Machine{ns = ?NS, id = ?ID} = Machine,
Context
) ->
process_call(Call, #mg_stateproc_Machine{ns = ?NS, id = ?ID} = Machine, Context) ->
process_call_(Call, Machine, Context);
process_call(Call, Machine, Context) ->
% This is for v5 proccessor
process_call(Call, #mg_stateproc_Machine{ns = ?NS, id = <<"primary/v4">>} = Machine, Context) ->
dmt_api_repository_v4:process_call(Call, Machine, Context);
process_call(Call, #mg_stateproc_Machine{ns = ?NS, id = <<"primary/v5">>} = Machine, Context) ->
dmt_api_repository_v5:process_call(Call, Machine, Context).
-spec process_call_(dmt_api_automaton_handler:call(), machine(), context()) -> no_return().
@ -101,14 +104,11 @@ process_call_(_Call, _Machine, _Context) ->
{dmt_api_automaton_handler:action(), dmt_api_automaton_handler:aux_state(), dmt_api_automaton_handler:events()} |
no_return().
process_signal(
Signal,
#mg_stateproc_Machine{ns = ?NS, id = ?ID} = Machine,
Context
) ->
process_signal(Signal, #mg_stateproc_Machine{ns = ?NS, id = ?ID} = Machine, Context) ->
process_signal_(Signal, Machine, Context);
process_signal(Signal, Machine, Context) ->
% This is for v5 proccessor
process_signal(Signal, #mg_stateproc_Machine{ns = ?NS, id = <<"primary/v4">>} = Machine, Context) ->
dmt_api_repository_v4:process_signal(Signal, Machine, Context);
process_signal(Signal, #mg_stateproc_Machine{ns = ?NS, id = <<"primary/v5">>} = Machine, Context) ->
dmt_api_repository_v5:process_signal(Signal, Machine, Context).
process_signal_({init, #mg_stateproc_InitSignal{}}, _Machine, _Context) ->
@ -125,6 +125,13 @@ is_migration_finished(Context) ->
AuxState = get_aux_state(get_machine(Context)),
maps:get(is_finished, AuxState).
is_safe_to_commit(Version, Context) ->
AuxState = get_aux_state(get_machine(Context)),
LastMigratedVersion = maps:get(version, AuxState),
Gap = maps:get(read_only_gap, get_migration_settings()),
% Well, I suppose it is impossible to migrate `Gap` commits until this call will end.
LastMigratedVersion + Gap < Version.
get_machine(Context) ->
case dmt_api_automaton_client:get_machine(?NS, ?ID, Context) of
{ok, Machine} ->