diff options
10 files changed, 46 insertions, 18 deletions
diff --git a/config/src/vespa/config/subscription/configsubscriptionset.cpp b/config/src/vespa/config/subscription/configsubscriptionset.cpp index 9ad4dfe3f9d..28eb8463ca7 100644 --- a/config/src/vespa/config/subscription/configsubscriptionset.cpp +++ b/config/src/vespa/config/subscription/configsubscriptionset.cpp @@ -17,7 +17,8 @@ using namespace std::chrono; namespace config { ConfigSubscriptionSet::ConfigSubscriptionSet(std::shared_ptr<IConfigContext> context) - : _context(std::move(context)), + : _maxNapTime(vespalib::from_s(10*1.0/vespalib::getVespaTimerHz())), //10x slower than default timer frequency. + _context(std::move(context)), _mgr(_context->getManagerInstance()), _currentGeneration(-1), _subscriptionList(), @@ -30,7 +31,7 @@ ConfigSubscriptionSet::~ConfigSubscriptionSet() } bool -ConfigSubscriptionSet::acquireSnapshot(milliseconds timeoutInMillis, bool ignoreChange) +ConfigSubscriptionSet::acquireSnapshot(vespalib::duration timeout, bool ignoreChange) { if (_state == CLOSED) { return false; @@ -39,7 +40,7 @@ ConfigSubscriptionSet::acquireSnapshot(milliseconds timeoutInMillis, bool ignore } steady_clock::time_point startTime = steady_clock::now(); - milliseconds timeLeft = timeoutInMillis; + vespalib::duration timeLeft = timeout; int64_t lastGeneration = _currentGeneration; bool inSync = false; @@ -53,7 +54,7 @@ ConfigSubscriptionSet::acquireSnapshot(milliseconds timeoutInMillis, bool ignore // Run nextUpdate on all subscribers to get them in sync. for (const auto & subscription : _subscriptionList) { - if (!subscription->nextUpdate(_currentGeneration, timeLeft) && !subscription->hasGenerationChanged()) { + if (!subscription->nextUpdate(_currentGeneration, duration_cast<milliseconds>(timeLeft)) && !subscription->hasGenerationChanged()) { subscription->reset(); continue; } @@ -76,13 +77,13 @@ ConfigSubscriptionSet::acquireSnapshot(milliseconds timeoutInMillis, bool ignore generationsInSync = false; } // Adjust timeout - timeLeft = timeoutInMillis - duration_cast<milliseconds>(steady_clock::now() - startTime); + timeLeft = timeout - (steady_clock::now() - startTime); } inSync = generationsInSync && (_subscriptionList.size() == numGenerationChanged) && (ignoreChange || numChanged > 0); lastGeneration = generation; - timeLeft = timeoutInMillis - duration_cast<milliseconds>(steady_clock::now() - startTime); + timeLeft = timeout - (steady_clock::now() - startTime); if (!inSync && (timeLeft.count() > 0)) { - std::this_thread::sleep_for(std::chrono::milliseconds(std::min(INT64_C(10), timeLeft.count()))); + std::this_thread::sleep_for(std::min(_maxNapTime, timeLeft)); } else { break; } @@ -123,14 +124,14 @@ ConfigSubscriptionSet::isClosed() const } std::shared_ptr<ConfigSubscription> -ConfigSubscriptionSet::subscribe(const ConfigKey & key, milliseconds timeoutInMillis) +ConfigSubscriptionSet::subscribe(const ConfigKey & key, vespalib::duration timeout) { if (_state != OPEN) { throw ConfigRuntimeException("Adding subscription after calling nextConfig() is not allowed"); } LOG(debug, "Subscribing with config Id(%s), defName(%s)", key.getConfigId().c_str(), key.getDefName().c_str()); - std::shared_ptr<ConfigSubscription> s = _mgr.subscribe(key, timeoutInMillis); + std::shared_ptr<ConfigSubscription> s = _mgr.subscribe(key, duration_cast<milliseconds>(timeout)); _subscriptionList.push_back(s); return s; } diff --git a/config/src/vespa/config/subscription/configsubscriptionset.h b/config/src/vespa/config/subscription/configsubscriptionset.h index 89c74a97be2..9cee3894aa9 100644 --- a/config/src/vespa/config/subscription/configsubscriptionset.h +++ b/config/src/vespa/config/subscription/configsubscriptionset.h @@ -3,8 +3,8 @@ #pragma once #include "subscriptionid.h" +#include <vespa/vespalib/util/time.h> #include <atomic> -#include <chrono> #include <memory> #include <vector> @@ -21,7 +21,6 @@ class ConfigKey; class ConfigSubscriptionSet { public: - using milliseconds = std::chrono::milliseconds; /** * Constructs a new ConfigSubscriptionSet object which can be used to subscribe for 1 * or more configs from a specific source. @@ -53,16 +52,17 @@ public: bool isClosed() const; // Helpers for doing the subscription - std::shared_ptr<ConfigSubscription> subscribe(const ConfigKey & key, milliseconds timeoutInMillis); + std::shared_ptr<ConfigSubscription> subscribe(const ConfigKey & key, vespalib::duration timeout); // Tries to acquire a new snapshot of config within the timeout - bool acquireSnapshot(milliseconds timeoutInMillis, bool requireDifference); + bool acquireSnapshot(vespalib::duration timeout, bool requireDifference); private: // Describes the state of the subscriber. enum SubscriberState { OPEN, FROZEN, CONFIGURED, CLOSED }; using SubscriptionList = std::vector<std::shared_ptr<ConfigSubscription>>; + const vespalib::duration _maxNapTime; std::shared_ptr<IConfigContext> _context; // Context to keep alive managers. IConfigManager & _mgr; // The config manager that we use. int64_t _currentGeneration; // Holds the current config generation. diff --git a/searchcore/src/vespa/searchcore/proton/server/proton.cpp b/searchcore/src/vespa/searchcore/proton/server/proton.cpp index 6001e6b88d4..0aa0e1fb2ba 100644 --- a/searchcore/src/vespa/searchcore/proton/server/proton.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/proton.cpp @@ -239,7 +239,7 @@ Proton::Proton(const config::ConfigUri & configUri, _shared_service(), _compile_cache_executor_binding(), _queryLimiter(), - _clock(0.001), + _clock(1.0/vespalib::getVespaTimerHz()), _threadPool(128_Ki), _distributionKey(-1), _isInitializing(true), diff --git a/searchcore/src/vespa/searchcore/proton/server/proton.h b/searchcore/src/vespa/searchcore/proton/server/proton.h index 90a257a0aaa..61e381cfebb 100644 --- a/searchcore/src/vespa/searchcore/proton/server/proton.h +++ b/searchcore/src/vespa/searchcore/proton/server/proton.h @@ -65,7 +65,6 @@ private: using DocumentDBMap = std::map<DocTypeName, DocumentDB::SP>; using InitializeThreads = std::shared_ptr<vespalib::ThreadExecutor>; using BucketSpace = document::BucketSpace; - using InvokeService = vespalib::InvokeService; class ProtonFileHeaderContext : public search::common::FileHeaderContext { diff --git a/searchcore/src/vespa/searchcore/proton/server/shared_threading_service.cpp b/searchcore/src/vespa/searchcore/proton/server/shared_threading_service.cpp index 7e799e506e3..80199c8c50c 100644 --- a/searchcore/src/vespa/searchcore/proton/server/shared_threading_service.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/shared_threading_service.cpp @@ -22,7 +22,8 @@ SharedThreadingService::SharedThreadingService(const SharedThreadingServiceConfi _shared(std::make_shared<vespalib::BlockingThreadStackExecutor>(cfg.shared_threads(), 128_Ki, cfg.shared_task_limit(), proton_shared_executor)), _field_writer(), - _invokeService(cfg.field_writer_config().reactionTime()), + _invokeService(std::max(vespalib::from_s(1.0/vespalib::getVespaTimerHz()), + cfg.field_writer_config().reactionTime())), _invokeRegistrations() { const auto& fw_cfg = cfg.field_writer_config(); diff --git a/storage/src/vespa/storage/distributor/distributor_stripe_pool.cpp b/storage/src/vespa/storage/distributor/distributor_stripe_pool.cpp index eca81b5d52b..d501172731a 100644 --- a/storage/src/vespa/storage/distributor/distributor_stripe_pool.cpp +++ b/storage/src/vespa/storage/distributor/distributor_stripe_pool.cpp @@ -15,7 +15,7 @@ DistributorStripePool::DistributorStripePool(bool test_mode, PrivateCtorTag) _mutex(), _parker_cond(), _parked_threads(0), - _bootstrap_tick_wait_duration(1ms), + _bootstrap_tick_wait_duration(vespalib::from_s(1.0/vespalib::getVespaTimerHz())), _bootstrap_ticks_before_wait(10), _single_threaded_test_mode(test_mode), _stopped(false) diff --git a/storage/src/vespa/storage/distributor/distributor_stripe_thread.cpp b/storage/src/vespa/storage/distributor/distributor_stripe_thread.cpp index 9ff189ee9cb..94e4dc648cc 100644 --- a/storage/src/vespa/storage/distributor/distributor_stripe_thread.cpp +++ b/storage/src/vespa/storage/distributor/distributor_stripe_thread.cpp @@ -11,7 +11,7 @@ DistributorStripeThread::DistributorStripeThread(TickableStripe& stripe, DistributorStripePool& stripe_pool) : _stripe(stripe), _stripe_pool(stripe_pool), - _tick_wait_duration(1ms), + _tick_wait_duration(vespalib::from_s(1.0/vespalib::getVespaTimerHz())), _mutex(), _event_cond(), _park_cond(), diff --git a/vespalib/src/tests/time/time_test.cpp b/vespalib/src/tests/time/time_test.cpp index 0bef18ddc0d..c2858308006 100644 --- a/vespalib/src/tests/time/time_test.cpp +++ b/vespalib/src/tests/time/time_test.cpp @@ -64,4 +64,8 @@ TEST(TimeTest, conversion_of_max) { EXPECT_EQ(9223372036.8547764, vespalib::to_s(vespalib::duration::max())); } +TEST(TimeTest, default_timer_frequency_is_1000_hz) { + EXPECT_EQ(1000u, getVespaTimerHz()); +} + GTEST_MAIN_RUN_ALL_TESTS() diff --git a/vespalib/src/vespa/vespalib/util/time.cpp b/vespalib/src/vespa/vespalib/util/time.cpp index b5c019b4a27..bcc289489ea 100644 --- a/vespalib/src/vespa/vespalib/util/time.cpp +++ b/vespalib/src/vespa/vespalib/util/time.cpp @@ -3,6 +3,9 @@ #include "time.h" #include <thread> +#include <vespa/log/log.h> + +LOG_SETUP(".vespalib.time"); namespace vespalib { system_time @@ -12,6 +15,21 @@ to_utc(steady_time ts) { return system_time(std::chrono::duration_cast<system_time::duration>(nowUtc.time_since_epoch() - nowSteady.time_since_epoch() + ts.time_since_epoch())); } +uint32_t +getVespaTimerHz() { + const char * vespa_timer_hz = getenv("VESPA_TIMER_HZ"); + if (vespa_timer_hz != nullptr) { + try { + size_t idx(0); + uint32_t tmp = std::stoi(vespa_timer_hz, &idx, 0); + return std::max(1u, std::min(1000u, tmp)); + } catch (const std::exception & e) { + LOG(warning, "Parsing environment VESPA_TIMER_HZ='%s' failed with exception: %s", vespa_timer_hz, e.what()); + } + } + return 1000u; +} + namespace { string diff --git a/vespalib/src/vespa/vespalib/util/time.h b/vespalib/src/vespa/vespalib/util/time.h index f19d71afb32..dbbae862a8d 100644 --- a/vespalib/src/vespa/vespalib/util/time.h +++ b/vespalib/src/vespa/vespalib/util/time.h @@ -88,4 +88,9 @@ public: static void waitAtLeast(duration dur, bool busyWait); }; +/** + * The default frequency (1000hz) for vespa timer, with environment override VESPA_TIMER_HZ capped to [1..1000] + */ +uint32_t getVespaTimerHz(); + } |