mirror of
https://github.com/valitydev/woody_erlang.git
synced 2024-11-06 02:15:19 +00:00
Fix flowed child_spec abstraction (#48)
* MG-64: Add find_pool function * MG-64: Refactor options * MG-64: Fix linter and dialyzer errors * MG-64: Fix tests * MG-64: Add review fixes Remove unnecessary functionality Rename pool_name -> name option Define child_spec as woody_client_behaviour * MG-64: Add review fixes 2
This commit is contained in:
parent
66884b7020
commit
7650c1f9f1
11
README.md
11
README.md
@ -55,19 +55,16 @@ Erlang реализация [Библиотеки RPC вызовов для об
|
||||
|
||||
`woody_context:new/0` - можно использовать для создания контекста корневого запроса с автоматически сгенерированным уникальным RPC ID.
|
||||
|
||||
Можно создать пул соединений для thrift клиента (например, для установления _keep alive_ соединений с сервером): `woody_client_thrift:start_pool/2` и затем использовать его при работе с `woody_client`. NB: второй параметр - Options из `hackney:start_pool/2`, например `{timeout, 150000}, {max_connections, 100}`:
|
||||
Можно создать пул соединений для thrift клиента (например, для установления _keep alive_ соединений с сервером). Для этого надо использовать
|
||||
`woody_client:connection_pool_spec/2`. Для работы с определенным пулом в Options есть поле `transport_opts => [{pool, pool_name}, {timeout, 150000}, {max_connections, 100}]`.
|
||||
|
||||
```erlang
|
||||
15> Pool = my_client_pool.
|
||||
16> ok = woody_client_thrift:start_pool(Pool, 10).
|
||||
15> Opts = Opts#{transport_opts => [{pool, my_client_pool}]}.
|
||||
16> supervisor:start_child(Sup, woody_client:connection_pool_spec(Opts)).
|
||||
17> Context2 = woody_context:new(<<"myUniqRequestID2">>).
|
||||
18> {ok, Result2} = woody_client:call(Request, Opts, Context2).
|
||||
```
|
||||
|
||||
Есть возможность стартовать пул в ручную. Для этого надо использовать `woody_client_thrift:child_spec/2`.
|
||||
|
||||
Закрыть пул можно с помошью `woody_client_thrift:stop_pool/1`.
|
||||
|
||||
`Context` также позволяет аннотировать RPC запросы дополнительными мета данными в виде _key-value_. `Context` передается только в запросах и его расширение возможно только в режиме _append-only_ (т.е. на попытку переопределить уже существующую запись в `context meta`, библиотека вернет ошибку). Поскольку на транспортном уровне контекст передается в виде custom HTTP заголовков, синтаксис _key-value_ должен следовать ограничениям [RFC7230 ](https://tools.ietf.org/html/rfc7230#section-3.2.6). Размер ключа записи метаданных не должен превышать _53 байта_ (см. остальные требования к метаданным в [описании библиотеки](http://coredocs.rbkmoney.com/design/ms/platform/rpc-lib/#rpc_2)).
|
||||
|
||||
```erlang
|
||||
|
@ -6,7 +6,9 @@
|
||||
-include("woody_defs.hrl").
|
||||
|
||||
%% API
|
||||
-export([call/2, call/3]).
|
||||
-export([connection_pool_spec/1]).
|
||||
-export([call /2]).
|
||||
-export([call /3]).
|
||||
|
||||
%% Types
|
||||
-type options() :: #{
|
||||
@ -28,6 +30,11 @@
|
||||
%%
|
||||
%% API
|
||||
%%
|
||||
-spec connection_pool_spec(options()) ->
|
||||
supervisor:child_spec().
|
||||
connection_pool_spec(Options) ->
|
||||
woody_client_behaviour:connection_pool_spec(Options).
|
||||
|
||||
-spec call(woody:request(), options()) ->
|
||||
{ok, woody:result()} |
|
||||
{exception, woody_error:business_error()} |
|
||||
|
@ -1,9 +1,17 @@
|
||||
-module(woody_client_behaviour).
|
||||
|
||||
-export([call/3]).
|
||||
-export([connection_pool_spec/1]).
|
||||
-export([call /3]).
|
||||
|
||||
%% Behaviour definition
|
||||
-callback call(woody:request(), woody_client:options(), woody_context:ctx()) -> woody_client:result().
|
||||
-callback connection_pool_spec(woody_client:options()) -> supervisor:child_spec().
|
||||
|
||||
-spec connection_pool_spec(woody_client:options()) ->
|
||||
supervisor:child_spec().
|
||||
connection_pool_spec(Options) ->
|
||||
Handler = woody_util:get_protocol_handler(client, Options),
|
||||
Handler:connection_pool_spec(Options).
|
||||
|
||||
-spec call(woody:request(), woody_client:options(), woody_context:ctx()) ->
|
||||
woody_client:result().
|
||||
|
@ -5,13 +5,9 @@
|
||||
-include_lib("thrift/include/thrift_constants.hrl").
|
||||
-include("woody_defs.hrl").
|
||||
|
||||
%% API
|
||||
-export([child_spec/2]).
|
||||
-export([start_pool/2]).
|
||||
-export([stop_pool /1]).
|
||||
|
||||
%% woody_client_behaviour callback
|
||||
-export([call/3]).
|
||||
-export([call /3]).
|
||||
-export([connection_pool_spec/1]).
|
||||
|
||||
%% Types
|
||||
-type thrift_client() :: term().
|
||||
@ -22,20 +18,10 @@
|
||||
%%
|
||||
%% API
|
||||
%%
|
||||
-spec child_spec(any(), list(tuple())) ->
|
||||
-spec connection_pool_spec(woody_client:options()) ->
|
||||
supervisor:child_spec().
|
||||
child_spec(Name, Options) ->
|
||||
woody_client_thrift_http_transport:child_spec(Name, Options).
|
||||
|
||||
-spec start_pool(any(), list(tuple())) ->
|
||||
ok.
|
||||
start_pool(Name, Options) ->
|
||||
woody_client_thrift_http_transport:start_client_pool(Name, Options).
|
||||
|
||||
-spec stop_pool(any()) ->
|
||||
ok | {error, not_found | simple_one_for_one}.
|
||||
stop_pool(Name) ->
|
||||
woody_client_thrift_http_transport:stop_client_pool(Name).
|
||||
connection_pool_spec(Options) ->
|
||||
woody_client_thrift_http_transport:connection_pool_spec(get_transport_opts(Options)).
|
||||
|
||||
-spec call(woody:request(), woody_client:options(), woody_context:ctx()) ->
|
||||
woody_client:result().
|
||||
|
@ -6,10 +6,8 @@
|
||||
-include("woody_defs.hrl").
|
||||
|
||||
%% API
|
||||
-export([new /3]).
|
||||
-export([start_client_pool/2]).
|
||||
-export([stop_client_pool /1]).
|
||||
-export([child_spec /2]).
|
||||
-export([new /3]).
|
||||
-export([connection_pool_spec/1]).
|
||||
|
||||
%% Thrift transport callbacks
|
||||
-export([read/2, write/2, flush/1, close/1]).
|
||||
@ -49,21 +47,12 @@ new(Url, Opts, Context) ->
|
||||
}),
|
||||
Transport.
|
||||
|
||||
-spec child_spec(any(), options()) ->
|
||||
-spec connection_pool_spec(options()) ->
|
||||
supervisor:child_spec().
|
||||
child_spec(Name, Options) ->
|
||||
connection_pool_spec(Options) ->
|
||||
Name = proplists:get_value(pool, Options),
|
||||
hackney_pool:child_spec(Name, Options).
|
||||
|
||||
-spec start_client_pool(any(), options()) ->
|
||||
ok.
|
||||
start_client_pool(Name, Options) ->
|
||||
hackney_pool:start_pool(Name, Options).
|
||||
|
||||
-spec stop_client_pool(any()) ->
|
||||
ok | {error, not_found | simple_one_for_one}.
|
||||
stop_client_pool(Name) ->
|
||||
hackney_pool:stop_pool(Name).
|
||||
|
||||
%%
|
||||
%% Thrift transport callbacks
|
||||
%%
|
||||
|
@ -51,7 +51,6 @@
|
||||
call_no_headers_503_test/1,
|
||||
call_no_headers_504_test/1,
|
||||
call3_ok_default_ev_handler_test/1,
|
||||
call_with_client_pool_test/1,
|
||||
call_thrift_multiplexed_test/1,
|
||||
server_http_req_validation_test/1,
|
||||
try_bad_handler_spec_test/1,
|
||||
@ -167,7 +166,6 @@ all() ->
|
||||
call_no_headers_503_test,
|
||||
call_no_headers_504_test,
|
||||
call3_ok_default_ev_handler_test,
|
||||
call_with_client_pool_test,
|
||||
call_thrift_multiplexed_test,
|
||||
server_http_req_validation_test,
|
||||
try_bad_handler_spec_test,
|
||||
@ -215,8 +213,8 @@ init_per_testcase(TC, C) when
|
||||
[{sup, Sup} | C];
|
||||
init_per_testcase(find_multiple_pools_test, C) ->
|
||||
{ok, Sup} = start_tc_sup(),
|
||||
Pool1 = {swords , {15000, 100}},
|
||||
Pool2 = {shields, {undefined, 50}},
|
||||
Pool1 = {swords, 15000, 100},
|
||||
Pool2 = {shields, undefined, 50},
|
||||
ok = start_woody_server_with_pools(woody_ct, Sup, ['Weapons', 'Powerups'], [Pool1, Pool2]),
|
||||
[{sup, Sup} | C];
|
||||
init_per_testcase(_, C) ->
|
||||
@ -254,12 +252,21 @@ start_woody_server_with_pools(Id, Sup, Services, Params) ->
|
||||
}),
|
||||
{ok, WoodyServer} = supervisor:start_child(Sup, Server),
|
||||
|
||||
Specs = [woody_client_thrift:child_spec(Pool, pool_options(Options)) || {Pool, Options} <- Params],
|
||||
_ = [supervisor:start_child(WoodyServer, Spec) || Spec <- Specs],
|
||||
Specs = [woody_client:connection_pool_spec(pool_opts(Pool)) || Pool <- Params],
|
||||
|
||||
_ = [supervisor:start_child(WoodyServer, Spec) || Spec <- Specs],
|
||||
ok.
|
||||
|
||||
pool_options({Timeout, MaxConnections}) ->
|
||||
[{timeout, Timeout}, {max_connections, MaxConnections}].
|
||||
pool_opts(Pool) ->
|
||||
{Url, _} = get_service_endpoint('Weapons'),
|
||||
#{
|
||||
url => Url,
|
||||
event_handler => ?MODULE,
|
||||
transport_opts => start_pool_opts(Pool)
|
||||
}.
|
||||
|
||||
start_pool_opts({Name, Timeout, MaxConnections}) ->
|
||||
[{pool, Name}, {timeout, Timeout}, {max_connections, MaxConnections}].
|
||||
|
||||
get_handler('Powerups') ->
|
||||
{
|
||||
@ -495,18 +502,6 @@ call_fail_w_no_headers(Id, Class, Details) ->
|
||||
ok
|
||||
end.
|
||||
|
||||
call_with_client_pool_test(_) ->
|
||||
Pool = guns,
|
||||
ok = woody_client_thrift:start_pool(Pool, [{max_connections, 10}]),
|
||||
Gun = <<"Enforcer">>,
|
||||
Context = make_context(<<"call_with_client_pool">>),
|
||||
{Url, Service} = get_service_endpoint('Weapons'),
|
||||
Expect = {ok, genlib_map:get(Gun, ?WEAPONS)},
|
||||
Expect = woody_client:call({Service, get_weapon, [Gun, self_to_bin()]},
|
||||
#{url => Url, event_handler => ?MODULE, pool => Pool}, Context),
|
||||
{ok, _} = receive_msg(Gun, Context),
|
||||
ok = woody_client_thrift:stop_pool(Pool).
|
||||
|
||||
find_multiple_pools_test(_) ->
|
||||
true = is_pid(hackney_pool:find_pool(swords)),
|
||||
true = is_pid(hackney_pool:find_pool(shields)).
|
||||
|
Loading…
Reference in New Issue
Block a user