From: Otto Moerbeek Date: Thu, 3 Jul 2025 11:26:00 +0000 (+0200) Subject: Reorg sources, split nsspeeds_t out into separate .cc and .hh X-Git-Tag: rec-5.4.0-alpha0~41^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9d98416c19811d240ffc94c589b00ef36987d255;p=thirdparty%2Fpdns.git Reorg sources, split nsspeeds_t out into separate .cc and .hh Signed-off-by: Otto Moerbeek --- diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index 1353ffd9b0..472f1307ee 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -174,6 +174,7 @@ pdns_recursor_SOURCES = \ pdns_recursor.cc \ pdnsexception.hh \ pollmplexer.cc \ + protozero-helpers.hh \ protozero-trace.cc protozero-trace.hh \ protozero.cc protozero.hh \ proxy-protocol.cc proxy-protocol.hh \ @@ -187,6 +188,7 @@ pdns_recursor_SOURCES = \ rec-eventtrace.cc rec-eventtrace.hh \ rec-lua-conf.hh rec-lua-conf.cc \ rec-main.hh rec-main.cc \ + rec-nsspeeds.cc rec-nsspeeds.hh \ rec-protozero.cc rec-protozero.hh \ rec-responsestats.hh rec-responsestats.cc \ rec-rust-lib/cxxsupport.cc \ diff --git a/pdns/recursordist/meson.build b/pdns/recursordist/meson.build index 883587ec0b..241d2665b3 100644 --- a/pdns/recursordist/meson.build +++ b/pdns/recursordist/meson.build @@ -144,6 +144,7 @@ common_sources += files( src_dir / 'rec-carbon.cc', src_dir / 'rec-eventtrace.cc', src_dir / 'rec-lua-conf.cc', + src_dir / 'rec-nsspeeds.cc', src_dir / 'rec-protozero.cc', src_dir / 'rec-responsestats.cc', src_dir / 'rec-system-resolve.cc', diff --git a/pdns/recursordist/rec-nsspeeds.cc b/pdns/recursordist/rec-nsspeeds.cc new file mode 100644 index 0000000000..8e02a6e7f1 --- /dev/null +++ b/pdns/recursordist/rec-nsspeeds.cc @@ -0,0 +1,218 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include "protozero-helpers.hh" + +#include "logging.hh" +#include "version.hh" + +#include "rec-nsspeeds.hh" + +enum class PBNSSpeedDump : protozero::pbf_tag_type +{ + required_string_version = 1, + required_string_identity = 2, + required_uint64_protocolVersion = 3, + required_int64_time = 4, + required_string_type = 5, + repeated_message_nsspeedEntry = 6, +}; + +enum class PBNSSpeedEntry : protozero::pbf_tag_type +{ + required_bytes_name = 1, + required_int64_lastgets = 2, + required_int64_lastgetus = 3, + repeated_message_map = 4, +}; + +enum class PBNSSpeedMap : protozero::pbf_tag_type +{ + required_bytes_address = 1, + required_float_val = 2, + required_int32_last = 3, +}; + +template +void nsspeeds_t::getPBEntry(T& message, U& entry) +{ + message.add_bytes(PBNSSpeedEntry::required_bytes_name, entry.d_name.toString()); + message.add_int64(PBNSSpeedEntry::required_int64_lastgets, entry.d_lastget.tv_sec); + message.add_int64(PBNSSpeedEntry::required_int64_lastgetus, entry.d_lastget.tv_usec); + for (const auto& [address, collection] : entry.d_collection) { + protozero::pbf_builder map(message, PBNSSpeedEntry::repeated_message_map); + encodeComboAddress(map, PBNSSpeedMap::required_bytes_address, address); + map.add_float(PBNSSpeedMap::required_float_val, collection.d_val); + map.add_int32(PBNSSpeedMap::required_int32_last, collection.d_last); + } +} + +size_t nsspeeds_t::getPB(const string& serverID, size_t maxSize, std::string& ret) const +{ + auto log = g_slog->withName("syncres")->withValues("maxSize", Logging::Loggable(maxSize)); + log->info(Logr::Info, "Producing nsspeed dump"); + + // A observed average record size is 60; + size_t estimate = maxSize == 0 ? size() * 60 : maxSize + 4096; // We may overshoot (will be rolled back) + + protozero::pbf_builder full(ret); + full.add_string(PBNSSpeedDump::required_string_version, getPDNSVersion()); + full.add_string(PBNSSpeedDump::required_string_identity, serverID); + full.add_uint64(PBNSSpeedDump::required_uint64_protocolVersion, 1); + full.add_int64(PBNSSpeedDump::required_int64_time, time(nullptr)); + full.add_string(PBNSSpeedDump::required_string_type, "PBNSSpeedDump"); + + size_t count = 0; + ret.reserve(estimate); + + for (const auto& entry : *this) { + protozero::pbf_builder message(full, PBNSSpeedDump::repeated_message_nsspeedEntry); + getPBEntry(message, entry); + if (ret.size() > maxSize) { + message.rollback(); + log->info(Logr::Info, "Produced nsspeed dump (max size reached)", "size", Logging::Loggable(ret.size()), "count", Logging::Loggable(count)); + return count; + } + ++count; + } + log->info(Logr::Info, "Produced nsspeed dump", "size", Logging::Loggable(ret.size()), "count", Logging::Loggable(count)); + return count; +} + +template +bool nsspeeds_t::putPBEntry(time_t cutoff, T& message) +{ + DecayingEwmaCollection entry{{}}; + while (message.next()) { + switch (message.tag()) { + case PBNSSpeedEntry::required_bytes_name: + entry.d_name = DNSName(message.get_bytes()); + break; + case PBNSSpeedEntry::required_int64_lastgets: + entry.d_lastget.tv_sec = message.get_int64(); + break; + case PBNSSpeedEntry::required_int64_lastgetus: + entry.d_lastget.tv_usec = message.get_int64(); + break; + case PBNSSpeedEntry::repeated_message_map: { + protozero::pbf_message map = message.get_message(); + ComboAddress address; + float val{}; + int last{}; + while (map.next()) { + switch (map.tag()) { + case PBNSSpeedMap::required_bytes_address: + decodeComboAddress(map, address); + break; + case PBNSSpeedMap::required_float_val: + val = map.get_float(); + break; + case PBNSSpeedMap::required_int32_last: + last = map.get_int32(); + break; + } + } + entry.insert(address, val, last); + break; + } + } + } + if (!entry.stale(cutoff)) { + return insert(std::move(entry)).second; + } + return false; +} + +size_t nsspeeds_t::putPB(time_t cutoff, const std::string& pbuf) +{ + auto log = g_slog->withName("syncres")->withValues("size", Logging::Loggable(pbuf.size())); + log->info(Logr::Debug, "Processing nsspeed dump"); + + protozero::pbf_message full(pbuf); + size_t count = 0; + size_t inserted = 0; + try { + bool protocolVersionSeen = false; + bool typeSeen = false; + while (full.next()) { + switch (full.tag()) { + case PBNSSpeedDump::required_string_version: { + auto version = full.get_string(); + log = log->withValues("version", Logging::Loggable(version)); + break; + } + case PBNSSpeedDump::required_string_identity: { + auto identity = full.get_string(); + log = log->withValues("identity", Logging::Loggable(identity)); + break; + } + case PBNSSpeedDump::required_uint64_protocolVersion: { + auto protocolVersion = full.get_uint64(); + log = log->withValues("protocolVersion", Logging::Loggable(protocolVersion)); + if (protocolVersion != 1) { + throw std::runtime_error("Protocol version mismatch"); + } + protocolVersionSeen = true; + break; + } + case PBNSSpeedDump::required_int64_time: { + auto time = full.get_int64(); + log = log->withValues("time", Logging::Loggable(time)); + break; + } + case PBNSSpeedDump::required_string_type: { + auto type = full.get_string(); + if (type != "PBNSSpeedDump") { + throw std::runtime_error("Data type mismatch"); + } + typeSeen = true; + break; + } + case PBNSSpeedDump::repeated_message_nsspeedEntry: { + if (!protocolVersionSeen || !typeSeen) { + throw std::runtime_error("Required field missing"); + } + protozero::pbf_message message = full.get_message(); + if (putPBEntry(cutoff, message)) { + ++inserted; + } + ++count; + break; + } + } + } + log->info(Logr::Info, "Processed nsspeed dump", "processed", Logging::Loggable(count), "inserted", Logging::Loggable(inserted)); + return inserted; + } + catch (const std::runtime_error& e) { + log->error(Logr::Error, e.what(), "Runtime exception processing cache dump"); + } + catch (const std::exception& e) { + log->error(Logr::Error, e.what(), "Exception processing cache dump"); + } + catch (...) { + log->error(Logr::Error, "Other exception processing cache dump"); + } + return 0; +} diff --git a/pdns/recursordist/rec-nsspeeds.hh b/pdns/recursordist/rec-nsspeeds.hh new file mode 100644 index 0000000000..cc4eca6e8a --- /dev/null +++ b/pdns/recursordist/rec-nsspeeds.hh @@ -0,0 +1,172 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once + +#include +#include +#include +#include +#include + +#include "iputils.hh" + +using namespace ::boost::multi_index; + +/** Class that implements a decaying EWMA. + This class keeps an exponentially weighted moving average which, additionally, decays over time. + The decaying is only done on get. +*/ + +//! This represents a number of decaying Ewmas, used to store performance per nameserver-name. +/** Modelled to work mostly like the underlying DecayingEwma */ +class DecayingEwmaCollection +{ +private: + struct DecayingEwma + { + public: + void submit(int arg, const struct timeval& last, const struct timeval& now) + { + d_last = arg; + auto val = static_cast(arg); + if (d_val == 0) { + d_val = val; + } + else { + auto diff = makeFloat(last - now); + auto factor = expf(diff) / 2.0F; // might be '0.5', or 0.0001 + d_val = (1.0F - factor) * val + factor * d_val; + } + } + + float get(float factor) + { + return d_val *= factor; + } + + [[nodiscard]] float peek() const + { + return d_val; + } + + [[nodiscard]] int last() const + { + return d_last; + } + + float d_val{0}; + int d_last{0}; + }; + +public: + DecayingEwmaCollection(DNSName name, const struct timeval val = {0, 0}) : + d_name(std::move(name)), d_lastget(val) + { + } + + void submit(const ComboAddress& remote, int usecs, const struct timeval& now) const + { + d_collection[remote].submit(usecs, d_lastget, now); + } + + float getFactor(const struct timeval& now) const + { + float diff = makeFloat(d_lastget - now); + return expf(diff / 60.0F); // is 1.0 or less + } + + bool stale(time_t limit) const + { + return limit > d_lastget.tv_sec; + } + + void purge(const std::map& keep) const + { + for (auto iter = d_collection.begin(); iter != d_collection.end();) { + if (keep.find(iter->first) != keep.end()) { + ++iter; + } + else { + iter = d_collection.erase(iter); + } + } + } + + void insert(const ComboAddress& address, float val, int last) + { + d_collection.insert(std::make_pair(address, DecayingEwma{val, last})); + } + + // d_collection is the modifyable part of the record, we index on DNSName and timeval, and DNSName never changes + mutable std::map d_collection; + DNSName d_name; + struct timeval d_lastget; +}; + +class nsspeeds_t : public multi_index_container, member>, + ordered_non_unique, member>>> +{ +public: + const auto& find_or_enter(const DNSName& name, const struct timeval& now) + { + const auto iter = insert(DecayingEwmaCollection{name, now}).first; + return *iter; + } + + const auto& find_or_enter(const DNSName& name) + { + const auto iter = insert(DecayingEwmaCollection{name}).first; + return *iter; + } + + float fastest(const DNSName& name, const struct timeval& now) + { + auto& ind = get(); + auto iter = insert(DecayingEwmaCollection{name, now}).first; + if (iter->d_collection.empty()) { + return 0; + } + // This could happen if find(DNSName) entered an entry; it's used only by test code + if (iter->d_lastget.tv_sec == 0 && iter->d_lastget.tv_usec == 0) { + ind.modify(iter, [&](DecayingEwmaCollection& dec) { dec.d_lastget = now; }); + } + + float ret = std::numeric_limits::max(); + const float factor = iter->getFactor(now); + for (auto& entry : iter->d_collection) { + ret = std::min(ret, entry.second.get(factor)); + } + ind.modify(iter, [&](DecayingEwmaCollection& dec) { dec.d_lastget = now; }); + return ret; + } + + size_t getPB(const string& serverID, size_t maxSize, std::string& ret) const; + size_t putPB(time_t cutoff, const std::string& pbuf); + +private: + template + static void getPBEntry(T& message, U& entry); + template + bool putPBEntry(time_t cutoff, T& message); +}; diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index a2d7350969..a7bc61d23a 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -40,11 +40,7 @@ #include "validate-recursor.hh" #include "rec-taskqueue.hh" #include "shuffle.hh" - -#include "version.hh" -#include -#include -#include "protozero-helpers.hh" +#include "rec-nsspeeds.hh" rec::GlobalCounters g_Counters; thread_local rec::TCounters t_Counters(g_Counters); @@ -121,335 +117,19 @@ private: cont_t d_cont; }; -/** Class that implements a decaying EWMA. - This class keeps an exponentially weighted moving average which, additionally, decays over time. - The decaying is only done on get. -*/ - -//! This represents a number of decaying Ewmas, used to store performance per nameserver-name. -/** Modelled to work mostly like the underlying DecayingEwma */ -class DecayingEwmaCollection -{ -private: - struct DecayingEwma - { - public: - void submit(int arg, const struct timeval& last, const struct timeval& now) - { - d_last = arg; - auto val = static_cast(arg); - if (d_val == 0) { - d_val = val; - } - else { - auto diff = makeFloat(last - now); - auto factor = expf(diff) / 2.0F; // might be '0.5', or 0.0001 - d_val = (1.0F - factor) * val + factor * d_val; - } - } - - float get(float factor) - { - return d_val *= factor; - } - - [[nodiscard]] float peek() const - { - return d_val; - } - - [[nodiscard]] int last() const - { - return d_last; - } - - float d_val{0}; - int d_last{0}; - }; - -public: - DecayingEwmaCollection(DNSName name, const struct timeval val = {0, 0}) : - d_name(std::move(name)), d_lastget(val) - { - } - - void submit(const ComboAddress& remote, int usecs, const struct timeval& now) const - { - d_collection[remote].submit(usecs, d_lastget, now); - } - - float getFactor(const struct timeval& now) const - { - float diff = makeFloat(d_lastget - now); - return expf(diff / 60.0F); // is 1.0 or less - } - - bool stale(time_t limit) const - { - return limit > d_lastget.tv_sec; - } - - void purge(const std::map& keep) const - { - for (auto iter = d_collection.begin(); iter != d_collection.end();) { - if (keep.find(iter->first) != keep.end()) { - ++iter; - } - else { - iter = d_collection.erase(iter); - } - } - } - - void insert(const ComboAddress& address, float val, int last) - { - d_collection.insert(std::make_pair(address, DecayingEwma{val, last})); - } - - // d_collection is the modifyable part of the record, we index on DNSName and timeval, and DNSName never changes - mutable std::map d_collection; - DNSName d_name; - struct timeval d_lastget; -}; - -class nsspeeds_t : public multi_index_container, member>, - ordered_non_unique, member>>> -{ -public: - const auto& find_or_enter(const DNSName& name, const struct timeval& now) - { - const auto iter = insert(DecayingEwmaCollection{name, now}).first; - return *iter; - } - - const auto& find_or_enter(const DNSName& name) - { - const auto iter = insert(DecayingEwmaCollection{name}).first; - return *iter; - } - - float fastest(const DNSName& name, const struct timeval& now) - { - auto& ind = get(); - auto iter = insert(DecayingEwmaCollection{name, now}).first; - if (iter->d_collection.empty()) { - return 0; - } - // This could happen if find(DNSName) entered an entry; it's used only by test code - if (iter->d_lastget.tv_sec == 0 && iter->d_lastget.tv_usec == 0) { - ind.modify(iter, [&](DecayingEwmaCollection& dec) { dec.d_lastget = now; }); - } - - float ret = std::numeric_limits::max(); - const float factor = iter->getFactor(now); - for (auto& entry : iter->d_collection) { - ret = std::min(ret, entry.second.get(factor)); - } - ind.modify(iter, [&](DecayingEwmaCollection& dec) { dec.d_lastget = now; }); - return ret; - } - - enum class PBNSSpeedDump : protozero::pbf_tag_type - { - required_string_version = 1, - required_string_identity = 2, - required_uint64_protocolVersion = 3, - required_int64_time = 4, - required_string_type = 5, - repeated_message_nsspeedEntry = 6, - }; - - enum class PBNSSpeedEntry : protozero::pbf_tag_type - { - required_bytes_name = 1, - required_int64_lastgets = 2, - required_int64_lastgetus = 3, - repeated_message_map = 4, - }; - - enum class PBNSSpeedMap : protozero::pbf_tag_type - { - required_bytes_address = 1, - required_float_val = 2, - required_int32_last = 3, - }; - - template - void getEntry(T& message, U entry) const - { - message.add_bytes(PBNSSpeedEntry::required_bytes_name, entry->d_name.toString()); - message.add_int64(PBNSSpeedEntry::required_int64_lastgets, entry->d_lastget.tv_sec); - message.add_int64(PBNSSpeedEntry::required_int64_lastgetus, entry->d_lastget.tv_usec); - for (const auto& [address, collection] : entry->d_collection) { - protozero::pbf_builder map(message, PBNSSpeedEntry::repeated_message_map); - encodeComboAddress(map, PBNSSpeedMap::required_bytes_address, address); - map.add_float(PBNSSpeedMap::required_float_val, collection.d_val); - map.add_int32(PBNSSpeedMap::required_int32_last, collection.d_last); - } - } - - size_t getPB(size_t maxSize, std::string& ret) const - { - auto log = g_slog->withName("syncres")->withValues("maxSize", Logging::Loggable(maxSize)); - log->info(Logr::Info, "Producing nsspeed dump"); - - // A observed average record size is 60; - size_t estimate = maxSize == 0 ? size() * 60 : maxSize + 4096; // We may overshoot (will be rolled back) - - protozero::pbf_builder full(ret); - full.add_string(PBNSSpeedDump::required_string_version, getPDNSVersion()); - full.add_string(PBNSSpeedDump::required_string_identity, SyncRes::s_serverID); - full.add_uint64(PBNSSpeedDump::required_uint64_protocolVersion, 1); - full.add_int64(PBNSSpeedDump::required_int64_time, time(nullptr)); - full.add_string(PBNSSpeedDump::required_string_type, "PBNSSpeedDump"); - - size_t count = 0; - ret.reserve(estimate); - - for (const auto& entry : *this) { - protozero::pbf_builder message(full, PBNSSpeedDump::repeated_message_nsspeedEntry); - getEntry(message, &entry); - if (ret.size() > maxSize) { - message.rollback(); - log->info(Logr::Info, "Produced nsspeed dump (max size reached)", "size", Logging::Loggable(ret.size()), "count", Logging::Loggable(count)); - return count; - } - ++count; - } - log->info(Logr::Info, "Produced nsspeed dump", "size", Logging::Loggable(ret.size()), "count", Logging::Loggable(count)); - return count; - } - - - template - bool putEntry(T& message) - { - DecayingEwmaCollection entry{{}}; - while (message.next()) { - switch (message.tag()) { - case PBNSSpeedEntry::required_bytes_name: - entry.d_name = DNSName(message.get_bytes()); - break; - case PBNSSpeedEntry::required_int64_lastgets: - entry.d_lastget.tv_sec = message.get_int64(); - break; - case PBNSSpeedEntry::required_int64_lastgetus: - entry.d_lastget.tv_usec = message.get_int64(); - break; - case PBNSSpeedEntry::repeated_message_map: { - protozero::pbf_message map = message.get_message(); - ComboAddress address; - float val{}; - int last{}; - while (map.next()) { - switch (map.tag()) { - case PBNSSpeedMap::required_bytes_address: - decodeComboAddress(map, address); - break; - case PBNSSpeedMap::required_float_val: - val = map.get_float(); - break; - case PBNSSpeedMap::required_int32_last: - last = map.get_int32(); - break; - } - } - entry.insert(address, val, last); - break; - } - } - } - return insert(std::move(entry)).second; - } - - size_t putPB(const std::string& pbuf) - { - auto log = g_slog->withName("syncres")->withValues("size", Logging::Loggable(pbuf.size())); - log->info(Logr::Debug, "Processing nsspeed dump"); - - protozero::pbf_message full(pbuf); - size_t count = 0; - size_t inserted = 0; - try { - bool protocolVersionSeen = false; - bool typeSeen = false; - while (full.next()) { - switch (full.tag()) { - case PBNSSpeedDump::required_string_version: { - auto version = full.get_string(); - log = log->withValues("version", Logging::Loggable(version)); - break; - } - case PBNSSpeedDump::required_string_identity: { - auto identity = full.get_string(); - log = log->withValues("identity", Logging::Loggable(identity)); - break; - } - case PBNSSpeedDump::required_uint64_protocolVersion: { - auto protocolVersion = full.get_uint64(); - log = log->withValues("protocolVersion", Logging::Loggable(protocolVersion)); - if (protocolVersion != 1) { - throw std::runtime_error("Protocol version mismatch"); - } - protocolVersionSeen = true; - break; - } - case PBNSSpeedDump::required_int64_time: { - auto time = full.get_int64(); - log = log->withValues("time", Logging::Loggable(time)); - break; - } - case PBNSSpeedDump::required_string_type: { - auto type = full.get_string(); - if (type != "PBNSSpeedDump") { - throw std::runtime_error("Data type mismatch"); - } - typeSeen = true; - break; - } - case PBNSSpeedDump::repeated_message_nsspeedEntry: { - if (!protocolVersionSeen || !typeSeen) { - throw std::runtime_error("Required field missing"); - } - protozero::pbf_message message = full.get_message(); - if (putEntry(message)) { - ++inserted; - } - ++count; - break; - } - } - } - log->info(Logr::Info, "Processed nsspeed dump", "processed", Logging::Loggable(count), "inserted", Logging::Loggable(inserted)); - return inserted; - } - catch (const std::runtime_error& e) { - log->error(Logr::Error, e.what(), "Runtime exception processing cache dump"); - } - catch (const std::exception& e) { - log->error(Logr::Error, e.what(), "Exception processing cache dump"); - } - catch (...) { - log->error(Logr::Error, "Other exception processing cache dump"); - } - return 0; - } -}; static LockGuarded s_nsSpeeds; size_t SyncRes::getNSSpeedTable(size_t maxSize, std::string& ret) { const auto copy = *s_nsSpeeds.lock(); - return copy.getPB(maxSize, ret); + return copy.getPB(s_serverID, maxSize, ret); } size_t SyncRes::putIntoNSSpeedTable(const std::string& ret) { auto lock = s_nsSpeeds.lock(); - return lock->putPB(ret); + return lock->putPB(time(nullptr) - 300, ret); } class Throttle