From b3b8c926c1fd640cd1ac78f9d18a9db40d5c89e9 Mon Sep 17 00:00:00 2001 From: timur <12267899-timur.5@users.noreply.gitlab.com> Date: Wed, 16 Nov 2022 07:32:17 -0400 Subject: [PATCH] SON connection pool. --- .../peerplays_sidechain_plugin.cpp | 2 +- .../sidechain_net_handler_hive.cpp | 56 ++++++++++++++++++- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp index 9e404315..bdb5ae57 100644 --- a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp +++ b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp @@ -857,7 +857,7 @@ void peerplays_sidechain_plugin_impl::on_applied_block(const signed_block &b) { void peerplays_sidechain_plugin_impl::schedule_rpc_client_selection() { fc::time_point now = fc::time_point::now(); - static const int64_t time_to_next_rpc_selection = 5000000; + static const int64_t time_to_next_rpc_selection = 100000;//5000000; fc::time_point next_wakeup = now + fc::microseconds(time_to_next_rpc_selection); _rpc_client_selection_task = fc::schedule([this] { rpc_client_selection(); diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp index 8678298b..7f7026b0 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp @@ -970,10 +970,62 @@ hive_rpc_client *sidechain_net_handler_hive::get_active_rpc_client() void sidechain_net_handler_hive::select_active_rpc_client() { + //ilog("n_active_rpc_client=${n}", ("n", n_active_rpc_client)); if (rpc_clients.size()) { - n_active_rpc_client = (n_active_rpc_client + 1) % rpc_clients.size(); - ilog("n_active_rpc_client=${n}", ("n", n_active_rpc_client)); + int best_n = -1; + int best_quality = -1; + + std::vector head_block_numbers; + head_block_numbers.resize(rpc_clients.size()); + + std::vector qualities; + qualities.resize(rpc_clients.size()); + + for (size_t n=0; n < rpc_clients.size(); n++) { + hive_rpc_client *rpc_client = rpc_clients[n]; + int quality = 0; + head_block_numbers[n] = std::numeric_limits::max(); + + // make the ping + fc::time_point t_sent = fc::time_point::now(); + const std::string reply = rpc_client->database_api_get_dynamic_global_properties(); + fc::time_point t_received = fc::time_point::now(); + if (!reply.empty()) { + std::stringstream ss(reply); + boost::property_tree::ptree json; + boost::property_tree::read_json(ss, json); + if (json.count("result")) { + uint64_t head_block_number = json.get("result.head_block_number"); + int t = (t_received - t_sent).count(); + t += rand() % 10; + FC_ASSERT(t != -1); + head_block_numbers[n] = head_block_number; + FC_ASSERT(head_block_numbers[n] != std::numeric_limits::max()); + static const int t_limit = 10*1000000; // 10 sec + if (t < t_limit) + quality = t_limit - t; // the less time, the higher quality + } + } + + //ilog("Hive RPC qual: ${n} -> ${q}", ("n", n)("q", quality)); + + // look for the best quality + if (quality > best_quality) { + best_n = n; + best_quality = quality; + } + } + + FC_ASSERT(best_n != -1 && best_quality != -1); + if (best_n != n_active_rpc_client) { // if the best client is not the current one, ... + uint64_t active_head_block_number = head_block_numbers[n_active_rpc_client]; + if (active_head_block_number == std::numeric_limits::max() // ... and the current one has no known head block... + || head_block_numbers[best_n] >= active_head_block_number) { // ...or the best client's head is more recent than the current, ... + n_active_rpc_client = best_n; // ...then select new one + ilog("!!! Hive rpc_client reselected, now ${n}", ("n", n_active_rpc_client)); + } + } } }