Catch HZ timeout on balance check

This commit is contained in:
Craig Everett 2025-12-30 16:33:32 +09:00
parent 52994a12cb
commit 99669a50c7
5 changed files with 302 additions and 4 deletions

View File

@ -641,11 +641,12 @@ do_refresh2(ChainID, State = #s{wallet = W = #wallet{poas = POAs}}) ->
check_balance(ChainID) ->
fun(This = #poa{id = ID}) ->
fun(This = #poa{id = ID, balances = [OldBalance]}) ->
Pucks =
case hz:acc(ID) of
{ok, #{"balance" := P}} -> P;
{error, "Account not found"} -> 0
{error, "Account not found"} -> 0;
{error, timeout} -> OldBalance
end,
Dist = [{ChainID, Pucks}],
Gaju = #balance{coin = "gaju", total = Pucks, dist = Dist},
@ -655,7 +656,6 @@ check_balance(ChainID) ->
ensure_hz_set(Node = #node{ip = IP, external = Port}) ->
tell("Ensuring hz is set..."),
case hz:chain_nodes() of
[{IP, Port}] ->
case hz:status() of
@ -1078,7 +1078,7 @@ do_drop_key(ID, State = #s{wallet = W, wallets = Wallets, pass = Pass}) ->
do_open_wallet(Path, Phrase, State) ->
Pass = pass(Phrase),
case read(Path, Pass) of
{ok, Recovered = #wallet{name = Name, poas = POAs, endpoint = Node}} ->
{ok, Recovered = #wallet{name = Name, poas = POAs, endpoint = _Node}} ->
ok = gd_gui:show(POAs),
ok = gd_gui:wallet(Name),
% TODO: set_hz/1 should dispatch async to the gd_netman.

81
src/gd_net.erl Normal file
View File

@ -0,0 +1,81 @@
%%% @doc
%%% GajuDesk: Net Worker
%%% @end
-module(gd_net).
-vsn("0.8.0").
-behavior(gen_server).
-author("Craig Everett <craigeverett@qpq.swiss>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").
%% gen_server
-export([start_link/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
code_change/3, terminate/2]).
-include("$zx_include/zx_logger.hrl").
%%% Type and Record Definitions
-record(s,
{}).
-type state() :: #s{}.
%%% Interface
%%% gen_server
-spec start_link() -> Result
when Result :: {ok, pid()}
| {error, Reason :: term()}.
start_link() ->
gen_server:start_link(?MODULE, none, []).
init(none) ->
State = #s{},
{ok, State}.
handle_call(Unexpected, From, State) ->
ok = log(warning, "Unexpected call from ~tp: ~tp", [From, Unexpected]),
{noreply, State}.
handle_cast(Unexpected, State) ->
ok = log(warning, "Unexpected cast: ~tp", [Unexpected]),
{noreply, State}.
handle_info(Unexpected, State) ->
ok = log(warning, "Unexpected info: ~tp", [Unexpected]),
{noreply, State}.
-spec code_change(OldVersion, State, Extra) -> {ok, NewState} | {error, Reason}
when OldVersion :: Version | {old, Version},
Version :: term(),
State :: state(),
Extra :: term(),
NewState :: term(),
Reason :: term().
code_change(_, State, _) ->
{ok, State}.
terminate(_, _) ->
ok.
%%% Doer Functions

119
src/gd_net_man.erl Normal file
View File

@ -0,0 +1,119 @@
%%% @doc
%%% GajuDesk: Net Worker Manager
%%% @end
-module(gd_net_man).
-vsn("0.8.0").
-behavior(gen_server).
-author("Craig Everett <craigeverett@qpq.swiss>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").
%% Worker interface
-export([enroll/0]).
%% gen_server
-export([start_link/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
code_change/3, terminate/2]).
-include("$zx_include/zx_logger.hrl").
%%% Type and Record Definitions
-record(s,
{nets = [] :: [pid()]}).
-type state() :: #s{}.
%%% Service Interface
%%% Worker Interface
-spec enroll() -> ok.
%% @doc
%% Workers register here after they initialize.
enroll() ->
gen_server:cast(?MODULE, {enroll, self()}).
%%% gen_server
-spec start_link() -> Result
when Result :: {ok, pid()}
| {error, Reason :: term()}.
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, none, []).
init(none) ->
State = #s{},
{ok, State}.
handle_call(Unexpected, From, State) ->
ok = log(warning, "Unexpected call from ~tp: ~tp", [From, Unexpected]),
{noreply, State}.
handle_cast({enroll, PID}, State) ->
NewState = do_enroll(PID, State),
{noreply, NewState};
handle_cast(Unexpected, State) ->
ok = log(warning, "Unexpected cast: ~tp", [Unexpected]),
{noreply, State}.
handle_info({'DOWN', Mon, process, PID, Reason}, State) ->
NewState = handle_down(Mon, PID, Reason, State),
{noreply, NewState};
handle_info(Unexpected, State) ->
ok = log(warning, "Unexpected info: ~tp", [Unexpected]),
{noreply, State}.
handle_down(Mon, PID, Reason, State = #s{nets = Nets}) ->
case lists:member(PID, Nets) of
true ->
NewNets = lists:delete(PID, Nets),
State#s{nets = NewNets};
false ->
Unexpected = {'DOWN', Mon, process, PID, Reason},
ok = log(warning, "Unexpected info: ~tp", [Unexpected]),
State
end.
code_change(_, State, _) ->
{ok, State}.
terminate(_, _) ->
ok.
%%% Doer Functions
-spec do_enroll(PID, State) -> NewState
when PID :: pid(),
State :: state(),
NewState :: state().
do_enroll(PID, State = #s{nets = Nets}) ->
case lists:member(PID, Nets) of
false ->
Mon = monitor(process, PID),
ok = log(info, "Enroll: ~tp @ ~tp", [PID, Mon]),
State#s{nets = [PID | Nets]};
true ->
State
end.

48
src/gd_net_sup.erl Normal file
View File

@ -0,0 +1,48 @@
%%% @doc
%%% GajuDesk : Net Worker Supervisor
%%% @end
-module(gd_net_sup).
-vsn("0.8.0").
-behaviour(supervisor).
-author("Craig Everett <craigeverett@qpq.swiss>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").
-export([start_net/0]).
-export([start_link/0]).
-export([init/1]).
-spec start_net() -> Result
when Result :: {ok, pid()}
| {error, Reason},
Reason :: {already_started, pid()}
| {shutdown, term()}
| term().
start_net() ->
supervisor:start_child(?MODULE, []).
-spec start_link() -> {ok, pid()}.
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, none).
-spec init(none) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}.
%% @private
%% The OTP init/1 function.
init(none) ->
RestartStrategy = {simple_one_for_one, 1, 60},
Net =
{gd_net,
{gd_net, start_link, []},
temporary,
brutal_kill,
worker,
[gd_net]},
{ok, {RestartStrategy, [Net]}}.

50
src/gd_nets.erl Normal file
View File

@ -0,0 +1,50 @@
%%% @doc
%%% GajuDesk: Net Service Supervisor
%%%
%%% This is the service-level supervisor of the system. It is the parent of both the
%%% client connection handlers and the client manager (which manages the client
%%% connection handlers). This is the child of gd_sup.
%%%
%%% See: http://erlang.org/doc/apps/kernel/application.html
%%% @end
-module(gd_nets).
-vsn("0.8.0").
-behavior(supervisor).
-author("Craig Everett <craigeverett@qpq.swiss>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").
-export([start_link/0]).
-export([init/1]).
-spec start_link() -> {ok, pid()}.
%% @private
%% This supervisor's own start function.
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, none).
-spec init(none) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}.
%% @private
%% The OTP init/1 function.
init(none) ->
RestartStrategy = {rest_for_one, 1, 60},
NetMan =
{gd_net_man,
{gd_net_man, start_link, []},
permanent,
5000,
worker,
[gd_net_man]},
NetSup =
{gd_net_sup,
{gd_net_sup, start_link, []},
permanent,
5000,
supervisor,
[gd_net_sup]},
Children = [NetSup, NetMan],
{ok, {RestartStrategy, Children}}.