From bfb80b4320933280dfc1e008852d21b7b4743859 Mon Sep 17 00:00:00 2001 From: Alexander Suprunenko Date: Sun, 10 Feb 2019 03:23:16 +0200 Subject: [PATCH 1/2] Random part added for supernode announce period. --- data/config.ini | 1 + include/lib/graft/handler_api.h | 5 +++-- include/lib/graft/task.h | 19 +++++++++++++------ include/supernode/supernode.h | 1 + src/lib/graft/task.cpp | 27 +++++++++++++++++---------- src/supernode/supernode.cpp | 4 +++- test/sys_info.cpp | 5 +++-- 7 files changed, 41 insertions(+), 21 deletions(-) diff --git a/data/config.ini b/data/config.ini index 948d4978..99ff30ca 100644 --- a/data/config.ini +++ b/data/config.ini @@ -30,6 +30,7 @@ data-dir= stake-wallet-name=stake-wallet testnet=true stake-wallet-refresh-interval-ms=50000 +stake-wallet-refresh-interval-random-factor=0 [ipfilter] ;; path to ipfilter rules file diff --git a/include/lib/graft/handler_api.h b/include/lib/graft/handler_api.h index 6c9b0092..18cee9fe 100644 --- a/include/lib/graft/handler_api.h +++ b/include/lib/graft/handler_api.h @@ -13,8 +13,9 @@ class HandlerAPI public: virtual void sendUpstreamBlocking(Output& output, Input& input, std::string& err) = 0; virtual bool addPeriodicTask(const Router::Handler& h_worker, - std::chrono::milliseconds interval_ms, - std::chrono::milliseconds initial_interval_ms = std::chrono::milliseconds::max()) = 0; + std::chrono::milliseconds interval_ms, + std::chrono::milliseconds initial_interval_ms = std::chrono::milliseconds::max(), + double random_factor = 0) = 0; virtual request::system_info::Counter& runtimeSysInfo() = 0; virtual const ConfigOpts& configOpts() const = 0; }; diff --git a/include/lib/graft/task.h b/include/lib/graft/task.h index 6fc8f1ad..65f438bb 100644 --- a/include/lib/graft/task.h +++ b/include/lib/graft/task.h @@ -153,19 +153,23 @@ class PeriodicTask : public BaseTask PeriodicTask( TaskManager& manager, const Router::Handler3& h3, std::chrono::milliseconds timeout_ms, - std::chrono::milliseconds initial_timeout_ms + std::chrono::milliseconds initial_timeout_ms, + double random_factor = 0 ) : BaseTask(manager, Router::JobParams({Input(), Router::vars_t(), h3})) , m_timeout_ms(timeout_ms), m_initial_timeout_ms(initial_timeout_ms) + , m_random_factor(random_factor) { } - PeriodicTask(TaskManager& manager, const Router::Handler3& h3, std::chrono::milliseconds timeout_ms) - : PeriodicTask(manager, h3, timeout_ms, timeout_ms) + PeriodicTask(TaskManager& manager, const Router::Handler3& h3, + std::chrono::milliseconds timeout_ms, double random_factor = 0) + : PeriodicTask(manager, h3, timeout_ms, timeout_ms, random_factor) { } std::chrono::milliseconds m_timeout_ms; std::chrono::milliseconds m_initial_timeout_ms; + double m_random_factor; bool m_initial_run {true}; public: @@ -199,7 +203,9 @@ class TaskManager : private HandlerAPI void sendUpstream(BaseTaskPtr bt); void addPeriodicTask(const Router::Handler3& h3, - std::chrono::milliseconds interval_ms, std::chrono::milliseconds initial_interval_ms = std::chrono::milliseconds::max()); + std::chrono::milliseconds interval_ms, + std::chrono::milliseconds initial_interval_ms = std::chrono::milliseconds::max(), + double random_factor = 0); ////getters virtual mg_mgr* getMgMgr() = 0; @@ -220,7 +226,8 @@ class TaskManager : private HandlerAPI virtual void sendUpstreamBlocking(Output& output, Input& input, std::string& err) override; virtual bool addPeriodicTask(const Router::Handler& h_worker, std::chrono::milliseconds interval_ms, - std::chrono::milliseconds initial_interval_ms = std::chrono::milliseconds::max()) override; + std::chrono::milliseconds initial_interval_ms = std::chrono::milliseconds::max(), + double random_factor = 0 ) override; virtual request::system_info::Counter& runtimeSysInfo() override; virtual const ConfigOpts& configOpts() const override; @@ -282,7 +289,7 @@ class TaskManager : private HandlerAPI using PromiseItem = UpstreamTask::PromiseItem; using PromiseQueue = tp::MPMCBoundedQueue; - using PeridicTaskItem = std::tuple; + using PeridicTaskItem = std::tuple; using PeriodicTaskQueue = tp::MPMCBoundedQueue; std::unique_ptr m_promiseQueue; diff --git a/include/supernode/supernode.h b/include/supernode/supernode.h index a6c9ec1c..751ae47e 100644 --- a/include/supernode/supernode.h +++ b/include/supernode/supernode.h @@ -13,6 +13,7 @@ class Supernode : public GraftServer std::string data_dir; std::string stake_wallet_name; size_t stake_wallet_refresh_interval_ms; + double stake_wallet_refresh_interval_random_factor; // runtime parameters. // path to watch-only wallets (supernodes) std::string watchonly_wallets_path; diff --git a/src/lib/graft/task.cpp b/src/lib/graft/task.cpp index 5fe8a0ab..30eef7f7 100644 --- a/src/lib/graft/task.cpp +++ b/src/lib/graft/task.cpp @@ -419,17 +419,18 @@ inline size_t TaskManager::next_pow2(size_t val) } bool TaskManager::addPeriodicTask(const Router::Handler& h_worker, - std::chrono::milliseconds interval_ms, - std::chrono::milliseconds initial_interval_ms) + std::chrono::milliseconds interval_ms, + std::chrono::milliseconds initial_interval_ms, + double random_factor) { if(io_thread) {//it is called from pre_action or post_action, and we can call requestAddPeriodicTask directly - addPeriodicTask({nullptr, h_worker, nullptr}, interval_ms, initial_interval_ms); + addPeriodicTask({nullptr, h_worker, nullptr}, interval_ms, initial_interval_ms, random_factor); return true; } else { - PeridicTaskItem item = std::make_tuple(Router::Handler3(nullptr, h_worker, nullptr), interval_ms, initial_interval_ms); + PeridicTaskItem item = std::make_tuple(Router::Handler3(nullptr, h_worker, nullptr), interval_ms, initial_interval_ms, random_factor); bool ok = m_periodicTaskQueue->push( std::move(item) ); if(!ok) return false; notifyJobReady(); @@ -457,7 +458,8 @@ void TaskManager::checkPeriodicTaskIO() Router::Handler3& h3 = std::get<0>(pti); std::chrono::milliseconds& interval_ms = std::get<1>(pti); std::chrono::milliseconds& initial_interval_ms = std::get<2>(pti); - addPeriodicTask(h3, interval_ms, initial_interval_ms); + double& random_factor = std::get<3>(pti); + addPeriodicTask(h3, interval_ms, initial_interval_ms, random_factor); } } @@ -813,11 +815,11 @@ void TaskManager::processOk(BaseTaskPtr bt) } void TaskManager::addPeriodicTask( - const Router::Handler3& h3, std::chrono::milliseconds interval_ms, std::chrono::milliseconds initial_interval_ms) + const Router::Handler3& h3, std::chrono::milliseconds interval_ms, std::chrono::milliseconds initial_interval_ms, double random_factor) { if(initial_interval_ms == std::chrono::milliseconds::max()) initial_interval_ms = interval_ms; - BaseTask* bt = BaseTask::Create(*this, h3, interval_ms, initial_interval_ms).get(); + BaseTask* bt = BaseTask::Create(*this, h3, interval_ms, initial_interval_ms, random_factor).get(); PeriodicTask* pt = dynamic_cast(bt); assert(pt); schedule(pt); @@ -973,9 +975,14 @@ void PeriodicTask::finalize() std::chrono::milliseconds PeriodicTask::getTimeout() { - auto ret = (m_initial_run) ? m_initial_timeout_ms : m_timeout_ms; - m_initial_run = false; - return ret; + if(m_initial_run) + { + m_initial_run = false; + return m_initial_timeout_ms; + } + if(m_random_factor < 0.0001) return m_timeout_ms; + + return std::chrono::milliseconds( int(m_timeout_ms.count() * (1.0 + std::rand()*m_random_factor/RAND_MAX) )); } ClientTask::ClientTask(ConnectionManager* connectionManager, mg_connection *client, Router::JobParams& prms) diff --git a/src/supernode/supernode.cpp b/src/supernode/supernode.cpp index cb8b60d1..f7d5611e 100644 --- a/src/supernode/supernode.cpp +++ b/src/supernode/supernode.cpp @@ -51,6 +51,7 @@ bool Supernode::initConfigOption(int argc, const char** argv, ConfigOpts& config m_configEx.stake_wallet_refresh_interval_ms = server_conf.get("stake-wallet-refresh-interval-ms", consts::DEFAULT_STAKE_WALLET_REFRESH_INTERFAL_MS); m_configEx.testnet = server_conf.get("testnet", false); + m_configEx.stake_wallet_refresh_interval_random_factor = server_conf.get("stake-wallet-refresh-interval-random-factor", 0); return res; } @@ -141,7 +142,8 @@ void Supernode::startSupernodePeriodicTasks() getLooper().addPeriodicTask( graft::Router::Handler3(nullptr, graft::supernode::request::sendAnnounce, nullptr), std::chrono::milliseconds(m_configEx.stake_wallet_refresh_interval_ms), - std::chrono::milliseconds(initial_interval_ms) + std::chrono::milliseconds(initial_interval_ms), + m_configEx.stake_wallet_refresh_interval_random_factor ); } } diff --git a/test/sys_info.cpp b/test/sys_info.cpp index 3b18a41d..845a10bf 100644 --- a/test/sys_info.cpp +++ b/test/sys_info.cpp @@ -151,8 +151,9 @@ class HandlerAPIImpl : public graft::HandlerAPI public: virtual void sendUpstreamBlocking(Output& output, Input& input, std::string& err) override { } virtual bool addPeriodicTask(const Router::Handler& h_worker, - std::chrono::milliseconds interval_ms, - std::chrono::milliseconds initial_interval_ms = std::chrono::milliseconds::max()) override { } + std::chrono::milliseconds interval_ms, + std::chrono::milliseconds initial_interval_ms = std::chrono::milliseconds::max(), + double random_factor = 0) override { } virtual graft::request::system_info::Counter& runtimeSysInfo() override { return m_sic; From 5d39440aa3f05609b78fdfefcc98d29016f3df7f Mon Sep 17 00:00:00 2001 From: Alexander Suprunenko Date: Mon, 11 Feb 2019 15:00:34 +0200 Subject: [PATCH 2/2] Random number generation improved. --- include/lib/graft/common/utils.h | 3 +-- src/lib/graft/task.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/lib/graft/common/utils.h b/include/lib/graft/common/utils.h index 5c1e3f25..6fe439cc 100644 --- a/include/lib/graft/common/utils.h +++ b/include/lib/graft/common/utils.h @@ -12,8 +12,7 @@ std::string base64_encode(const std::string &data); template T random_number(T startRange, T endRange) { - std::random_device rd; - std::mt19937 mt(rd()); + static std::mt19937 mt(std::random_device{}()); std::uniform_int_distribution dist(startRange, endRange); return dist(mt); } diff --git a/src/lib/graft/task.cpp b/src/lib/graft/task.cpp index 30eef7f7..6f61f707 100644 --- a/src/lib/graft/task.cpp +++ b/src/lib/graft/task.cpp @@ -6,6 +6,7 @@ #include "lib/graft/handler_api.h" #include "lib/graft/expiring_list.h" #include "lib/graft/sys_info.h" +#include "lib/graft/common/utils.h" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "supernode.task" @@ -981,8 +982,9 @@ std::chrono::milliseconds PeriodicTask::getTimeout() return m_initial_timeout_ms; } if(m_random_factor < 0.0001) return m_timeout_ms; - - return std::chrono::milliseconds( int(m_timeout_ms.count() * (1.0 + std::rand()*m_random_factor/RAND_MAX) )); + using i_type = decltype(m_timeout_ms.count()); + i_type v = graft::utils::random_number(m_timeout_ms.count(), (i_type)(m_timeout_ms.count()*(1.0 + m_random_factor))); + return std::chrono::milliseconds(v); } ClientTask::ClientTask(ConnectionManager* connectionManager, mg_connection *client, Router::JobParams& prms)