mirror of
https://github.com/valitydev/dominant.git
synced 2024-11-06 02:25:17 +00:00
DC-11: bumped to transient woody (#23)
This commit is contained in:
parent
3e59aea58d
commit
54b967b351
12
rebar.lock
12
rebar.lock
@ -1,4 +1,4 @@
|
||||
[{<<"certifi">>,{pkg,<<"certifi">>,<<"0.4.0">>},2},
|
||||
[{<<"certifi">>,{pkg,<<"certifi">>,<<"0.7.0">>},2},
|
||||
{<<"cowboy">>,{pkg,<<"cowboy">>,<<"1.0.4">>},1},
|
||||
{<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2},
|
||||
{<<"dmsl">>,
|
||||
@ -11,14 +11,14 @@
|
||||
0},
|
||||
{<<"dmt_client">>,
|
||||
{git,"git@github.com:rbkmoney/dmt_client.git",
|
||||
{ref,"22155b2dadd35298b4a1dbfb16b509b944eaed87"}},
|
||||
{ref,"8b2982e409b39076d41320dd08155eecf406cc1a"}},
|
||||
0},
|
||||
{<<"genlib">>,
|
||||
{git,"https://github.com/rbkmoney/genlib.git",
|
||||
{ref,"ea85932ecf19fe39c87237fe5916ba1f65fc0bd6"}},
|
||||
0},
|
||||
{<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.7">>},1},
|
||||
{<<"hackney">>,{pkg,<<"hackney">>,<<"1.5.7">>},1},
|
||||
{<<"hackney">>,{pkg,<<"hackney">>,<<"1.6.2">>},1},
|
||||
{<<"idna">>,{pkg,<<"idna">>,<<"1.2.0">>},2},
|
||||
{<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.0">>},1},
|
||||
{<<"lager">>,{pkg,<<"lager">>,<<"3.0.2">>},0},
|
||||
@ -34,12 +34,12 @@
|
||||
{git,"https://github.com/rbkmoney/snowflake.git",
|
||||
{ref,"36b978a3ad711c9d9349b799a24c5499a95ae29a"}},
|
||||
1},
|
||||
{<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.0">>},2},
|
||||
{<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.1">>},2},
|
||||
{<<"thrift">>,
|
||||
{git,"https://github.com/rbkmoney/thrift_erlang.git",
|
||||
{ref,"f132805904307376831fc2dd3780148b4b91aae2"}},
|
||||
{ref,"aca7fca9f1a7161a1324bf5b92f8402c90d0519e"}},
|
||||
1},
|
||||
{<<"woody">>,
|
||||
{git,"git@github.com:rbkmoney/woody_erlang.git",
|
||||
{ref,"49f47a8b3d0429269d389e2207b94879b9088380"}},
|
||||
{ref,"e1782b323ba324157f144ae75f1141e17dd5d027"}},
|
||||
0}].
|
||||
|
@ -20,34 +20,31 @@
|
||||
|
||||
-type context() :: woody_client:context().
|
||||
|
||||
-spec checkout(dmt:ref(), context()) ->
|
||||
{dmt:snapshot() | {error, version_not_found}, context()}.
|
||||
-spec checkout(dmt:ref(), context()) -> dmt:snapshot() | {error, version_not_found}.
|
||||
checkout(Reference, Context) ->
|
||||
try
|
||||
{dmt_cache:checkout(Reference), Context}
|
||||
dmt_cache:checkout(Reference)
|
||||
catch
|
||||
version_not_found ->
|
||||
dmt_api_context:map(
|
||||
try_get_snapshot(Reference, Context),
|
||||
fun
|
||||
(Snapshot = #'Snapshot'{}) -> dmt_cache:cache_snapshot(Snapshot);
|
||||
(Error = {error, _}) -> Error
|
||||
end
|
||||
)
|
||||
case try_get_snapshot(Reference, Context) of
|
||||
Snapshot = #'Snapshot'{} ->
|
||||
dmt_cache:cache_snapshot(Snapshot);
|
||||
{error, version_not_found} ->
|
||||
{error, version_not_found}
|
||||
end
|
||||
end.
|
||||
|
||||
-spec try_get_snapshot(dmt:ref(), context()) ->
|
||||
{dmt:snapshot() | {error, version_not_found}, context()}.
|
||||
-spec try_get_snapshot(dmt:ref(), context()) -> dmt:snapshot() | {error, version_not_found}.
|
||||
try_get_snapshot(Reference, Context) ->
|
||||
{History, Context1} = dmt_api_mg:get_history(undefined, reference_to_limit(Reference), Context),
|
||||
{case {Reference, dmt_history:head(History)} of
|
||||
History = dmt_api_mg:get_history(undefined, reference_to_limit(Reference), Context),
|
||||
case {Reference, dmt_history:head(History)} of
|
||||
{{head, #'Head'{}}, Snapshot} ->
|
||||
Snapshot;
|
||||
{{version, V}, Snapshot = #'Snapshot'{version = V}} ->
|
||||
Snapshot;
|
||||
{{version, V1}, #'Snapshot'{version = V2}} when V1 > V2 ->
|
||||
{error, version_not_found}
|
||||
end, Context1}.
|
||||
end.
|
||||
|
||||
-spec reference_to_limit(dmt:ref()) -> pos_integer() | undefined.
|
||||
reference_to_limit({head, #'Head'{}}) ->
|
||||
@ -56,15 +53,15 @@ reference_to_limit({version, Version}) ->
|
||||
Version.
|
||||
|
||||
-spec checkout_object(dmt:ref(), dmt:object_ref(), context()) ->
|
||||
{dmsl_domain_config_thrift:'VersionedObject'() | {error, version_not_found | object_not_found}, context()}.
|
||||
dmsl_domain_config_thrift:'VersionedObject'() | {error, version_not_found | object_not_found}.
|
||||
checkout_object(Reference, ObjectReference, Context) ->
|
||||
dmt_api_context:map(
|
||||
checkout(Reference, Context),
|
||||
fun
|
||||
(Snapshot = #'Snapshot'{}) -> try_get_object(ObjectReference, Snapshot);
|
||||
(Error = {error, _}) -> Error
|
||||
end
|
||||
).
|
||||
Snapshot = checkout(Reference, Context),
|
||||
case Snapshot of
|
||||
#'Snapshot'{} ->
|
||||
try_get_object(ObjectReference, Snapshot);
|
||||
{error, _} ->
|
||||
Snapshot
|
||||
end.
|
||||
|
||||
try_get_object(ObjectReference, #'Snapshot'{version = Version, domain = Domain}) ->
|
||||
case dmt_domain:get_object(ObjectReference, Domain) of
|
||||
@ -74,24 +71,21 @@ try_get_object(ObjectReference, #'Snapshot'{version = Version, domain = Domain})
|
||||
{error, object_not_found}
|
||||
end.
|
||||
|
||||
-spec pull(dmt:version(), context()) ->
|
||||
{dmt:history() | {error, version_not_found}, context()}.
|
||||
-spec pull(dmt:version(), context()) -> dmt:history() | {error, version_not_found}.
|
||||
pull(Version, Context) ->
|
||||
dmt_api_mg:get_history(Version, undefined, Context).
|
||||
|
||||
-spec commit(dmt:version(), dmt:commit(), context()) ->
|
||||
{dmt:version() | {error, version_not_found | operation_conflict}, context()}.
|
||||
dmt:version() | {error, version_not_found | operation_conflict}.
|
||||
commit(Version, Commit, Context) ->
|
||||
dmt_api_context:map(
|
||||
dmt_api_mg:commit(Version, Commit, Context),
|
||||
fun
|
||||
(Snapshot = #'Snapshot'{version = VersionNext}) ->
|
||||
_ = dmt_cache:cache_snapshot(Snapshot),
|
||||
VersionNext;
|
||||
(Error = {error, _}) ->
|
||||
Error
|
||||
end
|
||||
).
|
||||
Snapshot = dmt_api_mg:commit(Version, Commit, Context),
|
||||
case Snapshot of
|
||||
#'Snapshot'{version = VersionNext} ->
|
||||
_ = dmt_cache:cache_snapshot(Snapshot),
|
||||
VersionNext;
|
||||
{error, _} ->
|
||||
Snapshot
|
||||
end.
|
||||
|
||||
-spec apply_commit(dmt:version(), dmt:commit(), dmt:history()) ->
|
||||
{ok, dmt:snapshot()} | {error, term()}.
|
||||
@ -132,8 +126,8 @@ init([]) ->
|
||||
#{
|
||||
ip => IP,
|
||||
port => genlib_app:env(?MODULE, port, 8022),
|
||||
net_opts => [],
|
||||
event_handler => dmt_api_woody_event_handler,
|
||||
net_opts => #{},
|
||||
event_handler => woody_event_handler_default,
|
||||
handlers => [
|
||||
get_handler_spec(repository),
|
||||
get_handler_spec(repository_client),
|
||||
@ -144,25 +138,22 @@ init([]) ->
|
||||
Children = [API],
|
||||
{ok, {#{strategy => one_for_one, intensity => 10, period => 60}, Children}}.
|
||||
|
||||
-spec get_handler_spec(Which) -> {Path, {woody_t:service(), module(), term()}} when
|
||||
-spec get_handler_spec(Which) -> {Path, {woody:service(), module()}} when
|
||||
Which :: repository | repository_client | state_processor,
|
||||
Path :: iodata().
|
||||
|
||||
get_handler_spec(repository) ->
|
||||
{"/v1/domain/repository", {
|
||||
{dmsl_domain_config_thrift, 'Repository'},
|
||||
dmt_api_repository_handler,
|
||||
[]
|
||||
dmt_api_repository_handler
|
||||
}};
|
||||
get_handler_spec(repository_client) ->
|
||||
{"/v1/domain/repository_client", {
|
||||
{dmsl_domain_config_thrift, 'RepositoryClient'},
|
||||
dmt_api_repository_client_handler,
|
||||
[]
|
||||
dmt_api_repository_client_handler
|
||||
}};
|
||||
get_handler_spec(state_processor) ->
|
||||
{"/v1/stateproc", {
|
||||
{dmsl_state_processing_thrift, 'Processor'},
|
||||
dmt_api_state_processor,
|
||||
[]
|
||||
dmt_api_state_processor
|
||||
}}.
|
||||
|
@ -1,20 +0,0 @@
|
||||
-module(dmt_api_context).
|
||||
|
||||
-type context() :: woody_client:context().
|
||||
|
||||
-export([new/0]).
|
||||
-export([map/2]).
|
||||
|
||||
-spec new() -> woody_client:context().
|
||||
|
||||
new() ->
|
||||
ReqID = woody_client:make_unique_int(),
|
||||
woody_client:new_context(genlib:to_binary(ReqID), dmt_api_woody_event_handler).
|
||||
|
||||
-spec map({T1, context()}, fun((T1) -> T2)) ->
|
||||
{T2, woody_client:context()} when
|
||||
T1 :: term(),
|
||||
T2 :: term().
|
||||
|
||||
map({T, Context}, Fun) ->
|
||||
{Fun(T), Context}.
|
@ -26,24 +26,24 @@
|
||||
%%
|
||||
|
||||
-spec start(context()) ->
|
||||
{ok, context()} | no_return().
|
||||
ok | no_return().
|
||||
start(Context) ->
|
||||
try call('Start', [?NS, ?ID, <<>>], Context) catch
|
||||
{{exception, #'MachineAlreadyExists'{}}, Context1} ->
|
||||
{ok, Context1}
|
||||
error:#'MachineAlreadyExists'{} ->
|
||||
ok
|
||||
end.
|
||||
|
||||
-spec get_commit(dmt:version(), context()) ->
|
||||
{dmt:commit() | {error, version_not_found}, context()} | no_return().
|
||||
dmt:commit() | {error, version_not_found} | no_return().
|
||||
get_commit(ID, Context) ->
|
||||
dmt_api_context:map(
|
||||
get_history(get_prev_commit(ID), 1, Context),
|
||||
fun
|
||||
(#{ID := Commit}) -> Commit;
|
||||
(#{}) -> {error, version_not_found};
|
||||
(Error) -> Error
|
||||
end
|
||||
).
|
||||
case get_history(get_prev_commit(ID), 1, Context) of
|
||||
#{ID := Commit} ->
|
||||
Commit;
|
||||
#{} ->
|
||||
{error, version_not_found};
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
get_prev_commit(1) ->
|
||||
undefined;
|
||||
@ -52,41 +52,48 @@ get_prev_commit(N) ->
|
||||
|
||||
%% TODO: add range requests after they are fixed in mg
|
||||
-spec get_history(context()) ->
|
||||
{dmt:history(), context()}.
|
||||
dmt:history().
|
||||
get_history(Context) ->
|
||||
get_history(undefined, undefined, Context).
|
||||
|
||||
%% TODO: change this interface to accept dmt:version only
|
||||
-spec get_history(dmt:version() | undefined, pos_integer() | undefined, context()) ->
|
||||
{dmt:history() | {error, version_not_found}, context()}.
|
||||
dmt:history() | {error, version_not_found}.
|
||||
get_history(After, Limit, Context) ->
|
||||
Range = #'HistoryRange'{'after' = prepare_event_id(After), 'limit' = Limit},
|
||||
Descriptor = prepare_descriptor(?NS, ?REF, Range),
|
||||
try dmt_api_context:map(call('GetMachine', [Descriptor], Context), fun read_history/1) catch
|
||||
{{exception, #'EventNotFound'{}}, Context1} ->
|
||||
{{error, version_not_found}, Context1}
|
||||
try read_history(call('GetMachine', [Descriptor], Context)) catch
|
||||
error:#'EventNotFound'{} ->
|
||||
{error, version_not_found}
|
||||
end.
|
||||
|
||||
-spec commit(dmt:version(), dmt:commit(), context()) ->
|
||||
{dmt:version() | {error, version_not_found | operation_conflict}, context()}.
|
||||
dmt:snapshot() | {error, version_not_found | operation_conflict}.
|
||||
commit(Version, Commit, Context) ->
|
||||
Descriptor = prepare_descriptor(?NS, ?REF, #'HistoryRange'{}),
|
||||
Call = term_to_binary({commit, Version, Commit}),
|
||||
dmt_api_context:map(call('Call', [Descriptor, Call], Context), fun binary_to_term/1).
|
||||
binary_to_term(call('Call', [Descriptor, Call], Context)).
|
||||
|
||||
%%
|
||||
|
||||
-spec call(atom(), list(term()), context()) ->
|
||||
{ok, context()} | {{ok, term()}, context()} | no_return().
|
||||
-spec call(atom(), list(term()), context()) -> term() | no_return().
|
||||
call(Method, Args, Context) ->
|
||||
Request = {{dmsl_state_processing_thrift, 'Automaton'}, Method, Args},
|
||||
{ok, URL} = application:get_env(dmt_api, automaton_service_url),
|
||||
try
|
||||
woody_client:call(Context, Request, #{url => URL})
|
||||
catch
|
||||
throw:{{exception, #'MachineNotFound'{}}, Context1} ->
|
||||
{ok, Context2} = start(Context1),
|
||||
woody_client:call(Context2, Request, #{url => URL})
|
||||
Opts = #{url => URL, event_handler => {woody_event_handler_default, undefined}},
|
||||
case woody_client:call(Request, Opts, Context) of
|
||||
{ok, Result} ->
|
||||
Result;
|
||||
{exception, #'MachineNotFound'{}} ->
|
||||
ok = start(Context),
|
||||
case woody_client:call(Request, Opts, Context) of
|
||||
{ok, Result} ->
|
||||
Result;
|
||||
{exception, Exception} ->
|
||||
error(Exception)
|
||||
end;
|
||||
{exception, Exception} ->
|
||||
error(Exception)
|
||||
end.
|
||||
|
||||
%% utils
|
||||
|
@ -8,17 +8,17 @@
|
||||
-include_lib("dmsl/include/dmsl_domain_config_thrift.hrl").
|
||||
|
||||
-spec handle_function(
|
||||
woody_t:func(),
|
||||
woody:func(),
|
||||
woody_server_thrift_handler:args(),
|
||||
woody_client:context(),
|
||||
woody_server_thrift_handler:handler_opts()
|
||||
) -> {woody_server_thrift_handler:result(), woody_client:context()} | no_return().
|
||||
handle_function('checkoutObject', {Reference, ObjectReference}, Context, _Opts) ->
|
||||
) -> {ok, woody_server_thrift_handler:result()} | no_return().
|
||||
handle_function('checkoutObject', [Reference, ObjectReference], Context, _Opts) ->
|
||||
case dmt_api:checkout_object(Reference, ObjectReference, Context) of
|
||||
{Object = #'VersionedObject'{}, Context1} ->
|
||||
{Object, Context1};
|
||||
{{error, object_not_found}, Context1} ->
|
||||
throw({#'ObjectNotFound'{}, Context1});
|
||||
{{error, version_not_found}, Context1} ->
|
||||
throw({#'VersionNotFound'{}, Context1})
|
||||
Object = #'VersionedObject'{} ->
|
||||
{ok, Object};
|
||||
{error, object_not_found} ->
|
||||
woody_error:raise(business, #'ObjectNotFound'{});
|
||||
{error, version_not_found} ->
|
||||
woody_error:raise(business, #'VersionNotFound'{})
|
||||
end.
|
||||
|
@ -8,31 +8,31 @@
|
||||
-include_lib("dmsl/include/dmsl_domain_config_thrift.hrl").
|
||||
|
||||
-spec handle_function(
|
||||
woody_t:func(),
|
||||
woody:func(),
|
||||
woody_server_thrift_handler:args(),
|
||||
woody_client:context(),
|
||||
woody_server_thrift_handler:handler_opts()
|
||||
) -> {woody_server_thrift_handler:result(), woody_client:context()} | no_return().
|
||||
handle_function('Commit', {Version, Commit}, Context, _Opts) ->
|
||||
) -> {ok, woody_server_thrift_handler:result()} | no_return().
|
||||
handle_function('Commit', [Version, Commit], Context, _Opts) ->
|
||||
case dmt_api:commit(Version, Commit, Context) of
|
||||
{VersionNext, Context1} when is_integer(VersionNext) ->
|
||||
{VersionNext, Context1};
|
||||
{{error, operation_conflict}, Context1} ->
|
||||
throw({#'OperationConflict'{}, Context1});
|
||||
{{error, version_not_found}, Context1} ->
|
||||
throw({#'VersionNotFound'{}, Context1})
|
||||
VersionNext when is_integer(VersionNext) ->
|
||||
{ok, VersionNext};
|
||||
{error, operation_conflict} ->
|
||||
woody_error:raise(business, #'OperationConflict'{});
|
||||
{error, version_not_found} ->
|
||||
woody_error:raise(business, #'VersionNotFound'{})
|
||||
end;
|
||||
handle_function('Checkout', {Reference}, Context, _Opts) ->
|
||||
handle_function('Checkout', [Reference], Context, _Opts) ->
|
||||
case dmt_api:checkout(Reference, Context) of
|
||||
{Snapshot = #'Snapshot'{}, Context1} ->
|
||||
{Snapshot, Context1};
|
||||
{{error, version_not_found}, Context1} ->
|
||||
throw({#'VersionNotFound'{}, Context1})
|
||||
Snapshot = #'Snapshot'{} ->
|
||||
{ok, Snapshot};
|
||||
{error, version_not_found} ->
|
||||
woody_error:raise(business, #'VersionNotFound'{})
|
||||
end;
|
||||
handle_function('Pull', {Version}, Context, _Opts) ->
|
||||
handle_function('Pull', [Version], Context, _Opts) ->
|
||||
case dmt_api:pull(Version, Context) of
|
||||
{History = #{}, Context1} ->
|
||||
{History, Context1};
|
||||
{{error, version_not_found}, Context1} ->
|
||||
throw({#'VersionNotFound'{}, Context1})
|
||||
History = #{} ->
|
||||
{ok, History};
|
||||
{error, version_not_found} ->
|
||||
woody_error:raise(business, #'VersionNotFound'{})
|
||||
end.
|
||||
|
@ -9,40 +9,37 @@
|
||||
|
||||
|
||||
-spec handle_function(
|
||||
woody_t:func(),
|
||||
woody:func(),
|
||||
woody_server_thrift_handler:args(),
|
||||
woody_client:context(),
|
||||
woody_server_thrift_handler:handler_opts()
|
||||
) -> {woody_server_thrift_handler:result(), woody_client:context()} | no_return().
|
||||
handle_function('ProcessCall', {#'CallArgs'{arg = Payload, machine = Machine}}, Context, _Opts) ->
|
||||
) -> {ok, woody_server_thrift_handler:result()} | no_return().
|
||||
handle_function('ProcessCall', [#'CallArgs'{arg = Payload, machine = Machine}], _Context, _Opts) ->
|
||||
{Response, Events} = handle_call(binary_to_term(Payload), dmt_api_mg:read_history(Machine)),
|
||||
{
|
||||
#'CallResult'{
|
||||
change = #'MachineStateChange'{
|
||||
aux_state = <<>>,
|
||||
events = lists:map(fun term_to_binary/1, Events)
|
||||
},
|
||||
action = #'ComplexAction'{},
|
||||
response = term_to_binary(Response)
|
||||
{ok, #'CallResult'{
|
||||
change = #'MachineStateChange'{
|
||||
aux_state = <<>>,
|
||||
events = lists:map(fun term_to_binary/1, Events)
|
||||
},
|
||||
Context
|
||||
};
|
||||
handle_function('ProcessSignal', {#'SignalArgs'{signal = {init, #'InitSignal'{}}}}, Context, _Opts) ->
|
||||
{#'SignalResult'{
|
||||
action = #'ComplexAction'{},
|
||||
response = term_to_binary(Response)
|
||||
}};
|
||||
handle_function('ProcessSignal', [#'SignalArgs'{signal = {init, #'InitSignal'{}}}], _Context, _Opts) ->
|
||||
{ok, #'SignalResult'{
|
||||
change = #'MachineStateChange'{
|
||||
aux_state = <<>>,
|
||||
events = []
|
||||
},
|
||||
action = #'ComplexAction'{}
|
||||
}, Context};
|
||||
handle_function('ProcessSignal', {#'SignalArgs'{signal = {repair, #'RepairSignal'{}}}}, Context, _Opts) ->
|
||||
{#'SignalResult'{
|
||||
}};
|
||||
handle_function('ProcessSignal', [#'SignalArgs'{signal = {repair, #'RepairSignal'{}}}], _Context, _Opts) ->
|
||||
{ok, #'SignalResult'{
|
||||
change = #'MachineStateChange'{
|
||||
aux_state = <<>>,
|
||||
events = []
|
||||
},
|
||||
action = #'ComplexAction'{}
|
||||
}, Context}.
|
||||
}}.
|
||||
|
||||
%%
|
||||
|
||||
|
@ -1,21 +0,0 @@
|
||||
-module(dmt_api_woody_event_handler).
|
||||
|
||||
-behaviour(woody_event_handler).
|
||||
|
||||
-export([handle_event/3]).
|
||||
|
||||
-spec handle_event(EventType, RpcID, EventMeta)
|
||||
-> _ when
|
||||
EventType :: woody_event_handler:event_type(),
|
||||
RpcID :: woody_t:rpc_id(),
|
||||
EventMeta :: woody_event_handler:event_meta_type().
|
||||
|
||||
handle_event(EventType, RpcID, #{status := error, class := Class, reason := Reason, stack := Stack}) ->
|
||||
lager:error(
|
||||
maps:to_list(RpcID),
|
||||
"[server] ~s with ~s:~p at ~s",
|
||||
[EventType, Class, Reason, genlib_format:format_stacktrace(Stack, [newlines])]
|
||||
);
|
||||
|
||||
handle_event(EventType, RpcID, EventMeta) ->
|
||||
lager:debug(maps:to_list(RpcID), "[server] ~s: ~p", [EventType, EventMeta]).
|
Loading…
Reference in New Issue
Block a user