aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsnaury <snaury@ydb.tech>2023-05-16 13:43:28 +0300
committersnaury <snaury@ydb.tech>2023-05-16 13:43:28 +0300
commitc9df7fc86be0b15adc1e812144c41ab5c057baef (patch)
tree63c809b43d9e026188f6a66725ccac433ba0f734
parenta2e846788b0a6d372d15ab5de915616cc6bc00ce (diff)
downloadydb-c9df7fc86be0b15adc1e812144c41ab5c057baef.tar.gz
Support monotonic boot time with suspend awareness
-rw-r--r--library/cpp/actors/core/monotonic.cpp8
-rw-r--r--library/cpp/actors/core/monotonic.h5
-rw-r--r--library/cpp/actors/core/monotonic_provider.cpp8
-rw-r--r--library/cpp/actors/core/monotonic_provider.h6
-rw-r--r--library/cpp/actors/testlib/test_runtime.cpp26
-rw-r--r--library/cpp/actors/testlib/test_runtime.h4
-rw-r--r--library/cpp/time_provider/monotonic.cpp75
-rw-r--r--library/cpp/time_provider/monotonic.h265
-rw-r--r--library/cpp/time_provider/monotonic_provider.cpp53
-rw-r--r--library/cpp/time_provider/monotonic_provider.h34
-rw-r--r--library/cpp/time_provider/time_provider.cpp2
-rw-r--r--ydb/core/base/appdata.cpp1
-rw-r--r--ydb/core/base/appdata.h1
-rw-r--r--ydb/core/testlib/actors/test_runtime.cpp1
-rw-r--r--ydb/core/util/testactorsys.cpp8
-rw-r--r--ydb/core/util/testactorsys.h2
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;