Finally implement the "sticky" chain node
This commit is contained in:
parent
4c09490f8a
commit
e8febcf8d5
12
src/hz.erl
12
src/hz.erl
@ -582,7 +582,7 @@ next_nonce(AccountID) ->
|
|||||||
% {ok, #{"reason" := Reason}} -> {error, Reason};
|
% {ok, #{"reason" := Reason}} -> {error, Reason};
|
||||||
% Error -> Error
|
% Error -> Error
|
||||||
% end.
|
% end.
|
||||||
case request(["/v3/accounts/", AccountID]) of
|
case request_sticky(["/v3/accounts/", AccountID]) of
|
||||||
{ok, #{"nonce" := Nonce}} -> {ok, Nonce + 1};
|
{ok, #{"nonce" := Nonce}} -> {ok, Nonce + 1};
|
||||||
{ok, #{"reason" := "Account not found"}} -> {ok, 1};
|
{ok, #{"reason" := "Account not found"}} -> {ok, 1};
|
||||||
{ok, #{"reason" := Reason}} -> {error, Reason};
|
{ok, #{"reason" := Reason}} -> {error, Reason};
|
||||||
@ -729,7 +729,7 @@ tx_info(ID) ->
|
|||||||
|
|
||||||
post_tx(Data) when is_binary(Data) ->
|
post_tx(Data) when is_binary(Data) ->
|
||||||
JSON = zj:binary_encode(#{tx => Data}),
|
JSON = zj:binary_encode(#{tx => Data}),
|
||||||
request("/v3/transactions", JSON);
|
request_sticky("/v3/transactions", JSON);
|
||||||
post_tx(Data) when is_list(Data) ->
|
post_tx(Data) when is_list(Data) ->
|
||||||
post_tx(list_to_binary(Data)).
|
post_tx(list_to_binary(Data)).
|
||||||
|
|
||||||
@ -841,6 +841,14 @@ status_chainends() ->
|
|||||||
request("/v3/status/chain-ends").
|
request("/v3/status/chain-ends").
|
||||||
|
|
||||||
|
|
||||||
|
request_sticky(Path) ->
|
||||||
|
hz_man:request_sticky(unicode:characters_to_list(Path)).
|
||||||
|
|
||||||
|
|
||||||
|
request_sticky(Path, Payload) ->
|
||||||
|
hz_man:request_sticky(unicode:characters_to_list(Path), Payload).
|
||||||
|
|
||||||
|
|
||||||
request(Path) ->
|
request(Path) ->
|
||||||
hz_man:request(unicode:characters_to_list(Path)).
|
hz_man:request(unicode:characters_to_list(Path)).
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
timeout/0, timeout/1]).
|
timeout/0, timeout/1]).
|
||||||
|
|
||||||
%% The whole point of this module:
|
%% The whole point of this module:
|
||||||
-export([request/1, request/2]).
|
-export([request_sticky/1, request_sticky/2,request/1, request/2]).
|
||||||
|
|
||||||
%% gen_server goo
|
%% gen_server goo
|
||||||
-export([start_link/0]).
|
-export([start_link/0]).
|
||||||
@ -94,6 +94,25 @@ timeout(Value) when 0 < Value, Value =< 120000 ->
|
|||||||
gen_server:cast(?MODULE, {timeout, Value}).
|
gen_server:cast(?MODULE, {timeout, Value}).
|
||||||
|
|
||||||
|
|
||||||
|
-spec request_sticky(Path) -> {ok, Value} | {error, Reason}
|
||||||
|
when Path :: unicode:charlist(),
|
||||||
|
Value :: map(),
|
||||||
|
Reason :: hz:chain_error().
|
||||||
|
|
||||||
|
request_sticky(Path) ->
|
||||||
|
gen_server:call(?MODULE, {request_sticky, {get, Path}}, infinity).
|
||||||
|
|
||||||
|
|
||||||
|
-spec request_sticky(Path, Data) -> {ok, Value} | {error, Reason}
|
||||||
|
when Path :: unicode:charlist(),
|
||||||
|
Data :: unicode:charlist(),
|
||||||
|
Value :: map(),
|
||||||
|
Reason :: hz:chain_error().
|
||||||
|
|
||||||
|
request_sticky(Path, Data) ->
|
||||||
|
gen_server:call(?MODULE, {request_sticky, {post, Path, Data}}, infinity).
|
||||||
|
|
||||||
|
|
||||||
-spec request(Path) -> {ok, Value} | {error, Reason}
|
-spec request(Path) -> {ok, Value} | {error, Reason}
|
||||||
when Path :: unicode:charlist(),
|
when Path :: unicode:charlist(),
|
||||||
Value :: map(),
|
Value :: map(),
|
||||||
@ -145,6 +164,9 @@ init(none) ->
|
|||||||
handle_call({request, Request}, From, State) ->
|
handle_call({request, Request}, From, State) ->
|
||||||
NewState = do_request(Request, From, State),
|
NewState = do_request(Request, From, State),
|
||||||
{noreply, NewState};
|
{noreply, NewState};
|
||||||
|
handle_call({request_sticky, Request}, From, State) ->
|
||||||
|
NewState = do_request_sticky(Request, From, State),
|
||||||
|
{noreply, NewState};
|
||||||
handle_call(tls, _, State = #s{tls = TLS}) ->
|
handle_call(tls, _, State = #s{tls = TLS}) ->
|
||||||
{reply, TLS, State};
|
{reply, TLS, State};
|
||||||
handle_call(chain_nodes, _, State = #s{chain_nodes = {Wait, Used}}) ->
|
handle_call(chain_nodes, _, State = #s{chain_nodes = {Wait, Used}}) ->
|
||||||
@ -160,10 +182,9 @@ handle_call(Unexpected, From, State) ->
|
|||||||
handle_cast({tls, Boolean}, State) ->
|
handle_cast({tls, Boolean}, State) ->
|
||||||
NewState = do_tls(Boolean, State),
|
NewState = do_tls(Boolean, State),
|
||||||
{noreply, NewState};
|
{noreply, NewState};
|
||||||
handle_cast({chain_nodes, []}, State) ->
|
handle_cast({chain_nodes, List}, State) ->
|
||||||
{noreply, State#s{chain_nodes = {[], []}}};
|
NewState = do_chain_nodes(List, State),
|
||||||
handle_cast({chain_nodes, ToUse}, State) ->
|
{noreply, NewState};
|
||||||
{noreply, State#s{chain_nodes = {ToUse, []}}};
|
|
||||||
handle_cast({timeout, Value}, State) ->
|
handle_cast({timeout, Value}, State) ->
|
||||||
{noreply, State#s{timeout = Value}};
|
{noreply, State#s{timeout = Value}};
|
||||||
handle_cast(Unexpected, State) ->
|
handle_cast(Unexpected, State) ->
|
||||||
@ -218,6 +239,14 @@ terminate(_, _) ->
|
|||||||
|
|
||||||
%%% Doer Functions
|
%%% Doer Functions
|
||||||
|
|
||||||
|
do_chain_nodes([], State) ->
|
||||||
|
State#s{sticky = none, chain_nodes = {[], []}};
|
||||||
|
do_chain_nodes(List = [Sticky], State) ->
|
||||||
|
State#s{sticky = Sticky, chain_nodes = {List, []}};
|
||||||
|
do_chain_nodes([Sticky | List], State) ->
|
||||||
|
State#s{sticky = Sticky, chain_nodes = {List, []}}.
|
||||||
|
|
||||||
|
|
||||||
do_tls(true, State) ->
|
do_tls(true, State) ->
|
||||||
ok = ssl:start(),
|
ok = ssl:start(),
|
||||||
State#s{tls = true};
|
State#s{tls = true};
|
||||||
@ -227,17 +256,21 @@ do_tls(_, State) ->
|
|||||||
State.
|
State.
|
||||||
|
|
||||||
|
|
||||||
do_request(_, From, State = #s{chain_nodes = {[], []}}) ->
|
do_request_sticky(_, From, State = #s{sticky = none}) ->
|
||||||
ok = gen_server:reply(From, {error, no_nodes}),
|
ok = gen_server:reply(From, {error, no_nodes}),
|
||||||
State;
|
State;
|
||||||
do_request(Request,
|
do_request_sticky(Request,
|
||||||
From,
|
From,
|
||||||
State = #s{tls = false,
|
State = #s{tls = TLS,
|
||||||
fetchers = Fetchers,
|
fetchers = Fetchers,
|
||||||
chain_nodes = {[Node | Rest], Used},
|
sticky = Node,
|
||||||
timeout = Timeout}) ->
|
timeout = Timeout}) ->
|
||||||
Now = erlang:system_time(nanosecond),
|
Now = erlang:system_time(nanosecond),
|
||||||
Fetcher = fun() -> hz_fetcher:connect(Node, Request, From, Timeout) end,
|
Fetcher =
|
||||||
|
case TLS of
|
||||||
|
true -> fun() -> hz_fetcher:slowly_connect(Node, Request, From, Timeout) end;
|
||||||
|
false -> fun() -> hz_fetcher:connect(Node, Request, From, Timeout) end
|
||||||
|
end,
|
||||||
{PID, Mon} = spawn_monitor(Fetcher),
|
{PID, Mon} = spawn_monitor(Fetcher),
|
||||||
New = #fetcher{pid = PID,
|
New = #fetcher{pid = PID,
|
||||||
mon = Mon,
|
mon = Mon,
|
||||||
@ -245,15 +278,24 @@ do_request(Request,
|
|||||||
node = Node,
|
node = Node,
|
||||||
from = From,
|
from = From,
|
||||||
req = Request},
|
req = Request},
|
||||||
State#s{fetchers = [New | Fetchers], chain_nodes = {Rest, [Node | Used]}};
|
State#s{fetchers = [New | Fetchers]}.
|
||||||
|
|
||||||
|
|
||||||
|
do_request(_, From, State = #s{chain_nodes = {[], []}}) ->
|
||||||
|
ok = gen_server:reply(From, {error, no_nodes}),
|
||||||
|
State;
|
||||||
do_request(Request,
|
do_request(Request,
|
||||||
From,
|
From,
|
||||||
State = #s{tls = true,
|
State = #s{tls = TLS,
|
||||||
fetchers = Fetchers,
|
fetchers = Fetchers,
|
||||||
chain_nodes = {[Node | Rest], Used},
|
chain_nodes = {[Node | Rest], Used},
|
||||||
timeout = Timeout}) ->
|
timeout = Timeout}) ->
|
||||||
Now = erlang:system_time(nanosecond),
|
Now = erlang:system_time(nanosecond),
|
||||||
Fetcher = fun() -> hz_fetcher:slowly_connect(Node, Request, From, Timeout) end,
|
Fetcher =
|
||||||
|
case TLS of
|
||||||
|
true -> fun() -> hz_fetcher:slowly_connect(Node, Request, From, Timeout) end;
|
||||||
|
false -> fun() -> hz_fetcher:connect(Node, Request, From, Timeout) end
|
||||||
|
end,
|
||||||
{PID, Mon} = spawn_monitor(Fetcher),
|
{PID, Mon} = spawn_monitor(Fetcher),
|
||||||
New = #fetcher{pid = PID,
|
New = #fetcher{pid = PID,
|
||||||
mon = Mon,
|
mon = Mon,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user