From 709a2c7b7c27ebda7f606dc4314cf92ec1ef69f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Blin?= Date: Tue, 29 May 2018 15:21:17 -0400 Subject: [PATCH] dht_proxy_server: avoid mutex when getting / The dht_proxy_server should be always up, so getNodesStats will be pretty always up-to-date. We can add it into a job and avoid to wait for this method to finish (and this method use an internal lock) to have a quick answer about the status of the proxy. Note: the update is forced during the initialization of the proxy --- include/opendht/dht_proxy_server.h | 10 +++++++--- src/dht_proxy_server.cpp | 27 +++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/include/opendht/dht_proxy_server.h b/include/opendht/dht_proxy_server.h index b5216ad4..ecf8fbb4 100644 --- a/include/opendht/dht_proxy_server.h +++ b/include/opendht/dht_proxy_server.h @@ -21,12 +21,13 @@ #pragma once +#include "callbacks.h" #include "def.h" -#include "sockaddr.h" #include "infohash.h" -#include "scheduler.h" -#include "value.h" #include "proxy.h" +#include "scheduler.h" +#include "sockaddr.h" +#include "value.h" #include #include @@ -237,6 +238,9 @@ private: std::thread schedulerThread_; Sp printStatsJob_; + mutable std::mutex statsMutex_; + mutable NodeStats ipv4Stats_ {}; + mutable NodeStats ipv6Stats_ {}; // Handle client quit for listen. // NOTE: can be simplified when we will supports restbed 5.0 diff --git a/src/dht_proxy_server.cpp b/src/dht_proxy_server.cpp index d92c03b6..86eb6ab7 100644 --- a/src/dht_proxy_server.cpp +++ b/src/dht_proxy_server.cpp @@ -30,6 +30,8 @@ #include #include +#include + using namespace std::placeholders; namespace dht { @@ -128,6 +130,16 @@ DhtProxyServer::DhtProxyServer(std::shared_ptr dht, in_port_t port , std::cout << getStats().toString() << std::endl; scheduler_.edit(printStatsJob_, scheduler_.time() + PRINT_STATS_PERIOD); } + if (not stopListeners) { + // Refresh stats cache + auto newIpv4Stats = dht_->getNodesStats(AF_INET); + auto newIpv6Stats = dht_->getNodesStats(AF_INET6); + { + std::lock_guard lck(statsMutex_); + ipv4Stats_ = std::move(newIpv4Stats); + ipv6Stats_ = std::move(newIpv6Stats); + } + } }); while (service_->is_up() and not stopListeners) { std::unique_lock lock(schedulerLock_); @@ -205,8 +217,19 @@ DhtProxyServer::getNodeInfo(const std::shared_ptr& session) co if (id) result["id"] = id.toString(); result["node_id"] = dht_->getNodeId().toString(); - result["ipv4"] = dht_->getNodesStats(AF_INET).toJson(); - result["ipv6"] = dht_->getNodesStats(AF_INET6).toJson(); + { + std::lock_guard lck(statsMutex_); + if (ipv4Stats_.good_nodes == 0 && ipv6Stats_.good_nodes == 0) { + // NOTE: we want to avoid the disconnected state as much as possible + // So, if the node is disconnected, we should force the update of the cache + // and reconnect as soon as possible + // This should not happen much + ipv4Stats_ = dht_->getNodesStats(AF_INET); + ipv6Stats_ = dht_->getNodesStats(AF_INET); + } + result["ipv4"] = ipv4Stats_.toJson(); + result["ipv6"] = ipv6Stats_.toJson(); + } result["public_ip"] = s->get_origin(); // [ipv6:ipv4]:port or ipv4:port Json::StreamWriterBuilder wbuilder; wbuilder["commentStyle"] = "None";