Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2a33d06bd6 | |||
| 8cb2c76614 | |||
| 07b658d509 | |||
| 8a68244c90 |
@@ -1,6 +1,6 @@
|
||||
{application,gmhive_client,
|
||||
[{description,"Gajumaru Hive Client"},
|
||||
{vsn,"0.5.1"},
|
||||
{vsn,"0.6.1"},
|
||||
{registered,[]},
|
||||
{applications,[kernel,stdlib,sasl,gproc,inets,ssl,enoise,
|
||||
gmconfig,gmhive_protocol,gmhive_worker]},
|
||||
|
||||
+10
-1
@@ -1,6 +1,6 @@
|
||||
%% -*- mode: erlang; erlang-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
-module(gmhc_app).
|
||||
-vsn("0.4.8").
|
||||
-vsn("0.6.1").
|
||||
|
||||
-behaviour(application).
|
||||
|
||||
@@ -49,4 +49,13 @@ set_things_up() ->
|
||||
gmhc_config:load_config(),
|
||||
logger:set_module_level([gmhw_pow_cuckoo], notice),
|
||||
?LOG_DEBUG("Config: ~p", [gmconfig:user_config()]),
|
||||
case gmhc_config:get_config([<<"report">>]) of
|
||||
<<"debug">> ->
|
||||
?LOG_NOTICE("Starting debug reporter", []),
|
||||
gmhc_events:debug();
|
||||
<<"progress">> ->
|
||||
?LOG_NOTICE("Starting progress reporter", []),
|
||||
gmhc_events:progress();
|
||||
_ -> ok
|
||||
end,
|
||||
ok.
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
-module(gmhc_config).
|
||||
-vsn("0.4.8").
|
||||
-vsn("0.6.1").
|
||||
|
||||
-export([ load_config/0
|
||||
, get_config/1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
-module(gmhc_config_schema).
|
||||
-vsn("0.4.8").
|
||||
-vsn("0.6.1").
|
||||
|
||||
-export([ schema/0
|
||||
, to_json/0 ]).
|
||||
@@ -39,6 +39,9 @@ schema() ->
|
||||
, pool => pool()
|
||||
, pool_admin => pool_admin()
|
||||
, workers => workers()
|
||||
, report => str(#{ enum => [<<"debug">>, <<"progress">>, <<"silent">>]
|
||||
, default => <<"silent">>
|
||||
, description => <<"Progress reporting">> })
|
||||
}).
|
||||
|
||||
pool() ->
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
-module(gmhc_connector).
|
||||
-vsn("0.4.8").
|
||||
-vsn("0.6.1").
|
||||
|
||||
-behaviour(gen_server).
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
-module(gmhc_connectors_sup).
|
||||
-vsn("0.4.8").
|
||||
-vsn("0.6.1").
|
||||
-behavior(supervisor).
|
||||
|
||||
-export([ start_link/0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
-module(gmhc_counters).
|
||||
-vsn("0.4.8").
|
||||
-vsn("0.6.1").
|
||||
|
||||
-export([ initialize/0 ]).
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
-module(gmhc_eureka).
|
||||
-vsn("0.4.8").
|
||||
-vsn("0.6.1").
|
||||
|
||||
-export([get_pool_address/0]).
|
||||
|
||||
|
||||
+104
-17
@@ -1,5 +1,5 @@
|
||||
-module(gmhc_events).
|
||||
-vsn("0.4.8").
|
||||
-vsn("0.6.1").
|
||||
|
||||
-export([subscribe/1,
|
||||
ensure_subscribed/1,
|
||||
@@ -7,7 +7,17 @@
|
||||
ensure_unsubscribed/1,
|
||||
publish/2]).
|
||||
|
||||
-export([debug/0]).
|
||||
-export([debug/0,
|
||||
progress/0,
|
||||
stop/0]).
|
||||
|
||||
-export([rpt_debug/2,
|
||||
rpt_progress/2]).
|
||||
|
||||
%% internal
|
||||
-export([init_reporter/2]).
|
||||
|
||||
-include_lib("kernel/include/logger.hrl").
|
||||
|
||||
-export_type([event/0]).
|
||||
|
||||
@@ -60,23 +70,100 @@ ensure_unsubscribed(Event) ->
|
||||
|
||||
debug() ->
|
||||
ok = application:ensure_started(gproc),
|
||||
spawn(fun() ->
|
||||
subscribe(pool_notification),
|
||||
subscribe({pool_notification, new_generation}),
|
||||
subscribe(connected),
|
||||
subscribe(puzzle),
|
||||
subscribe(result),
|
||||
subscribe(error),
|
||||
subscribe(disconnected),
|
||||
gmhive_worker:subscribe_returns(),
|
||||
loop()
|
||||
end).
|
||||
spawn_reporter(fun() ->
|
||||
sub(),
|
||||
gmhive_worker:subscribe_returns(),
|
||||
loop(fun rpt_debug/2, false)
|
||||
end).
|
||||
|
||||
loop() ->
|
||||
progress() ->
|
||||
ok = application:ensure_started(gproc),
|
||||
spawn_reporter(fun() ->
|
||||
sub(),
|
||||
loop(fun rpt_progress/2, true)
|
||||
end).
|
||||
|
||||
spawn_reporter(F) ->
|
||||
Parent = self(),
|
||||
proc_lib:start_link(?MODULE, init_reporter, [F, Parent]).
|
||||
|
||||
init_reporter(F, Parent) ->
|
||||
try_register_reporter(),
|
||||
proc_lib:init_ack(Parent, self()),
|
||||
F().
|
||||
|
||||
stop() ->
|
||||
case whereis(gmhc_reporter) of
|
||||
undefined ->
|
||||
not_running;
|
||||
Pid ->
|
||||
exit(Pid, kill)
|
||||
end.
|
||||
|
||||
sub() ->
|
||||
subscribe(pool_notification),
|
||||
subscribe({pool_notification, new_generation}),
|
||||
subscribe(connected),
|
||||
subscribe(puzzle),
|
||||
subscribe(result),
|
||||
subscribe(error),
|
||||
subscribe(disconnected).
|
||||
|
||||
loop(F, Ts) ->
|
||||
receive
|
||||
stop -> ok;
|
||||
{gproc_ps_event, E, Data} ->
|
||||
io:fwrite("EVENT ~p: ~p~n", [E, Data]),
|
||||
loop()
|
||||
maybe_print(F(E, Data), Ts),
|
||||
loop(F, Ts)
|
||||
end.
|
||||
|
||||
|
||||
try_register_reporter() ->
|
||||
try register(gmhc_reporter, self())
|
||||
catch
|
||||
error:_ ->
|
||||
?LOG_ERROR("Reporter already running. Try gmhc_events:stop().", []),
|
||||
error(already_running)
|
||||
end.
|
||||
|
||||
maybe_print([], _) ->
|
||||
ok;
|
||||
maybe_print(String, Ts) when is_boolean(Ts) ->
|
||||
TSstr = [[ts(), " "] || Ts],
|
||||
io:put_chars([TSstr, String, "\n"]).
|
||||
|
||||
ts() ->
|
||||
calendar:system_time_to_rfc3339(erlang:system_time(millisecond),
|
||||
[{unit, millisecond}, {offset, "Z"}]).
|
||||
|
||||
rpt_debug(E, Data) ->
|
||||
io_lib:fwrite("EVENT ~p: ~p", [E, Data]).
|
||||
|
||||
rpt_progress(puzzle, #{info := {_Data, _Target, Nonce, _Config}}) ->
|
||||
w("Trying nonce: ~p", [Nonce]);
|
||||
rpt_progress(result, #{info := Info}) ->
|
||||
case Info of
|
||||
{error, no_solution} ->
|
||||
[];
|
||||
{ok, Cycles} ->
|
||||
w("Found! Reporting ~w cycles to leader.", [length(Cycles)]);
|
||||
Other ->
|
||||
w("Unexpected 'result': ~tp", [Other])
|
||||
end;
|
||||
rpt_progress(pool_notification, #{info := #{msg := Msg}}) ->
|
||||
case Msg of
|
||||
#{solution_accepted := #{seq := Seq}} ->
|
||||
w("The hive has produced a solution! Sequence: ~w", [Seq]);
|
||||
#{new_generation := _} -> [];
|
||||
#{candidate := _} -> [];
|
||||
Other ->
|
||||
w("Unexpected 'pool_notification': ~tp", [Other])
|
||||
end;
|
||||
rpt_progress(connected, _) ->
|
||||
w("Connected!", []);
|
||||
rpt_progress(disconnected, _) ->
|
||||
w("Disconnected!", []);
|
||||
rpt_progress(_, _) ->
|
||||
[].
|
||||
|
||||
w(Fmt, Args) ->
|
||||
io_lib:fwrite(Fmt, Args).
|
||||
|
||||
+37
-15
@@ -1,5 +1,5 @@
|
||||
-module(gmhc_handler).
|
||||
-vsn("0.4.8").
|
||||
-vsn("0.6.1").
|
||||
-behavior(gen_server).
|
||||
|
||||
-export([ start_link/0
|
||||
@@ -12,6 +12,7 @@
|
||||
]).
|
||||
|
||||
-export([ call/1
|
||||
, async_call/1
|
||||
, notify/1
|
||||
, pool_connected/2
|
||||
, from_pool/1 ]).
|
||||
@@ -38,6 +39,13 @@ call(Req) ->
|
||||
{error, Reason}
|
||||
end.
|
||||
|
||||
async_call(Req) ->
|
||||
try gen_server:call(?MODULE, {async_call, Req}, ?CALL_TIMEOUT)
|
||||
catch
|
||||
exit:Reason ->
|
||||
{error, Reason}
|
||||
end.
|
||||
|
||||
notify(Msg) ->
|
||||
gen_server:cast(?MODULE, {notify, Msg}).
|
||||
|
||||
@@ -56,6 +64,8 @@ init([]) ->
|
||||
|
||||
handle_call({call, Req}, _From, #st{} = S) ->
|
||||
{reply, call_connector(Req), S};
|
||||
handle_call({async_call, Req}, _From, #st{} = S) ->
|
||||
{reply, call_connector(Req, false), S};
|
||||
handle_call(_Req, _From, S) ->
|
||||
{reply, {error, unknown_method}, S}.
|
||||
|
||||
@@ -119,27 +129,39 @@ maybe_publish(_) ->
|
||||
maybe_via(#{via := Via}, Info) ->
|
||||
Info#{via => Via}.
|
||||
|
||||
call_connector(Req0) ->
|
||||
call_connector(Req) ->
|
||||
call_connector(Req, true).
|
||||
|
||||
call_connector(Req0, Wait) ->
|
||||
{ViaId, Req} = maps:take(via, Req0),
|
||||
case gmhc_connector:whereis_id(ViaId) of
|
||||
undefined ->
|
||||
{error, no_connection};
|
||||
Pid when is_pid(Pid) ->
|
||||
Id = erlang:unique_integer(),
|
||||
MRef = erlang:monitor(process, Pid),
|
||||
MRef = case Wait of
|
||||
true -> erlang:monitor(process, Pid);
|
||||
false -> none
|
||||
end,
|
||||
gmhc_connector:send(ViaId, #{call => Req#{ id => Id }}),
|
||||
receive
|
||||
{from_pool, #{reply := #{ id := Id, result := Result }}} ->
|
||||
erlang:demonitor(MRef),
|
||||
Result;
|
||||
{from_pool, #{error := #{ id := Id } = Error}} ->
|
||||
erlang:demonitor(MRef),
|
||||
{error, maps:remove(id, Error)};
|
||||
{'DOWN', MRef, _, _, _} ->
|
||||
{error, no_connection}
|
||||
after 5000 ->
|
||||
erlang:demonitor(MRef),
|
||||
{error, {timeout, process_info(self(), messages)}}
|
||||
case Wait of
|
||||
true ->
|
||||
receive
|
||||
{from_pool, #{reply := #{ id := Id
|
||||
, result := Result }}} ->
|
||||
erlang:demonitor(MRef),
|
||||
Result;
|
||||
{from_pool, #{error := #{ id := Id } = Error}} ->
|
||||
erlang:demonitor(MRef),
|
||||
{error, maps:remove(id, Error)};
|
||||
{'DOWN', MRef, _, _, _} ->
|
||||
{error, no_connection}
|
||||
after 5000 ->
|
||||
erlang:demonitor(MRef),
|
||||
{error, {timeout, process_info(self(), messages)}}
|
||||
end;
|
||||
false ->
|
||||
ok
|
||||
end
|
||||
end.
|
||||
|
||||
|
||||
+19
-11
@@ -1,5 +1,5 @@
|
||||
-module(gmhc_server).
|
||||
-vsn("0.4.8").
|
||||
-vsn("0.6.1").
|
||||
|
||||
-behaviour(gen_server).
|
||||
|
||||
@@ -184,6 +184,9 @@ code_change(_FromVsn, S, _Extra) ->
|
||||
|
||||
report_solutions(Solutions, W, #st{} = S) when ?CONNECTED(S) ->
|
||||
#{via := Via, seq := Seq} = W#worker.cand,
|
||||
Nonces = all_nonces(W),
|
||||
[report_no_solution_(Via, Seq, N)
|
||||
|| N <- Nonces, not lists:keymember(N, 1, Solutions)],
|
||||
gmhc_handler:call(
|
||||
#{via => Via,
|
||||
solutions => #{ seq => Seq
|
||||
@@ -191,18 +194,23 @@ report_solutions(Solutions, W, #st{} = S) when ?CONNECTED(S) ->
|
||||
, evidence => Evd }
|
||||
|| {Nonce, Evd} <- Solutions] }}).
|
||||
|
||||
%% report_solution(Nonce, Solution, W, #st{connected = true}) ->
|
||||
%% #{seq := Seq} = W#worker.cand,
|
||||
%% gmhc_handler:call(#{solution => #{ seq => Seq
|
||||
%% , nonce => Nonce
|
||||
%% , evidence => Solution }}).
|
||||
|
||||
report_no_solution(Nonce, W, #st{} = S) when ?CONNECTED(S) ->
|
||||
report_no_solution(_Nonce, W, #st{} = S) when ?CONNECTED(S) ->
|
||||
#{via := Via, seq := Seq} = W#worker.cand,
|
||||
Nonces = all_nonces(W),
|
||||
%% ?LOG_DEBUG("report no_solution Seq = ~p, Nonce = ~p", [Seq, Nonce]),
|
||||
gmhc_handler:call(#{via => Via,
|
||||
no_solution => #{ seq => Seq
|
||||
, nonce => Nonce}}).
|
||||
[report_no_solution_(Via, Seq, Nonce1) || Nonce1 <- Nonces],
|
||||
ok.
|
||||
|
||||
report_no_solution_(Via, Seq, Nonce) ->
|
||||
gmhc_handler:async_call(#{via => Via,
|
||||
no_solution => #{ seq => Seq
|
||||
, nonce => Nonce}}).
|
||||
|
||||
all_nonces(#worker{nonce = Nonce, config = Config}) ->
|
||||
case gmhw_pow_cuckoo:repeats(Config) of
|
||||
1 -> [Nonce];
|
||||
Rs -> lists:seq(Nonce, Nonce + Rs - 1)
|
||||
end.
|
||||
|
||||
maybe_request_nonces(#st{ candidate = #{via := Via, seq := Seq, nonces := Nonces}
|
||||
, nonces = N} = S) when ?CONNECTED(S) ->
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
%% -*- mode: erlang; erlang-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
-module(gmhc_sup).
|
||||
-vsn("0.4.8").
|
||||
-vsn("0.6.1").
|
||||
|
||||
-behaviour(supervisor).
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
|
||||
-module(gmhc_workers).
|
||||
-vsn("0.4.8").
|
||||
-vsn("0.6.1").
|
||||
|
||||
-export([
|
||||
get_worker_configs/0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
-module(gmhive_client).
|
||||
-vsn("0.4.8").
|
||||
-vsn("0.6.1").
|
||||
|
||||
-export([ connect/1
|
||||
, disconnect/1
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
{type,app}.
|
||||
{modules,[]}.
|
||||
{prefix,"gmhc"}.
|
||||
{desc,"Gajumaru Hive Client"}.
|
||||
{author,"Ulf Wiger, QPQ AG"}.
|
||||
{package_id,{"uwiger","gmhive_client",{0,5,1}}}.
|
||||
{desc,"Gajumaru Hive Client"}.
|
||||
{package_id,{"uwiger","gmhive_client",{0,6,1}}}.
|
||||
{deps,[{"uwiger","gmhive_worker",{0,5,1}},
|
||||
{"uwiger","gmcuckoo",{1,2,4}},
|
||||
{"otpr","eblake2",{1,0,1}},
|
||||
|
||||
Reference in New Issue
Block a user