FIN-31: Adds support for snapshot creation timestamp (#7)

* FIN-31: Adds support for snapshot creation timestamp

* Bumps CI workflow

* Temporarily disables codecov report upload; fixes protocol and dialyzer warnings

* Fix possible bug for partial history backwards traversal
This commit is contained in:
Aleksey Kashapov 2024-05-14 13:44:13 +03:00 committed by GitHub
parent 75841332fe
commit 19d8f57198
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 32 additions and 10 deletions

View File

@ -30,9 +30,10 @@ jobs:
run: run:
name: Run checks name: Run checks
needs: setup needs: setup
uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.1 uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.14
with: with:
otp-version: ${{ needs.setup.outputs.otp-version }} otp-version: ${{ needs.setup.outputs.otp-version }}
rebar-version: ${{ needs.setup.outputs.rebar-version }} rebar-version: ${{ needs.setup.outputs.rebar-version }}
use-thrift: true use-thrift: true
thrift-version: ${{ needs.setup.outputs.thrift-version }} thrift-version: ${{ needs.setup.outputs.thrift-version }}
upload-coverage: false

View File

@ -45,7 +45,7 @@
% mandatory % mandatory
unmatched_returns, unmatched_returns,
error_handling, error_handling,
race_conditions, % NOTE 'race_conditions' was removed https://www.erlang.org/doc/apps/dialyzer/notes#dialyzer-5.0
unknown unknown
]}, ]},
{plt_apps, all_deps} {plt_apps, all_deps}

View File

@ -1,6 +1,6 @@
[{<<"damsel">>, [{<<"damsel">>,
{git,"https://github.com/valitydev/damsel.git", {git,"https://github.com/valitydev/damsel.git",
{ref,"dac2cb599499cc0701e60856f4092c9ab283eedf"}}, {ref,"ab292d91f5265237351342675c8f69de17add673"}},
0}, 0},
{<<"genlib">>, {<<"genlib">>,
{git,"https://github.com/rbkmoney/genlib.git", {git,"https://github.com/rbkmoney/genlib.git",

View File

@ -12,7 +12,7 @@
-spec head(history()) -> {ok, snapshot()} | {error, dmt_domain:operation_error()}. -spec head(history()) -> {ok, snapshot()} | {error, dmt_domain:operation_error()}.
head(History) -> head(History) ->
head(History, #domain_conf_Snapshot{version = 0, domain = dmt_domain:new()}). head(History, #domain_conf_Snapshot{version = 0, domain = dmt_domain:new(), created_at = undefined}).
-spec head(history(), snapshot()) -> {ok, snapshot()} | {error, dmt_domain:operation_error()}. -spec head(history(), snapshot()) -> {ok, snapshot()} | {error, dmt_domain:operation_error()}.
head(History, Snapshot) when map_size(History) =:= 0 -> head(History, Snapshot) when map_size(History) =:= 0 ->
@ -25,12 +25,13 @@ head(History, Snapshot) ->
travel(To, _History, #domain_conf_Snapshot{version = From} = Snapshot) when To =:= From -> travel(To, _History, #domain_conf_Snapshot{version = From} = Snapshot) when To =:= From ->
{ok, Snapshot}; {ok, Snapshot};
travel(To, History, #domain_conf_Snapshot{version = From, domain = Domain}) when To > From -> travel(To, History, #domain_conf_Snapshot{version = From, domain = Domain}) when To > From ->
#domain_conf_Commit{ops = Ops} = maps:get(From + 1, History), #domain_conf_Commit{ops = Ops, created_at = CreatedAt} = maps:get(From + 1, History),
case dmt_domain:apply_operations(Ops, Domain) of case dmt_domain:apply_operations(Ops, Domain) of
{ok, NewDomain} -> {ok, NewDomain} ->
NextSnapshot = #domain_conf_Snapshot{ NextSnapshot = #domain_conf_Snapshot{
version = From + 1, version = From + 1,
domain = NewDomain domain = NewDomain,
created_at = CreatedAt
}, },
travel(To, History, NextSnapshot); travel(To, History, NextSnapshot);
{error, _} = Error -> {error, _} = Error ->
@ -38,11 +39,20 @@ travel(To, History, #domain_conf_Snapshot{version = From, domain = Domain}) when
end; end;
travel(To, History, #domain_conf_Snapshot{version = From, domain = Domain}) when To < From -> travel(To, History, #domain_conf_Snapshot{version = From, domain = Domain}) when To < From ->
#domain_conf_Commit{ops = Ops} = maps:get(From, History), #domain_conf_Commit{ops = Ops} = maps:get(From, History),
%% NOTE In case of backwards traversal of partial history of
%% commits there may be no 'previous' commit. Use 'undefined'
%% for creation timestamp as a fallback value.
CreatedAt =
case maps:get(From - 1, History, undefined) of
#domain_conf_Commit{created_at = T} -> T;
undefined -> undefined
end,
case dmt_domain:revert_operations(Ops, Domain) of case dmt_domain:revert_operations(Ops, Domain) of
{ok, NewDomain} -> {ok, NewDomain} ->
PreviousSnapshot = #domain_conf_Snapshot{ PreviousSnapshot = #domain_conf_Snapshot{
version = From - 1, version = From - 1,
domain = NewDomain domain = NewDomain,
created_at = CreatedAt
}, },
travel(To, History, PreviousSnapshot); travel(To, History, PreviousSnapshot);
{error, _} = Error -> {error, _} = Error ->

View File

@ -12,7 +12,7 @@
-type commit() :: dmsl_domain_conf_thrift:'Commit'(). -type commit() :: dmsl_domain_conf_thrift:'Commit'().
-record(st, { -record(st, {
snapshot = #domain_conf_Snapshot{version = 0, domain = dmt_domain:new()} :: snapshot(), snapshot = #domain_conf_Snapshot{version = 0, domain = dmt_domain:new(), created_at = undefined} :: snapshot(),
history = #{} :: #{_Version => commit()} history = #{} :: #{_Version => commit()}
}). }).

View File

@ -194,7 +194,14 @@ wrong_spec_order_test() ->
terms = #domain_ProvisionTermSet{ terms = #domain_ProvisionTermSet{
payments = #domain_PaymentsProvisionTerms{ payments = #domain_PaymentsProvisionTerms{
categories = {value, [?category_ref(1)]}, categories = {value, [?category_ref(1)]},
payment_methods = {value, [#domain_PaymentMethodRef{id = {bank_card, visa}}]}, payment_methods =
{value, [
?payment_method_ref(
{bank_card, #domain_BankCardPaymentMethod{
payment_system = #domain_PaymentSystemRef{id = <<"visa-ref">>}
}}
)
]},
cash_flow = {value, []} cash_flow = {value, []}
} }
} }
@ -214,7 +221,11 @@ wrong_spec_order_test() ->
PaymentMethod = { PaymentMethod = {
payment_method, payment_method,
#domain_PaymentMethodObject{ #domain_PaymentMethodObject{
ref = ?payment_method_ref({bank_card, visa}), ref = ?payment_method_ref(
{bank_card, #domain_BankCardPaymentMethod{
payment_system = #domain_PaymentSystemRef{id = <<"visa-ref">>}
}}
),
data = #domain_PaymentMethodDefinition{ data = #domain_PaymentMethodDefinition{
name = <<"VISA">>, name = <<"VISA">>,
description = <<"VISA BANK CARD">> description = <<"VISA BANK CARD">>