diff options
author | snaury <snaury@ydb.tech> | 2023-05-16 13:43:28 +0300 |
---|---|---|
committer | snaury <snaury@ydb.tech> | 2023-05-16 13:43:28 +0300 |
commit | c9df7fc86be0b15adc1e812144c41ab5c057baef (patch) | |
tree | 63c809b43d9e026188f6a66725ccac433ba0f734 | |
parent | a2e846788b0a6d372d15ab5de915616cc6bc00ce (diff) | |
download | ydb-c9df7fc86be0b15adc1e812144c41ab5c057baef.tar.gz |
Support monotonic boot time with suspend awareness
-rw-r--r-- | library/cpp/actors/core/monotonic.cpp | 8 | ||||
-rw-r--r-- | library/cpp/actors/core/monotonic.h | 5 | ||||
-rw-r--r-- | library/cpp/actors/core/monotonic_provider.cpp | 8 | ||||
-rw-r--r-- | library/cpp/actors/core/monotonic_provider.h | 6 | ||||
-rw-r--r-- | library/cpp/actors/testlib/test_runtime.cpp | 26 | ||||
-rw-r--r-- | library/cpp/actors/testlib/test_runtime.h | 4 | ||||
-rw-r--r-- | library/cpp/time_provider/monotonic.cpp | 75 | ||||
-rw-r--r-- | library/cpp/time_provider/monotonic.h | 265 | ||||
-rw-r--r-- | library/cpp/time_provider/monotonic_provider.cpp | 53 | ||||
-rw-r--r-- | library/cpp/time_provider/monotonic_provider.h | 34 | ||||
-rw-r--r-- | library/cpp/time_provider/time_provider.cpp | 2 | ||||
-rw-r--r-- | ydb/core/base/appdata.cpp | 1 | ||||
-rw-r--r-- | ydb/core/base/appdata.h | 1 | ||||
-rw-r--r-- | ydb/core/testlib/actors/test_runtime.cpp | 1 | ||||
-rw-r--r-- | ydb/core/util/testactorsys.cpp | 8 | ||||
-rw-r--r-- | ydb/core/util/testactorsys.h | 2 |
16 files changed, 345 insertions, 154 deletions
diff --git a/library/cpp/actors/core/monotonic.cpp b/library/cpp/actors/core/monotonic.cpp index 4d2c28ef0c..581d80d849 100644 --- a/library/cpp/actors/core/monotonic.cpp +++ b/library/cpp/actors/core/monotonic.cpp @@ -1,9 +1 @@ #include "monotonic.h" - -namespace NActors { - -ui64 GetMonotonicMicroSeconds() { - return NMonotonic::GetMonotonicMicroSeconds(); -} - -} // namespace NActors diff --git a/library/cpp/actors/core/monotonic.h b/library/cpp/actors/core/monotonic.h index 46fd13f335..06759ee5ec 100644 --- a/library/cpp/actors/core/monotonic.h +++ b/library/cpp/actors/core/monotonic.h @@ -5,7 +5,10 @@ namespace NActors { -ui64 GetMonotonicMicroSeconds(); +using NMonotonic::GetMonotonicMicroSeconds; +using NMonotonic::GetBootTimeMicroSeconds; using TMonotonic = NMonotonic::TMonotonic; +using TBootTime = NMonotonic::TBootTime; + } // namespace NActors diff --git a/library/cpp/actors/core/monotonic_provider.cpp b/library/cpp/actors/core/monotonic_provider.cpp index 9e5bb1aadf..f8d91a4eec 100644 --- a/library/cpp/actors/core/monotonic_provider.cpp +++ b/library/cpp/actors/core/monotonic_provider.cpp @@ -1,9 +1 @@ #include "monotonic_provider.h" - -namespace NActors { - -TIntrusivePtr<NActors::IMonotonicTimeProvider> CreateDefaultMonotonicTimeProvider() { - return NMonotonic::CreateDefaultMonotonicTimeProvider(); -} - -} // namespace NActors diff --git a/library/cpp/actors/core/monotonic_provider.h b/library/cpp/actors/core/monotonic_provider.h index 1f6c44aeb9..ad77c171b9 100644 --- a/library/cpp/actors/core/monotonic_provider.h +++ b/library/cpp/actors/core/monotonic_provider.h @@ -4,8 +4,10 @@ namespace NActors { -using IMonotonicTimeProvider = ::IMonotonicTimeProvider; +using IMonotonicTimeProvider = NMonotonic::IMonotonicTimeProvider; +using IBootTimeProvider = NMonotonic::IBootTimeProvider; -TIntrusivePtr<IMonotonicTimeProvider> CreateDefaultMonotonicTimeProvider(); +using NMonotonic::CreateDefaultMonotonicTimeProvider; +using NMonotonic::CreateDefaultBootTimeProvider; } // namespace NActors diff --git a/library/cpp/actors/testlib/test_runtime.cpp b/library/cpp/actors/testlib/test_runtime.cpp index 6fedca1cd2..2ec0b27ddc 100644 --- a/library/cpp/actors/testlib/test_runtime.cpp +++ b/library/cpp/actors/testlib/test_runtime.cpp @@ -246,6 +246,20 @@ namespace NActors { TTestActorRuntimeBase& Runtime; }; + class TTestActorRuntimeBase::TBootTimeProvider : public IBootTimeProvider { + public: + TBootTimeProvider(TTestActorRuntimeBase& runtime) + : Runtime(runtime) + { } + + TBootTime Now() override { + return Runtime.GetCurrentBootTime(); + } + + private: + TTestActorRuntimeBase& Runtime; + }; + class TTestActorRuntimeBase::TSchedulerThreadStub : public ISchedulerThread { public: TSchedulerThreadStub(TTestActorRuntimeBase* runtime, TTestActorRuntimeBase::TNodeDataBase* node) @@ -496,6 +510,7 @@ namespace NActors { , RandomProvider(CreateDeterministicRandomProvider(DefaultRandomSeed)) , TimeProvider(new TTimeProvider(*this)) , MonotonicTimeProvider(new TMonotonicTimeProvider(*this)) + , BootTimeProvider(new TBootTimeProvider(*this)) , ShouldContinue() , CurrentTimestamp(0) , DispatchTimeout(DEFAULT_DISPATCH_TIMEOUT) @@ -829,6 +844,12 @@ namespace NActors { return TMonotonic::MicroSeconds(CurrentTimestamp); } + TBootTime TTestActorRuntimeBase::GetCurrentBootTime() const { + TGuard<TMutex> guard(Mutex); + Y_VERIFY(!UseRealThreads); + return TBootTime::MicroSeconds(CurrentTimestamp); + } + void TTestActorRuntimeBase::UpdateCurrentTime(TInstant newTime) { static int counter = 0; ++counter; @@ -860,6 +881,11 @@ namespace NActors { return MonotonicTimeProvider; } + TIntrusivePtr<IBootTimeProvider> TTestActorRuntimeBase::GetBootTimeProvider() { + Y_VERIFY(!UseRealThreads); + return BootTimeProvider; + } + ui32 TTestActorRuntimeBase::GetNodeId(ui32 index) const { Y_VERIFY(index < NodeCount); return FirstNodeId + index; diff --git a/library/cpp/actors/testlib/test_runtime.h b/library/cpp/actors/testlib/test_runtime.h index 0c1e4207cc..a5d6b3b6e9 100644 --- a/library/cpp/actors/testlib/test_runtime.h +++ b/library/cpp/actors/testlib/test_runtime.h @@ -190,6 +190,7 @@ namespace NActors { class TExecutorPoolStub; class TTimeProvider; class TMonotonicTimeProvider; + class TBootTimeProvider; enum class EEventAction { PROCESS, @@ -232,8 +233,10 @@ namespace NActors { void SetLogPriority(NActors::NLog::EComponent component, NActors::NLog::EPriority priority); TIntrusivePtr<ITimeProvider> GetTimeProvider(); TIntrusivePtr<IMonotonicTimeProvider> GetMonotonicTimeProvider(); + TIntrusivePtr<IBootTimeProvider> GetBootTimeProvider(); TInstant GetCurrentTime() const; TMonotonic GetCurrentMonotonicTime() const; + TBootTime GetCurrentBootTime() const; void UpdateCurrentTime(TInstant newTime); void AdvanceCurrentTime(TDuration duration); void AddLocalService(const TActorId& actorId, const TActorSetupCmd& cmd, ui32 nodeIndex = 0); @@ -549,6 +552,7 @@ namespace NActors { TIntrusivePtr<IRandomProvider> RandomProvider; TIntrusivePtr<ITimeProvider> TimeProvider; TIntrusivePtr<IMonotonicTimeProvider> MonotonicTimeProvider; + TIntrusivePtr<IBootTimeProvider> BootTimeProvider; protected: struct TNodeDataBase: public TThrRefBase { diff --git a/library/cpp/time_provider/monotonic.cpp b/library/cpp/time_provider/monotonic.cpp index 99126080e2..ee0f29e498 100644 --- a/library/cpp/time_provider/monotonic.cpp +++ b/library/cpp/time_provider/monotonic.cpp @@ -1,31 +1,76 @@ #include "monotonic.h" #include <chrono> +#include <optional> +#include <util/system/platform.h> + +#ifdef _linux + #include <time.h> + #include <string.h> +#endif namespace NMonotonic { -namespace { -// Unfortunately time_since_epoch() is sometimes negative on wine -// Remember initial time point at program start and use offsets from that -std::chrono::steady_clock::time_point MonotonicOffset = std::chrono::steady_clock::now(); -} + namespace { + // Unfortunately time_since_epoch() is sometimes negative on wine + // Remember initial time point at program start and use offsets from that + std::chrono::steady_clock::time_point MonotonicOffset = std::chrono::steady_clock::now(); + } -ui64 GetMonotonicMicroSeconds() { - auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - MonotonicOffset).count(); - // Steady clock is supposed to never jump backwards, but it's better to be safe in case of buggy implementations - if (Y_UNLIKELY(microseconds < 0)) { - microseconds = 0; + ui64 GetMonotonicMicroSeconds() { + auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - MonotonicOffset).count(); + // Steady clock is supposed to never jump backwards, but it's better to be safe in case of buggy implementations + if (Y_UNLIKELY(microseconds < 0)) { + microseconds = 0; + } + // Add one so we never return zero + return microseconds + 1; } - // Add one so we never return zero - return microseconds + 1; -} -} // namespace TMonotonic +#ifdef _linux_ + namespace { + std::optional<ui64> GetClockBootTimeMicroSeconds() { + struct timespec t; + std::optional<ui64> r; + if (0 == ::clock_gettime(CLOCK_BOOTTIME, &t)) { + r.emplace(t.tv_nsec / 1000ULL + t.tv_sec * 1000000ULL); + } + return r; + } + + // We want time relative to process start + std::optional<ui64> BootTimeOffset = GetClockBootTimeMicroSeconds(); + } + + ui64 GetBootTimeMicroSeconds() { + if (Y_UNLIKELY(!BootTimeOffset)) { + return GetMonotonicMicroSeconds(); + } + + auto r = GetClockBootTimeMicroSeconds(); + Y_VERIFY(r, "Unexpected clock_gettime(CLOCK_BOOTTIME) failure: %s", strerror(errno)); + return *r - *BootTimeOffset + 1; + } +#else + ui64 GetBootTimeMicroSeconds() { + return GetMonotonicMicroSeconds(); + } +#endif + +} -template<> +template <> void Out<NMonotonic::TMonotonic>( IOutputStream& o, NMonotonic::TMonotonic t) { o << t - NMonotonic::TMonotonic::Zero(); } + +template <> +void Out<NMonotonic::TBootTime>( + IOutputStream& o, + NMonotonic::TBootTime t) +{ + o << t - NMonotonic::TBootTime::Zero(); +} diff --git a/library/cpp/time_provider/monotonic.h b/library/cpp/time_provider/monotonic.h index e36902d884..9b5e5df149 100644 --- a/library/cpp/time_provider/monotonic.h +++ b/library/cpp/time_provider/monotonic.h @@ -1,111 +1,202 @@ #pragma once #include <util/datetime/base.h> -namespace NMonotonic { -/** - * Returns current monotonic time in microseconds - */ -ui64 GetMonotonicMicroSeconds(); - -/** - * Similar to TInstant, but measuring monotonic time - */ -class TMonotonic: public TTimeBase<TMonotonic> { - using TBase = TTimeBase<TMonotonic>; - -private: - constexpr explicit TMonotonic(TValue value) noexcept - : TBase(value) { - } - -public: - constexpr TMonotonic() noexcept { - } - - static constexpr TMonotonic FromValue(TValue value) noexcept { - return TMonotonic(value); - } - - static inline TMonotonic Now() { - return TMonotonic::MicroSeconds(GetMonotonicMicroSeconds()); - } - using TBase::Days; - using TBase::Hours; - using TBase::MicroSeconds; - using TBase::MilliSeconds; - using TBase::Minutes; - using TBase::Seconds; - - static constexpr TMonotonic Max() noexcept { - return TMonotonic(::Max<ui64>()); - } +namespace NMonotonic { - static constexpr TMonotonic Zero() noexcept { - return TMonotonic(); - } + template <class TDerived> + class TMonotonicBase: public TTimeBase<TDerived> { + using TBase = TTimeBase<TDerived>; + + public: + using TBase::TBase; + + using TBase::Days; + using TBase::Hours; + using TBase::MicroSeconds; + using TBase::MilliSeconds; + using TBase::Minutes; + using TBase::Seconds; + + static constexpr TDerived Max() noexcept { + return TDerived::FromValue(::Max<ui64>()); + } + + static constexpr TDerived Zero() noexcept { + return TDerived::FromValue(0); + } + + static constexpr TDerived MicroSeconds(ui64 us) noexcept { + return TDerived::FromValue(TInstant::MicroSeconds(us).GetValue()); + } + + static constexpr TDerived MilliSeconds(ui64 ms) noexcept { + return TDerived::FromValue(TInstant::MilliSeconds(ms).GetValue()); + } + + static constexpr TDerived Seconds(ui64 s) noexcept { + return TDerived::FromValue(TInstant::Seconds(s).GetValue()); + } + + static constexpr TDerived Minutes(ui64 m) noexcept { + return TDerived::FromValue(TInstant::Minutes(m).GetValue()); + } + + static constexpr TDerived Hours(ui64 h) noexcept { + return TDerived::FromValue(TInstant::Hours(h).GetValue()); + } + + static constexpr TDerived Days(ui64 d) noexcept { + return TDerived::FromValue(TInstant::Days(d).GetValue()); + } + }; + + /** + * Returns current monotonic time in microseconds + */ + ui64 GetMonotonicMicroSeconds(); + + /** + * Similar to TInstant, but measuring monotonic time + */ + class TMonotonic: public TMonotonicBase<TMonotonic> { + using TBase = TMonotonicBase<TMonotonic>; + + protected: + constexpr explicit TMonotonic(TValue value) noexcept + : TBase(value) + { + } + + public: + constexpr TMonotonic() noexcept { + } + + static constexpr TMonotonic FromValue(TValue value) noexcept { + return TMonotonic(value); + } + + static inline TMonotonic Now() { + return TMonotonic::MicroSeconds(GetMonotonicMicroSeconds()); + } + + using TBase::Days; + using TBase::Hours; + using TBase::MicroSeconds; + using TBase::MilliSeconds; + using TBase::Minutes; + using TBase::Seconds; + + template <class T> + inline TMonotonic& operator+=(const T& t) noexcept { + return (*this = (*this + t)); + } + + template <class T> + inline TMonotonic& operator-=(const T& t) noexcept { + return (*this = (*this - t)); + } + }; + + /** + * Returns current CLOCK_BOOTTIME time in microseconds + */ + ui64 GetBootTimeMicroSeconds(); + + /** + * Similar to TInstant, but measuring CLOCK_BOOTTIME time + */ + class TBootTime: public TMonotonicBase<TBootTime> { + using TBase = TMonotonicBase<TBootTime>; + + protected: + constexpr explicit TBootTime(TValue value) noexcept + : TBase(value) + { + } + + public: + constexpr TBootTime() noexcept { + } + + static constexpr TBootTime FromValue(TValue value) noexcept { + return TBootTime(value); + } + + static inline TBootTime Now() { + return TBootTime::MicroSeconds(GetBootTimeMicroSeconds()); + } + + using TBase::Days; + using TBase::Hours; + using TBase::MicroSeconds; + using TBase::MilliSeconds; + using TBase::Minutes; + using TBase::Seconds; + + template <class T> + inline TBootTime& operator+=(const T& t) noexcept { + return (*this = (*this + t)); + } + + template <class T> + inline TBootTime& operator-=(const T& t) noexcept { + return (*this = (*this - t)); + } + }; - static constexpr TMonotonic MicroSeconds(ui64 us) noexcept { - return TMonotonic(TInstant::MicroSeconds(us).GetValue()); - } +} // namespace NMonotonic - static constexpr TMonotonic MilliSeconds(ui64 ms) noexcept { - return TMonotonic(TInstant::MilliSeconds(ms).GetValue()); - } +Y_DECLARE_PODTYPE(NMonotonic::TMonotonic); +Y_DECLARE_PODTYPE(NMonotonic::TBootTime); + +namespace std { + template <> + struct hash<NMonotonic::TMonotonic> { + size_t operator()(const NMonotonic::TMonotonic& key) const noexcept { + return hash<NMonotonic::TMonotonic::TValue>()(key.GetValue()); + } + }; + + template <> + struct hash<NMonotonic::TBootTime> { + size_t operator()(const NMonotonic::TBootTime& key) const noexcept { + return hash<NMonotonic::TBootTime::TValue>()(key.GetValue()); + } + }; +} - static constexpr TMonotonic Seconds(ui64 s) noexcept { - return TMonotonic(TInstant::Seconds(s).GetValue()); - } +namespace NMonotonic { - static constexpr TMonotonic Minutes(ui64 m) noexcept { - return TMonotonic(TInstant::Minutes(m).GetValue()); + constexpr TDuration operator-(const TMonotonic& l, const TMonotonic& r) { + return TInstant::FromValue(l.GetValue()) - TInstant::FromValue(r.GetValue()); } - static constexpr TMonotonic Hours(ui64 h) noexcept { - return TMonotonic(TInstant::Hours(h).GetValue()); + constexpr TMonotonic operator+(const TMonotonic& l, const TDuration& r) { + TInstant result = TInstant::FromValue(l.GetValue()) + r; + return TMonotonic::FromValue(result.GetValue()); } - static constexpr TMonotonic Days(ui64 d) noexcept { - return TMonotonic(TInstant::Days(d).GetValue()); + constexpr TMonotonic operator-(const TMonotonic& l, const TDuration& r) { + TInstant result = TInstant::FromValue(l.GetValue()) - r; + return TMonotonic::FromValue(result.GetValue()); } - template<class T> - inline TMonotonic& operator+=(const T& t) noexcept { - return (*this = (*this + t)); + constexpr TDuration operator-(const TBootTime& l, const TBootTime& r) { + return TInstant::FromValue(l.GetValue()) - TInstant::FromValue(r.GetValue()); } - template<class T> - inline TMonotonic& operator-=(const T& t) noexcept { - return (*this = (*this - t)); + constexpr TBootTime operator+(const TBootTime& l, const TDuration& r) { + TInstant result = TInstant::FromValue(l.GetValue()) + r; + return TBootTime::FromValue(result.GetValue()); } -}; -} // namespace NMonotonic - -Y_DECLARE_PODTYPE(NMonotonic::TMonotonic); -template<> -struct THash<NMonotonic::TMonotonic> { - size_t operator()(const NMonotonic::TMonotonic& key) const { - return THash<NMonotonic::TMonotonic::TValue>()(key.GetValue()); + constexpr TBootTime operator-(const TBootTime& l, const TDuration& r) { + TInstant result = TInstant::FromValue(l.GetValue()) - r; + return TBootTime::FromValue(result.GetValue()); } -}; - -namespace NMonotonic { - -constexpr TDuration operator-(const TMonotonic& l, const TMonotonic& r) { - return TInstant::FromValue(l.GetValue()) - TInstant::FromValue(r.GetValue()); -} - -constexpr TMonotonic operator+(const TMonotonic& l, const TDuration& r) { - TInstant result = TInstant::FromValue(l.GetValue()) + r; - return TMonotonic::FromValue(result.GetValue()); -} - -constexpr TMonotonic operator-(const TMonotonic& l, const TDuration& r) { - TInstant result = TInstant::FromValue(l.GetValue()) - r; - return TMonotonic::FromValue(result.GetValue()); -} } // namespace NMonotonic +// TODO: remove, alias for compatibility using TMonotonic = NMonotonic::TMonotonic; diff --git a/library/cpp/time_provider/monotonic_provider.cpp b/library/cpp/time_provider/monotonic_provider.cpp index 22937bd873..cc9297213a 100644 --- a/library/cpp/time_provider/monotonic_provider.cpp +++ b/library/cpp/time_provider/monotonic_provider.cpp @@ -1,32 +1,43 @@ #include "monotonic_provider.h" -namespace { -TIntrusivePtr<IMonotonicTimeProvider> GlobalMonotonicTimeProvider; -} +namespace NMonotonic { -void TMonotonicOperator::RegisterProvider(TIntrusivePtr<IMonotonicTimeProvider> provider) { - GlobalMonotonicTimeProvider = provider; -} + namespace { + TIntrusivePtr<IMonotonicTimeProvider> GlobalMonotonicTimeProvider; + } -NMonotonic::TMonotonic TMonotonicOperator::Now() { - if (GlobalMonotonicTimeProvider) { - return GlobalMonotonicTimeProvider->Now(); - } else { - return TMonotonic::Now(); + void TMonotonicOperator::RegisterProvider(TIntrusivePtr<IMonotonicTimeProvider> provider) { + GlobalMonotonicTimeProvider = provider; } -} -namespace NMonotonic { + NMonotonic::TMonotonic TMonotonicOperator::Now() { + if (GlobalMonotonicTimeProvider) { + return GlobalMonotonicTimeProvider->Now(); + } else { + return TMonotonic::Now(); + } + } + + class TDefaultMonotonicTimeProvider: public IMonotonicTimeProvider { + public: + TMonotonic Now() override { + return TMonotonic::Now(); + } + }; -class TDefaultMonotonicTimeProvider: public IMonotonicTimeProvider { -public: - TMonotonic Now() override { - return TMonotonic::Now(); + TIntrusivePtr<IMonotonicTimeProvider> CreateDefaultMonotonicTimeProvider() { + return TIntrusivePtr<IMonotonicTimeProvider>(new TDefaultMonotonicTimeProvider); } -}; -TIntrusivePtr<IMonotonicTimeProvider> CreateDefaultMonotonicTimeProvider() { - return TIntrusivePtr<IMonotonicTimeProvider>(new TDefaultMonotonicTimeProvider); -} + class TDefaultBootTimeProvider: public IBootTimeProvider { + public: + TBootTime Now() override { + return TBootTime::Now(); + } + }; + + TIntrusivePtr<IBootTimeProvider> CreateDefaultBootTimeProvider() { + return TIntrusivePtr<IBootTimeProvider>(new TDefaultBootTimeProvider); + } } diff --git a/library/cpp/time_provider/monotonic_provider.h b/library/cpp/time_provider/monotonic_provider.h index 966e2e496b..49f2835490 100644 --- a/library/cpp/time_provider/monotonic_provider.h +++ b/library/cpp/time_provider/monotonic_provider.h @@ -3,19 +3,31 @@ #include <util/datetime/base.h> #include "monotonic.h" -class IMonotonicTimeProvider: public TThrRefBase { -public: - virtual TMonotonic Now() = 0; -}; +namespace NMonotonic { -class TMonotonicOperator { -public: - static void RegisterProvider(TIntrusivePtr<IMonotonicTimeProvider> provider); - static TMonotonic Now(); -}; + class IMonotonicTimeProvider: public TThrRefBase { + public: + virtual TMonotonic Now() = 0; + }; -namespace NMonotonic { + class IBootTimeProvider: public TThrRefBase { + public: + virtual TBootTime Now() = 0; + }; + + class TMonotonicOperator { + public: + static void RegisterProvider(TIntrusivePtr<IMonotonicTimeProvider> provider); + static TMonotonic Now(); + }; -TIntrusivePtr<IMonotonicTimeProvider> CreateDefaultMonotonicTimeProvider(); + TIntrusivePtr<IMonotonicTimeProvider> CreateDefaultMonotonicTimeProvider(); + TIntrusivePtr<IBootTimeProvider> CreateDefaultBootTimeProvider(); } + +// TODO: remove, alias for compatibility +using IMonotonicTimeProvider = NMonotonic::IMonotonicTimeProvider; + +// TODO: remove, alias for compatibility +using NMonotonic::CreateDefaultMonotonicTimeProvider; diff --git a/library/cpp/time_provider/time_provider.cpp b/library/cpp/time_provider/time_provider.cpp index 687681f1ff..e1045dae05 100644 --- a/library/cpp/time_provider/time_provider.cpp +++ b/library/cpp/time_provider/time_provider.cpp @@ -30,7 +30,7 @@ TIntrusivePtr<ITimeProvider> CreateDeterministicTimeProvider(ui64 seed) { } namespace { -TIntrusivePtr<ITimeProvider> GlobalTimeProvider; + TIntrusivePtr<ITimeProvider> GlobalTimeProvider; } void TInstantOperator::RegisterProvider(TIntrusivePtr<ITimeProvider> provider) { diff --git a/ydb/core/base/appdata.cpp b/ydb/core/base/appdata.cpp index e91a3b3d84..2099660b95 100644 --- a/ydb/core/base/appdata.cpp +++ b/ydb/core/base/appdata.cpp @@ -20,6 +20,7 @@ TAppData::TAppData( , FunctionRegistry(functionRegistry) , FormatFactory(formatFactory) , MonotonicTimeProvider(CreateDefaultMonotonicTimeProvider()) + , BootTimeProvider(CreateDefaultBootTimeProvider()) , ProxySchemeCacheNodes(Max<ui64>() / 4) , ProxySchemeCacheDistrNodes(Max<ui64>() / 4) , CompilerSchemeCachePaths(Max<ui64>() / 4) diff --git a/ydb/core/base/appdata.h b/ydb/core/base/appdata.h index 0b1c70780c..24810316d8 100644 --- a/ydb/core/base/appdata.h +++ b/ydb/core/base/appdata.h @@ -108,6 +108,7 @@ struct TAppData { static TIntrusivePtr<IRandomProvider> RandomProvider; static TIntrusivePtr<ITimeProvider> TimeProvider; TIntrusivePtr<IMonotonicTimeProvider> MonotonicTimeProvider; + TIntrusivePtr<IBootTimeProvider> BootTimeProvider; TIntrusivePtr<TDomainsInfo> DomainsInfo; TIntrusivePtr<TChannelProfiles> ChannelProfiles; TIntrusivePtr<TDynamicNameserviceConfig> DynamicNameserviceConfig; diff --git a/ydb/core/testlib/actors/test_runtime.cpp b/ydb/core/testlib/actors/test_runtime.cpp index b8443e7206..d696457025 100644 --- a/ydb/core/testlib/actors/test_runtime.cpp +++ b/ydb/core/testlib/actors/test_runtime.cpp @@ -127,6 +127,7 @@ namespace NActors { auto* nodeAppData = node->GetAppData<NKikimr::TAppData>(); if (!UseRealThreads) { nodeAppData->MonotonicTimeProvider = MonotonicTimeProvider; + nodeAppData->BootTimeProvider = BootTimeProvider; } nodeAppData->DataShardExportFactory = app0->DataShardExportFactory; nodeAppData->DomainsInfo = app0->DomainsInfo; diff --git a/ydb/core/util/testactorsys.cpp b/ydb/core/util/testactorsys.cpp index 6dd2760001..e6b8bba585 100644 --- a/ydb/core/util/testactorsys.cpp +++ b/ydb/core/util/testactorsys.cpp @@ -238,4 +238,12 @@ TIntrusivePtr<IMonotonicTimeProvider> TTestActorSystem::CreateMonotonicTimeProvi return MakeIntrusive<TTestActorMonotonicTimeProvider>(); } +TIntrusivePtr<IBootTimeProvider> TTestActorSystem::CreateBootTimeProvider() { + class TTestActorBootTimeProvider : public IBootTimeProvider { + public: + TBootTime Now() override { return TBootTime::MicroSeconds(CurrentTestActorSystem->Clock.MicroSeconds()); } + }; + return MakeIntrusive<TTestActorBootTimeProvider>(); +} + } diff --git a/ydb/core/util/testactorsys.h b/ydb/core/util/testactorsys.h index d2f2707be7..43d3494632 100644 --- a/ydb/core/util/testactorsys.h +++ b/ydb/core/util/testactorsys.h @@ -194,6 +194,7 @@ public: CurrentTestActorSystem = this; AppData.MonotonicTimeProvider = CreateMonotonicTimeProvider(); + AppData.BootTimeProvider = CreateBootTimeProvider(); } ~TTestActorSystem() { @@ -203,6 +204,7 @@ public: static TIntrusivePtr<ITimeProvider> CreateTimeProvider(); static TIntrusivePtr<IMonotonicTimeProvider> CreateMonotonicTimeProvider(); + static TIntrusivePtr<IBootTimeProvider> CreateBootTimeProvider(); TAppData *GetAppData() { return &AppData; |