Cache connection info for faster and more robust reconnect #17

Merged
uwiger merged 6 commits from uw-cache-conn into master 2025-10-16 00:20:04 +09:00
4 changed files with 59 additions and 18 deletions
Showing only changes of commit 570f31ab3c - Show all commits

View File

@ -82,6 +82,20 @@ only does this inform the client of the network for which the client should
mine, but it also changes what URL the client will use to find the hive mine, but it also changes what URL the client will use to find the hive
server. (For `"testnet"` this will be `"test.gajumining.com"`.) server. (For `"testnet"` this will be `"test.gajumining.com"`.)
### Caching of connection data
The client retrieves the Hive Server connection info from gajumining.com.
This information is account-specific, and may change over time.
To speed up the reconnecting process, should the Hive Server restart,
this connection information is cached locally for up to 24 hours.
The normal place for the cached data would be
`$ZOMP_DIR//var/uwiger/gmhive_client/Vsn/setup.data/mainnet/gmhc_eureka.XXXXXXXX.cache`,
where `Vsn` is the current version of `gmhive_client`, and `XXXXXXXX` is a fragment
of the current account ID. The data location can be changed with the command-line
option `-setup data_dir Dir`.
## JSON Schema ## JSON Schema
```json ```json

View File

@ -1,6 +1,6 @@
{application,gmhive_client, {application,gmhive_client,
[{description,"Gajumaru Hive Client"}, [{description,"Gajumaru Hive Client"},
{vsn,"0.8.0"}, {vsn,"0.8.1"},
{registered,[]}, {registered,[]},
{applications,[kernel,stdlib,sasl,gproc,inets,ssl,enoise, {applications,[kernel,stdlib,sasl,gproc,inets,ssl,enoise,
gmconfig,gmhive_protocol,gmhive_worker]}, gmconfig,gmhive_protocol,gmhive_worker]},

View File

@ -16,7 +16,8 @@ get_pool_address() ->
end. end.
cached_address() -> cached_address() ->
CacheF = cache_filename(), I0 = cache_info(),
CacheF = cache_filename(I0),
?LOG_DEBUG("Eureka cache filename: ~p", [CacheF]), ?LOG_DEBUG("Eureka cache filename: ~p", [CacheF]),
case file:read_file(CacheF) of case file:read_file(CacheF) of
{ok, Bin} -> {ok, Bin} ->
@ -24,9 +25,12 @@ cached_address() ->
OldestTS = NowTS - 24*60*60, OldestTS = NowTS - 24*60*60,
try binary_to_term(Bin) of try binary_to_term(Bin) of
#{ ts := TS #{ ts := TS
, network := N
, pubkey := PK
, host := _ , host := _
, port := _ , port := _
, pool_id := _} = Map -> , pool_id := _} = Map when N == map_get(network, I0),
PK == map_get(pubkey, I0) ->
if TS >= OldestTS -> if TS >= OldestTS ->
Result = maps:remove(ts, Map), Result = maps:remove(ts, Map),
?LOG_DEBUG("Cached eureka info: ~p", [Result]), ?LOG_DEBUG("Cached eureka info: ~p", [Result]),
@ -44,14 +48,15 @@ cached_address() ->
Err Err
end. end.
cache_good_address(#{host := Addr, cache_good_address(#{host := _,
port := Port, port := _,
pool_id := PoolId}) -> pool_id := _} = I0) ->
CacheF = cache_filename(), CacheInfo = cache_info(I0),
ToCache = #{ host => unicode:characters_to_binary(Addr) CacheF = cache_filename(CacheInfo),
, port => Port
, pool_id => unicode:characters_to_binary(PoolId) ToCache = CacheInfo#{ts => erlang:system_time(seconds)},
, ts => erlang:system_time(seconds)}, case filelib:ensure_dir(CacheF) of
ok ->
case file:write_file(CacheF, term_to_binary(ToCache)) of case file:write_file(CacheF, term_to_binary(ToCache)) of
ok -> ok ->
?LOG_DEBUG("Cached eureka info in: ~p", [CacheF]), ?LOG_DEBUG("Cached eureka info in: ~p", [CacheF]),
@ -59,6 +64,10 @@ cache_good_address(#{host := Addr,
{error, _} = Err -> {error, _} = Err ->
?LOG_DEBUG("Couldn't cache eureka in ~p: ~p", [CacheF, Err]), ?LOG_DEBUG("Couldn't cache eureka in ~p: ~p", [CacheF, Err]),
Err Err
end;
{error, _} = Err ->
?LOG_ERROR("Cannot save cached info to ~s", [CacheF]),
Err
end. end.
invalidate_cache() -> invalidate_cache() ->
@ -72,9 +81,27 @@ invalidate_cache() ->
Err Err
end. end.
cache_info(#{ host := Addr
, port := Port
, pool_id := PoolId }) ->
I0 = cache_info(),
I0#{ host => unicode:characters_to_binary(Addr)
, port => Port
, pool_id => unicode:characters_to_binary(PoolId)}.
cache_info() ->
Pubkey = gmhc_config:get_config([<<"pubkey">>]),
Network = gmhc_config:get_config([<<"network">>]),
#{ pubkey => Pubkey
, network => Network }.
cache_filename() -> cache_filename() ->
<<"ak_", PKShort:8/binary, _/binary>> = gmhc_config:get_config([<<"pubkey">>]), cache_filename(cache_info()).
filename:join(setup:data_dir(), "gmhc_eureka." ++ binary_to_list(PKShort) ++ ".cache").
cache_filename(#{network := Network, pubkey := Pubkey}) ->
Path = filename:join(setup:data_dir(), Network),
<<"ak_", PKShort:8/binary, _/binary>> = Pubkey,
filename:join(Path, "gmhc_eureka." ++ binary_to_list(PKShort) ++ ".cache").
get_pool_address_() -> get_pool_address_() ->
case gmconfig:find_config([<<"pool_admin">>, <<"url">>], [user_config]) of case gmconfig:find_config([<<"pool_admin">>, <<"url">>], [user_config]) of

View File

@ -4,7 +4,7 @@
{prefix,"gmhc"}. {prefix,"gmhc"}.
{desc,"Gajumaru Hive Client"}. {desc,"Gajumaru Hive Client"}.
{author,"Ulf Wiger, QPQ AG"}. {author,"Ulf Wiger, QPQ AG"}.
{package_id,{"uwiger","gmhive_client",{0,8,0}}}. {package_id,{"uwiger","gmhive_client",{0,8,1}}}.
{deps,[{"uwiger","gmhive_protocol",{0,2,0}}, {deps,[{"uwiger","gmhive_protocol",{0,2,0}},
{"uwiger","gmhive_worker",{0,5,1}}, {"uwiger","gmhive_worker",{0,5,1}},
{"uwiger","gmcuckoo",{1,2,4}}, {"uwiger","gmcuckoo",{1,2,4}},