diff options
author | ddoarn <ddoarn@yandex-team.ru> | 2022-02-10 16:49:53 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:49:53 +0300 |
commit | 3bf10d3f40b502d181ef52f5c4602c98cb135360 (patch) | |
tree | 5d5cb817648f650d76cf1076100726fd9b8448e8 | |
parent | 0783fe3f48d91a3b741ce2ea32b11fbfc1637e7e (diff) | |
download | ydb-3bf10d3f40b502d181ef52f5c4602c98cb135360.tar.gz |
Restoring authorship annotation for <ddoarn@yandex-team.ru>. Commit 2 of 2.
555 files changed, 30853 insertions, 30853 deletions
diff --git a/library/cpp/actors/core/actor.cpp b/library/cpp/actors/core/actor.cpp index b9f1eb1b9d..6f9ba6a42b 100644 --- a/library/cpp/actors/core/actor.cpp +++ b/library/cpp/actors/core/actor.cpp @@ -1,16 +1,16 @@ -#include "actor.h" -#include "executor_thread.h" -#include "mailbox.h" +#include "actor.h" +#include "executor_thread.h" +#include "mailbox.h" #include <library/cpp/actors/util/datetime.h> - -namespace NActors { - Y_POD_THREAD(TActivationContext*) - TlsActivationContext((TActivationContext*)nullptr); - + +namespace NActors { + Y_POD_THREAD(TActivationContext*) + TlsActivationContext((TActivationContext*)nullptr); + bool TActorContext::Send(const TActorId& recipient, IEventBase* ev, ui32 flags, ui64 cookie, NWilson::TTraceId traceId) const { return Send(new IEventHandle(recipient, SelfID, ev, flags, cookie, nullptr, std::move(traceId))); - } - + } + bool TActorContext::Send(TAutoPtr<IEventHandle> ev) const { return ExecutorThread.Send(ev); } @@ -26,13 +26,13 @@ namespace NActors { } bool IActor::Send(const TActorId& recipient, IEventBase* ev, ui32 flags, ui64 cookie, NWilson::TTraceId traceId) const noexcept { - return SelfActorId.Send(recipient, ev, flags, cookie, std::move(traceId)); - } - - bool TActivationContext::Send(TAutoPtr<IEventHandle> ev) { - return TlsActivationContext->ExecutorThread.Send(ev); - } - + return SelfActorId.Send(recipient, ev, flags, cookie, std::move(traceId)); + } + + bool TActivationContext::Send(TAutoPtr<IEventHandle> ev) { + return TlsActivationContext->ExecutorThread.Send(ev); + } + void TActivationContext::Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) { TlsActivationContext->ExecutorThread.Schedule(deadline, ev, cookie); } @@ -46,9 +46,9 @@ namespace NActors { } bool TActorIdentity::Send(const TActorId& recipient, IEventBase* ev, ui32 flags, ui64 cookie, NWilson::TTraceId traceId) const { - return TActivationContext::Send(new IEventHandle(recipient, *this, ev, flags, cookie, nullptr, std::move(traceId))); - } - + return TActivationContext::Send(new IEventHandle(recipient, *this, ev, flags, cookie, nullptr, std::move(traceId))); + } + void TActorIdentity::Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie) const { return TActivationContext::Schedule(deadline, new IEventHandle(*this, {}, ev), cookie); } @@ -62,31 +62,31 @@ namespace NActors { } TActorId TActivationContext::RegisterWithSameMailbox(IActor* actor, TActorId parentId) { - Y_VERIFY_DEBUG(parentId); - auto& ctx = *TlsActivationContext; - return ctx.ExecutorThread.RegisterActor(actor, &ctx.Mailbox, parentId.Hint(), parentId); - } - + Y_VERIFY_DEBUG(parentId); + auto& ctx = *TlsActivationContext; + return ctx.ExecutorThread.RegisterActor(actor, &ctx.Mailbox, parentId.Hint(), parentId); + } + TActorId TActorContext::RegisterWithSameMailbox(IActor* actor) const { - return ExecutorThread.RegisterActor(actor, &Mailbox, SelfID.Hint(), SelfID); - } - + return ExecutorThread.RegisterActor(actor, &Mailbox, SelfID.Hint(), SelfID); + } + TActorId IActor::RegisterWithSameMailbox(IActor* actor) const noexcept { - return TlsActivationContext->ExecutorThread.RegisterActor(actor, &TlsActivationContext->Mailbox, SelfActorId.Hint(), SelfActorId); - } - + return TlsActivationContext->ExecutorThread.RegisterActor(actor, &TlsActivationContext->Mailbox, SelfActorId.Hint(), SelfActorId); + } + TActorId TActivationContext::Register(IActor* actor, TActorId parentId, TMailboxType::EType mailboxType, ui32 poolId) { - return TlsActivationContext->ExecutorThread.RegisterActor(actor, mailboxType, poolId, parentId); - } - + return TlsActivationContext->ExecutorThread.RegisterActor(actor, mailboxType, poolId, parentId); + } + TActorId TActivationContext::InterconnectProxy(ui32 destinationNodeId) { - return TlsActivationContext->ExecutorThread.ActorSystem->InterconnectProxy(destinationNodeId); - } - - TActorSystem* TActivationContext::ActorSystem() { - return TlsActivationContext->ExecutorThread.ActorSystem; - } - + return TlsActivationContext->ExecutorThread.ActorSystem->InterconnectProxy(destinationNodeId); + } + + TActorSystem* TActivationContext::ActorSystem() { + return TlsActivationContext->ExecutorThread.ActorSystem; + } + i64 TActivationContext::GetCurrentEventTicks() { return GetCycleCountFast() - TlsActivationContext->EventStart; } @@ -96,13 +96,13 @@ namespace NActors { } TActorId TActorContext::Register(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId) const { - return ExecutorThread.RegisterActor(actor, mailboxType, poolId, SelfID); - } - + return ExecutorThread.RegisterActor(actor, mailboxType, poolId, SelfID); + } + TActorId IActor::Register(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId) const noexcept { - return TlsActivationContext->ExecutorThread.RegisterActor(actor, mailboxType, poolId, SelfActorId); - } - + return TlsActivationContext->ExecutorThread.RegisterActor(actor, mailboxType, poolId, SelfActorId); + } + void TActorContext::Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie) const { ExecutorThread.Schedule(deadline, new IEventHandle(SelfID, TActorId(), ev), cookie); } @@ -111,10 +111,10 @@ namespace NActors { ExecutorThread.Schedule(deadline, new IEventHandle(SelfID, TActorId(), ev), cookie); } - void TActorContext::Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie) const { + void TActorContext::Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie) const { ExecutorThread.Schedule(delta, new IEventHandle(SelfID, TActorId(), ev), cookie); - } - + } + void IActor::Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie) const noexcept { TlsActivationContext->ExecutorThread.Schedule(deadline, new IEventHandle(SelfActorId, TActorId(), ev), cookie); } @@ -125,20 +125,20 @@ namespace NActors { void IActor::Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie) const noexcept { TlsActivationContext->ExecutorThread.Schedule(delta, new IEventHandle(SelfActorId, TActorId(), ev), cookie); - } - - TInstant TActivationContext::Now() { - return TlsActivationContext->ExecutorThread.ActorSystem->Timestamp(); - } - + } + + TInstant TActivationContext::Now() { + return TlsActivationContext->ExecutorThread.ActorSystem->Timestamp(); + } + TMonotonic TActivationContext::Monotonic() { return TlsActivationContext->ExecutorThread.ActorSystem->Monotonic(); } TInstant TActorContext::Now() const { return ExecutorThread.ActorSystem->Timestamp(); - } - + } + TMonotonic TActorContext::Monotonic() const { return ExecutorThread.ActorSystem->Monotonic(); } @@ -147,26 +147,26 @@ namespace NActors { return ExecutorThread.ActorSystem->LoggerSettings(); } - std::pair<ui32, ui32> TActorContext::CountMailboxEvents(ui32 maxTraverse) const { - return Mailbox.CountMailboxEvents(SelfID.LocalId(), maxTraverse); - } - - std::pair<ui32, ui32> IActor::CountMailboxEvents(ui32 maxTraverse) const { - return TlsActivationContext->Mailbox.CountMailboxEvents(SelfActorId.LocalId(), maxTraverse); - } - - void IActor::Die(const TActorContext& ctx) { - if (ctx.SelfID) - Y_VERIFY(ctx.SelfID == SelfActorId); - PassAway(); - } - - void IActor::PassAway() { - auto& cx = *TlsActivationContext; - cx.ExecutorThread.UnregisterActor(&cx.Mailbox, SelfActorId.LocalId()); - } - - double IActor::GetElapsedTicksAsSeconds() const { - return NHPTimer::GetSeconds(ElapsedTicks); - } -} + std::pair<ui32, ui32> TActorContext::CountMailboxEvents(ui32 maxTraverse) const { + return Mailbox.CountMailboxEvents(SelfID.LocalId(), maxTraverse); + } + + std::pair<ui32, ui32> IActor::CountMailboxEvents(ui32 maxTraverse) const { + return TlsActivationContext->Mailbox.CountMailboxEvents(SelfActorId.LocalId(), maxTraverse); + } + + void IActor::Die(const TActorContext& ctx) { + if (ctx.SelfID) + Y_VERIFY(ctx.SelfID == SelfActorId); + PassAway(); + } + + void IActor::PassAway() { + auto& cx = *TlsActivationContext; + cx.ExecutorThread.UnregisterActor(&cx.Mailbox, SelfActorId.LocalId()); + } + + double IActor::GetElapsedTicksAsSeconds() const { + return NHPTimer::GetSeconds(ElapsedTicks); + } +} diff --git a/library/cpp/actors/core/actor.h b/library/cpp/actors/core/actor.h index a790101c34..ed29bd14b9 100644 --- a/library/cpp/actors/core/actor.h +++ b/library/cpp/actors/core/actor.h @@ -1,41 +1,41 @@ -#pragma once - -#include "event.h" +#pragma once + +#include "event.h" #include "monotonic.h" -#include <util/system/tls.h> +#include <util/system/tls.h> #include <library/cpp/actors/util/local_process_key.h> - -namespace NActors { + +namespace NActors { class TActorSystem; - class TMailboxTable; - struct TMailboxHeader; - - class TExecutorThread; - class IActor; - class ISchedulerCookie; - - namespace NLog { - struct TSettings; + class TMailboxTable; + struct TMailboxHeader; + + class TExecutorThread; + class IActor; + class ISchedulerCookie; + + namespace NLog { + struct TSettings; } - - struct TActorContext; - struct TActivationContext { - public: - TMailboxHeader& Mailbox; - TExecutorThread& ExecutorThread; + struct TActorContext; + + struct TActivationContext { + public: + TMailboxHeader& Mailbox; + TExecutorThread& ExecutorThread; const NHPTimer::STime EventStart; - - protected: + + protected: explicit TActivationContext(TMailboxHeader& mailbox, TExecutorThread& executorThread, NHPTimer::STime eventStart) - : Mailbox(mailbox) - , ExecutorThread(executorThread) + : Mailbox(mailbox) + , ExecutorThread(executorThread) , EventStart(eventStart) - { - } - - public: - static bool Send(TAutoPtr<IEventHandle> ev); + { + } + + public: + static bool Send(TAutoPtr<IEventHandle> ev); /** * Schedule one-shot event that will be send at given time point in the future. @@ -63,40 +63,40 @@ namespace NActors { * @param cookie cookie that will be piggybacked with event */ static void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr); - - static TInstant Now(); + + static TInstant Now(); static TMonotonic Monotonic(); NLog::TSettings* LoggerSettings() const; - - // register new actor in ActorSystem on new fresh mailbox. + + // register new actor in ActorSystem on new fresh mailbox. static TActorId Register(IActor* actor, TActorId parentId = TActorId(), TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>()); - + // Register new actor in ActorSystem on same _mailbox_ as current actor. // There is one thread per mailbox to execute actor, which mean // no _cpu core scalability_ for such actors. // This method of registration can be usefull if multiple actors share // some memory. static TActorId RegisterWithSameMailbox(IActor* actor, TActorId parentId); - - static const TActorContext& AsActorContext(); + + static const TActorContext& AsActorContext(); static TActorContext ActorContextFor(TActorId id); - + static TActorId InterconnectProxy(ui32 nodeid); - static TActorSystem* ActorSystem(); + static TActorSystem* ActorSystem(); static i64 GetCurrentEventTicks(); static double GetCurrentEventTicksAsSeconds(); - }; - - struct TActorContext: public TActivationContext { + }; + + struct TActorContext: public TActivationContext { const TActorId SelfID; - + explicit TActorContext(TMailboxHeader& mailbox, TExecutorThread& executorThread, NHPTimer::STime eventStart, const TActorId& selfID) : TActivationContext(mailbox, executorThread, eventStart) - , SelfID(selfID) - { - } - + , SelfID(selfID) + { + } + bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const; template <typename TEvent> bool Send(const TActorId& recipient, THolder<TEvent> ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const { @@ -132,47 +132,47 @@ namespace NActors { * @param ev the event to send * @param cookie cookie that will be piggybacked with event */ - void Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const; + void Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const; TActorContext MakeFor(const TActorId& otherId) const { return TActorContext(Mailbox, ExecutorThread, EventStart, otherId); - } - - // register new actor in ActorSystem on new fresh mailbox. + } + + // register new actor in ActorSystem on new fresh mailbox. TActorId Register(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>()) const; - + // Register new actor in ActorSystem on same _mailbox_ as current actor. // There is one thread per mailbox to execute actor, which mean // no _cpu core scalability_ for such actors. // This method of registration can be usefull if multiple actors share // some memory. TActorId RegisterWithSameMailbox(IActor* actor) const; - - std::pair<ui32, ui32> CountMailboxEvents(ui32 maxTraverse = Max<ui32>()) const; - }; - - extern Y_POD_THREAD(TActivationContext*) TlsActivationContext; - + + std::pair<ui32, ui32> CountMailboxEvents(ui32 maxTraverse = Max<ui32>()) const; + }; + + extern Y_POD_THREAD(TActivationContext*) TlsActivationContext; + struct TActorIdentity: public TActorId { explicit TActorIdentity(TActorId actorId) : TActorId(actorId) - { - } - + { + } + void operator=(TActorId actorId) { - *this = TActorIdentity(actorId); - } - + *this = TActorIdentity(actorId); + } + bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const; void Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const; void Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const; void Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const; - }; - + }; + class IActor; class IActorOps : TNonCopyable { - public: + public: virtual void Describe(IOutputStream&) const noexcept = 0; virtual bool Send(const TActorId& recipient, IEventBase*, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const noexcept = 0; @@ -211,24 +211,24 @@ namespace NActors { class IActor : protected IActorOps { public: - typedef void (IActor::*TReceiveFunc)(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx); - - private: - TReceiveFunc StateFunc; - TActorIdentity SelfActorId; - i64 ElapsedTicks; - ui64 HandledEvents; + typedef void (IActor::*TReceiveFunc)(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx); + + private: + TReceiveFunc StateFunc; + TActorIdentity SelfActorId; + i64 ElapsedTicks; + ui64 HandledEvents; friend void DoActorInit(TActorSystem*, IActor*, const TActorId&, const TActorId&); friend class TDecorator; - - public: + + public: /// @sa services.proto NKikimrServices::TActivity::EType - enum EActorActivity { - OTHER = 0, - ACTOR_SYSTEM = 1, - ACTORLIB_COMMON = 2, - ACTORLIB_STATS = 3, + enum EActorActivity { + OTHER = 0, + ACTOR_SYSTEM = 1, + ACTORLIB_COMMON = 2, + ACTORLIB_STATS = 3, LOG_ACTOR = 4, INTERCONNECT_PROXY_TCP = 12, INTERCONNECT_SESSION_TCP = 13, @@ -246,64 +246,64 @@ namespace NActors { NAMESERVICE = 450, DNS_RESOLVER = 481, INTERCONNECT_PROXY_WRAPPER = 546, - }; + }; using EActivityType = EActorActivity; ui32 ActivityType; - protected: + protected: IActor(TReceiveFunc stateFunc, ui32 activityType = OTHER) - : StateFunc(stateFunc) + : StateFunc(stateFunc) , SelfActorId(TActorId()) - , ElapsedTicks(0) - , HandledEvents(0) - , ActivityType(activityType) - { - } - - public: - virtual ~IActor() { - } // must not be called for registered actors, see Die method instead - - protected: - virtual void Die(const TActorContext& ctx); // would unregister actor so call exactly once and only from inside of message processing - virtual void PassAway(); - - public: - template <typename T> - void Become(T stateFunc) { - StateFunc = static_cast<TReceiveFunc>(stateFunc); - } - + , ElapsedTicks(0) + , HandledEvents(0) + , ActivityType(activityType) + { + } + + public: + virtual ~IActor() { + } // must not be called for registered actors, see Die method instead + + protected: + virtual void Die(const TActorContext& ctx); // would unregister actor so call exactly once and only from inside of message processing + virtual void PassAway(); + + public: + template <typename T> + void Become(T stateFunc) { + StateFunc = static_cast<TReceiveFunc>(stateFunc); + } + template <typename T, typename... TArgs> void Become(T stateFunc, const TActorContext& ctx, TArgs&&... args) { - StateFunc = static_cast<TReceiveFunc>(stateFunc); + StateFunc = static_cast<TReceiveFunc>(stateFunc); ctx.Schedule(std::forward<TArgs>(args)...); - } - + } + template <typename T, typename... TArgs> void Become(T stateFunc, TArgs&&... args) { - StateFunc = static_cast<TReceiveFunc>(stateFunc); + StateFunc = static_cast<TReceiveFunc>(stateFunc); Schedule(std::forward<TArgs>(args)...); - } - - protected: + } + + protected: void SetActivityType(ui32 activityType) { - ActivityType = activityType; - } - - public: - TReceiveFunc CurrentStateFunc() const { - return StateFunc; - } - - // NOTE: exceptions must not escape state function but if an exception hasn't be caught - // by the actor then we want to crash an see the stack - void Receive(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) { - (this->*StateFunc)(ev, ctx); - HandledEvents++; - } - + ActivityType = activityType; + } + + public: + TReceiveFunc CurrentStateFunc() const { + return StateFunc; + } + + // NOTE: exceptions must not escape state function but if an exception hasn't be caught + // by the actor then we want to crash an see the stack + void Receive(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) { + (this->*StateFunc)(ev, ctx); + HandledEvents++; + } + // must be called to wrap any call trasitions from one actor to another template<typename TActor, typename TMethod, typename... TArgs> static decltype((std::declval<TActor>().*std::declval<TMethod>())(std::declval<TArgs>()...)) @@ -326,29 +326,29 @@ namespace NActors { virtual void Registered(TActorSystem* sys, const TActorId& owner); virtual TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parentId) { - Y_UNUSED(self); - Y_UNUSED(parentId); - return TAutoPtr<IEventHandle>(); - } - - i64 GetElapsedTicks() const { - return ElapsedTicks; - } - double GetElapsedTicksAsSeconds() const; - void AddElapsedTicks(i64 ticks) { - ElapsedTicks += ticks; - } + Y_UNUSED(self); + Y_UNUSED(parentId); + return TAutoPtr<IEventHandle>(); + } + + i64 GetElapsedTicks() const { + return ElapsedTicks; + } + double GetElapsedTicksAsSeconds() const; + void AddElapsedTicks(i64 ticks) { + ElapsedTicks += ticks; + } auto GetActivityType() const { - return ActivityType; - } - ui64 GetHandledEvents() const { - return HandledEvents; - } - TActorIdentity SelfId() const { - return SelfActorId; - } - - protected: + return ActivityType; + } + ui64 GetHandledEvents() const { + return HandledEvents; + } + TActorIdentity SelfId() const { + return SelfActorId; + } + + protected: void Describe(IOutputStream&) const noexcept override; bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const noexcept final; template <typename TEvent> @@ -364,25 +364,25 @@ namespace NActors { void Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const noexcept final; void Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const noexcept final; void Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const noexcept final; - - // register new actor in ActorSystem on new fresh mailbox. + + // register new actor in ActorSystem on new fresh mailbox. TActorId Register(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>()) const noexcept final; - + // Register new actor in ActorSystem on same _mailbox_ as current actor. // There is one thread per mailbox to execute actor, which mean // no _cpu core scalability_ for such actors. // This method of registration can be usefull if multiple actors share // some memory. TActorId RegisterWithSameMailbox(IActor* actor) const noexcept final; - - std::pair<ui32, ui32> CountMailboxEvents(ui32 maxTraverse = Max<ui32>()) const; + + std::pair<ui32, ui32> CountMailboxEvents(ui32 maxTraverse = Max<ui32>()) const; private: void ChangeSelfId(TActorId actorId) { SelfActorId = actorId; } - }; - + }; + struct TActorActivityTag {}; inline size_t GetActivityTypeCount() { @@ -417,10 +417,10 @@ namespace NActors { } } - protected: + protected: //* Comment this function to find unmarked activities - static constexpr IActor::EActivityType ActorActivityType() { - return EActorActivity::OTHER; + static constexpr IActor::EActivityType ActorActivityType() { + return EActorActivity::OTHER; } //*/ // static constexpr char ActorName[] = "UNNAMED"; @@ -428,17 +428,17 @@ namespace NActors { TActor(void (TDerived::*func)(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx), ui32 activityType = GetActivityTypeIndex()) : IActor(static_cast<TReceiveFunc>(func), activityType) { } - - public: - typedef TDerived TThis; - }; - + + public: + typedef TDerived TThis; + }; + #define STFUNC_SIG TAutoPtr< ::NActors::IEventHandle>&ev, const ::NActors::TActorContext &ctx #define STATEFN_SIG TAutoPtr<::NActors::IEventHandle>& ev -#define STFUNC(funcName) void funcName(TAutoPtr< ::NActors::IEventHandle>& ev, const ::NActors::TActorContext& ctx) -#define STATEFN(funcName) void funcName(TAutoPtr< ::NActors::IEventHandle>& ev, const ::NActors::TActorContext& ) - +#define STFUNC(funcName) void funcName(TAutoPtr< ::NActors::IEventHandle>& ev, const ::NActors::TActorContext& ctx) +#define STATEFN(funcName) void funcName(TAutoPtr< ::NActors::IEventHandle>& ev, const ::NActors::TActorContext& ) + #define STRICT_STFUNC(NAME, HANDLERS) \ void NAME(STFUNC_SIG) { \ Y_UNUSED(ctx); \ @@ -449,15 +449,15 @@ namespace NActors { } \ } - inline const TActorContext& TActivationContext::AsActorContext() { - TActivationContext* tls = TlsActivationContext; - return *static_cast<TActorContext*>(tls); - } - + inline const TActorContext& TActivationContext::AsActorContext() { + TActivationContext* tls = TlsActivationContext; + return *static_cast<TActorContext*>(tls); + } + inline TActorContext TActivationContext::ActorContextFor(TActorId id) { - auto& tls = *TlsActivationContext; + auto& tls = *TlsActivationContext; return TActorContext(tls.Mailbox, tls.ExecutorThread, tls.EventStart, id); - } + } class TDecorator : public IActor { protected: @@ -515,16 +515,16 @@ namespace NActors { return true; } }; -} - -template <> -inline void Out<NActors::TActorIdentity>(IOutputStream& o, const NActors::TActorIdentity& x) { - return x.Out(o); -} - -template <> -struct THash<NActors::TActorIdentity> { - inline ui64 operator()(const NActors::TActorIdentity& x) const { - return x.Hash(); - } -}; +} + +template <> +inline void Out<NActors::TActorIdentity>(IOutputStream& o, const NActors::TActorIdentity& x) { + return x.Out(o); +} + +template <> +struct THash<NActors::TActorIdentity> { + inline ui64 operator()(const NActors::TActorIdentity& x) const { + return x.Hash(); + } +}; diff --git a/library/cpp/actors/core/actor_bootstrapped.h b/library/cpp/actors/core/actor_bootstrapped.h index 90ab0168a2..a37887c939 100644 --- a/library/cpp/actors/core/actor_bootstrapped.h +++ b/library/cpp/actors/core/actor_bootstrapped.h @@ -1,19 +1,19 @@ -#pragma once - -#include "actor.h" -#include "events.h" - -namespace NActors { +#pragma once + +#include "actor.h" +#include "events.h" + +namespace NActors { template<typename T> struct dependent_false : std::false_type {}; template<typename TDerived> class TActorBootstrapped : public TActor<TDerived> { - protected: + protected: TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parentId) override { return new IEventHandle(TEvents::TSystem::Bootstrap, 0, self, parentId, {}, 0); - } - - STFUNC(StateBootstrap) { + } + + STFUNC(StateBootstrap) { Y_VERIFY(ev->GetTypeRewrite() == TEvents::TSystem::Bootstrap, "Unexpected bootstrap message"); using T = decltype(&TDerived::Bootstrap); TDerived& self = static_cast<TDerived&>(*this); @@ -27,11 +27,11 @@ namespace NActors { self.Bootstrap(ev->Sender); } else { static_assert(dependent_false<TDerived>::value, "No correct Bootstrap() signature"); - } + } } - TActorBootstrapped() - : TActor<TDerived>(&TDerived::StateBootstrap) + TActorBootstrapped() + : TActor<TDerived>(&TDerived::StateBootstrap) {} - }; + }; } diff --git a/library/cpp/actors/core/actor_coroutine.cpp b/library/cpp/actors/core/actor_coroutine.cpp index 538cdac971..0ab4d2b24d 100644 --- a/library/cpp/actors/core/actor_coroutine.cpp +++ b/library/cpp/actors/core/actor_coroutine.cpp @@ -5,17 +5,17 @@ #include <util/system/type_name.h> namespace NActors { - static constexpr size_t StackOverflowGap = 4096; - static char GoodStack[StackOverflowGap]; - - static struct TInitGoodStack { - TInitGoodStack() { - // fill stack with some pseudo-random pattern - for (size_t k = 0; k < StackOverflowGap; ++k) { - GoodStack[k] = k + k * 91; - } + static constexpr size_t StackOverflowGap = 4096; + static char GoodStack[StackOverflowGap]; + + static struct TInitGoodStack { + TInitGoodStack() { + // fill stack with some pseudo-random pattern + for (size_t k = 0; k < StackOverflowGap; ++k) { + GoodStack[k] = k + k * 91; + } } - } initGoodStack; + } initGoodStack; TActorCoroImpl::TActorCoroImpl(size_t stackSize, bool allowUnhandledPoisonPill, bool allowUnhandledDtor) : Stack(stackSize) @@ -25,15 +25,15 @@ namespace NActors { , FiberContext(FiberClosure) { #ifndef NDEBUG - char* p; + char* p; #if STACK_GROW_DOWN - p = Stack.Begin(); + p = Stack.Begin(); #else - p = Stack.End() - StackOverflowGap; + p = Stack.End() - StackOverflowGap; #endif - memcpy(p, GoodStack, StackOverflowGap); + memcpy(p, GoodStack, StackOverflowGap); #endif - } + } TActorCoroImpl::~TActorCoroImpl() { if (!Finished && !NSan::TSanIsOn()) { // only resume when we have bootstrapped and Run() was entered and not yet finished; in other case simply terminate @@ -53,11 +53,11 @@ namespace NActors { 0, cookie)); } - // ensure we have no unprocessed event and return back to actor system to receive one - Y_VERIFY(!PendingEvent); - ReturnToActorSystem(); + // ensure we have no unprocessed event and return back to actor system to receive one + Y_VERIFY(!PendingEvent); + ReturnToActorSystem(); - // obtain pending event and ensure we've got one + // obtain pending event and ensure we've got one while (THolder<IEventHandle> event = std::exchange(PendingEvent, {})) { if (event->GetTypeRewrite() != TEvents::TSystem::CoroTimeout) { // special handling for poison pill -- we throw exception @@ -72,17 +72,17 @@ namespace NActors { } else { ReturnToActorSystem(); // drop this event and wait for the next one } - } + } Y_FAIL("no pending event"); } const TActorContext& TActorCoroImpl::GetActorContext() const { Y_VERIFY(ActorContext); return *ActorContext; - } + } bool TActorCoroImpl::ProcessEvent(THolder<IEventHandle> ev) { - Y_VERIFY(!PendingEvent); + Y_VERIFY(!PendingEvent); if (!SelfActorId) { // process bootstrap message, extract actor ids Y_VERIFY(ev->GetTypeRewrite() == TEvents::TSystem::Bootstrap); SelfActorId = ev->Recipient; @@ -104,40 +104,40 @@ namespace NActors { ActorContext = nullptr; return Finished; - } + } void TActorCoroImpl::Resume() { - // save caller context for a later return - Y_VERIFY(!ActorSystemContext); + // save caller context for a later return + Y_VERIFY(!ActorSystemContext); TExceptionSafeContext actorSystemContext; - ActorSystemContext = &actorSystemContext; + ActorSystemContext = &actorSystemContext; - // go to actor coroutine + // go to actor coroutine BeforeResume(); ActorSystemContext->SwitchTo(&FiberContext); // check for stack overflow #ifndef NDEBUG - const char* p; + const char* p; #if STACK_GROW_DOWN - p = Stack.Begin(); + p = Stack.Begin(); #else - p = Stack.End() - StackOverflowGap; + p = Stack.End() - StackOverflowGap; #endif - Y_VERIFY_DEBUG(memcmp(p, GoodStack, StackOverflowGap) == 0); + Y_VERIFY_DEBUG(memcmp(p, GoodStack, StackOverflowGap) == 0); #endif } void TActorCoroImpl::DoRun() { - try { + try { if (ActorContext) { // ActorContext may be nullptr here if the destructor was invoked before bootstrapping Y_VERIFY(!PendingEvent); Run(); } - } catch (const TPoisonPillException& /*ex*/) { - if (!AllowUnhandledPoisonPill) { - Y_FAIL("unhandled TPoisonPillException"); - } + } catch (const TPoisonPillException& /*ex*/) { + if (!AllowUnhandledPoisonPill) { + Y_FAIL("unhandled TPoisonPillException"); + } } catch (const TDtorException& /*ex*/) { if (!AllowUnhandledDtor) { Y_FAIL("unhandled TDtorException"); @@ -147,19 +147,19 @@ namespace NActors { } catch (...) { Y_FAIL("unhandled exception of type not derived from std::exception"); } - Finished = true; - ReturnToActorSystem(); + Finished = true; + ReturnToActorSystem(); } void TActorCoroImpl::ReturnToActorSystem() { TExceptionSafeContext* returnContext = std::exchange(ActorSystemContext, nullptr); - Y_VERIFY(returnContext); - FiberContext.SwitchTo(returnContext); + Y_VERIFY(returnContext); + FiberContext.SwitchTo(returnContext); if (!PendingEvent) { // we have returned from the actor system and it kindly asks us to terminate the coroutine as it is being // stopped throw TDtorException(); } - } + } } diff --git a/library/cpp/actors/core/actor_coroutine.h b/library/cpp/actors/core/actor_coroutine.h index 2f61e5db8b..6bcb768eaf 100644 --- a/library/cpp/actors/core/actor_coroutine.h +++ b/library/cpp/actors/core/actor_coroutine.h @@ -12,13 +12,13 @@ namespace NActors { class TActorCoro; class TActorCoroImpl : public ITrampoLine { - TMappedAllocation Stack; - bool AllowUnhandledPoisonPill; + TMappedAllocation Stack; + bool AllowUnhandledPoisonPill; bool AllowUnhandledDtor; - TContClosure FiberClosure; + TContClosure FiberClosure; TExceptionSafeContext FiberContext; TExceptionSafeContext* ActorSystemContext = nullptr; - THolder<IEventHandle> PendingEvent; + THolder<IEventHandle> PendingEvent; bool Finished = false; ui64 WaitCookie = 0; TActorContext *ActorContext = nullptr; @@ -27,83 +27,83 @@ namespace NActors { TActorIdentity SelfActorId = TActorIdentity(TActorId()); TActorId ParentActorId; - private: - template <typename TFirstEvent, typename... TOtherEvents> - struct TIsOneOf: public TIsOneOf<TOtherEvents...> { - bool operator()(IEventHandle& ev) const { - return ev.GetTypeRewrite() == TFirstEvent::EventType || TIsOneOf<TOtherEvents...>()(ev); - } - }; - - template <typename TSingleEvent> - struct TIsOneOf<TSingleEvent> { - bool operator()(IEventHandle& ev) const { - return ev.GetTypeRewrite() == TSingleEvent::EventType; - } - }; + private: + template <typename TFirstEvent, typename... TOtherEvents> + struct TIsOneOf: public TIsOneOf<TOtherEvents...> { + bool operator()(IEventHandle& ev) const { + return ev.GetTypeRewrite() == TFirstEvent::EventType || TIsOneOf<TOtherEvents...>()(ev); + } + }; + + template <typename TSingleEvent> + struct TIsOneOf<TSingleEvent> { + bool operator()(IEventHandle& ev) const { + return ev.GetTypeRewrite() == TSingleEvent::EventType; + } + }; struct TEvCoroTimeout : TEventLocal<TEvCoroTimeout, TEvents::TSystem::CoroTimeout> {}; protected: struct TPoisonPillException : yexception {}; struct TDtorException : yexception {}; - - public: + + public: TActorCoroImpl(size_t stackSize, bool allowUnhandledPoisonPill = false, bool allowUnhandledDtor = false); // specify stackSize explicitly for each actor; don't forget about overflow control gap virtual ~TActorCoroImpl(); - virtual void Run() = 0; + virtual void Run() = 0; virtual void BeforeResume() {} - // Handle all events that are not expected in wait loops. - virtual void ProcessUnexpectedEvent(TAutoPtr<IEventHandle> ev) = 0; + // Handle all events that are not expected in wait loops. + virtual void ProcessUnexpectedEvent(TAutoPtr<IEventHandle> ev) = 0; - // Release execution ownership and wait for some event to arrive. When PoisonPill event is received, then - // TPoisonPillException is thrown. + // Release execution ownership and wait for some event to arrive. When PoisonPill event is received, then + // TPoisonPillException is thrown. THolder<IEventHandle> WaitForEvent(TInstant deadline = TInstant::Max()); - // Wait for specific event set by filter functor. Function returns first event that matches filter. On any other - // kind of event ProcessUnexpectedEvent() is called. - // - // Example: WaitForSpecificEvent([](IEventHandle& ev) { return ev.Cookie == 42; }); - template <typename TFunc> + // Wait for specific event set by filter functor. Function returns first event that matches filter. On any other + // kind of event ProcessUnexpectedEvent() is called. + // + // Example: WaitForSpecificEvent([](IEventHandle& ev) { return ev.Cookie == 42; }); + template <typename TFunc> THolder<IEventHandle> WaitForSpecificEvent(TFunc&& filter, TInstant deadline = TInstant::Max()) { - for (;;) { + for (;;) { if (THolder<IEventHandle> event = WaitForEvent(deadline); !event) { return nullptr; } else if (filter(*event)) { - return event; - } else { - ProcessUnexpectedEvent(event); - } + return event; + } else { + ProcessUnexpectedEvent(event); + } } } - // Wait for specific event or set of events. Function returns first event that matches enlisted type. On any other - // kind of event ProcessUnexpectedEvent() is called. - // - // Example: WaitForSpecificEvent<TEvReadResult, TEvFinished>(); - template <typename TFirstEvent, typename TSecondEvent, typename... TOtherEvents> + // Wait for specific event or set of events. Function returns first event that matches enlisted type. On any other + // kind of event ProcessUnexpectedEvent() is called. + // + // Example: WaitForSpecificEvent<TEvReadResult, TEvFinished>(); + template <typename TFirstEvent, typename TSecondEvent, typename... TOtherEvents> THolder<IEventHandle> WaitForSpecificEvent(TInstant deadline = TInstant::Max()) { - TIsOneOf<TFirstEvent, TSecondEvent, TOtherEvents...> filter; + TIsOneOf<TFirstEvent, TSecondEvent, TOtherEvents...> filter; return WaitForSpecificEvent(filter, deadline); - } + } - // Wait for single specific event. - template <typename TEventType> + // Wait for single specific event. + template <typename TEventType> THolder<typename TEventType::THandle> WaitForSpecificEvent(TInstant deadline = TInstant::Max()) { - auto filter = [](IEventHandle& ev) { - return ev.GetTypeRewrite() == TEventType::EventType; - }; + auto filter = [](IEventHandle& ev) { + return ev.GetTypeRewrite() == TEventType::EventType; + }; THolder<IEventHandle> event = WaitForSpecificEvent(filter, deadline); return THolder<typename TEventType::THandle>(static_cast<typename TEventType::THandle*>(event ? event.Release() : nullptr)); - } + } protected: // Actor System compatibility section - const TActorContext& GetActorContext() const; + const TActorContext& GetActorContext() const; TActorSystem *GetActorSystem() const { return GetActorContext().ExecutorThread.ActorSystem; } TInstant Now() const { return GetActorContext().Now(); } @@ -138,17 +138,17 @@ namespace NActors { return GetActorContext().RegisterWithSameMailbox(actor); } - private: + private: friend class TActorCoro; bool ProcessEvent(THolder<IEventHandle> ev); private: - /* Resume() function goes to actor coroutine context and continues (or starts) to execute it until actor finishes + /* Resume() function goes to actor coroutine context and continues (or starts) to execute it until actor finishes * his job or it is blocked on WaitForEvent. Then the function returns. */ void Resume(); - void ReturnToActorSystem(); + void ReturnToActorSystem(); void DoRun() override final; - }; + }; class TActorCoro : public IActor { THolder<TActorCoroImpl> Impl; diff --git a/library/cpp/actors/core/actor_coroutine_ut.cpp b/library/cpp/actors/core/actor_coroutine_ut.cpp index 715d44be4f..951512b877 100644 --- a/library/cpp/actors/core/actor_coroutine_ut.cpp +++ b/library/cpp/actors/core/actor_coroutine_ut.cpp @@ -19,16 +19,16 @@ Y_UNIT_TEST_SUITE(ActorCoro) { Enough }; - struct TEvRequest: public TEventLocal<TEvRequest, Request> { + struct TEvRequest: public TEventLocal<TEvRequest, Request> { }; - struct TEvResponse: public TEventLocal<TEvResponse, Response> { + struct TEvResponse: public TEventLocal<TEvResponse, Response> { }; - struct TEvEnough: public TEventLocal<TEvEnough, Enough> { + struct TEvEnough: public TEventLocal<TEvEnough, Enough> { }; - class TBasicResponderActor: public TActorBootstrapped<TBasicResponderActor> { + class TBasicResponderActor: public TActorBootstrapped<TBasicResponderActor> { TDeque<TActorId> RespondTo; public: @@ -73,8 +73,8 @@ Y_UNIT_TEST_SUITE(ActorCoro) { , DoneEvent(doneEvent) , ItemsProcessed(itemsProcessed) , Finish(false) - { - } + { + } void Run() override { TActorId child = GetActorContext().Register(new TBasicResponderActor); @@ -101,7 +101,7 @@ Y_UNIT_TEST_SUITE(ActorCoro) { } }; - void Check(THolder<IEventBase> && message) { + void Check(THolder<IEventBase> && message) { THolder<TActorSystemSetup> setup = MakeHolder<TActorSystemSetup>(); setup->NodeId = 0; setup->ExecutorsCount = 1; diff --git a/library/cpp/actors/core/actorid.cpp b/library/cpp/actors/core/actorid.cpp index 6f2a816fc1..ccda035eac 100644 --- a/library/cpp/actors/core/actorid.cpp +++ b/library/cpp/actors/core/actorid.cpp @@ -1,34 +1,34 @@ -#include "actorid.h" -#include <util/string/builder.h> +#include "actorid.h" +#include <util/string/builder.h> #include <util/string/cast.h> - -namespace NActors { + +namespace NActors { void TActorId::Out(IOutputStream& o) const { - o << "[" << NodeId() << ":" << LocalId() << ":" << Hint() << "]"; - } - + o << "[" << NodeId() << ":" << LocalId() << ":" << Hint() << "]"; + } + TString TActorId::ToString() const { - TString x; - TStringOutput o(x); - Out(o); - return x; - } - + TString x; + TStringOutput o(x); + Out(o); + return x; + } + bool TActorId::Parse(const char* buf, ui32 sz) { - if (sz < 4 || buf[0] != '[' || buf[sz - 1] != ']') - return false; - - size_t semicolons[2]; - TStringBuf str(buf, sz); - semicolons[0] = str.find(':', 1); - if (semicolons[0] == TStringBuf::npos) - return false; - semicolons[1] = str.find(':', semicolons[0] + 1); - if (semicolons[1] == TStringBuf::npos) - return false; + if (sz < 4 || buf[0] != '[' || buf[sz - 1] != ']') + return false; + + size_t semicolons[2]; + TStringBuf str(buf, sz); + semicolons[0] = str.find(':', 1); + if (semicolons[0] == TStringBuf::npos) + return false; + semicolons[1] = str.find(':', semicolons[0] + 1); + if (semicolons[1] == TStringBuf::npos) + return false; - bool success = TryFromString(buf + 1, semicolons[0] - 1, Raw.N.NodeId) && TryFromString(buf + semicolons[0] + 1, semicolons[1] - semicolons[0] - 1, Raw.N.LocalId) && TryFromString(buf + semicolons[1] + 1, sz - semicolons[1] - 2, Raw.N.Hint); + bool success = TryFromString(buf + 1, semicolons[0] - 1, Raw.N.NodeId) && TryFromString(buf + semicolons[0] + 1, semicolons[1] - semicolons[0] - 1, Raw.N.LocalId) && TryFromString(buf + semicolons[1] + 1, sz - semicolons[1] - 2, Raw.N.Hint); - return success; - } -} + return success; + } +} diff --git a/library/cpp/actors/core/actorid.h b/library/cpp/actors/core/actorid.h index 7d3ac61808..d972b1a0ff 100644 --- a/library/cpp/actors/core/actorid.h +++ b/library/cpp/actors/core/actorid.h @@ -1,16 +1,16 @@ -#pragma once - -#include "defs.h" +#pragma once + +#include "defs.h" #include <util/stream/output.h> // for IOutputStream #include <util/generic/hash.h> - -namespace NActors { - // used as global uniq address of actor - // also could be used to transport service id (12 byte strings placed in hint-localid) - // highest 1 bit of node - mark of service id - // next 11 bits of node-id - pool id - // next 20 bits - node id itself - + +namespace NActors { + // used as global uniq address of actor + // also could be used to transport service id (12 byte strings placed in hint-localid) + // highest 1 bit of node - mark of service id + // next 11 bits of node-id - pool id + // next 20 bits - node id itself + struct TActorId { static constexpr ui32 MaxServiceIDLength = 12; static constexpr ui32 MaxPoolID = 0x000007FF; @@ -19,174 +19,174 @@ namespace NActors { static constexpr ui32 PoolIndexMask = MaxPoolID << PoolIndexShift; static constexpr ui32 ServiceMask = 0x80000000; static constexpr ui32 NodeIdMask = MaxNodeId; - - private: - union { - struct { - ui64 LocalId; - ui32 Hint; - ui32 NodeId; - } N; - - struct { - ui64 X1; - ui64 X2; - } X; - - ui8 Buf[16]; - } Raw; - - public: + + private: + union { + struct { + ui64 LocalId; + ui32 Hint; + ui32 NodeId; + } N; + + struct { + ui64 X1; + ui64 X2; + } X; + + ui8 Buf[16]; + } Raw; + + public: TActorId() noexcept { - Raw.X.X1 = 0; - Raw.X.X2 = 0; - } - + Raw.X.X1 = 0; + Raw.X.X2 = 0; + } + explicit TActorId(ui32 nodeId, ui32 poolId, ui64 localId, ui32 hint) noexcept { - Y_VERIFY_DEBUG(poolId <= MaxPoolID); - Raw.N.LocalId = localId; - Raw.N.Hint = hint; - Raw.N.NodeId = nodeId | (poolId << PoolIndexShift); - } - + Y_VERIFY_DEBUG(poolId <= MaxPoolID); + Raw.N.LocalId = localId; + Raw.N.Hint = hint; + Raw.N.NodeId = nodeId | (poolId << PoolIndexShift); + } + explicit TActorId(ui32 nodeId, const TStringBuf& x) noexcept { - Y_VERIFY(x.size() <= MaxServiceIDLength, "service id is too long"); - Raw.N.LocalId = 0; - Raw.N.Hint = 0; - Raw.N.NodeId = nodeId | ServiceMask; - memcpy(Raw.Buf, x.data(), x.size()); - } - + Y_VERIFY(x.size() <= MaxServiceIDLength, "service id is too long"); + Raw.N.LocalId = 0; + Raw.N.Hint = 0; + Raw.N.NodeId = nodeId | ServiceMask; + memcpy(Raw.Buf, x.data(), x.size()); + } + explicit TActorId(ui64 x1, ui64 x2) noexcept { - Raw.X.X1 = x1; - Raw.X.X2 = x2; - } - - explicit operator bool() const noexcept { - return Raw.X.X1 != 0 || Raw.X.X2 != 0; - } - + Raw.X.X1 = x1; + Raw.X.X2 = x2; + } + + explicit operator bool() const noexcept { + return Raw.X.X1 != 0 || Raw.X.X2 != 0; + } + ui64 LocalId() const noexcept { - return Raw.N.LocalId; - } - + return Raw.N.LocalId; + } + ui32 Hint() const noexcept { - return Raw.N.Hint; - } - + return Raw.N.Hint; + } + ui32 NodeId() const noexcept { - return Raw.N.NodeId & NodeIdMask; - } - + return Raw.N.NodeId & NodeIdMask; + } + bool IsService() const noexcept { - return (Raw.N.NodeId & ServiceMask); - } - + return (Raw.N.NodeId & ServiceMask); + } + TStringBuf ServiceId() const noexcept { - Y_VERIFY_DEBUG(IsService()); - return TStringBuf((const char*)Raw.Buf, MaxServiceIDLength); - } - + Y_VERIFY_DEBUG(IsService()); + return TStringBuf((const char*)Raw.Buf, MaxServiceIDLength); + } + static ui32 PoolIndex(ui32 nodeid) noexcept { - return ((nodeid & PoolIndexMask) >> PoolIndexShift); - } - + return ((nodeid & PoolIndexMask) >> PoolIndexShift); + } + ui32 PoolID() const noexcept { - return PoolIndex(Raw.N.NodeId); - } - + return PoolIndex(Raw.N.NodeId); + } + ui64 RawX1() const noexcept { - return Raw.X.X1; - } - + return Raw.X.X1; + } + ui64 RawX2() const noexcept { - return Raw.X.X2; - } - + return Raw.X.X2; + } + bool operator<(const TActorId& x) const noexcept { - const ui64 s1 = Raw.X.X1; - const ui64 s2 = Raw.X.X2; - const ui64 x1 = x.Raw.X.X1; - const ui64 x2 = x.Raw.X.X2; - - return (s1 != x1) ? (s1 < x1) : (s2 < x2); - } - + const ui64 s1 = Raw.X.X1; + const ui64 s2 = Raw.X.X2; + const ui64 x1 = x.Raw.X.X1; + const ui64 x2 = x.Raw.X.X2; + + return (s1 != x1) ? (s1 < x1) : (s2 < x2); + } + bool operator!=(const TActorId& x) const noexcept { - return Raw.X.X1 != x.Raw.X.X1 || Raw.X.X2 != x.Raw.X.X2; - } - + return Raw.X.X1 != x.Raw.X.X1 || Raw.X.X2 != x.Raw.X.X2; + } + bool operator==(const TActorId& x) const noexcept { - return !(x != *this); - } - - ui64 Hash() const noexcept { - const ui32* x = (const ui32*)Raw.Buf; - - const ui64 x1 = x[0] * 0x001DFF3D8DC48F5Dull; - const ui64 x2 = x[1] * 0x179CA10C9242235Dull; - const ui64 x3 = x[2] * 0x0F530CAD458B0FB1ull; - const ui64 x4 = x[3] * 0xB5026F5AA96619E9ull; - - const ui64 z1 = x1 + x2; - const ui64 z2 = x3 + x4; - - const ui64 sum = 0x5851F42D4C957F2D + z1 + z2; - - return (sum >> 32) | (sum << 32); - } - - ui32 Hash32() const noexcept { - const ui32* x = (const ui32*)Raw.Buf; - - const ui64 x1 = x[0] * 0x001DFF3D8DC48F5Dull; - const ui64 x2 = x[1] * 0x179CA10C9242235Dull; - const ui64 x3 = x[2] * 0x0F530CAD458B0FB1ull; - const ui64 x4 = x[3] * 0xB5026F5AA96619E9ull; - - const ui64 z1 = x1 + x2; - const ui64 z2 = x3 + x4; - - const ui64 sum = 0x5851F42D4C957F2D + z1 + z2; - - return sum >> 32; - } - - struct THash { + return !(x != *this); + } + + ui64 Hash() const noexcept { + const ui32* x = (const ui32*)Raw.Buf; + + const ui64 x1 = x[0] * 0x001DFF3D8DC48F5Dull; + const ui64 x2 = x[1] * 0x179CA10C9242235Dull; + const ui64 x3 = x[2] * 0x0F530CAD458B0FB1ull; + const ui64 x4 = x[3] * 0xB5026F5AA96619E9ull; + + const ui64 z1 = x1 + x2; + const ui64 z2 = x3 + x4; + + const ui64 sum = 0x5851F42D4C957F2D + z1 + z2; + + return (sum >> 32) | (sum << 32); + } + + ui32 Hash32() const noexcept { + const ui32* x = (const ui32*)Raw.Buf; + + const ui64 x1 = x[0] * 0x001DFF3D8DC48F5Dull; + const ui64 x2 = x[1] * 0x179CA10C9242235Dull; + const ui64 x3 = x[2] * 0x0F530CAD458B0FB1ull; + const ui64 x4 = x[3] * 0xB5026F5AA96619E9ull; + + const ui64 z1 = x1 + x2; + const ui64 z2 = x3 + x4; + + const ui64 sum = 0x5851F42D4C957F2D + z1 + z2; + + return sum >> 32; + } + + struct THash { ui64 operator()(const TActorId& actorId) const noexcept { return actorId.Hash(); - } - }; - - struct THash32 { + } + }; + + struct THash32 { ui64 operator()(const TActorId& actorId) const noexcept { return actorId.Hash(); - } - }; - - struct TOrderedCmp { + } + }; + + struct TOrderedCmp { bool operator()(const TActorId &left, const TActorId &right) const noexcept { - Y_VERIFY_DEBUG(!left.IsService() && !right.IsService(), "ordered compare works for plain actorids only"); - const ui32 n1 = left.NodeId(); - const ui32 n2 = right.NodeId(); - - return (n1 != n2) ? (n1 < n2) : left.LocalId() < right.LocalId(); - } - }; - - TString ToString() const; + Y_VERIFY_DEBUG(!left.IsService() && !right.IsService(), "ordered compare works for plain actorids only"); + const ui32 n1 = left.NodeId(); + const ui32 n2 = right.NodeId(); + + return (n1 != n2) ? (n1 < n2) : left.LocalId() < right.LocalId(); + } + }; + + TString ToString() const; void Out(IOutputStream& o) const; - bool Parse(const char* buf, ui32 sz); - }; - + bool Parse(const char* buf, ui32 sz); + }; + static_assert(sizeof(TActorId) == 16, "expect sizeof(TActorId) == 16"); static_assert(MaxPools < TActorId::MaxPoolID); // current implementation of united pool has limit MaxPools on pool id -} - -template <> +} + +template <> inline void Out<NActors::TActorId>(IOutputStream& o, const NActors::TActorId& x) { - return x.Out(o); -} + return x.Out(o); +} template <> struct THash<NActors::TActorId> { diff --git a/library/cpp/actors/core/actorsystem.cpp b/library/cpp/actors/core/actorsystem.cpp index 3e2060b806..c58698a206 100644 --- a/library/cpp/actors/core/actorsystem.cpp +++ b/library/cpp/actors/core/actorsystem.cpp @@ -1,85 +1,85 @@ -#include "defs.h" -#include "actorsystem.h" +#include "defs.h" +#include "actorsystem.h" #include "callstack.h" #include "cpu_manager.h" -#include "mailbox.h" -#include "events.h" -#include "interconnect.h" -#include "servicemap.h" -#include "scheduler_queue.h" +#include "mailbox.h" +#include "events.h" +#include "interconnect.h" +#include "servicemap.h" +#include "scheduler_queue.h" #include "scheduler_actor.h" #include "log.h" #include "probes.h" #include "ask.h" #include <library/cpp/actors/util/affinity.h> #include <library/cpp/actors/util/datetime.h> -#include <util/generic/hash.h> -#include <util/system/rwlock.h> -#include <util/random/random.h> - -namespace NActors { - LWTRACE_USING(ACTORLIB_PROVIDER); - - struct TActorSystem::TServiceMap : TNonCopyable { +#include <util/generic/hash.h> +#include <util/system/rwlock.h> +#include <util/random/random.h> + +namespace NActors { + LWTRACE_USING(ACTORLIB_PROVIDER); + + struct TActorSystem::TServiceMap : TNonCopyable { NActors::TServiceMap<TActorId, TActorId, TActorId::THash> LocalMap; - TTicketLock Lock; - + TTicketLock Lock; + TActorId RegisterLocalService(const TActorId& serviceId, const TActorId& actorId) { - TTicketLock::TGuard guard(&Lock); + TTicketLock::TGuard guard(&Lock); const TActorId old = LocalMap.Update(serviceId, actorId); - return old; - } - + return old; + } + TActorId LookupLocal(const TActorId& x) { - return LocalMap.Find(x); - } - }; - - TActorSystem::TActorSystem(THolder<TActorSystemSetup>& setup, void* appData, - TIntrusivePtr<NLog::TSettings> loggerSettings) - : NodeId(setup->NodeId) + return LocalMap.Find(x); + } + }; + + TActorSystem::TActorSystem(THolder<TActorSystemSetup>& setup, void* appData, + TIntrusivePtr<NLog::TSettings> loggerSettings) + : NodeId(setup->NodeId) , CpuManager(new TCpuManager(setup)) , ExecutorPoolCount(CpuManager->GetExecutorsCount()) - , Scheduler(setup->Scheduler) - , InterconnectCount((ui32)setup->Interconnect.ProxyActors.size()) - , CurrentTimestamp(0) + , Scheduler(setup->Scheduler) + , InterconnectCount((ui32)setup->Interconnect.ProxyActors.size()) + , CurrentTimestamp(0) , CurrentMonotonic(0) - , CurrentIDCounter(RandomNumber<ui64>()) - , SystemSetup(setup.Release()) - , DefSelfID(NodeId, "actorsystem") - , AppData0(appData) - , LoggerSettings0(loggerSettings) - , StartExecuted(false) - , StopExecuted(false) - , CleanupExecuted(false) - { - ServiceMap.Reset(new TServiceMap()); - } - - TActorSystem::~TActorSystem() { - Cleanup(); - } - - bool TActorSystem::Send(TAutoPtr<IEventHandle> ev) const { - if (Y_UNLIKELY(!ev)) - return false; - + , CurrentIDCounter(RandomNumber<ui64>()) + , SystemSetup(setup.Release()) + , DefSelfID(NodeId, "actorsystem") + , AppData0(appData) + , LoggerSettings0(loggerSettings) + , StartExecuted(false) + , StopExecuted(false) + , CleanupExecuted(false) + { + ServiceMap.Reset(new TServiceMap()); + } + + TActorSystem::~TActorSystem() { + Cleanup(); + } + + bool TActorSystem::Send(TAutoPtr<IEventHandle> ev) const { + if (Y_UNLIKELY(!ev)) + return false; + #ifdef USE_ACTOR_CALLSTACK - ev->Callstack.TraceIfEmpty(); + ev->Callstack.TraceIfEmpty(); #endif TActorId recipient = ev->GetRecipientRewrite(); const ui32 recpNodeId = recipient.NodeId(); - - if (recpNodeId != NodeId && recpNodeId != 0) { - // if recipient is not local one - rewrite with forward instruction - Y_VERIFY_DEBUG(!ev->HasEvent() || ev->GetBase()->IsSerializable()); + + if (recpNodeId != NodeId && recpNodeId != 0) { + // if recipient is not local one - rewrite with forward instruction + Y_VERIFY_DEBUG(!ev->HasEvent() || ev->GetBase()->IsSerializable()); Y_VERIFY(ev->Recipient == recipient, "Event rewrite from %s to %s would be lost via interconnect", ev->Recipient.ToString().c_str(), recipient.ToString().c_str()); - recipient = InterconnectProxy(recpNodeId); - ev->Rewrite(TEvInterconnect::EvForward, recipient); + recipient = InterconnectProxy(recpNodeId); + ev->Rewrite(TEvInterconnect::EvForward, recipient); } if (recipient.IsService()) { TActorId target = ServiceMap->LookupLocal(recipient); @@ -100,24 +100,24 @@ namespace NActors { } recipient = target; ev->Rewrite(ev->GetTypeRewrite(), recipient); - } - + } + Y_VERIFY_DEBUG(recipient == ev->GetRecipientRewrite()); - const ui32 recpPool = recipient.PoolID(); - if (recipient && recpPool < ExecutorPoolCount) { + const ui32 recpPool = recipient.PoolID(); + if (recipient && recpPool < ExecutorPoolCount) { if (CpuManager->GetExecutorPool(recpPool)->Send(ev)) { - return true; + return true; } } - - Send(ev->ForwardOnNondelivery(TEvents::TEvUndelivered::ReasonActorUnknown)); - return false; - } - + + Send(ev->ForwardOnNondelivery(TEvents::TEvUndelivered::ReasonActorUnknown)); + return false; + } + bool TActorSystem::Send(const TActorId& recipient, IEventBase* ev, ui32 flags) const { - return this->Send(new IEventHandle(recipient, DefSelfID, ev, flags)); - } - + return this->Send(new IEventHandle(recipient, DefSelfID, ev, flags)); + } + void TActorSystem::Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) const { Schedule(deadline - Timestamp(), ev, cookie); } @@ -136,15 +136,15 @@ namespace NActors { TTicketLock::TGuard guard(&ScheduleLock); ScheduleQueue->Writer.Push(deadline.MicroSeconds(), ev.Release(), cookie); - } - + } + TActorId TActorSystem::Register(IActor* actor, TMailboxType::EType mailboxType, ui32 executorPool, ui64 revolvingCounter, const TActorId& parentId) { - Y_VERIFY(executorPool < ExecutorPoolCount, "executorPool# %" PRIu32 ", ExecutorPoolCount# %" PRIu32, - (ui32)executorPool, (ui32)ExecutorPoolCount); + Y_VERIFY(executorPool < ExecutorPoolCount, "executorPool# %" PRIu32 ", ExecutorPoolCount# %" PRIu32, + (ui32)executorPool, (ui32)ExecutorPoolCount); return CpuManager->GetExecutorPool(executorPool)->Register(actor, mailboxType, revolvingCounter, parentId); - } - + } + NThreading::TFuture<THolder<IEventBase>> TActorSystem::AskGeneric(TMaybe<ui32> expectedEventType, TActorId recipient, THolder<IEventBase> event, TDuration timeout) { @@ -154,34 +154,34 @@ namespace NActors { } ui64 TActorSystem::AllocateIDSpace(ui64 count) { - Y_VERIFY_DEBUG(count < Max<ui32>() / 65536); - - static_assert(sizeof(TAtomic) == sizeof(ui64), "expect sizeof(TAtomic) == sizeof(ui64)"); - - // get high 32 bits as seconds from epoch - // it could wrap every century, but we don't expect any actor-reference to live this long so such wrap will do no harm + Y_VERIFY_DEBUG(count < Max<ui32>() / 65536); + + static_assert(sizeof(TAtomic) == sizeof(ui64), "expect sizeof(TAtomic) == sizeof(ui64)"); + + // get high 32 bits as seconds from epoch + // it could wrap every century, but we don't expect any actor-reference to live this long so such wrap will do no harm const ui64 timeFromEpoch = TInstant::MicroSeconds(RelaxedLoad(&CurrentTimestamp)).Seconds(); - - // get low 32 bits as counter value - ui32 lowPartEnd = (ui32)(AtomicAdd(CurrentIDCounter, count)); - while (lowPartEnd < count) // if our request crosses 32bit boundary - retry - lowPartEnd = (ui32)(AtomicAdd(CurrentIDCounter, count)); - - const ui64 lowPart = lowPartEnd - count; - const ui64 ret = (timeFromEpoch << 32) | lowPart; - - return ret; - } - + + // get low 32 bits as counter value + ui32 lowPartEnd = (ui32)(AtomicAdd(CurrentIDCounter, count)); + while (lowPartEnd < count) // if our request crosses 32bit boundary - retry + lowPartEnd = (ui32)(AtomicAdd(CurrentIDCounter, count)); + + const ui64 lowPart = lowPartEnd - count; + const ui64 ret = (timeFromEpoch << 32) | lowPart; + + return ret; + } + TActorId TActorSystem::InterconnectProxy(ui32 destinationNode) const { - if (destinationNode < InterconnectCount) - return Interconnect[destinationNode]; + if (destinationNode < InterconnectCount) + return Interconnect[destinationNode]; else if (destinationNode != NodeId) return MakeInterconnectProxyId(destinationNode); - else + else return TActorId(); - } - + } + ui32 TActorSystem::BroadcastToProxies(const std::function<IEventHandle*(const TActorId&)>& eventFabric) { // TODO: get rid of this method for (ui32 i = 0; i < InterconnectCount; ++i) { @@ -191,87 +191,87 @@ namespace NActors { } TActorId TActorSystem::LookupLocalService(const TActorId& x) const { - return ServiceMap->LookupLocal(x); - } - + return ServiceMap->LookupLocal(x); + } + TActorId TActorSystem::RegisterLocalService(const TActorId& serviceId, const TActorId& actorId) { // TODO: notify old actor about demotion return ServiceMap->RegisterLocalService(serviceId, actorId); - } - + } + void TActorSystem::GetPoolStats(ui32 poolId, TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const { CpuManager->GetPoolStats(poolId, poolStats, statsCopy); } - void TActorSystem::Start() { - Y_VERIFY(StartExecuted == false); - StartExecuted = true; - + void TActorSystem::Start() { + Y_VERIFY(StartExecuted == false); + StartExecuted = true; + ScheduleQueue.Reset(new NSchedulerQueue::TQueueType()); TVector<NSchedulerQueue::TReader*> scheduleReaders; - scheduleReaders.push_back(&ScheduleQueue->Reader); + scheduleReaders.push_back(&ScheduleQueue->Reader); CpuManager->PrepareStart(scheduleReaders, this); Scheduler->Prepare(this, &CurrentTimestamp, &CurrentMonotonic); Scheduler->PrepareSchedules(&scheduleReaders.front(), (ui32)scheduleReaders.size()); - - // setup interconnect proxies - { - const TInterconnectSetup& setup = SystemSetup->Interconnect; + + // setup interconnect proxies + { + const TInterconnectSetup& setup = SystemSetup->Interconnect; Interconnect.Reset(new TActorId[InterconnectCount + 1]); - for (ui32 i = 0, e = InterconnectCount; i != e; ++i) { - const TActorSetupCmd& x = setup.ProxyActors[i]; - if (x.Actor) { - Interconnect[i] = Register(x.Actor, x.MailboxType, x.PoolId, i); - Y_VERIFY(!!Interconnect[i]); - } - } + for (ui32 i = 0, e = InterconnectCount; i != e; ++i) { + const TActorSetupCmd& x = setup.ProxyActors[i]; + if (x.Actor) { + Interconnect[i] = Register(x.Actor, x.MailboxType, x.PoolId, i); + Y_VERIFY(!!Interconnect[i]); + } + } ProxyWrapperFactory = std::move(SystemSetup->Interconnect.ProxyWrapperFactory); - } - - // setup local services - { - for (ui32 i = 0, e = (ui32)SystemSetup->LocalServices.size(); i != e; ++i) { + } + + // setup local services + { + for (ui32 i = 0, e = (ui32)SystemSetup->LocalServices.size(); i != e; ++i) { const std::pair<TActorId, TActorSetupCmd>& x = SystemSetup->LocalServices[i]; const TActorId xid = Register(x.second.Actor, x.second.MailboxType, x.second.PoolId, i); - Y_VERIFY(!!xid); - if (!!x.first) - RegisterLocalService(x.first, xid); - } - } - - // ok, setup complete, we could destroy setup config - SystemSetup.Destroy(); - + Y_VERIFY(!!xid); + if (!!x.first) + RegisterLocalService(x.first, xid); + } + } + + // ok, setup complete, we could destroy setup config + SystemSetup.Destroy(); + Scheduler->PrepareStart(); CpuManager->Start(); Send(MakeSchedulerActorId(), new TEvSchedulerInitialize(scheduleReaders, &CurrentTimestamp, &CurrentMonotonic)); - Scheduler->Start(); - } - - void TActorSystem::Stop() { - if (StopExecuted || !StartExecuted) - return; - - StopExecuted = true; - + Scheduler->Start(); + } + + void TActorSystem::Stop() { + if (StopExecuted || !StartExecuted) + return; + + StopExecuted = true; + for (auto&& fn : std::exchange(DeferredPreStop, {})) { fn(); } - Scheduler->PrepareStop(); + Scheduler->PrepareStop(); CpuManager->PrepareStop(); - Scheduler->Stop(); + Scheduler->Stop(); CpuManager->Shutdown(); - } - - void TActorSystem::Cleanup() { - Stop(); - if (CleanupExecuted || !StartExecuted) - return; - CleanupExecuted = true; + } + + void TActorSystem::Cleanup() { + Stop(); + if (CleanupExecuted || !StartExecuted) + return; + CleanupExecuted = true; CpuManager->Cleanup(); - Scheduler.Destroy(); - } - - ui32 TActorSystem::MemProfActivityBase; -} + Scheduler.Destroy(); + } + + ui32 TActorSystem::MemProfActivityBase; +} diff --git a/library/cpp/actors/core/actorsystem.h b/library/cpp/actors/core/actorsystem.h index 6306ab7ce3..40499d7586 100644 --- a/library/cpp/actors/core/actorsystem.h +++ b/library/cpp/actors/core/actorsystem.h @@ -1,28 +1,28 @@ -#pragma once - -#include "defs.h" +#pragma once + +#include "defs.h" #include "actor.h" #include "balancer.h" #include "config.h" -#include "event.h" +#include "event.h" #include "log_settings.h" -#include "scheduler_cookie.h" +#include "scheduler_cookie.h" #include "mon_stats.h" #include <library/cpp/threading/future/future.h> #include <library/cpp/actors/util/ticket_lock.h> -#include <util/generic/vector.h> -#include <util/datetime/base.h> +#include <util/generic/vector.h> +#include <util/datetime/base.h> #include <util/system/mutex.h> - -namespace NActors { - class TActorSystem; + +namespace NActors { + class TActorSystem; class TCpuManager; - class IExecutorPool; + class IExecutorPool; struct TWorkerContext; - + inline TActorId MakeInterconnectProxyId(ui32 destNodeId) { char data[12]; memcpy(data, "ICProxy@", 8); @@ -40,32 +40,32 @@ namespace NActors { return nodeId; } - namespace NSchedulerQueue { - class TReader; + namespace NSchedulerQueue { + class TReader; struct TQueueType; - } - - class IExecutorPool : TNonCopyable { - public: - const ui32 PoolId; - - TAtomic ActorRegistrations; - TAtomic DestroyedActors; - - IExecutorPool(ui32 poolId) - : PoolId(poolId) - , ActorRegistrations(0) - , DestroyedActors(0) - { - } - - virtual ~IExecutorPool() { - } - + } + + class IExecutorPool : TNonCopyable { + public: + const ui32 PoolId; + + TAtomic ActorRegistrations; + TAtomic DestroyedActors; + + IExecutorPool(ui32 poolId) + : PoolId(poolId) + , ActorRegistrations(0) + , DestroyedActors(0) + { + } + + virtual ~IExecutorPool() { + } + // for workers virtual ui32 GetReadyActivation(TWorkerContext& wctx, ui64 revolvingCounter) = 0; virtual void ReclaimMailbox(TMailboxType::EType mailboxType, ui32 hint, TWorkerId workerId, ui64 revolvingCounter) = 0; - + /** * Schedule one-shot event that will be send at given time point in the future. * @@ -96,103 +96,103 @@ namespace NActors { */ virtual void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) = 0; - // for actorsystem - virtual bool Send(TAutoPtr<IEventHandle>& ev) = 0; - virtual void ScheduleActivation(ui32 activation) = 0; - virtual void ScheduleActivationEx(ui32 activation, ui64 revolvingCounter) = 0; + // for actorsystem + virtual bool Send(TAutoPtr<IEventHandle>& ev) = 0; + virtual void ScheduleActivation(ui32 activation) = 0; + virtual void ScheduleActivationEx(ui32 activation, ui64 revolvingCounter) = 0; virtual TActorId Register(IActor* actor, TMailboxType::EType mailboxType, ui64 revolvingCounter, const TActorId& parentId) = 0; virtual TActorId Register(IActor* actor, TMailboxHeader* mailbox, ui32 hint, const TActorId& parentId) = 0; - - // lifecycle stuff + + // lifecycle stuff virtual void Prepare(TActorSystem* actorSystem, NSchedulerQueue::TReader** scheduleReaders, ui32* scheduleSz) = 0; - virtual void Start() = 0; - virtual void PrepareStop() = 0; - virtual void Shutdown() = 0; - virtual bool Cleanup() = 0; - + virtual void Start() = 0; + virtual void PrepareStop() = 0; + virtual void Shutdown() = 0; + virtual bool Cleanup() = 0; + virtual void GetCurrentStats(TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const { - // TODO: make pure virtual and override everywhere - Y_UNUSED(poolStats); - Y_UNUSED(statsCopy); - } - - virtual TString GetName() const { - return TString(); - } - + // TODO: make pure virtual and override everywhere + Y_UNUSED(poolStats); + Y_UNUSED(statsCopy); + } + + virtual TString GetName() const { + return TString(); + } + virtual ui32 GetThreads() const { return 1; } - // generic - virtual TAffinity* Affinity() const = 0; - + // generic + virtual TAffinity* Affinity() const = 0; + virtual void SetRealTimeMode() const {} - }; + }; - // could be proxy to in-pool schedulers (for NUMA-aware executors) - class ISchedulerThread : TNonCopyable { - public: - virtual ~ISchedulerThread() { - } + // could be proxy to in-pool schedulers (for NUMA-aware executors) + class ISchedulerThread : TNonCopyable { + public: + virtual ~ISchedulerThread() { + } virtual void Prepare(TActorSystem* actorSystem, volatile ui64* currentTimestamp, volatile ui64* currentMonotonic) = 0; virtual void PrepareSchedules(NSchedulerQueue::TReader** readers, ui32 scheduleReadersCount) = 0; virtual void PrepareStart() { /* empty */ } - virtual void Start() = 0; - virtual void PrepareStop() = 0; - virtual void Stop() = 0; - }; - - struct TActorSetupCmd { - TMailboxType::EType MailboxType; - ui32 PoolId; - IActor* Actor; - - TActorSetupCmd() - : MailboxType(TMailboxType::HTSwap) - , PoolId(0) - , Actor(nullptr) - { - } - - TActorSetupCmd(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId) - : MailboxType(mailboxType) - , PoolId(poolId) - , Actor(actor) - { - } - - void Set(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId) { - MailboxType = mailboxType; - PoolId = poolId; - Actor = actor; - } - }; - + virtual void Start() = 0; + virtual void PrepareStop() = 0; + virtual void Stop() = 0; + }; + + struct TActorSetupCmd { + TMailboxType::EType MailboxType; + ui32 PoolId; + IActor* Actor; + + TActorSetupCmd() + : MailboxType(TMailboxType::HTSwap) + , PoolId(0) + , Actor(nullptr) + { + } + + TActorSetupCmd(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId) + : MailboxType(mailboxType) + , PoolId(poolId) + , Actor(actor) + { + } + + void Set(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId) { + MailboxType = mailboxType; + PoolId = poolId; + Actor = actor; + } + }; + using TProxyWrapperFactory = std::function<TActorId(TActorSystem*, ui32)>; - struct TInterconnectSetup { + struct TInterconnectSetup { TVector<TActorSetupCmd> ProxyActors; TProxyWrapperFactory ProxyWrapperFactory; - }; - - struct TActorSystemSetup { - ui32 NodeId = 0; - + }; + + struct TActorSystemSetup { + ui32 NodeId = 0; + // Either Executors or CpuManager must be initialized - ui32 ExecutorsCount = 0; - TArrayHolder<TAutoPtr<IExecutorPool>> Executors; + ui32 ExecutorsCount = 0; + TArrayHolder<TAutoPtr<IExecutorPool>> Executors; TAutoPtr<IBalancer> Balancer; // main implementation will be implicitly created if not set TCpuManagerConfig CpuManager; - TAutoPtr<ISchedulerThread> Scheduler; - ui32 MaxActivityType = 5; // for default entries - - TInterconnectSetup Interconnect; - + TAutoPtr<ISchedulerThread> Scheduler; + ui32 MaxActivityType = 5; // for default entries + + TInterconnectSetup Interconnect; + using TLocalServices = TVector<std::pair<TActorId, TActorSetupCmd>>; TLocalServices LocalServices; @@ -207,60 +207,60 @@ namespace NActors { ui32 GetThreads(ui32 poolId) const { return Executors ? Executors[poolId]->GetThreads() : CpuManager.GetThreads(poolId); } - }; - - class TActorSystem : TNonCopyable { - struct TServiceMap; - - public: - const ui32 NodeId; - - private: + }; + + class TActorSystem : TNonCopyable { + struct TServiceMap; + + public: + const ui32 NodeId; + + private: THolder<TCpuManager> CpuManager; - const ui32 ExecutorPoolCount; - - TAutoPtr<ISchedulerThread> Scheduler; - THolder<TServiceMap> ServiceMap; - - const ui32 InterconnectCount; + const ui32 ExecutorPoolCount; + + TAutoPtr<ISchedulerThread> Scheduler; + THolder<TServiceMap> ServiceMap; + + const ui32 InterconnectCount; TArrayHolder<TActorId> Interconnect; - - volatile ui64 CurrentTimestamp; + + volatile ui64 CurrentTimestamp; volatile ui64 CurrentMonotonic; - volatile ui64 CurrentIDCounter; - + volatile ui64 CurrentIDCounter; + THolder<NSchedulerQueue::TQueueType> ScheduleQueue; - mutable TTicketLock ScheduleLock; - - friend class TExecutorThread; + mutable TTicketLock ScheduleLock; - THolder<TActorSystemSetup> SystemSetup; + friend class TExecutorThread; + + THolder<TActorSystemSetup> SystemSetup; TActorId DefSelfID; - void* AppData0; - TIntrusivePtr<NLog::TSettings> LoggerSettings0; + void* AppData0; + TIntrusivePtr<NLog::TSettings> LoggerSettings0; TProxyWrapperFactory ProxyWrapperFactory; TMutex ProxyCreationLock; - - bool StartExecuted; - bool StopExecuted; - bool CleanupExecuted; + + bool StartExecuted; + bool StopExecuted; + bool CleanupExecuted; std::deque<std::function<void()>> DeferredPreStop; - public: - TActorSystem(THolder<TActorSystemSetup>& setup, void* appData = nullptr, - TIntrusivePtr<NLog::TSettings> loggerSettings = TIntrusivePtr<NLog::TSettings>(nullptr)); - ~TActorSystem(); - - void Start(); - void Stop(); - void Cleanup(); - + public: + TActorSystem(THolder<TActorSystemSetup>& setup, void* appData = nullptr, + TIntrusivePtr<NLog::TSettings> loggerSettings = TIntrusivePtr<NLog::TSettings>(nullptr)); + ~TActorSystem(); + + void Start(); + void Stop(); + void Cleanup(); + TActorId Register(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 executorPool = 0, ui64 revolvingCounter = 0, const TActorId& parentId = TActorId()); - - bool Send(TAutoPtr<IEventHandle> ev) const; + + bool Send(TAutoPtr<IEventHandle> ev) const; bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0) const; - + /** * Schedule one-shot event that will be send at given time point in the future. * @@ -321,47 +321,47 @@ namespace NActors { THolder<IEventBase> event, TDuration timeout); - ui64 AllocateIDSpace(ui64 count); - + ui64 AllocateIDSpace(ui64 count); + TActorId InterconnectProxy(ui32 destinationNode) const; ui32 BroadcastToProxies(const std::function<IEventHandle*(const TActorId&)>&); - - void UpdateLinkStatus(ui8 status, ui32 destinationNode); - ui8 LinkStatus(ui32 destinationNode); - + + void UpdateLinkStatus(ui8 status, ui32 destinationNode); + ui8 LinkStatus(ui32 destinationNode); + TActorId LookupLocalService(const TActorId& x) const; TActorId RegisterLocalService(const TActorId& serviceId, const TActorId& actorId); ui32 GetMaxActivityType() const { return SystemSetup ? SystemSetup->MaxActivityType : 1; - } - - TInstant Timestamp() const { - return TInstant::MicroSeconds(RelaxedLoad(&CurrentTimestamp)); - } + } + + TInstant Timestamp() const { + return TInstant::MicroSeconds(RelaxedLoad(&CurrentTimestamp)); + } TMonotonic Monotonic() const { return TMonotonic::MicroSeconds(RelaxedLoad(&CurrentMonotonic)); } - template <typename T> - T* AppData() const { - return (T*)AppData0; - } + template <typename T> + T* AppData() const { + return (T*)AppData0; + } - NLog::TSettings* LoggerSettings() const { - return LoggerSettings0.Get(); - } + NLog::TSettings* LoggerSettings() const { + return LoggerSettings0.Get(); + } void GetPoolStats(ui32 poolId, TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const; - + void DeferPreStop(std::function<void()> fn) { DeferredPreStop.push_back(std::move(fn)); } - /* This is the base for memory profiling tags. + /* This is the base for memory profiling tags. System sets memory profiling tag for debug version of lfalloc. The tag is set as "base_tag + actor_activity_type". */ - static ui32 MemProfActivityBase; - }; -} + static ui32 MemProfActivityBase; + }; +} diff --git a/library/cpp/actors/core/buffer.cpp b/library/cpp/actors/core/buffer.cpp index 7b7f5f059a..48128d76ef 100644 --- a/library/cpp/actors/core/buffer.cpp +++ b/library/cpp/actors/core/buffer.cpp @@ -6,51 +6,51 @@ TBufferBase::TBufferBase(size_t size) noexcept : Size(size) -{ -} +{ +} size_t -TBufferBase::GetSize() const noexcept { - return Size; +TBufferBase::GetSize() const noexcept { + return Size; } -void TBufferBase::SetSize(size_t size) noexcept { - Size = size; +void TBufferBase::SetSize(size_t size) noexcept { + Size = size; } ///////////////////////////////////////////////////////////////////// -template <typename PointerType> +template <typename PointerType> TBufferBaseT<PointerType>::TBufferBaseT(PointerType data, size_t size) noexcept - : TBufferBase(size) - , Data(data) -{ -} + : TBufferBase(size) + , Data(data) +{ +} -template <typename PointerType> +template <typename PointerType> PointerType -TBufferBaseT<PointerType>::GetPointer() const noexcept { - return Data; +TBufferBaseT<PointerType>::GetPointer() const noexcept { + return Data; } -template <typename PointerType> -void TBufferBaseT<PointerType>::Assign(PointerType data, size_t size) noexcept { - Data = data; - Size = size; +template <typename PointerType> +void TBufferBaseT<PointerType>::Assign(PointerType data, size_t size) noexcept { + Data = data; + Size = size; } -template <> -void TBufferBaseT<void*>::Cut(size_t offset) noexcept { - Y_VERIFY_DEBUG(offset <= Size); - Data = static_cast<char*>(Data) + offset; - TBufferBase::Size -= offset; +template <> +void TBufferBaseT<void*>::Cut(size_t offset) noexcept { + Y_VERIFY_DEBUG(offset <= Size); + Data = static_cast<char*>(Data) + offset; + TBufferBase::Size -= offset; } -template <> -void TBufferBaseT<const void*>::Cut(size_t offset) noexcept { - Y_VERIFY_DEBUG(offset <= Size); - Data = static_cast<const char*>(Data) + offset; - TBufferBase::Size -= offset; +template <> +void TBufferBaseT<const void*>::Cut(size_t offset) noexcept { + Y_VERIFY_DEBUG(offset <= Size); + Data = static_cast<const char*>(Data) + offset; + TBufferBase::Size -= offset; } template class TBufferBaseT<void*>; @@ -60,34 +60,34 @@ template class TBufferBaseT<const void*>; TConstBuffer::TConstBuffer(const void* data, size_t size) noexcept : TBufferBaseT<const void*>(data, size) -{ -} +{ +} TConstBuffer::TConstBuffer(const TMutableBuffer& buffer) noexcept : TBufferBaseT<const void*>(buffer.GetPointer(), buffer.GetSize()) -{ -} +{ +} TConstBuffer -TConstBuffer::Offset(ptrdiff_t offset, size_t size) const noexcept { - return TConstBuffer(static_cast<const char*>(Data) + offset, std::min(Size - offset, size)); +TConstBuffer::Offset(ptrdiff_t offset, size_t size) const noexcept { + return TConstBuffer(static_cast<const char*>(Data) + offset, std::min(Size - offset, size)); } //////////////////////////////////////////////////////////////////////////////// TMutableBuffer::TMutableBuffer(void* data, size_t size) noexcept - : TBufferBaseT<void*>(data, size) -{ -} + : TBufferBaseT<void*>(data, size) +{ +} TMutableBuffer -TMutableBuffer::Offset(ptrdiff_t offset, size_t size) const noexcept { - return TMutableBuffer(static_cast<char*>(Data) + offset, std::min(Size - offset, size)); +TMutableBuffer::Offset(ptrdiff_t offset, size_t size) const noexcept { + return TMutableBuffer(static_cast<char*>(Data) + offset, std::min(Size - offset, size)); } size_t -TMutableBuffer::CopyFrom(const TConstBuffer& buffer) const noexcept { - const auto size = std::min(Size, buffer.Size); - std::memcpy(Data, buffer.Data, size); - return size; +TMutableBuffer::CopyFrom(const TConstBuffer& buffer) const noexcept { + const auto size = std::min(Size, buffer.Size); + std::memcpy(Data, buffer.Data, size); + return size; } diff --git a/library/cpp/actors/core/buffer.h b/library/cpp/actors/core/buffer.h index fb8bd563d7..95425046d6 100644 --- a/library/cpp/actors/core/buffer.h +++ b/library/cpp/actors/core/buffer.h @@ -5,7 +5,7 @@ class TConstBuffer; class TMutableBuffer; -class TBufferBase { +class TBufferBase { public: size_t GetSize() const noexcept; @@ -17,8 +17,8 @@ protected: size_t Size; }; -template <typename PointerType> -class TBufferBaseT: public TBufferBase { +template <typename PointerType> +class TBufferBaseT: public TBufferBase { public: PointerType GetPointer() const noexcept; @@ -33,30 +33,30 @@ protected: }; /// Represents constant memory buffer, but do not owns it. -class TConstBuffer: public TBufferBaseT<const void*> { - friend class TMutableBuffer; - +class TConstBuffer: public TBufferBaseT<const void*> { + friend class TMutableBuffer; + public: - TConstBuffer(const TMutableBuffer& buffer) noexcept; + TConstBuffer(const TMutableBuffer& buffer) noexcept; - TConstBuffer(const void* data = nullptr, size_t size = 0U) noexcept; + TConstBuffer(const void* data = nullptr, size_t size = 0U) noexcept; - TConstBuffer Offset(ptrdiff_t offset, size_t size = std::numeric_limits<size_t>::max()) const noexcept; + TConstBuffer Offset(ptrdiff_t offset, size_t size = std::numeric_limits<size_t>::max()) const noexcept; }; /// Represents mutable memory buffer, but do not owns it. -class TMutableBuffer: public TBufferBaseT<void*> { - friend class TConstBuffer; - +class TMutableBuffer: public TBufferBaseT<void*> { + friend class TConstBuffer; + public: - TMutableBuffer(void* data = nullptr, size_t size = 0U) noexcept; + TMutableBuffer(void* data = nullptr, size_t size = 0U) noexcept; - TMutableBuffer(const TMutableBuffer& value) noexcept - : TBufferBaseT<void*>(value) - { - } + TMutableBuffer(const TMutableBuffer& value) noexcept + : TBufferBaseT<void*>(value) + { + } - TMutableBuffer Offset(ptrdiff_t offset, size_t size = std::numeric_limits<size_t>::max()) const noexcept; + TMutableBuffer Offset(ptrdiff_t offset, size_t size = std::numeric_limits<size_t>::max()) const noexcept; - size_t CopyFrom(const TConstBuffer& buffer) const noexcept; + size_t CopyFrom(const TConstBuffer& buffer) const noexcept; }; diff --git a/library/cpp/actors/core/callstack.cpp b/library/cpp/actors/core/callstack.cpp index 8a3b1df406..9297c1a079 100644 --- a/library/cpp/actors/core/callstack.cpp +++ b/library/cpp/actors/core/callstack.cpp @@ -4,88 +4,88 @@ #ifdef USE_ACTOR_CALLSTACK namespace NActors { - namespace { + namespace { void (*PreviousFormatBackTrace)(IOutputStream*) = 0; - ui32 ActorBackTraceEnableCounter = 0; + ui32 ActorBackTraceEnableCounter = 0; } void ActorFormatBackTrace(IOutputStream* out) { - TStringStream str; - PreviousFormatBackTrace(&str); - str << Endl; - TCallstack::DumpCallstack(str); - *out << str.Str(); - } + TStringStream str; + PreviousFormatBackTrace(&str); + str << Endl; + TCallstack::DumpCallstack(str); + *out << str.Str(); + } - void EnableActorCallstack() { - if (ActorBackTraceEnableCounter == 0) { - Y_VERIFY(PreviousFormatBackTrace == 0); - PreviousFormatBackTrace = SetFormatBackTraceFn(ActorFormatBackTrace); - } + void EnableActorCallstack() { + if (ActorBackTraceEnableCounter == 0) { + Y_VERIFY(PreviousFormatBackTrace == 0); + PreviousFormatBackTrace = SetFormatBackTraceFn(ActorFormatBackTrace); + } - ++ActorBackTraceEnableCounter; + ++ActorBackTraceEnableCounter; } - void DisableActorCallstack() { - --ActorBackTraceEnableCounter; + void DisableActorCallstack() { + --ActorBackTraceEnableCounter; - if (ActorBackTraceEnableCounter == 0) { - Y_VERIFY(PreviousFormatBackTrace); - SetFormatBackTraceFn(PreviousFormatBackTrace); - PreviousFormatBackTrace = 0; - } - } + if (ActorBackTraceEnableCounter == 0) { + Y_VERIFY(PreviousFormatBackTrace); + SetFormatBackTraceFn(PreviousFormatBackTrace); + PreviousFormatBackTrace = 0; + } + } - TCallstack::TCallstack() - : BeginIdx(0) - , Size(0) - , LinesToSkip(0) - { + TCallstack::TCallstack() + : BeginIdx(0) + , Size(0) + , LinesToSkip(0) + { } - void TCallstack::SetLinesToSkip() { - TTrace record; - LinesToSkip = BackTrace(record.Data, TTrace::CAPACITY); - } + void TCallstack::SetLinesToSkip() { + TTrace record; + LinesToSkip = BackTrace(record.Data, TTrace::CAPACITY); + } - void TCallstack::Trace() { - size_t currentIdx = (BeginIdx + Size) % RECORDS; - if (Size == RECORDS) { - ++BeginIdx; - } else { - ++Size; - } - TTrace& record = Record[currentIdx]; - record.Size = BackTrace(record.Data, TTrace::CAPACITY); - record.LinesToSkip = LinesToSkip; - } + void TCallstack::Trace() { + size_t currentIdx = (BeginIdx + Size) % RECORDS; + if (Size == RECORDS) { + ++BeginIdx; + } else { + ++Size; + } + TTrace& record = Record[currentIdx]; + record.Size = BackTrace(record.Data, TTrace::CAPACITY); + record.LinesToSkip = LinesToSkip; + } - void TCallstack::TraceIfEmpty() { - if (Size == 0) { - LinesToSkip = 0; - Trace(); - } + void TCallstack::TraceIfEmpty() { + if (Size == 0) { + LinesToSkip = 0; + Trace(); + } } - TCallstack& TCallstack::GetTlsCallstack() { - return *FastTlsSingleton<TCallstack>(); + TCallstack& TCallstack::GetTlsCallstack() { + return *FastTlsSingleton<TCallstack>(); } - void TCallstack::DumpCallstack(TStringStream& str) { - TCallstack& callstack = GetTlsCallstack(); - for (int i = callstack.Size - 1; i >= 0; --i) { - TTrace& record = callstack.Record[(callstack.BeginIdx + i) % RECORDS]; - str << Endl << "Trace entry " << i << Endl << Endl; - size_t size = record.Size; - if (size > record.LinesToSkip && size < TTrace::CAPACITY) { - size -= record.LinesToSkip; - } - if (size > RECORDS_TO_SKIP) { - FormatBackTrace(&str, &record.Data[RECORDS_TO_SKIP], size - RECORDS_TO_SKIP); - } else { - FormatBackTrace(&str, record.Data, size); - } - str << Endl; + void TCallstack::DumpCallstack(TStringStream& str) { + TCallstack& callstack = GetTlsCallstack(); + for (int i = callstack.Size - 1; i >= 0; --i) { + TTrace& record = callstack.Record[(callstack.BeginIdx + i) % RECORDS]; + str << Endl << "Trace entry " << i << Endl << Endl; + size_t size = record.Size; + if (size > record.LinesToSkip && size < TTrace::CAPACITY) { + size -= record.LinesToSkip; + } + if (size > RECORDS_TO_SKIP) { + FormatBackTrace(&str, &record.Data[RECORDS_TO_SKIP], size - RECORDS_TO_SKIP); + } else { + FormatBackTrace(&str, record.Data, size); + } + str << Endl; } } } diff --git a/library/cpp/actors/core/callstack.h b/library/cpp/actors/core/callstack.h index 1c45b0468e..176717d2ae 100644 --- a/library/cpp/actors/core/callstack.h +++ b/library/cpp/actors/core/callstack.h @@ -5,53 +5,53 @@ #endif #ifdef ENABLE_ACTOR_CALLSTACK -#include "defs.h" -#include <util/system/backtrace.h> -#include <util/stream/str.h> -#include <util/generic/deque.h> -#define USE_ACTOR_CALLSTACK +#include "defs.h" +#include <util/system/backtrace.h> +#include <util/stream/str.h> +#include <util/generic/deque.h> +#define USE_ACTOR_CALLSTACK namespace NActors { - struct TCallstack { - struct TTrace { - static const size_t CAPACITY = 50; - void* Data[CAPACITY]; - size_t Size; - size_t LinesToSkip; - - TTrace() - : Size(0) - , LinesToSkip(0) - { - } - }; - - static const size_t RECORDS = 8; - static const size_t RECORDS_TO_SKIP = 2; - TTrace Record[RECORDS]; - size_t BeginIdx; + struct TCallstack { + struct TTrace { + static const size_t CAPACITY = 50; + void* Data[CAPACITY]; + size_t Size; + size_t LinesToSkip; + + TTrace() + : Size(0) + , LinesToSkip(0) + { + } + }; + + static const size_t RECORDS = 8; + static const size_t RECORDS_TO_SKIP = 2; + TTrace Record[RECORDS]; + size_t BeginIdx; size_t Size; size_t LinesToSkip; - TCallstack(); - void SetLinesToSkip(); - void Trace(); - void TraceIfEmpty(); - static TCallstack& GetTlsCallstack(); - static void DumpCallstack(TStringStream& str); + TCallstack(); + void SetLinesToSkip(); + void Trace(); + void TraceIfEmpty(); + static TCallstack& GetTlsCallstack(); + static void DumpCallstack(TStringStream& str); }; - void EnableActorCallstack(); - void DisableActorCallstack(); + void EnableActorCallstack(); + void DisableActorCallstack(); } #else namespace NActors { - inline void EnableActorCallstack(){}; + inline void EnableActorCallstack(){}; - inline void DisableActorCallstack(){}; + inline void DisableActorCallstack(){}; } diff --git a/library/cpp/actors/core/defs.h b/library/cpp/actors/core/defs.h index 34ddee397e..980b7d767b 100644 --- a/library/cpp/actors/core/defs.h +++ b/library/cpp/actors/core/defs.h @@ -1,18 +1,18 @@ -#pragma once - -// unique tag to fix pragma once gcc glueing: ./library/actorlib/core/defs.h - +#pragma once + +// unique tag to fix pragma once gcc glueing: ./library/actorlib/core/defs.h + #include <library/cpp/actors/util/defs.h> #include <util/generic/hash.h> #include <util/string/printf.h> - + // Enables collection of // event send/receive counts // activation time histograms // event processing time histograms #define ACTORSLIB_COLLECT_EXEC_STATS -namespace NActors { +namespace NActors { using TPoolId = ui8; using TPoolsMask = ui64; static constexpr TPoolId PoolBits = 6; @@ -37,19 +37,19 @@ namespace NActors { using TThreadId = ui64; static constexpr TThreadId UnknownThreadId = ui64(-1); - struct TMailboxType { - enum EType { + struct TMailboxType { + enum EType { Inherited = -1, // inherit mailbox from parent - Simple = 0, // simplest queue under producer lock. fastest in no-contention case - Revolving = 1, // somewhat outdated, tries to be wait-free. replaced by ReadAsFilled - HTSwap = 2, // other simple lf queue, suggested for low-contention case - ReadAsFilled = 3, // wait-free queue, suggested for high-contention or latency critical - TinyReadAsFilled = 4, // same as 3 but with lower overhead - //Inplace; - //Direct; - //Virtual - }; - }; + Simple = 0, // simplest queue under producer lock. fastest in no-contention case + Revolving = 1, // somewhat outdated, tries to be wait-free. replaced by ReadAsFilled + HTSwap = 2, // other simple lf queue, suggested for low-contention case + ReadAsFilled = 3, // wait-free queue, suggested for high-contention or latency critical + TinyReadAsFilled = 4, // same as 3 but with lower overhead + //Inplace; + //Direct; + //Virtual + }; + }; struct TScopeId : std::pair<ui64, ui64> { using TBase = std::pair<ui64, ui64>; @@ -61,9 +61,9 @@ namespace NActors { return Sprintf("<%" PRIu64 ":%" PRIu64 ">", scopeId.first, scopeId.second); } -} - +} + template<> struct hash<NActors::TScopeId> : hash<std::pair<ui64, ui64>> {}; -class TAffinity; +class TAffinity; diff --git a/library/cpp/actors/core/event.cpp b/library/cpp/actors/core/event.cpp index 2ce75ac717..33f8ce2aaf 100644 --- a/library/cpp/actors/core/event.cpp +++ b/library/cpp/actors/core/event.cpp @@ -1,4 +1,4 @@ -#include "event.h" +#include "event.h" #include "event_pb.h" namespace NActors { @@ -7,32 +7,32 @@ namespace NActors { Max<ui64>(), Max<ui64>() }; - TIntrusivePtr<TEventSerializedData> IEventHandle::ReleaseChainBuffer() { - if (Buffer) { - TIntrusivePtr<TEventSerializedData> result; - DoSwap(result, Buffer); - Event.Reset(); - return result; - } - if (Event) { - TAllocChunkSerializer serializer; + TIntrusivePtr<TEventSerializedData> IEventHandle::ReleaseChainBuffer() { + if (Buffer) { + TIntrusivePtr<TEventSerializedData> result; + DoSwap(result, Buffer); + Event.Reset(); + return result; + } + if (Event) { + TAllocChunkSerializer serializer; Event->SerializeToArcadiaStream(&serializer); auto chainBuf = serializer.Release(Event->IsExtendedFormat()); - Event.Reset(); - return chainBuf; - } - return new TEventSerializedData; + Event.Reset(); + return chainBuf; + } + return new TEventSerializedData; } - TIntrusivePtr<TEventSerializedData> IEventHandle::GetChainBuffer() { - if (Buffer) - return Buffer; - if (Event) { - TAllocChunkSerializer serializer; + TIntrusivePtr<TEventSerializedData> IEventHandle::GetChainBuffer() { + if (Buffer) + return Buffer; + if (Event) { + TAllocChunkSerializer serializer; Event->SerializeToArcadiaStream(&serializer); Buffer = serializer.Release(Event->IsExtendedFormat()); - return Buffer; - } - return new TEventSerializedData; + return Buffer; + } + return new TEventSerializedData; } } diff --git a/library/cpp/actors/core/event.h b/library/cpp/actors/core/event.h index 617c67fdb9..6ff02aaf94 100644 --- a/library/cpp/actors/core/event.h +++ b/library/cpp/actors/core/event.h @@ -1,40 +1,40 @@ -#pragma once - -#include "defs.h" -#include "actorid.h" +#pragma once + +#include "defs.h" +#include "actorid.h" #include "callstack.h" #include "event_load.h" - + #include <library/cpp/actors/wilson/wilson_trace.h> #include <util/system/hp_timer.h> #include <util/generic/maybe.h> -namespace NActors { - class TChunkSerializer; - - class ISerializerToStream { - public: +namespace NActors { + class TChunkSerializer; + + class ISerializerToStream { + public: virtual bool SerializeToArcadiaStream(TChunkSerializer*) const = 0; - }; - - class IEventBase - : TNonCopyable, - public ISerializerToStream { - public: - // actual typing is performed by IEventHandle - - virtual ~IEventBase() { - } - - virtual TString ToStringHeader() const = 0; - virtual TString ToString() const { - return ToStringHeader(); - } - virtual ui32 CalculateSerializedSize() const { - return 0; - } - virtual ui32 Type() const = 0; + }; + + class IEventBase + : TNonCopyable, + public ISerializerToStream { + public: + // actual typing is performed by IEventHandle + + virtual ~IEventBase() { + } + + virtual TString ToStringHeader() const = 0; + virtual TString ToString() const { + return ToStringHeader(); + } + virtual ui32 CalculateSerializedSize() const { + return 0; + } + virtual ui32 Type() const = 0; virtual bool SerializeToArcadiaStream(TChunkSerializer*) const = 0; virtual bool IsSerializable() const = 0; virtual bool IsExtendedFormat() const { @@ -43,20 +43,20 @@ namespace NActors { virtual ui32 CalculateSerializedSizeCached() const { return CalculateSerializedSize(); } - }; - - // fat handle + }; + + // fat handle class IEventHandle : TNonCopyable { struct TOnNondelivery { TActorId Recipient; - + TOnNondelivery(const TActorId& recipient) - : Recipient(recipient) - { - } - }; - - public: + : Recipient(recipient) + { + } + }; + + public: template <typename TEv> inline TEv* CastAsLocal() const noexcept { auto fits = GetTypeRewrite() == TEv::EventType; @@ -64,256 +64,256 @@ namespace NActors { return fits ? static_cast<TEv*>(Event.Get()) : nullptr; } - template <typename TEventType> - TEventType* Get() { - if (Type != TEventType::EventType) - Y_FAIL("Event type %" PRIu32 " doesn't match the expected type %" PRIu32, Type, TEventType::EventType); - - if (!Event) { + template <typename TEventType> + TEventType* Get() { + if (Type != TEventType::EventType) + Y_FAIL("Event type %" PRIu32 " doesn't match the expected type %" PRIu32, Type, TEventType::EventType); + + if (!Event) { Event.Reset(TEventType::Load(Buffer.Get())); - } - + } + if (Event) { - return static_cast<TEventType*>(Event.Get()); + return static_cast<TEventType*>(Event.Get()); } - + Y_FAIL("Failed to Load() event type %" PRIu32 " class %s", Type, TypeName<TEventType>().data()); - } - - template <typename T> - TAutoPtr<T> Release() { - TAutoPtr<T> x = Get<T>(); + } + + template <typename T> + TAutoPtr<T> Release() { + TAutoPtr<T> x = Get<T>(); Y_UNUSED(Event.Release()); - Buffer.Reset(); - return x; - } - - enum EFlags { - FlagTrackDelivery = 1 << 0, - FlagForwardOnNondelivery = 1 << 1, - FlagSubscribeOnSession = 1 << 2, - FlagUseSubChannel = 1 << 3, + Buffer.Reset(); + return x; + } + + enum EFlags { + FlagTrackDelivery = 1 << 0, + FlagForwardOnNondelivery = 1 << 1, + FlagSubscribeOnSession = 1 << 2, + FlagUseSubChannel = 1 << 3, FlagGenerateUnsureUndelivered = 1 << 4, FlagExtendedFormat = 1 << 5, - }; - - const ui32 Type; - const ui32 Flags; + }; + + const ui32 Type; + const ui32 Flags; const TActorId Recipient; const TActorId Sender; - const ui64 Cookie; + const ui64 Cookie; const TScopeId OriginScopeId = TScopeId::LocallyGenerated; // filled in when the message is received from Interconnect - - // if set, used by ActorSystem/Interconnect to report tracepoints - NWilson::TTraceId TraceId; - // filled if feeded by interconnect session + // if set, used by ActorSystem/Interconnect to report tracepoints + NWilson::TTraceId TraceId; + + // filled if feeded by interconnect session const TActorId InterconnectSession; - + #ifdef ACTORSLIB_COLLECT_EXEC_STATS - ::NHPTimer::STime SendTime; + ::NHPTimer::STime SendTime; #endif - static const size_t ChannelBits = 12; - static const size_t ChannelShift = (sizeof(ui32) << 3) - ChannelBits; + static const size_t ChannelBits = 12; + static const size_t ChannelShift = (sizeof(ui32) << 3) - ChannelBits; #ifdef USE_ACTOR_CALLSTACK - TCallstack Callstack; + TCallstack Callstack; #endif - ui16 GetChannel() const noexcept { - return Flags >> ChannelShift; - } - - ui64 GetSubChannel() const noexcept { - return Flags & FlagUseSubChannel ? Sender.LocalId() : 0ULL; - } - - static ui32 MakeFlags(ui32 channel, ui32 flags) { - Y_VERIFY(channel < (1 << ChannelBits)); - Y_VERIFY(flags < (1 << ChannelShift)); - return (flags | (channel << ChannelShift)); - } - - private: - THolder<IEventBase> Event; - TIntrusivePtr<TEventSerializedData> Buffer; - + ui16 GetChannel() const noexcept { + return Flags >> ChannelShift; + } + + ui64 GetSubChannel() const noexcept { + return Flags & FlagUseSubChannel ? Sender.LocalId() : 0ULL; + } + + static ui32 MakeFlags(ui32 channel, ui32 flags) { + Y_VERIFY(channel < (1 << ChannelBits)); + Y_VERIFY(flags < (1 << ChannelShift)); + return (flags | (channel << ChannelShift)); + } + + private: + THolder<IEventBase> Event; + TIntrusivePtr<TEventSerializedData> Buffer; + TActorId RewriteRecipient; - ui32 RewriteType; - - THolder<TOnNondelivery> OnNondeliveryHolder; // only for local events + ui32 RewriteType; + + THolder<TOnNondelivery> OnNondeliveryHolder; // only for local events - public: + public: void Rewrite(ui32 typeRewrite, TActorId recipientRewrite) { - RewriteRecipient = recipientRewrite; - RewriteType = typeRewrite; - } - - void DropRewrite() { - RewriteRecipient = Recipient; - RewriteType = Type; - } - + RewriteRecipient = recipientRewrite; + RewriteType = typeRewrite; + } + + void DropRewrite() { + RewriteRecipient = Recipient; + RewriteType = Type; + } + const TActorId& GetRecipientRewrite() const { - return RewriteRecipient; - } - - ui32 GetTypeRewrite() const { - return RewriteType; - } - + return RewriteRecipient; + } + + ui32 GetTypeRewrite() const { + return RewriteType; + } + TActorId GetForwardOnNondeliveryRecipient() const { return OnNondeliveryHolder.Get() ? OnNondeliveryHolder->Recipient : TActorId(); - } + } IEventHandle(const TActorId& recipient, const TActorId& sender, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0, const TActorId* forwardOnNondelivery = nullptr, NWilson::TTraceId traceId = {}) - : Type(ev->Type()) - , Flags(flags) - , Recipient(recipient) - , Sender(sender) - , Cookie(cookie) - , TraceId(std::move(traceId)) + : Type(ev->Type()) + , Flags(flags) + , Recipient(recipient) + , Sender(sender) + , Cookie(cookie) + , TraceId(std::move(traceId)) #ifdef ACTORSLIB_COLLECT_EXEC_STATS - , SendTime(0) + , SendTime(0) #endif - , Event(ev) - , RewriteRecipient(Recipient) - , RewriteType(Type) - { - if (forwardOnNondelivery) - OnNondeliveryHolder.Reset(new TOnNondelivery(*forwardOnNondelivery)); - } - - IEventHandle(ui32 type, - ui32 flags, + , Event(ev) + , RewriteRecipient(Recipient) + , RewriteType(Type) + { + if (forwardOnNondelivery) + OnNondeliveryHolder.Reset(new TOnNondelivery(*forwardOnNondelivery)); + } + + IEventHandle(ui32 type, + ui32 flags, const TActorId& recipient, const TActorId& sender, - TIntrusivePtr<TEventSerializedData> buffer, - ui64 cookie, + TIntrusivePtr<TEventSerializedData> buffer, + ui64 cookie, const TActorId* forwardOnNondelivery = nullptr, - NWilson::TTraceId traceId = {}) - : Type(type) - , Flags(flags) - , Recipient(recipient) - , Sender(sender) - , Cookie(cookie) - , TraceId(std::move(traceId)) + NWilson::TTraceId traceId = {}) + : Type(type) + , Flags(flags) + , Recipient(recipient) + , Sender(sender) + , Cookie(cookie) + , TraceId(std::move(traceId)) #ifdef ACTORSLIB_COLLECT_EXEC_STATS - , SendTime(0) + , SendTime(0) #endif - , Buffer(std::move(buffer)) - , RewriteRecipient(Recipient) - , RewriteType(Type) - { - if (forwardOnNondelivery) - OnNondeliveryHolder.Reset(new TOnNondelivery(*forwardOnNondelivery)); - } - - // Special ctor for events from interconnect. + , Buffer(std::move(buffer)) + , RewriteRecipient(Recipient) + , RewriteType(Type) + { + if (forwardOnNondelivery) + OnNondeliveryHolder.Reset(new TOnNondelivery(*forwardOnNondelivery)); + } + + // Special ctor for events from interconnect. IEventHandle(const TActorId& session, - ui32 type, - ui32 flags, + ui32 type, + ui32 flags, const TActorId& recipient, const TActorId& sender, - TIntrusivePtr<TEventSerializedData> buffer, - ui64 cookie, + TIntrusivePtr<TEventSerializedData> buffer, + ui64 cookie, TScopeId originScopeId, NWilson::TTraceId traceId) noexcept - : Type(type) - , Flags(flags) - , Recipient(recipient) - , Sender(sender) - , Cookie(cookie) + : Type(type) + , Flags(flags) + , Recipient(recipient) + , Sender(sender) + , Cookie(cookie) , OriginScopeId(originScopeId) - , TraceId(std::move(traceId)) - , InterconnectSession(session) + , TraceId(std::move(traceId)) + , InterconnectSession(session) #ifdef ACTORSLIB_COLLECT_EXEC_STATS - , SendTime(0) + , SendTime(0) #endif - , Buffer(std::move(buffer)) - , RewriteRecipient(Recipient) - , RewriteType(Type) - { - } + , Buffer(std::move(buffer)) + , RewriteRecipient(Recipient) + , RewriteType(Type) + { + } TIntrusivePtr<TEventSerializedData> GetChainBuffer(); TIntrusivePtr<TEventSerializedData> ReleaseChainBuffer(); - + ui32 GetSize() const { - if (Buffer) { + if (Buffer) { return Buffer->GetSize(); } else if (Event) { return Event->CalculateSerializedSize(); } else { return 0; - } + } } - bool HasBuffer() const { - return bool(Buffer); + bool HasBuffer() const { + return bool(Buffer); } - - bool HasEvent() const { - return bool(Event); + + bool HasEvent() const { + return bool(Event); } - - IEventBase* GetBase() { - if (!Event) { - if (!Buffer) - return nullptr; - else - ythrow TWithBackTrace<yexception>() << "don't know how to load the event from buffer"; - } - - return Event.Get(); - } - - TAutoPtr<IEventBase> ReleaseBase() { - TAutoPtr<IEventBase> x = GetBase(); + + IEventBase* GetBase() { + if (!Event) { + if (!Buffer) + return nullptr; + else + ythrow TWithBackTrace<yexception>() << "don't know how to load the event from buffer"; + } + + return Event.Get(); + } + + TAutoPtr<IEventBase> ReleaseBase() { + TAutoPtr<IEventBase> x = GetBase(); Y_UNUSED(Event.Release()); - Buffer.Reset(); - return x; - } + Buffer.Reset(); + return x; + } TAutoPtr<IEventHandle> Forward(const TActorId& dest) { - if (Event) - return new IEventHandle(dest, Sender, Event.Release(), Flags, Cookie, nullptr, std::move(TraceId)); - else - return new IEventHandle(Type, Flags, dest, Sender, Buffer, Cookie, nullptr, std::move(TraceId)); - } - + if (Event) + return new IEventHandle(dest, Sender, Event.Release(), Flags, Cookie, nullptr, std::move(TraceId)); + else + return new IEventHandle(Type, Flags, dest, Sender, Buffer, Cookie, nullptr, std::move(TraceId)); + } + TAutoPtr<IEventHandle> ForwardOnNondelivery(ui32 reason, bool unsure = false); - }; - - template <typename TEventType> - class TEventHandle: public IEventHandle { - TEventHandle(); // we never made instance of TEventHandle - public: - TEventType* Get() { - return IEventHandle::Get<TEventType>(); - } - - TAutoPtr<TEventType> Release() { - return IEventHandle::Release<TEventType>(); - } - }; - - static_assert(sizeof(TEventHandle<IEventBase>) == sizeof(IEventHandle), "expect sizeof(TEventHandle<IEventBase>) == sizeof(IEventHandle)"); - - template <typename TEventType, ui32 EventType0> - class TEventBase: public IEventBase { - public: - static constexpr ui32 EventType = EventType0; - ui32 Type() const override { - return EventType0; - } - // still abstract - - typedef TEventHandle<TEventType> THandle; - typedef TAutoPtr<THandle> TPtr; - }; - + }; + + template <typename TEventType> + class TEventHandle: public IEventHandle { + TEventHandle(); // we never made instance of TEventHandle + public: + TEventType* Get() { + return IEventHandle::Get<TEventType>(); + } + + TAutoPtr<TEventType> Release() { + return IEventHandle::Release<TEventType>(); + } + }; + + static_assert(sizeof(TEventHandle<IEventBase>) == sizeof(IEventHandle), "expect sizeof(TEventHandle<IEventBase>) == sizeof(IEventHandle)"); + + template <typename TEventType, ui32 EventType0> + class TEventBase: public IEventBase { + public: + static constexpr ui32 EventType = EventType0; + ui32 Type() const override { + return EventType0; + } + // still abstract + + typedef TEventHandle<TEventType> THandle; + typedef TAutoPtr<THandle> TPtr; + }; + #define DEFINE_SIMPLE_LOCAL_EVENT(eventType, header) \ TString ToStringHeader() const override { \ return TString(header); \ @@ -327,7 +327,7 @@ namespace NActors { bool IsSerializable() const override { \ return false; \ } - + #define DEFINE_SIMPLE_NONLOCAL_EVENT(eventType, header) \ TString ToStringHeader() const override { \ return TString(header); \ @@ -341,4 +341,4 @@ namespace NActors { bool IsSerializable() const override { \ return true; \ } -} +} diff --git a/library/cpp/actors/core/event_load.h b/library/cpp/actors/core/event_load.h index 30a2cb50d2..0dab1dd374 100644 --- a/library/cpp/actors/core/event_load.h +++ b/library/cpp/actors/core/event_load.h @@ -1,5 +1,5 @@ #pragma once - + #include <util/stream/walk.h> #include <util/system/types.h> #include <util/generic/string.h> @@ -7,17 +7,17 @@ #include <library/cpp/actors/wilson/wilson_trace.h> namespace NActors { - class IEventHandle; + class IEventHandle; - struct TConstIoVec { - const void* Data; - size_t Size; - }; + struct TConstIoVec { + const void* Data; + size_t Size; + }; - struct TIoVec { - void* Data; - size_t Size; - }; + struct TIoVec { + void* Data; + size_t Size; + }; class TEventSerializedData : public TThrRefBase @@ -80,14 +80,14 @@ namespace NActors { void Append(TRope&& from) { Rope.Insert(Rope.End(), std::move(from)); - } + } void Append(TString buffer) { if (buffer) { Rope.Insert(Rope.End(), TRope(std::move(buffer))); } - } - }; + } + }; } class TChainBufWalk : public IWalkInput { diff --git a/library/cpp/actors/core/event_local.h b/library/cpp/actors/core/event_local.h index 492df07a27..2845aa94dd 100644 --- a/library/cpp/actors/core/event_local.h +++ b/library/cpp/actors/core/event_local.h @@ -1,74 +1,74 @@ -#pragma once - -#include "event.h" -#include "scheduler_cookie.h" +#pragma once + +#include "event.h" +#include "scheduler_cookie.h" #include "event_load.h" #include <util/system/type_name.h> - -namespace NActors { - template <typename TEv, ui32 TEventType> - class TEventLocal: public TEventBase<TEv, TEventType> { - public: + +namespace NActors { + template <typename TEv, ui32 TEventType> + class TEventLocal: public TEventBase<TEv, TEventType> { + public: TString ToStringHeader() const override { - return TypeName<TEv>(); - } - + return TypeName<TEv>(); + } + bool SerializeToArcadiaStream(TChunkSerializer* /*serializer*/) const override { Y_FAIL("Serialization of local event %s type %" PRIu32, TypeName<TEv>().data(), TEventType); - } - + } + bool IsSerializable() const override { return false; } - static IEventBase* Load(TEventSerializedData*) { + static IEventBase* Load(TEventSerializedData*) { Y_FAIL("Loading of local event %s type %" PRIu32, TypeName<TEv>().data(), TEventType); - } - }; - - template <typename TEv, ui32 TEventType> - class TEventScheduler: public TEventLocal<TEv, TEventType> { - public: - TSchedulerCookieHolder Cookie; - - TEventScheduler(ISchedulerCookie* cookie) - : Cookie(cookie) - { - } - }; - - template <ui32 TEventType> - class TEventSchedulerEv: public TEventScheduler<TEventSchedulerEv<TEventType>, TEventType> { - public: - TEventSchedulerEv(ISchedulerCookie* cookie) - : TEventScheduler<TEventSchedulerEv<TEventType>, TEventType>(cookie) - { - } - }; - - template <typename TEv, ui32 TEventType> + } + }; + + template <typename TEv, ui32 TEventType> + class TEventScheduler: public TEventLocal<TEv, TEventType> { + public: + TSchedulerCookieHolder Cookie; + + TEventScheduler(ISchedulerCookie* cookie) + : Cookie(cookie) + { + } + }; + + template <ui32 TEventType> + class TEventSchedulerEv: public TEventScheduler<TEventSchedulerEv<TEventType>, TEventType> { + public: + TEventSchedulerEv(ISchedulerCookie* cookie) + : TEventScheduler<TEventSchedulerEv<TEventType>, TEventType>(cookie) + { + } + }; + + template <typename TEv, ui32 TEventType> class TEventSimple: public TEventBase<TEv, TEventType> { - public: - TString ToStringHeader() const override { - static TString header(TypeName<TEv>()); - return header; - } - + public: + TString ToStringHeader() const override { + static TString header(TypeName<TEv>()); + return header; + } + bool SerializeToArcadiaStream(TChunkSerializer* /*serializer*/) const override { static_assert(sizeof(TEv) == sizeof(TEventSimple<TEv, TEventType>), "Descendant should be an empty class"); return true; - } - + } + bool IsSerializable() const override { return true; } - static IEventBase* Load(NActors::TEventSerializedData*) { - return new TEv(); - } + static IEventBase* Load(NActors::TEventSerializedData*) { + return new TEv(); + } - static IEventBase* Load(const TString&) { - return new TEv(); - } - }; -} + static IEventBase* Load(const TString&) { + return new TEv(); + } + }; +} diff --git a/library/cpp/actors/core/event_pb.cpp b/library/cpp/actors/core/event_pb.cpp index b8f40c28ef..018ff9ac34 100644 --- a/library/cpp/actors/core/event_pb.cpp +++ b/library/cpp/actors/core/event_pb.cpp @@ -9,43 +9,43 @@ namespace NActors { Iter += *size; } else if (Iter.Valid()) { Iter.AdvanceToNextContiguousBlock(); - } + } TotalByteCount += *size; return *size != 0; - } + } void TRopeStream::BackUp(int count) { Y_VERIFY(count <= TotalByteCount); Iter -= count; TotalByteCount -= count; - } + } bool TRopeStream::Skip(int count) { if (static_cast<size_t>(TotalByteCount + count) > Size) { count = Size - TotalByteCount; - } + } Iter += count; TotalByteCount += count; return static_cast<size_t>(TotalByteCount) != Size; } - TCoroutineChunkSerializer::TCoroutineChunkSerializer() - : TotalSerializedDataSize(0) + TCoroutineChunkSerializer::TCoroutineChunkSerializer() + : TotalSerializedDataSize(0) , Stack(64 * 1024) , SelfClosure{this, TArrayRef(Stack.Begin(), Stack.End())} - , InnerContext(SelfClosure) + , InnerContext(SelfClosure) {} - TCoroutineChunkSerializer::~TCoroutineChunkSerializer() { - CancelFlag = true; + TCoroutineChunkSerializer::~TCoroutineChunkSerializer() { + CancelFlag = true; Resume(); Y_VERIFY(Finished); } - - bool TCoroutineChunkSerializer::AllowsAliasing() const { - return true; - } - + + bool TCoroutineChunkSerializer::AllowsAliasing() const { + return true; + } + bool TCoroutineChunkSerializer::Produce(const void *data, size_t size) { Y_VERIFY(size <= SizeRemain); SizeRemain -= size; @@ -71,11 +71,11 @@ namespace NActors { return true; } - bool TCoroutineChunkSerializer::WriteAliasedRaw(const void* data, int size) { - Y_VERIFY(size >= 0); + bool TCoroutineChunkSerializer::WriteAliasedRaw(const void* data, int size) { + Y_VERIFY(size >= 0); while (size) { if (CancelFlag || AbortFlag) { - return false; + return false; } else if (const size_t bytesToAppend = Min<size_t>(size, SizeRemain)) { if (!Produce(data, bytesToAppend)) { return false; @@ -86,29 +86,29 @@ namespace NActors { InnerContext.SwitchTo(BufFeedContext); } } - return true; + return true; } - bool TCoroutineChunkSerializer::Next(void** data, int* size) { + bool TCoroutineChunkSerializer::Next(void** data, int* size) { if (CancelFlag || AbortFlag) { - return false; + return false; } if (!SizeRemain) { - InnerContext.SwitchTo(BufFeedContext); + InnerContext.SwitchTo(BufFeedContext); if (CancelFlag || AbortFlag) { - return false; + return false; } - } + } Y_VERIFY(SizeRemain); *data = BufferPtr; *size = SizeRemain; BufferPtr += SizeRemain; return Produce(*data, *size); - } - - void TCoroutineChunkSerializer::BackUp(int count) { + } + + void TCoroutineChunkSerializer::BackUp(int count) { if (!count) { - return; + return; } Y_VERIFY(count > 0); Y_VERIFY(NumChunks); @@ -121,13 +121,13 @@ namespace NActors { } BufferPtr -= count; SizeRemain += count; - TotalSerializedDataSize -= count; + TotalSerializedDataSize -= count; } - void TCoroutineChunkSerializer::Resume() { - TContMachineContext feedContext; - BufFeedContext = &feedContext; - feedContext.SwitchTo(&InnerContext); + void TCoroutineChunkSerializer::Resume() { + TContMachineContext feedContext; + BufFeedContext = &feedContext; + feedContext.SwitchTo(&InnerContext); BufFeedContext = nullptr; } @@ -155,14 +155,14 @@ namespace NActors { Resume(); return {Chunks, Chunks + NumChunks}; - } + } void TCoroutineChunkSerializer::SetSerializingEvent(const IEventBase *event) { Y_VERIFY(Event == nullptr); Event = event; - TotalSerializedDataSize = 0; + TotalSerializedDataSize = 0; AbortFlag = false; - } + } void TCoroutineChunkSerializer::Abort() { Y_VERIFY(Event); @@ -170,7 +170,7 @@ namespace NActors { Resume(); } - void TCoroutineChunkSerializer::DoRun() { + void TCoroutineChunkSerializer::DoRun() { while (!CancelFlag) { Y_VERIFY(Event); SerializationSuccess = Event->SerializeToArcadiaStream(this); @@ -178,12 +178,12 @@ namespace NActors { if (!CancelFlag) { // cancel flag may have been received during serialization InnerContext.SwitchTo(BufFeedContext); } - } + } Finished = true; InnerContext.SwitchTo(BufFeedContext); } - bool TAllocChunkSerializer::Next(void** pdata, int* psize) { + bool TAllocChunkSerializer::Next(void** pdata, int* psize) { if (Backup) { // we have some data in backup rope -- move the first chunk from the backup rope to the buffer and return // pointer to the buffer; it is safe to remove 'const' here as we uniquely own this buffer @@ -199,17 +199,17 @@ namespace NActors { *psize = item->GetCapacity(); Buffers->Append(TRope(std::move(item))); } - return true; + return true; } - void TAllocChunkSerializer::BackUp(int count) { + void TAllocChunkSerializer::BackUp(int count) { Backup.Insert(Backup.Begin(), Buffers->EraseBack(count)); - } + } - bool TAllocChunkSerializer::WriteAliasedRaw(const void*, int) { - Y_VERIFY(false); - return false; - } + bool TAllocChunkSerializer::WriteAliasedRaw(const void*, int) { + Y_VERIFY(false); + return false; + } bool TAllocChunkSerializer::WriteRope(const TRope *rope) { Buffers->Append(TRope(*rope)); diff --git a/library/cpp/actors/core/event_pb.h b/library/cpp/actors/core/event_pb.h index 76731cbca9..d7546b901a 100644 --- a/library/cpp/actors/core/event_pb.h +++ b/library/cpp/actors/core/event_pb.h @@ -1,6 +1,6 @@ -#pragma once - -#include "event.h" +#pragma once + +#include "event.h" #include "event_load.h" #include <google/protobuf/io/zero_copy_stream.h> @@ -10,19 +10,19 @@ #include <util/system/context.h> #include <util/system/filemap.h> #include <array> - -namespace NActors { + +namespace NActors { class TRopeStream : public NProtoBuf::io::ZeroCopyInputStream { TRope::TConstIterator Iter; const size_t Size; - public: + public: TRopeStream(TRope::TConstIterator iter, size_t size) : Iter(iter) , Size(size) {} - + bool Next(const void** data, int* size) override; void BackUp(int count) override; bool Skip(int count) override; @@ -32,19 +32,19 @@ namespace NActors { private: int64_t TotalByteCount = 0; - }; + }; class TChunkSerializer : public NProtoBuf::io::ZeroCopyOutputStream { - public: + public: TChunkSerializer() = default; virtual ~TChunkSerializer() = default; virtual bool WriteRope(const TRope *rope) = 0; virtual bool WriteString(const TString *s) = 0; - }; + }; class TAllocChunkSerializer final : public TChunkSerializer { - public: + public: bool Next(void** data, int* size) override; void BackUp(int count) override; int64_t ByteCount() const override { @@ -61,29 +61,29 @@ namespace NActors { Buffers->SetExtendedFormat(); } return std::move(Buffers); - } + } - protected: + protected: TIntrusivePtr<TEventSerializedData> Buffers = new TEventSerializedData; TRope Backup; - }; + }; class TCoroutineChunkSerializer final : public TChunkSerializer, protected ITrampoLine { - public: + public: using TChunk = std::pair<const char*, size_t>; - TCoroutineChunkSerializer(); - ~TCoroutineChunkSerializer(); + TCoroutineChunkSerializer(); + ~TCoroutineChunkSerializer(); void SetSerializingEvent(const IEventBase *event); void Abort(); std::pair<TChunk*, TChunk*> FeedBuf(void* data, size_t size); - bool IsComplete() const { + bool IsComplete() const { return !Event; - } - bool IsSuccessfull() const { - return SerializationSuccess; - } + } + bool IsSuccessfull() const { + return SerializationSuccess; + } const IEventBase *GetCurrentEvent() const { return Event; } @@ -99,15 +99,15 @@ namespace NActors { bool WriteRope(const TRope *rope) override; bool WriteString(const TString *s) override; - protected: + protected: void DoRun() override; - void Resume(); + void Resume(); bool Produce(const void *data, size_t size); - i64 TotalSerializedDataSize; - TMappedAllocation Stack; - TContClosure SelfClosure; - TContMachineContext InnerContext; + i64 TotalSerializedDataSize; + TMappedAllocation Stack; + TContClosure SelfClosure; + TContMachineContext InnerContext; TContMachineContext *BufFeedContext = nullptr; char *BufferPtr; size_t SizeRemain; @@ -119,7 +119,7 @@ namespace NActors { bool AbortFlag; bool SerializationSuccess; bool Finished = false; - }; + }; #ifdef ACTORLIB_HUGE_PB_SIZE static const size_t EventMaxByteSize = 140 << 20; // (140MB) @@ -132,11 +132,11 @@ namespace NActors { // a vector of data buffers referenced by record; if filled, then extended serialization mechanism applies TVector<TRope> Payload; - public: + public: using TRecHolder::Record; public: - using ProtoRecordType = TRecord; + using ProtoRecordType = TRecord; TEventPBBase() = default; @@ -150,13 +150,13 @@ namespace NActors { Record = std::move(rec); } - TString ToStringHeader() const override { - return Record.GetTypeName(); - } + TString ToStringHeader() const override { + return Record.GetTypeName(); + } - TString ToString() const override { + TString ToString() const override { return Record.ShortDebugString(); - } + } bool IsSerializable() const override { return true; @@ -213,9 +213,9 @@ namespace NActors { } } - return Record.SerializeToZeroCopyStream(chunker); - } - + return Record.SerializeToZeroCopyStream(chunker); + } + ui32 CalculateSerializedSize() const override { ssize_t result = Record.ByteSize(); if (result >= 0 && Payload) { @@ -227,10 +227,10 @@ namespace NActors { result += rope.GetSize(); } } - return result; + return result; } - static IEventBase* Load(TIntrusivePtr<TEventSerializedData> input) { + static IEventBase* Load(TIntrusivePtr<TEventSerializedData> input) { THolder<TEventPBBase> ev(new TEv()); if (!input->GetSize()) { Y_PROTOBUF_SUPPRESS_NODISCARD ev->Record.ParseFromString(TString()); @@ -270,7 +270,7 @@ namespace NActors { if (!ev->Record.ParseFromZeroCopyStream(&stream)) { Y_FAIL("Failed to parse protobuf event type %" PRIu32 " class %s", TEventType, TypeName(ev->Record).data()); } - } + } ev->CachedByteSize = input->GetSize(); return ev.Release(); } @@ -278,18 +278,18 @@ namespace NActors { size_t GetCachedByteSize() const { if (CachedByteSize == 0) { CachedByteSize = CalculateSerializedSize(); - } - return CachedByteSize; - } + } + return CachedByteSize; + } ui32 CalculateSerializedSizeCached() const override { return GetCachedByteSize(); } - void InvalidateCachedByteSize() { - CachedByteSize = 0; - } - + void InvalidateCachedByteSize() { + CachedByteSize = 0; + } + public: void ReservePayload(size_t size) { Payload.reserve(size); @@ -316,7 +316,7 @@ namespace NActors { } protected: - mutable size_t CachedByteSize = 0; + mutable size_t CachedByteSize = 0; static constexpr char PayloadMarker = 0x07; static constexpr size_t MaxNumberBytes = (sizeof(size_t) * CHAR_BIT + 6) / 7; @@ -367,8 +367,8 @@ namespace NActors { } return res; } - }; - + }; + // Protobuf record not using arena template <typename TRecord> struct TRecordHolder { @@ -490,11 +490,11 @@ namespace NActors { inline TActorId ActorIdFromProto(const NActorsProto::TActorId& actorId) { return TActorId(actorId.GetRawX1(), actorId.GetRawX2()); - } - + } + inline void ActorIdToProto(const TActorId& src, NActorsProto::TActorId* dest) { - Y_VERIFY_DEBUG(dest); - dest->SetRawX1(src.RawX1()); - dest->SetRawX2(src.RawX2()); - } -} + Y_VERIFY_DEBUG(dest); + dest->SetRawX1(src.RawX1()); + dest->SetRawX2(src.RawX2()); + } +} diff --git a/library/cpp/actors/core/events.h b/library/cpp/actors/core/events.h index 5ff747efee..702cf50fad 100644 --- a/library/cpp/actors/core/events.h +++ b/library/cpp/actors/core/events.h @@ -1,99 +1,99 @@ -#pragma once - -#include "event.h" +#pragma once + +#include "event.h" #include "event_pb.h" - + #include <library/cpp/actors/protos/actors.pb.h> #include <util/system/unaligned_mem.h> -namespace NActors { - struct TEvents { - enum EEventSpace { - ES_HELLOWORLD = 0, - ES_SYSTEM = 1, - ES_INTERCONNECT = 2, - ES_INTERCONNECT_MSGBUS = 3, - ES_DNS = 4, - ES_SOCKET_POLLER = 5, - ES_LOGGER = 6, - ES_MON = 7, - ES_INTERCONNECT_TCP = 8, - ES_PROFILER = 9, +namespace NActors { + struct TEvents { + enum EEventSpace { + ES_HELLOWORLD = 0, + ES_SYSTEM = 1, + ES_INTERCONNECT = 2, + ES_INTERCONNECT_MSGBUS = 3, + ES_DNS = 4, + ES_SOCKET_POLLER = 5, + ES_LOGGER = 6, + ES_MON = 7, + ES_INTERCONNECT_TCP = 8, + ES_PROFILER = 9, ES_YF = 10, ES_HTTP = 11, - - ES_USERSPACE = 4096, - - ES_PRIVATE = (1 << 15) - 16, - ES_MAX = (1 << 15), - }; - -#define EventSpaceBegin(eventSpace) (eventSpace << 16u) -#define EventSpaceEnd(eventSpace) ((eventSpace << 16u) + (1u << 16u)) - - struct THelloWorld { - enum { - Start = EventSpaceBegin(ES_HELLOWORLD), - Ping, - Pong, - Blob, - End - }; - - static_assert(End < EventSpaceEnd(ES_HELLOWORLD), "expect End < EventSpaceEnd(ES_HELLOWORLD)"); - }; - - struct TEvPing: public TEventBase<TEvPing, THelloWorld::Ping> { - DEFINE_SIMPLE_NONLOCAL_EVENT(TEvPing, "HelloWorld: Ping"); - }; - - struct TEvPong: public TEventBase<TEvPong, THelloWorld::Pong> { - DEFINE_SIMPLE_NONLOCAL_EVENT(TEvPong, "HelloWorld: Pong"); - }; - - struct TEvBlob: public TEventBase<TEvBlob, THelloWorld::Blob> { - const TString Blob; - - TEvBlob(const TString& blob) noexcept - : Blob(blob) - { - } - - TString ToStringHeader() const noexcept override { - return "THelloWorld::Blob"; - } + + ES_USERSPACE = 4096, + + ES_PRIVATE = (1 << 15) - 16, + ES_MAX = (1 << 15), + }; + +#define EventSpaceBegin(eventSpace) (eventSpace << 16u) +#define EventSpaceEnd(eventSpace) ((eventSpace << 16u) + (1u << 16u)) + + struct THelloWorld { + enum { + Start = EventSpaceBegin(ES_HELLOWORLD), + Ping, + Pong, + Blob, + End + }; + + static_assert(End < EventSpaceEnd(ES_HELLOWORLD), "expect End < EventSpaceEnd(ES_HELLOWORLD)"); + }; + + struct TEvPing: public TEventBase<TEvPing, THelloWorld::Ping> { + DEFINE_SIMPLE_NONLOCAL_EVENT(TEvPing, "HelloWorld: Ping"); + }; + + struct TEvPong: public TEventBase<TEvPong, THelloWorld::Pong> { + DEFINE_SIMPLE_NONLOCAL_EVENT(TEvPong, "HelloWorld: Pong"); + }; + + struct TEvBlob: public TEventBase<TEvBlob, THelloWorld::Blob> { + const TString Blob; + + TEvBlob(const TString& blob) noexcept + : Blob(blob) + { + } + + TString ToStringHeader() const noexcept override { + return "THelloWorld::Blob"; + } bool SerializeToArcadiaStream(TChunkSerializer *serializer) const override { return serializer->WriteString(&Blob); - } + } - static IEventBase* Load(TEventSerializedData* bufs) noexcept { + static IEventBase* Load(TEventSerializedData* bufs) noexcept { return new TEvBlob(bufs->GetString()); - } + } bool IsSerializable() const override { return true; } - }; - - struct TSystem { - enum { - Start = EventSpaceBegin(ES_SYSTEM), - Bootstrap, // generic bootstrap event - Wakeup, // generic timeout - Subscribe, // generic subscribe to something - Unsubscribe, // generic unsubscribe from something - Delivered, // event delivered - Undelivered, // event undelivered + }; + + struct TSystem { + enum { + Start = EventSpaceBegin(ES_SYSTEM), + Bootstrap, // generic bootstrap event + Wakeup, // generic timeout + Subscribe, // generic subscribe to something + Unsubscribe, // generic unsubscribe from something + Delivered, // event delivered + Undelivered, // event undelivered Poison, // request actor to shutdown - Completed, // generic async job result event + Completed, // generic async job result event PoisonTaken, // generic Poison taken (reply to PoisonPill event, i.e. died completely) - FlushLog, - CallbackCompletion, - CallbackException, + FlushLog, + CallbackCompletion, + CallbackException, Gone, // Generic notification of actor death - TrackActor, - UntrackActor, + TrackActor, + UntrackActor, InvokeResult, CoroTimeout, InvokeQuery, @@ -102,61 +102,61 @@ namespace NActors { // Compatibility section PoisonPill = Poison, ActorDied = Gone, - }; - - static_assert(End < EventSpaceEnd(ES_SYSTEM), "expect End < EventSpaceEnd(ES_SYSTEM)"); - }; - - struct TEvBootstrap: public TEventBase<TEvBootstrap, TSystem::Bootstrap> { - DEFINE_SIMPLE_LOCAL_EVENT(TEvBootstrap, "System: TEvBootstrap") - }; - + }; + + static_assert(End < EventSpaceEnd(ES_SYSTEM), "expect End < EventSpaceEnd(ES_SYSTEM)"); + }; + + struct TEvBootstrap: public TEventBase<TEvBootstrap, TSystem::Bootstrap> { + DEFINE_SIMPLE_LOCAL_EVENT(TEvBootstrap, "System: TEvBootstrap") + }; + struct TEvPoison : public TEventBase<TEvPoison, TSystem::Poison> { DEFINE_SIMPLE_NONLOCAL_EVENT(TEvPoison, "System: TEvPoison") - }; - - struct TEvWakeup: public TEventBase<TEvWakeup, TSystem::Wakeup> { - DEFINE_SIMPLE_LOCAL_EVENT(TEvWakeup, "System: TEvWakeup") + }; + + struct TEvWakeup: public TEventBase<TEvWakeup, TSystem::Wakeup> { + DEFINE_SIMPLE_LOCAL_EVENT(TEvWakeup, "System: TEvWakeup") TEvWakeup(ui64 tag = 0) : Tag(tag) { } const ui64 Tag = 0; - }; - - struct TEvSubscribe: public TEventBase<TEvSubscribe, TSystem::Subscribe> { - DEFINE_SIMPLE_LOCAL_EVENT(TEvSubscribe, "System: TEvSubscribe") - }; - - struct TEvUnsubscribe: public TEventBase<TEvUnsubscribe, TSystem::Unsubscribe> { - DEFINE_SIMPLE_LOCAL_EVENT(TEvUnsubscribe, "System: TEvUnsubscribe") - }; - - struct TEvUndelivered: public TEventBase<TEvUndelivered, TSystem::Undelivered> { - enum EReason { - ReasonUnknown, - ReasonActorUnknown, - Disconnected - }; - const ui32 SourceType; - const EReason Reason; + }; + + struct TEvSubscribe: public TEventBase<TEvSubscribe, TSystem::Subscribe> { + DEFINE_SIMPLE_LOCAL_EVENT(TEvSubscribe, "System: TEvSubscribe") + }; + + struct TEvUnsubscribe: public TEventBase<TEvUnsubscribe, TSystem::Unsubscribe> { + DEFINE_SIMPLE_LOCAL_EVENT(TEvUnsubscribe, "System: TEvUnsubscribe") + }; + + struct TEvUndelivered: public TEventBase<TEvUndelivered, TSystem::Undelivered> { + enum EReason { + ReasonUnknown, + ReasonActorUnknown, + Disconnected + }; + const ui32 SourceType; + const EReason Reason; const bool Unsure; const TString Data; TEvUndelivered(ui32 sourceType, ui32 reason, bool unsure = false) - : SourceType(sourceType) - , Reason(static_cast<EReason>(reason)) + : SourceType(sourceType) + , Reason(static_cast<EReason>(reason)) , Unsure(unsure) , Data(MakeData(sourceType, reason)) {} - - TString ToStringHeader() const override; + + TString ToStringHeader() const override; bool SerializeToArcadiaStream(TChunkSerializer *serializer) const override; - static IEventBase* Load(TEventSerializedData* bufs); + static IEventBase* Load(TEventSerializedData* bufs); bool IsSerializable() const override; - + ui32 CalculateSerializedSize() const override { return 2 * sizeof(ui32); } - static void Out(IOutputStream& o, EReason x); + static void Out(IOutputStream& o, EReason x); private: static TString MakeData(ui32 sourceType, ui32 reason) { @@ -166,57 +166,57 @@ namespace NActors { WriteUnaligned<ui32>(p + 4, reason); return s; } - }; - - struct TEvCompleted: public TEventBase<TEvCompleted, TSystem::Completed> { - const ui32 Id; - const ui32 Status; - TEvCompleted(ui32 id = 0, ui32 status = 0) - : Id(id) - , Status(status) - { - } - - DEFINE_SIMPLE_LOCAL_EVENT(TEvCompleted, "System: TEvCompleted") - }; - - struct TEvPoisonTaken: public TEventBase<TEvPoisonTaken, TSystem::PoisonTaken> { - DEFINE_SIMPLE_LOCAL_EVENT(TEvPoisonTaken, "System: TEvPoisonTaken") - }; - - struct TEvFlushLog: public TEventBase<TEvFlushLog, TSystem::FlushLog> { - DEFINE_SIMPLE_LOCAL_EVENT(TEvFlushLog, "System: TEvFlushLog") - }; - - struct TEvCallbackException: public TEventPB<TEvCallbackException, - NActorsProto::TCallbackException, - TSystem::CallbackException> { + }; + + struct TEvCompleted: public TEventBase<TEvCompleted, TSystem::Completed> { + const ui32 Id; + const ui32 Status; + TEvCompleted(ui32 id = 0, ui32 status = 0) + : Id(id) + , Status(status) + { + } + + DEFINE_SIMPLE_LOCAL_EVENT(TEvCompleted, "System: TEvCompleted") + }; + + struct TEvPoisonTaken: public TEventBase<TEvPoisonTaken, TSystem::PoisonTaken> { + DEFINE_SIMPLE_LOCAL_EVENT(TEvPoisonTaken, "System: TEvPoisonTaken") + }; + + struct TEvFlushLog: public TEventBase<TEvFlushLog, TSystem::FlushLog> { + DEFINE_SIMPLE_LOCAL_EVENT(TEvFlushLog, "System: TEvFlushLog") + }; + + struct TEvCallbackException: public TEventPB<TEvCallbackException, + NActorsProto::TCallbackException, + TSystem::CallbackException> { TEvCallbackException(const TActorId& id, const TString& msg) { ActorIdToProto(id, Record.MutableActorId()); - Record.SetExceptionMessage(msg); - } - }; + Record.SetExceptionMessage(msg); + } + }; - struct TEvCallbackCompletion: public TEventPB<TEvCallbackCompletion, + struct TEvCallbackCompletion: public TEventPB<TEvCallbackCompletion, NActorsProto::TActorId, - TSystem::CallbackCompletion> { + TSystem::CallbackCompletion> { TEvCallbackCompletion(const TActorId& id) { ActorIdToProto(id, &Record); - } - }; - + } + }; + struct TEvGone: public TEventBase<TEvGone, TSystem::Gone> { DEFINE_SIMPLE_LOCAL_EVENT(TEvGone, "System: TEvGone") - }; + }; struct TEvInvokeResult; using TEvPoisonPill = TEvPoison; // Legacy name, deprecated using TEvActorDied = TEvGone; }; -} - -template <> -inline void Out<NActors::TEvents::TEvUndelivered::EReason>(IOutputStream& o, NActors::TEvents::TEvUndelivered::EReason x) { - NActors::TEvents::TEvUndelivered::Out(o, x); -} +} + +template <> +inline void Out<NActors::TEvents::TEvUndelivered::EReason>(IOutputStream& o, NActors::TEvents::TEvUndelivered::EReason x) { + NActors::TEvents::TEvUndelivered::Out(o, x); +} diff --git a/library/cpp/actors/core/events_undelivered.cpp b/library/cpp/actors/core/events_undelivered.cpp index 6ba2d685ee..23deaffd10 100644 --- a/library/cpp/actors/core/events_undelivered.cpp +++ b/library/cpp/actors/core/events_undelivered.cpp @@ -1,54 +1,54 @@ -#include "events.h" +#include "events.h" #include "actorsystem.h" - -namespace NActors { - TString TEvents::TEvUndelivered::ToStringHeader() const { - return "TSystem::Undelivered"; - } - + +namespace NActors { + TString TEvents::TEvUndelivered::ToStringHeader() const { + return "TSystem::Undelivered"; + } + bool TEvents::TEvUndelivered::SerializeToArcadiaStream(TChunkSerializer *serializer) const { Y_VERIFY(!Unsure); // these are local-only events generated by Interconnect return serializer->WriteString(&Data); - } - - void TEvents::TEvUndelivered::Out(IOutputStream& o, EReason x) { - switch (x) { - case ReasonActorUnknown: - o << "ActorUnknown"; - break; - case Disconnected: - o << "Disconnected"; - break; - default: - o << "Undefined"; - break; - } - } - + } + + void TEvents::TEvUndelivered::Out(IOutputStream& o, EReason x) { + switch (x) { + case ReasonActorUnknown: + o << "ActorUnknown"; + break; + case Disconnected: + o << "Disconnected"; + break; + default: + o << "Undefined"; + break; + } + } + bool TEvents::TEvUndelivered::IsSerializable() const { return true; } - IEventBase* TEvents::TEvUndelivered::Load(TEventSerializedData* bufs) { + IEventBase* TEvents::TEvUndelivered::Load(TEventSerializedData* bufs) { TString str = bufs->GetString(); - Y_VERIFY(str.size() == (sizeof(ui32) + sizeof(ui32))); + Y_VERIFY(str.size() == (sizeof(ui32) + sizeof(ui32))); const char* p = str.data(); const ui64 sourceType = ReadUnaligned<ui32>(p + 0); const ui64 reason = ReadUnaligned<ui32>(p + 4); - return new TEvUndelivered(sourceType, reason); - } - + return new TEvUndelivered(sourceType, reason); + } + TAutoPtr<IEventHandle> IEventHandle::ForwardOnNondelivery(ui32 reason, bool unsure) { if (Flags & FlagForwardOnNondelivery) { - const ui32 updatedFlags = Flags & ~(FlagForwardOnNondelivery | FlagSubscribeOnSession); + const ui32 updatedFlags = Flags & ~(FlagForwardOnNondelivery | FlagSubscribeOnSession); const TActorId recp = OnNondeliveryHolder ? OnNondeliveryHolder->Recipient : TActorId(); - - if (Event) - return new IEventHandle(recp, Sender, Event.Release(), updatedFlags, Cookie, &Recipient, TraceId.Clone()); - else + + if (Event) + return new IEventHandle(recp, Sender, Event.Release(), updatedFlags, Cookie, &Recipient, TraceId.Clone()); + else return new IEventHandle(Type, updatedFlags, recp, Sender, Buffer, Cookie, &Recipient, TraceId.Clone()); - } - + } + if (Flags & FlagTrackDelivery) { const ui32 updatedFlags = Flags & ~(FlagTrackDelivery | FlagSubscribeOnSession | FlagGenerateUnsureUndelivered); return new IEventHandle(Sender, Recipient, new TEvents::TEvUndelivered(Type, reason, unsure), updatedFlags, @@ -56,5 +56,5 @@ namespace NActors { } return nullptr; - } -} + } +} diff --git a/library/cpp/actors/core/executelater.h b/library/cpp/actors/core/executelater.h index dd617047d8..e7a13c1005 100644 --- a/library/cpp/actors/core/executelater.h +++ b/library/cpp/actors/core/executelater.h @@ -5,36 +5,36 @@ #include <utility> namespace NActors { - template <typename TCallback> - class TExecuteLater: public TActorBootstrapped<TExecuteLater<TCallback>> { - public: + template <typename TCallback> + class TExecuteLater: public TActorBootstrapped<TExecuteLater<TCallback>> { + public: static constexpr IActor::EActivityType ActorActivityType() { return IActor::ACTORLIB_COMMON; } - TExecuteLater( + TExecuteLater( TCallback&& callback, IActor::EActivityType activityType, ui32 channel = 0, ui64 cookie = 0, const TActorId& reportCompletionTo = TActorId(), const TActorId& reportExceptionTo = TActorId()) noexcept - : Callback(std::move(callback)) - , Channel(channel) - , Cookie(cookie) - , ReportCompletionTo(reportCompletionTo) - , ReportExceptionTo(reportExceptionTo) - { - this->SetActivityType(activityType); - } + : Callback(std::move(callback)) + , Channel(channel) + , Cookie(cookie) + , ReportCompletionTo(reportCompletionTo) + , ReportExceptionTo(reportExceptionTo) + { + this->SetActivityType(activityType); + } - void Bootstrap(const TActorContext& ctx) noexcept { - try { - { - /* RAII, Callback should be destroyed right before sending + void Bootstrap(const TActorContext& ctx) noexcept { + try { + { + /* RAII, Callback should be destroyed right before sending TEvCallbackCompletion */ - auto local = std::move(Callback); + auto local = std::move(Callback); using T = decltype(local); if constexpr (std::is_invocable_v<T, const TActorContext&>) { @@ -42,46 +42,46 @@ namespace NActors { } else { local(); } - } - - if (ReportCompletionTo) { - ctx.Send(ReportCompletionTo, - new TEvents::TEvCallbackCompletion(ctx.SelfID), - Channel, Cookie); - } - } catch (...) { - if (ReportExceptionTo) { - const TString msg = CurrentExceptionMessage(); - ctx.Send(ReportExceptionTo, - new TEvents::TEvCallbackException(ctx.SelfID, msg), - Channel, Cookie); - } + } + + if (ReportCompletionTo) { + ctx.Send(ReportCompletionTo, + new TEvents::TEvCallbackCompletion(ctx.SelfID), + Channel, Cookie); + } + } catch (...) { + if (ReportExceptionTo) { + const TString msg = CurrentExceptionMessage(); + ctx.Send(ReportExceptionTo, + new TEvents::TEvCallbackException(ctx.SelfID, msg), + Channel, Cookie); + } } - this->Die(ctx); + this->Die(ctx); } - private: - TCallback Callback; - const ui32 Channel; - const ui64 Cookie; + private: + TCallback Callback; + const ui32 Channel; + const ui64 Cookie; const TActorId ReportCompletionTo; const TActorId ReportExceptionTo; - }; + }; - template <typename T> - IActor* CreateExecuteLaterActor( + template <typename T> + IActor* CreateExecuteLaterActor( T&& func, IActor::EActivityType activityType, ui32 channel = 0, ui64 cookie = 0, const TActorId& reportCompletionTo = TActorId(), const TActorId& reportExceptionTo = TActorId()) noexcept { - return new TExecuteLater<T>(std::forward<T>(func), - activityType, - channel, - cookie, - reportCompletionTo, - reportExceptionTo); - } + return new TExecuteLater<T>(std::forward<T>(func), + activityType, + channel, + cookie, + reportCompletionTo, + reportExceptionTo); + } } diff --git a/library/cpp/actors/core/executor_pool_base.cpp b/library/cpp/actors/core/executor_pool_base.cpp index 1e47aa179c..c3b9999168 100644 --- a/library/cpp/actors/core/executor_pool_base.cpp +++ b/library/cpp/actors/core/executor_pool_base.cpp @@ -1,21 +1,21 @@ -#include "executor_pool_base.h" -#include "executor_thread.h" -#include "mailbox.h" +#include "executor_pool_base.h" +#include "executor_thread.h" +#include "mailbox.h" #include "probes.h" #include <library/cpp/actors/util/datetime.h> - -namespace NActors { - LWTRACE_USING(ACTORLIB_PROVIDER); - + +namespace NActors { + LWTRACE_USING(ACTORLIB_PROVIDER); + void DoActorInit(TActorSystem* sys, IActor* actor, const TActorId& self, const TActorId& owner) { actor->SelfActorId = self; actor->Registered(sys, owner); - } + } TExecutorPoolBaseMailboxed::TExecutorPoolBaseMailboxed(ui32 poolId, ui32 maxActivityType) - : IExecutorPool(poolId) - , ActorSystem(nullptr) - , MailboxTable(new TMailboxTable) + : IExecutorPool(poolId) + , ActorSystem(nullptr) + , MailboxTable(new TMailboxTable) #ifdef ACTORSLIB_COLLECT_EXEC_STATS , Stats(maxActivityType) #endif @@ -23,146 +23,146 @@ namespace NActors { TExecutorPoolBaseMailboxed::~TExecutorPoolBaseMailboxed() { MailboxTable.Destroy(); - } - + } + TExecutorPoolBase::TExecutorPoolBase(ui32 poolId, ui32 threads, TAffinity* affinity, ui32 maxActivityType) : TExecutorPoolBaseMailboxed(poolId, maxActivityType) , PoolThreads(threads) , ThreadsAffinity(affinity) {} - TExecutorPoolBase::~TExecutorPoolBase() { - while (Activations.Pop(0)) - ; - } - + TExecutorPoolBase::~TExecutorPoolBase() { + while (Activations.Pop(0)) + ; + } + void TExecutorPoolBaseMailboxed::ReclaimMailbox(TMailboxType::EType mailboxType, ui32 hint, TWorkerId workerId, ui64 revolvingWriteCounter) { Y_UNUSED(workerId); - MailboxTable->ReclaimMailbox(mailboxType, hint, revolvingWriteCounter); - } - + MailboxTable->ReclaimMailbox(mailboxType, hint, revolvingWriteCounter); + } + ui64 TExecutorPoolBaseMailboxed::AllocateID() { - return ActorSystem->AllocateIDSpace(1); - } - + return ActorSystem->AllocateIDSpace(1); + } + bool TExecutorPoolBaseMailboxed::Send(TAutoPtr<IEventHandle>& ev) { - Y_VERIFY_DEBUG(ev->GetRecipientRewrite().PoolID() == PoolId); + Y_VERIFY_DEBUG(ev->GetRecipientRewrite().PoolID() == PoolId); #ifdef ACTORSLIB_COLLECT_EXEC_STATS RelaxedStore(&ev->SendTime, (::NHPTimer::STime)GetCycleCountFast()); #endif - return MailboxTable->SendTo(ev, this); - } - - void TExecutorPoolBase::ScheduleActivation(ui32 activation) { - ScheduleActivationEx(activation, AtomicIncrement(ActivationsRevolvingCounter)); - } - + return MailboxTable->SendTo(ev, this); + } + + void TExecutorPoolBase::ScheduleActivation(ui32 activation) { + ScheduleActivationEx(activation, AtomicIncrement(ActivationsRevolvingCounter)); + } + TActorId TExecutorPoolBaseMailboxed::Register(IActor* actor, TMailboxType::EType mailboxType, ui64 revolvingWriteCounter, const TActorId& parentId) { NHPTimer::STime hpstart = GetCycleCountFast(); #ifdef ACTORSLIB_COLLECT_EXEC_STATS - ui32 at = actor->GetActivityType(); - if (at >= Stats.MaxActivityType()) - at = 0; - AtomicIncrement(Stats.ActorsAliveByActivity[at]); + ui32 at = actor->GetActivityType(); + if (at >= Stats.MaxActivityType()) + at = 0; + AtomicIncrement(Stats.ActorsAliveByActivity[at]); #endif - AtomicIncrement(ActorRegistrations); + AtomicIncrement(ActorRegistrations); - // first step - find good enough mailbox - ui32 hint = 0; - TMailboxHeader* mailbox = nullptr; + // first step - find good enough mailbox + ui32 hint = 0; + TMailboxHeader* mailbox = nullptr; - if (revolvingWriteCounter == 0) + if (revolvingWriteCounter == 0) revolvingWriteCounter = AtomicIncrement(RegisterRevolvingCounter); - { - ui32 hintBackoff = 0; + { + ui32 hintBackoff = 0; - while (hint == 0) { - hint = MailboxTable->AllocateMailbox(mailboxType, ++revolvingWriteCounter); - mailbox = MailboxTable->Get(hint); + while (hint == 0) { + hint = MailboxTable->AllocateMailbox(mailboxType, ++revolvingWriteCounter); + mailbox = MailboxTable->Get(hint); - if (!mailbox->LockFromFree()) { - MailboxTable->ReclaimMailbox(mailboxType, hintBackoff, ++revolvingWriteCounter); - hintBackoff = hint; - hint = 0; - } + if (!mailbox->LockFromFree()) { + MailboxTable->ReclaimMailbox(mailboxType, hintBackoff, ++revolvingWriteCounter); + hintBackoff = hint; + hint = 0; + } } - - MailboxTable->ReclaimMailbox(mailboxType, hintBackoff, ++revolvingWriteCounter); + + MailboxTable->ReclaimMailbox(mailboxType, hintBackoff, ++revolvingWriteCounter); } - const ui64 localActorId = AllocateID(); + const ui64 localActorId = AllocateID(); - // ok, got mailbox - mailbox->AttachActor(localActorId, actor); + // ok, got mailbox + mailbox->AttachActor(localActorId, actor); - // do init + // do init const TActorId actorId(ActorSystem->NodeId, PoolId, localActorId, hint); DoActorInit(ActorSystem, actor, actorId, parentId); - // Once we unlock the mailbox the actor starts running and we cannot use the pointer any more - actor = nullptr; + // Once we unlock the mailbox the actor starts running and we cannot use the pointer any more + actor = nullptr; - switch (mailboxType) { - case TMailboxType::Simple: + switch (mailboxType) { + case TMailboxType::Simple: UnlockFromExecution((TMailboxTable::TSimpleMailbox*)mailbox, this, false, hint, MaxWorkers, ++revolvingWriteCounter); - break; - case TMailboxType::Revolving: + break; + case TMailboxType::Revolving: UnlockFromExecution((TMailboxTable::TRevolvingMailbox*)mailbox, this, false, hint, MaxWorkers, ++revolvingWriteCounter); - break; - case TMailboxType::HTSwap: + break; + case TMailboxType::HTSwap: UnlockFromExecution((TMailboxTable::THTSwapMailbox*)mailbox, this, false, hint, MaxWorkers, ++revolvingWriteCounter); - break; - case TMailboxType::ReadAsFilled: + break; + case TMailboxType::ReadAsFilled: UnlockFromExecution((TMailboxTable::TReadAsFilledMailbox*)mailbox, this, false, hint, MaxWorkers, ++revolvingWriteCounter); - break; - case TMailboxType::TinyReadAsFilled: + break; + case TMailboxType::TinyReadAsFilled: UnlockFromExecution((TMailboxTable::TTinyReadAsFilledMailbox*)mailbox, this, false, hint, MaxWorkers, ++revolvingWriteCounter); - break; - default: - Y_FAIL(); - } + break; + default: + Y_FAIL(); + } NHPTimer::STime elapsed = GetCycleCountFast() - hpstart; - if (elapsed > 1000000) { - LWPROBE(SlowRegisterNew, PoolId, NHPTimer::GetSeconds(elapsed) * 1000.0); - } + if (elapsed > 1000000) { + LWPROBE(SlowRegisterNew, PoolId, NHPTimer::GetSeconds(elapsed) * 1000.0); + } - return actorId; + return actorId; } TActorId TExecutorPoolBaseMailboxed::Register(IActor* actor, TMailboxHeader* mailbox, ui32 hint, const TActorId& parentId) { NHPTimer::STime hpstart = GetCycleCountFast(); #ifdef ACTORSLIB_COLLECT_EXEC_STATS - ui32 at = actor->GetActivityType(); - if (at >= Stats.MaxActivityType()) - at = 0; - AtomicIncrement(Stats.ActorsAliveByActivity[at]); + ui32 at = actor->GetActivityType(); + if (at >= Stats.MaxActivityType()) + at = 0; + AtomicIncrement(Stats.ActorsAliveByActivity[at]); #endif - AtomicIncrement(ActorRegistrations); + AtomicIncrement(ActorRegistrations); - const ui64 localActorId = AllocateID(); - mailbox->AttachActor(localActorId, actor); + const ui64 localActorId = AllocateID(); + mailbox->AttachActor(localActorId, actor); const TActorId actorId(ActorSystem->NodeId, PoolId, localActorId, hint); DoActorInit(ActorSystem, actor, actorId, parentId); NHPTimer::STime elapsed = GetCycleCountFast() - hpstart; - if (elapsed > 1000000) { - LWPROBE(SlowRegisterAdd, PoolId, NHPTimer::GetSeconds(elapsed) * 1000.0); - } - - return actorId; + if (elapsed > 1000000) { + LWPROBE(SlowRegisterAdd, PoolId, NHPTimer::GetSeconds(elapsed) * 1000.0); + } + + return actorId; } - TAffinity* TExecutorPoolBase::Affinity() const { - return ThreadsAffinity.Get(); - } + TAffinity* TExecutorPoolBase::Affinity() const { + return ThreadsAffinity.Get(); + } bool TExecutorPoolBaseMailboxed::Cleanup() { - return MailboxTable->Cleanup(); - } + return MailboxTable->Cleanup(); + } ui32 TExecutorPoolBase::GetThreads() const { return PoolThreads; } -} +} diff --git a/library/cpp/actors/core/executor_pool_base.h b/library/cpp/actors/core/executor_pool_base.h index 1f8c036376..c84ce1af77 100644 --- a/library/cpp/actors/core/executor_pool_base.h +++ b/library/cpp/actors/core/executor_pool_base.h @@ -1,34 +1,34 @@ -#pragma once - -#include "actorsystem.h" -#include "executor_thread.h" -#include "scheduler_queue.h" +#pragma once + +#include "actorsystem.h" +#include "executor_thread.h" +#include "scheduler_queue.h" #include <library/cpp/actors/util/affinity.h> #include <library/cpp/actors/util/unordered_cache.h> #include <library/cpp/actors/util/threadparkpad.h> - -namespace NActors { + +namespace NActors { class TExecutorPoolBaseMailboxed: public IExecutorPool { - protected: - TActorSystem* ActorSystem; - THolder<TMailboxTable> MailboxTable; + protected: + TActorSystem* ActorSystem; + THolder<TMailboxTable> MailboxTable; #ifdef ACTORSLIB_COLLECT_EXEC_STATS - // Need to have per pool object to collect stats like actor registrations (because - // registrations might be done in threads from other pools) - TExecutorThreadStats Stats; + // Need to have per pool object to collect stats like actor registrations (because + // registrations might be done in threads from other pools) + TExecutorThreadStats Stats; #endif TAtomic RegisterRevolvingCounter = 0; ui64 AllocateID(); - public: + public: TExecutorPoolBaseMailboxed(ui32 poolId, ui32 maxActivityType); ~TExecutorPoolBaseMailboxed(); void ReclaimMailbox(TMailboxType::EType mailboxType, ui32 hint, TWorkerId workerId, ui64 revolvingWriteCounter) override; - bool Send(TAutoPtr<IEventHandle>& ev) override; + bool Send(TAutoPtr<IEventHandle>& ev) override; TActorId Register(IActor* actor, TMailboxType::EType mailboxType, ui64 revolvingWriteCounter, const TActorId& parentId) override; TActorId Register(IActor* actor, TMailboxHeader* mailbox, ui32 hint, const TActorId& parentId) override; - bool Cleanup() override; + bool Cleanup() override; }; - + class TExecutorPoolBase: public TExecutorPoolBaseMailboxed { protected: const ui32 PoolThreads; @@ -41,9 +41,9 @@ namespace NActors { TExecutorPoolBase(ui32 poolId, ui32 threads, TAffinity* affinity, ui32 maxActivityType); ~TExecutorPoolBase(); void ScheduleActivation(ui32 activation) override; - TAffinity* Affinity() const override; + TAffinity* Affinity() const override; ui32 GetThreads() const override; - }; + }; void DoActorInit(TActorSystem*, IActor*, const TActorId&, const TActorId&); -} +} diff --git a/library/cpp/actors/core/executor_pool_basic.cpp b/library/cpp/actors/core/executor_pool_basic.cpp index 1645ba1910..4dce16939a 100644 --- a/library/cpp/actors/core/executor_pool_basic.cpp +++ b/library/cpp/actors/core/executor_pool_basic.cpp @@ -1,43 +1,43 @@ -#include "executor_pool_basic.h" +#include "executor_pool_basic.h" #include "probes.h" -#include "mailbox.h" +#include "mailbox.h" #include <library/cpp/actors/util/affinity.h> #include <library/cpp/actors/util/datetime.h> - + #ifdef _linux_ -#include <pthread.h> +#include <pthread.h> #endif -namespace NActors { - LWTRACE_USING(ACTORLIB_PROVIDER); - - constexpr TDuration TBasicExecutorPool::DEFAULT_TIME_PER_MAILBOX; +namespace NActors { + LWTRACE_USING(ACTORLIB_PROVIDER); + + constexpr TDuration TBasicExecutorPool::DEFAULT_TIME_PER_MAILBOX; - TBasicExecutorPool::TBasicExecutorPool( + TBasicExecutorPool::TBasicExecutorPool( ui32 poolId, ui32 threads, ui64 spinThreshold, const TString& poolName, - TAffinity* affinity, + TAffinity* affinity, TDuration timePerMailbox, ui32 eventsPerMailbox, int realtimePriority, ui32 maxActivityType) : TExecutorPoolBase(poolId, threads, affinity, maxActivityType) - , SpinThreshold(spinThreshold) - , SpinThresholdCycles(spinThreshold * NHPTimer::GetCyclesPerSecond() * 0.000001) // convert microseconds to cycles - , Threads(new TThreadCtx[threads]) - , PoolName(poolName) - , TimePerMailbox(timePerMailbox) - , EventsPerMailbox(eventsPerMailbox) - , RealtimePriority(realtimePriority) - , ThreadUtilization(0) - , MaxUtilizationCounter(0) - , MaxUtilizationAccumulator(0) + , SpinThreshold(spinThreshold) + , SpinThresholdCycles(spinThreshold * NHPTimer::GetCyclesPerSecond() * 0.000001) // convert microseconds to cycles + , Threads(new TThreadCtx[threads]) + , PoolName(poolName) + , TimePerMailbox(timePerMailbox) + , EventsPerMailbox(eventsPerMailbox) + , RealtimePriority(realtimePriority) + , ThreadUtilization(0) + , MaxUtilizationCounter(0) + , MaxUtilizationAccumulator(0) , ThreadCount(threads) - { - } - + { + } + TBasicExecutorPool::TBasicExecutorPool(const TBasicExecutorPoolConfig& cfg) : TBasicExecutorPool( cfg.PoolId, @@ -52,20 +52,20 @@ namespace NActors { ) {} - TBasicExecutorPool::~TBasicExecutorPool() { - Threads.Destroy(); - } - + TBasicExecutorPool::~TBasicExecutorPool() { + Threads.Destroy(); + } + ui32 TBasicExecutorPool::GetReadyActivation(TWorkerContext& wctx, ui64 revolvingCounter) { ui32 workerId = wctx.WorkerId; Y_VERIFY_DEBUG(workerId < PoolThreads); - - NHPTimer::STime elapsed = 0; - NHPTimer::STime parked = 0; + + NHPTimer::STime elapsed = 0; + NHPTimer::STime parked = 0; NHPTimer::STime blocked = 0; NHPTimer::STime hpstart = GetCycleCountFast(); - NHPTimer::STime hpnow; - + NHPTimer::STime hpnow; + TThreadCtx& threadCtx = Threads[workerId]; AtomicSet(threadCtx.WaitingFlag, TThreadCtx::WS_NONE); @@ -82,11 +82,11 @@ namespace NActors { } while (AtomicGet(threadCtx.BlockedFlag) != TThreadCtx::BS_NONE && !AtomicLoad(&StopFlag)); } - const TAtomic x = AtomicDecrement(Semaphore); - - if (x < 0) { -#if defined ACTORSLIB_COLLECT_EXEC_STATS - if (AtomicGetAndIncrement(ThreadUtilization) == 0) { + const TAtomic x = AtomicDecrement(Semaphore); + + if (x < 0) { +#if defined ACTORSLIB_COLLECT_EXEC_STATS + if (AtomicGetAndIncrement(ThreadUtilization) == 0) { // Initially counter contains -t0, the pool start timestamp // When the first thread goes to sleep we add t1, so the counter // becomes t1-t0 >= 0, or the duration of max utilization so far. @@ -98,67 +98,67 @@ namespace NActors { const i64 x = AtomicGetAndAdd(MaxUtilizationCounter, t); if (x < 0 && x + t > 0) AtomicStore(&MaxUtilizationAccumulator, x + t); - } -#endif - + } +#endif + Y_VERIFY(AtomicLoad(&threadCtx.WaitingFlag) == TThreadCtx::WS_NONE); - - if (SpinThreshold > 0) { - // spin configured period - AtomicSet(threadCtx.WaitingFlag, TThreadCtx::WS_ACTIVE); + + if (SpinThreshold > 0) { + // spin configured period + AtomicSet(threadCtx.WaitingFlag, TThreadCtx::WS_ACTIVE); ui64 start = GetCycleCountFast(); - bool doSpin = true; - while (true) { - for (ui32 j = 0; doSpin && j < 12; ++j) { + bool doSpin = true; + while (true) { + for (ui32 j = 0; doSpin && j < 12; ++j) { if (GetCycleCountFast() >= (start + SpinThresholdCycles)) { doSpin = false; break; } - for (ui32 i = 0; i < 12; ++i) { - if (AtomicLoad(&threadCtx.WaitingFlag) == TThreadCtx::WS_ACTIVE) { - SpinLockPause(); - } else { - doSpin = false; - break; - } - } + for (ui32 i = 0; i < 12; ++i) { + if (AtomicLoad(&threadCtx.WaitingFlag) == TThreadCtx::WS_ACTIVE) { + SpinLockPause(); + } else { + doSpin = false; + break; + } + } + } + if (!doSpin) { + break; } - if (!doSpin) { - break; - } if (RelaxedLoad(&StopFlag)) { - break; - } - } - // then - sleep - if (AtomicLoad(&threadCtx.WaitingFlag) == TThreadCtx::WS_ACTIVE) { - if (AtomicCas(&threadCtx.WaitingFlag, TThreadCtx::WS_BLOCKED, TThreadCtx::WS_ACTIVE)) { - do { + break; + } + } + // then - sleep + if (AtomicLoad(&threadCtx.WaitingFlag) == TThreadCtx::WS_ACTIVE) { + if (AtomicCas(&threadCtx.WaitingFlag, TThreadCtx::WS_BLOCKED, TThreadCtx::WS_ACTIVE)) { + do { hpnow = GetCycleCountFast(); - elapsed += hpnow - hpstart; - if (threadCtx.Pad.Park()) // interrupted - return 0; + elapsed += hpnow - hpstart; + if (threadCtx.Pad.Park()) // interrupted + return 0; hpstart = GetCycleCountFast(); - parked += hpstart - hpnow; - } while (AtomicLoad(&threadCtx.WaitingFlag) == TThreadCtx::WS_BLOCKED); - } + parked += hpstart - hpnow; + } while (AtomicLoad(&threadCtx.WaitingFlag) == TThreadCtx::WS_BLOCKED); + } } - } else { + } else { AtomicSet(threadCtx.WaitingFlag, TThreadCtx::WS_BLOCKED); - do { + do { hpnow = GetCycleCountFast(); - elapsed += hpnow - hpstart; - if (threadCtx.Pad.Park()) // interrupted - return 0; + elapsed += hpnow - hpstart; + if (threadCtx.Pad.Park()) // interrupted + return 0; hpstart = GetCycleCountFast(); - parked += hpstart - hpnow; - } while (AtomicLoad(&threadCtx.WaitingFlag) == TThreadCtx::WS_BLOCKED); - } - + parked += hpstart - hpnow; + } while (AtomicLoad(&threadCtx.WaitingFlag) == TThreadCtx::WS_BLOCKED); + } + Y_VERIFY_DEBUG(AtomicLoad(&StopFlag) || AtomicLoad(&threadCtx.WaitingFlag) == TThreadCtx::WS_RUNNING); - -#if defined ACTORSLIB_COLLECT_EXEC_STATS - if (AtomicDecrement(ThreadUtilization) == 0) { + +#if defined ACTORSLIB_COLLECT_EXEC_STATS + if (AtomicDecrement(ThreadUtilization) == 0) { // When we started sleeping counter contained t1-t0, or the // last duration of max utilization. Now we subtract t2 >= t1, // which turns counter negative again, and the next sleep cycle @@ -173,34 +173,34 @@ namespace NActors { const i64 t = GetCycleCountFast(); const i64 x = AtomicGetAndAdd(MaxUtilizationCounter, -t); if (x > 0 && x - t < 0) - AtomicStore(&MaxUtilizationAccumulator, x); - } -#endif + AtomicStore(&MaxUtilizationAccumulator, x); + } +#endif } else { AtomicSet(threadCtx.WaitingFlag, TThreadCtx::WS_RUNNING); - } - - // ok, has work suggested, must dequeue - while (!RelaxedLoad(&StopFlag)) { - if (const ui32 activation = Activations.Pop(++revolvingCounter)) { + } + + // ok, has work suggested, must dequeue + while (!RelaxedLoad(&StopFlag)) { + if (const ui32 activation = Activations.Pop(++revolvingCounter)) { hpnow = GetCycleCountFast(); - elapsed += hpnow - hpstart; + elapsed += hpnow - hpstart; wctx.AddElapsedCycles(IActor::ACTOR_SYSTEM, elapsed); - if (parked > 0) { + if (parked > 0) { wctx.AddParkedCycles(parked); - } + } if (blocked > 0) { wctx.AddBlockedCycles(blocked); } - return activation; + return activation; } - SpinLockPause(); + SpinLockPause(); } - - // stopping, die! - return 0; - } - + + // stopping, die! + return 0; + } + inline void TBasicExecutorPool::WakeUpLoop() { for (ui32 i = 0;;) { TThreadCtx& threadCtx = Threads[i % PoolThreads]; @@ -226,83 +226,83 @@ namespace NActors { } } - void TBasicExecutorPool::ScheduleActivationEx(ui32 activation, ui64 revolvingCounter) { - Activations.Push(activation, revolvingCounter); - const TAtomic x = AtomicIncrement(Semaphore); - if (x <= 0) { // we must find someone to wake-up + void TBasicExecutorPool::ScheduleActivationEx(ui32 activation, ui64 revolvingCounter) { + Activations.Push(activation, revolvingCounter); + const TAtomic x = AtomicIncrement(Semaphore); + if (x <= 0) { // we must find someone to wake-up WakeUpLoop(); - } - } - + } + } + void TBasicExecutorPool::GetCurrentStats(TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const { - poolStats.MaxUtilizationTime = RelaxedLoad(&MaxUtilizationAccumulator) / (i64)(NHPTimer::GetCyclesPerSecond() / 1000); - - statsCopy.resize(PoolThreads + 1); - // Save counters from the pool object - statsCopy[0] = TExecutorThreadStats(); - statsCopy[0].Aggregate(Stats); - // Per-thread stats - for (size_t i = 0; i < PoolThreads; ++i) { - Threads[i].Thread->GetCurrentStats(statsCopy[i + 1]); - } + poolStats.MaxUtilizationTime = RelaxedLoad(&MaxUtilizationAccumulator) / (i64)(NHPTimer::GetCyclesPerSecond() / 1000); + + statsCopy.resize(PoolThreads + 1); + // Save counters from the pool object + statsCopy[0] = TExecutorThreadStats(); + statsCopy[0].Aggregate(Stats); + // Per-thread stats + for (size_t i = 0; i < PoolThreads; ++i) { + Threads[i].Thread->GetCurrentStats(statsCopy[i + 1]); + } } void TBasicExecutorPool::Prepare(TActorSystem* actorSystem, NSchedulerQueue::TReader** scheduleReaders, ui32* scheduleSz) { - TAffinityGuard affinityGuard(Affinity()); - - ActorSystem = actorSystem; - - ScheduleReaders.Reset(new NSchedulerQueue::TReader[PoolThreads]); - ScheduleWriters.Reset(new NSchedulerQueue::TWriter[PoolThreads]); - - for (ui32 i = 0; i != PoolThreads; ++i) { - Threads[i].Thread.Reset( - new TExecutorThread( - i, + TAffinityGuard affinityGuard(Affinity()); + + ActorSystem = actorSystem; + + ScheduleReaders.Reset(new NSchedulerQueue::TReader[PoolThreads]); + ScheduleWriters.Reset(new NSchedulerQueue::TWriter[PoolThreads]); + + for (ui32 i = 0; i != PoolThreads; ++i) { + Threads[i].Thread.Reset( + new TExecutorThread( + i, 0, // CpuId is not used in BASIC pool - actorSystem, - this, - MailboxTable.Get(), - PoolName, - TimePerMailbox, - EventsPerMailbox)); - ScheduleWriters[i].Init(ScheduleReaders[i]); - } - - *scheduleReaders = ScheduleReaders.Get(); - *scheduleSz = PoolThreads; - } - - void TBasicExecutorPool::Start() { - TAffinityGuard affinityGuard(Affinity()); - - ThreadUtilization = 0; + actorSystem, + this, + MailboxTable.Get(), + PoolName, + TimePerMailbox, + EventsPerMailbox)); + ScheduleWriters[i].Init(ScheduleReaders[i]); + } + + *scheduleReaders = ScheduleReaders.Get(); + *scheduleSz = PoolThreads; + } + + void TBasicExecutorPool::Start() { + TAffinityGuard affinityGuard(Affinity()); + + ThreadUtilization = 0; AtomicAdd(MaxUtilizationCounter, -(i64)GetCycleCountFast()); - - for (ui32 i = 0; i != PoolThreads; ++i) { - Threads[i].Thread->Start(); - } - } - - void TBasicExecutorPool::PrepareStop() { - AtomicStore(&StopFlag, true); + + for (ui32 i = 0; i != PoolThreads; ++i) { + Threads[i].Thread->Start(); + } + } + + void TBasicExecutorPool::PrepareStop() { + AtomicStore(&StopFlag, true); for (ui32 i = 0; i != PoolThreads; ++i) { - Threads[i].Pad.Interrupt(); + Threads[i].Pad.Interrupt(); Threads[i].BlockedPad.Interrupt(); } - } - - void TBasicExecutorPool::Shutdown() { - for (ui32 i = 0; i != PoolThreads; ++i) - Threads[i].Thread->Join(); - } - + } + + void TBasicExecutorPool::Shutdown() { + for (ui32 i = 0; i != PoolThreads; ++i) + Threads[i].Thread->Join(); + } + void TBasicExecutorPool::Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) { Y_VERIFY_DEBUG(workerId < PoolThreads); - + Schedule(deadline - ActorSystem->Timestamp(), ev, cookie, workerId); - } - + } + void TBasicExecutorPool::Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) { Y_VERIFY_DEBUG(workerId < PoolThreads); @@ -320,21 +320,21 @@ namespace NActors { ScheduleWriters[workerId].Push(deadline.MicroSeconds(), ev.Release(), cookie); } - void TBasicExecutorPool::SetRealTimeMode() const { -// TODO: musl-libc version of `sched_param` struct is for some reason different from pthread -// version in Ubuntu 12.04 + void TBasicExecutorPool::SetRealTimeMode() const { +// TODO: musl-libc version of `sched_param` struct is for some reason different from pthread +// version in Ubuntu 12.04 #if defined(_linux_) && !defined(_musl_) - if (RealtimePriority != 0) { - pthread_t threadSelf = pthread_self(); - sched_param param = {RealtimePriority}; - if (pthread_setschedparam(threadSelf, SCHED_FIFO, ¶m)) { - Y_FAIL("Cannot set realtime priority"); - } + if (RealtimePriority != 0) { + pthread_t threadSelf = pthread_self(); + sched_param param = {RealtimePriority}; + if (pthread_setschedparam(threadSelf, SCHED_FIFO, ¶m)) { + Y_FAIL("Cannot set realtime priority"); + } } #else - Y_UNUSED(RealtimePriority); + Y_UNUSED(RealtimePriority); #endif - } + } ui32 TBasicExecutorPool::GetThreadCount() const { return AtomicGet(ThreadCount); @@ -428,4 +428,4 @@ namespace NActors { } } } -} +} diff --git a/library/cpp/actors/core/executor_pool_basic.h b/library/cpp/actors/core/executor_pool_basic.h index 755f679957..023190f7fe 100644 --- a/library/cpp/actors/core/executor_pool_basic.h +++ b/library/cpp/actors/core/executor_pool_basic.h @@ -1,37 +1,37 @@ -#pragma once - -#include "actorsystem.h" -#include "executor_thread.h" -#include "scheduler_queue.h" -#include "executor_pool_base.h" +#pragma once + +#include "actorsystem.h" +#include "executor_thread.h" +#include "scheduler_queue.h" +#include "executor_pool_base.h" #include <library/cpp/actors/util/unordered_cache.h> #include <library/cpp/actors/util/threadparkpad.h> #include <library/cpp/monlib/dynamic_counters/counters.h> - + #include <util/system/mutex.h> -namespace NActors { - class TBasicExecutorPool: public TExecutorPoolBase { - struct TThreadCtx { - TAutoPtr<TExecutorThread> Thread; - TThreadParkPad Pad; +namespace NActors { + class TBasicExecutorPool: public TExecutorPoolBase { + struct TThreadCtx { + TAutoPtr<TExecutorThread> Thread; + TThreadParkPad Pad; TThreadParkPad BlockedPad; - TAtomic WaitingFlag; + TAtomic WaitingFlag; TAtomic BlockedFlag; - - // different threads must spin/block on different cache-lines. - // we add some padding bytes to enforce this rule + + // different threads must spin/block on different cache-lines. + // we add some padding bytes to enforce this rule static const size_t SizeWithoutPadding = sizeof(TAutoPtr<TExecutorThread>) + 2 * sizeof(TThreadParkPad) + 2 * sizeof(TAtomic); ui8 Padding[64 - SizeWithoutPadding]; static_assert(64 >= SizeWithoutPadding); - - enum EWaitState { - WS_NONE, - WS_ACTIVE, + + enum EWaitState { + WS_NONE, + WS_ACTIVE, WS_BLOCKED, WS_RUNNING - }; - + }; + enum EBlockedState { BS_NONE, BS_BLOCKING, @@ -42,70 +42,70 @@ namespace NActors { : WaitingFlag(WS_NONE) , BlockedFlag(BS_NONE) { - } - }; - - const ui64 SpinThreshold; - const ui64 SpinThresholdCycles; - - TArrayHolder<TThreadCtx> Threads; - - TArrayHolder<NSchedulerQueue::TReader> ScheduleReaders; - TArrayHolder<NSchedulerQueue::TWriter> ScheduleWriters; - - const TString PoolName; - const TDuration TimePerMailbox; - const ui32 EventsPerMailbox; - - const int RealtimePriority; - - TAtomic ThreadUtilization; - TAtomic MaxUtilizationCounter; - TAtomic MaxUtilizationAccumulator; + } + }; + + const ui64 SpinThreshold; + const ui64 SpinThresholdCycles; + + TArrayHolder<TThreadCtx> Threads; + + TArrayHolder<NSchedulerQueue::TReader> ScheduleReaders; + TArrayHolder<NSchedulerQueue::TWriter> ScheduleWriters; + + const TString PoolName; + const TDuration TimePerMailbox; + const ui32 EventsPerMailbox; + + const int RealtimePriority; + + TAtomic ThreadUtilization; + TAtomic MaxUtilizationCounter; + TAtomic MaxUtilizationAccumulator; TAtomic ThreadCount; TMutex ChangeThreadsLock; - public: + public: static constexpr TDuration DEFAULT_TIME_PER_MAILBOX = TBasicExecutorPoolConfig::DEFAULT_TIME_PER_MAILBOX; static constexpr ui32 DEFAULT_EVENTS_PER_MAILBOX = TBasicExecutorPoolConfig::DEFAULT_EVENTS_PER_MAILBOX; - - TBasicExecutorPool(ui32 poolId, - ui32 threads, - ui64 spinThreshold, - const TString& poolName = "", - TAffinity* affinity = nullptr, - TDuration timePerMailbox = DEFAULT_TIME_PER_MAILBOX, - ui32 eventsPerMailbox = DEFAULT_EVENTS_PER_MAILBOX, + + TBasicExecutorPool(ui32 poolId, + ui32 threads, + ui64 spinThreshold, + const TString& poolName = "", + TAffinity* affinity = nullptr, + TDuration timePerMailbox = DEFAULT_TIME_PER_MAILBOX, + ui32 eventsPerMailbox = DEFAULT_EVENTS_PER_MAILBOX, int realtimePriority = 0, ui32 maxActivityType = 1); explicit TBasicExecutorPool(const TBasicExecutorPoolConfig& cfg); - ~TBasicExecutorPool(); + ~TBasicExecutorPool(); ui32 GetReadyActivation(TWorkerContext& wctx, ui64 revolvingReadCounter) override; - + void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override; void Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override; void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override; - void ScheduleActivationEx(ui32 activation, ui64 revolvingWriteCounter) override; - + void ScheduleActivationEx(ui32 activation, ui64 revolvingWriteCounter) override; + void Prepare(TActorSystem* actorSystem, NSchedulerQueue::TReader** scheduleReaders, ui32* scheduleSz) override; - void Start() override; - void PrepareStop() override; - void Shutdown() override; - + void Start() override; + void PrepareStop() override; + void Shutdown() override; + void GetCurrentStats(TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const override; - TString GetName() const override { - return PoolName; - } - - void SetRealTimeMode() const override; + TString GetName() const override { + return PoolName; + } + + void SetRealTimeMode() const override; ui32 GetThreadCount() const; void SetThreadCount(ui32 threads); private: void WakeUpLoop(); - }; -} + }; +} diff --git a/library/cpp/actors/core/executor_pool_basic_ut.cpp b/library/cpp/actors/core/executor_pool_basic_ut.cpp index 42669685be..76dff693af 100644 --- a/library/cpp/actors/core/executor_pool_basic_ut.cpp +++ b/library/cpp/actors/core/executor_pool_basic_ut.cpp @@ -116,8 +116,8 @@ Y_UNIT_TEST_SUITE(BasicExecutorPool) { for (size_t testIdx = 0; testIdx < testCount; ++testIdx) { for (size_t i = 0; i < size; ++i) { actors[i]->Start(actors[i]->SelfId(), msgCount); - } - for (size_t i = 0; i < size; ++i) { + } + for (size_t i = 0; i < size; ++i) { actorSystem.Send(actorIds[i], new TEvMsg()); } @@ -143,8 +143,8 @@ Y_UNIT_TEST_SUITE(BasicExecutorPool) { for (size_t testIdx = 0; testIdx < testCount; ++testIdx) { for (size_t i = 0; i < size; ++i) { actors[i]->Start(actors[i]->SelfId(), msgCount); - } - for (size_t i = 0; i < size; ++i) { + } + for (size_t i = 0; i < size; ++i) { actorSystem.Send(actorIds[i], new TEvMsg()); } @@ -184,8 +184,8 @@ Y_UNIT_TEST_SUITE(BasicExecutorPool) { for (size_t i = 0; i < size; ++i) { actors[i]->Start(actorIds[i], msgCount); - } - for (size_t i = 0; i < size; ++i) { + } + for (size_t i = 0; i < size; ++i) { actorSystem.Send(actorIds[i], new TEvMsg()); } @@ -268,8 +268,8 @@ Y_UNIT_TEST_SUITE(BasicExecutorPool) { } for (size_t i = 0; i < size; ++i) { actors[i]->Start(actors[i]->SelfId(), msgCount); - } - for (size_t i = 0; i < size; ++i) { + } + for (size_t i = 0; i < size; ++i) { actorSystem.Send(actorIds[i], new TEvMsg()); } @@ -312,8 +312,8 @@ Y_UNIT_TEST_SUITE(BasicExecutorPool) { } for (size_t i = 0; i < actorsCount; ++i) { actors[i]->Start(actors[i]->SelfId(), msgCount); - } - for (size_t i = 0; i < actorsCount; ++i) { + } + for (size_t i = 0; i < actorsCount; ++i) { actorSystem.Send(actorIds[i], new TEvMsg()); } @@ -356,8 +356,8 @@ Y_UNIT_TEST_SUITE(BasicExecutorPool) { } for (size_t i = 0; i < actorsCount; ++i) { actors[i]->Start(actorIds[(i + 1) % actorsCount], msgCount); - } - for (size_t i = 0; i < actorsCount; ++i) { + } + for (size_t i = 0; i < actorsCount; ++i) { actorSystem.Send(actorIds[i], new TEvMsg()); } diff --git a/library/cpp/actors/core/executor_pool_io.cpp b/library/cpp/actors/core/executor_pool_io.cpp index aea38e39e7..fb557ae6b0 100644 --- a/library/cpp/actors/core/executor_pool_io.cpp +++ b/library/cpp/actors/core/executor_pool_io.cpp @@ -1,15 +1,15 @@ -#include "executor_pool_io.h" -#include "mailbox.h" +#include "executor_pool_io.h" +#include "mailbox.h" #include <library/cpp/actors/util/affinity.h> #include <library/cpp/actors/util/datetime.h> - -namespace NActors { + +namespace NActors { TIOExecutorPool::TIOExecutorPool(ui32 poolId, ui32 threads, const TString& poolName, TAffinity* affinity, ui32 maxActivityType) : TExecutorPoolBase(poolId, threads, affinity, maxActivityType) - , Threads(new TThreadCtx[threads]) - , PoolName(poolName) + , Threads(new TThreadCtx[threads]) + , PoolName(poolName) {} - + TIOExecutorPool::TIOExecutorPool(const TIOExecutorPoolConfig& cfg) : TIOExecutorPool( cfg.PoolId, @@ -20,34 +20,34 @@ namespace NActors { ) {} - TIOExecutorPool::~TIOExecutorPool() { - Threads.Destroy(); - while (ThreadQueue.Pop(0)) - ; - } - + TIOExecutorPool::~TIOExecutorPool() { + Threads.Destroy(); + while (ThreadQueue.Pop(0)) + ; + } + ui32 TIOExecutorPool::GetReadyActivation(TWorkerContext& wctx, ui64 revolvingCounter) { ui32 workerId = wctx.WorkerId; Y_VERIFY_DEBUG(workerId < PoolThreads); - + NHPTimer::STime elapsed = 0; NHPTimer::STime parked = 0; NHPTimer::STime hpstart = GetCycleCountFast(); NHPTimer::STime hpnow; - const TAtomic x = AtomicDecrement(Semaphore); - if (x < 0) { + const TAtomic x = AtomicDecrement(Semaphore); + if (x < 0) { TThreadCtx& threadCtx = Threads[workerId]; ThreadQueue.Push(workerId + 1, revolvingCounter); hpnow = GetCycleCountFast(); elapsed += hpnow - hpstart; - if (threadCtx.Pad.Park()) - return 0; + if (threadCtx.Pad.Park()) + return 0; hpstart = GetCycleCountFast(); parked += hpstart - hpnow; - } - - while (!RelaxedLoad(&StopFlag)) { + } + + while (!RelaxedLoad(&StopFlag)) { if (const ui32 activation = Activations.Pop(++revolvingCounter)) { hpnow = GetCycleCountFast(); elapsed += hpnow - hpstart; @@ -55,18 +55,18 @@ namespace NActors { if (parked > 0) { wctx.AddParkedCycles(parked); } - return activation; + return activation; } - SpinLockPause(); - } - - return 0; - } - + SpinLockPause(); + } + + return 0; + } + void TIOExecutorPool::Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) { Schedule(deadline - ActorSystem->Timestamp(), ev, cookie, workerId); - } - + } + void TIOExecutorPool::Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) { Y_UNUSED(workerId); @@ -86,53 +86,53 @@ namespace NActors { ScheduleQueue->Writer.Push(deadline.MicroSeconds(), ev.Release(), cookie); } - void TIOExecutorPool::ScheduleActivationEx(ui32 activation, ui64 revolvingWriteCounter) { - Activations.Push(activation, revolvingWriteCounter); - const TAtomic x = AtomicIncrement(Semaphore); - if (x <= 0) { - for (;; ++revolvingWriteCounter) { - if (const ui32 x = ThreadQueue.Pop(revolvingWriteCounter)) { - const ui32 threadIdx = x - 1; - Threads[threadIdx].Pad.Unpark(); - return; - } - SpinLockPause(); - } - } - } - + void TIOExecutorPool::ScheduleActivationEx(ui32 activation, ui64 revolvingWriteCounter) { + Activations.Push(activation, revolvingWriteCounter); + const TAtomic x = AtomicIncrement(Semaphore); + if (x <= 0) { + for (;; ++revolvingWriteCounter) { + if (const ui32 x = ThreadQueue.Pop(revolvingWriteCounter)) { + const ui32 threadIdx = x - 1; + Threads[threadIdx].Pad.Unpark(); + return; + } + SpinLockPause(); + } + } + } + void TIOExecutorPool::Prepare(TActorSystem* actorSystem, NSchedulerQueue::TReader** scheduleReaders, ui32* scheduleSz) { - TAffinityGuard affinityGuard(Affinity()); - - ActorSystem = actorSystem; - + TAffinityGuard affinityGuard(Affinity()); + + ActorSystem = actorSystem; + ScheduleQueue.Reset(new NSchedulerQueue::TQueueType()); - - for (ui32 i = 0; i != PoolThreads; ++i) { + + for (ui32 i = 0; i != PoolThreads; ++i) { Threads[i].Thread.Reset(new TExecutorThread(i, 0, actorSystem, this, MailboxTable.Get(), PoolName)); - } - - *scheduleReaders = &ScheduleQueue->Reader; - *scheduleSz = 1; - } - - void TIOExecutorPool::Start() { - TAffinityGuard affinityGuard(Affinity()); - - for (ui32 i = 0; i != PoolThreads; ++i) - Threads[i].Thread->Start(); - } - - void TIOExecutorPool::PrepareStop() { - AtomicStore(&StopFlag, true); - for (ui32 i = 0; i != PoolThreads; ++i) - Threads[i].Pad.Interrupt(); - } - - void TIOExecutorPool::Shutdown() { - for (ui32 i = 0; i != PoolThreads; ++i) - Threads[i].Thread->Join(); - } + } + + *scheduleReaders = &ScheduleQueue->Reader; + *scheduleSz = 1; + } + + void TIOExecutorPool::Start() { + TAffinityGuard affinityGuard(Affinity()); + + for (ui32 i = 0; i != PoolThreads; ++i) + Threads[i].Thread->Start(); + } + + void TIOExecutorPool::PrepareStop() { + AtomicStore(&StopFlag, true); + for (ui32 i = 0; i != PoolThreads; ++i) + Threads[i].Pad.Interrupt(); + } + + void TIOExecutorPool::Shutdown() { + for (ui32 i = 0; i != PoolThreads; ++i) + Threads[i].Thread->Join(); + } void TIOExecutorPool::GetCurrentStats(TExecutorPoolStats& /*poolStats*/, TVector<TExecutorThreadStats>& statsCopy) const { statsCopy.resize(PoolThreads + 1); @@ -148,4 +148,4 @@ namespace NActors { TString TIOExecutorPool::GetName() const { return PoolName; } -} +} diff --git a/library/cpp/actors/core/executor_pool_io.h b/library/cpp/actors/core/executor_pool_io.h index 3917a1b9ad..e576d642a1 100644 --- a/library/cpp/actors/core/executor_pool_io.h +++ b/library/cpp/actors/core/executor_pool_io.h @@ -1,49 +1,49 @@ -#pragma once - -#include "actorsystem.h" -#include "executor_thread.h" -#include "scheduler_queue.h" -#include "executor_pool_base.h" +#pragma once + +#include "actorsystem.h" +#include "executor_thread.h" +#include "scheduler_queue.h" +#include "executor_pool_base.h" #include <library/cpp/actors/util/ticket_lock.h> #include <library/cpp/actors/util/unordered_cache.h> #include <library/cpp/actors/util/threadparkpad.h> -#include <util/system/condvar.h> - -namespace NActors { - class TIOExecutorPool: public TExecutorPoolBase { - struct TThreadCtx { - TAutoPtr<TExecutorThread> Thread; - TThreadParkPad Pad; - }; - - TArrayHolder<TThreadCtx> Threads; +#include <util/system/condvar.h> + +namespace NActors { + class TIOExecutorPool: public TExecutorPoolBase { + struct TThreadCtx { + TAutoPtr<TExecutorThread> Thread; + TThreadParkPad Pad; + }; + + TArrayHolder<TThreadCtx> Threads; TUnorderedCache<ui32, 512, 4> ThreadQueue; - + THolder<NSchedulerQueue::TQueueType> ScheduleQueue; - TTicketLock ScheduleLock; - - const TString PoolName; + TTicketLock ScheduleLock; - public: + const TString PoolName; + + public: TIOExecutorPool(ui32 poolId, ui32 threads, const TString& poolName = "", TAffinity* affinity = nullptr, ui32 maxActivityType = 1); explicit TIOExecutorPool(const TIOExecutorPoolConfig& cfg); - ~TIOExecutorPool(); + ~TIOExecutorPool(); ui32 GetReadyActivation(TWorkerContext& wctx, ui64 revolvingCounter) override; - + void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override; void Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override; void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override; - void ScheduleActivationEx(ui32 activation, ui64 revolvingWriteCounter) override; - + void ScheduleActivationEx(ui32 activation, ui64 revolvingWriteCounter) override; + void Prepare(TActorSystem* actorSystem, NSchedulerQueue::TReader** scheduleReaders, ui32* scheduleSz) override; - void Start() override; - void PrepareStop() override; - void Shutdown() override; + void Start() override; + void PrepareStop() override; + void Shutdown() override; void GetCurrentStats(TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const override; TString GetName() const override; - }; -} + }; +} diff --git a/library/cpp/actors/core/executor_pool_united.cpp b/library/cpp/actors/core/executor_pool_united.cpp index 99c9ca32f7..dac6245635 100644 --- a/library/cpp/actors/core/executor_pool_united.cpp +++ b/library/cpp/actors/core/executor_pool_united.cpp @@ -4,32 +4,32 @@ #include "cpu_state.h" #include "executor_thread.h" #include "probes.h" -#include "mailbox.h" +#include "mailbox.h" #include "scheduler_queue.h" #include <library/cpp/actors/util/affinity.h> #include <library/cpp/actors/util/datetime.h> #include <library/cpp/actors/util/futex.h> #include <library/cpp/actors/util/intrinsics.h> #include <library/cpp/actors/util/timerfd.h> - + #include <util/system/datetime.h> #include <util/system/hp_timer.h> #include <algorithm> -namespace NActors { - LWTRACE_USING(ACTORLIB_PROVIDER); - +namespace NActors { + LWTRACE_USING(ACTORLIB_PROVIDER); + struct TUnitedWorkers::TWorker: public TNonCopyable { TAutoPtr<TExecutorThread> Thread; volatile TThreadId ThreadId = UnknownThreadId; NSchedulerQueue::TQueueType SchedulerQueue; }; - + struct TUnitedWorkers::TPool: public TNonCopyable { TAtomic Waiters = 0; // Number of idle cpus, waiting for activations in this pool char Padding[64 - sizeof(TAtomic)]; - + TUnorderedCache<ui32, 512, 4> Activations; // MPMC-queue for mailbox activations TAtomic Active = 0; // Number of mailboxes ready for execution or currently executing TAtomic Tokens = 0; // Pending tokens (token is required for worker to start execution, guarantees concurrency limit and activation availability) @@ -93,7 +93,7 @@ namespace NActors { bool TryAcquireToken() { return TryAcquireTokenImpl<false>(&Tokens); } - + // Try acquire pending token. Must be done before execution bool TryAcquireTokenRelaxed() { return TryAcquireTokenImpl<true>(&Tokens); @@ -106,10 +106,10 @@ namespace NActors { return; } SpinLockPause(); - } + } activation = 0; // should stop } - + // End currently active execution and start new one if token is available. // Reuses token if it's not destroyed. // Returned `true` means successful switch, `activation` is filled. @@ -124,7 +124,7 @@ namespace NActors { } return false; // no more tokens available } - + // Stop active execution. Returns released token (unless it is destroyed) bool StopExecution() { TAtomicBase active = AtomicDecrement(Active); @@ -534,13 +534,13 @@ namespace NActors { case Standby: if (!idleTimer) { idleTimer = IdleQueue.Enqueue(); - } + } SetPriority(0, IdlePriority); idleTimer->Wait(); - break; + break; case Stopped: return false; default: Y_FAIL(); - } + } } else { // lease has expired and hard preemption occured, so we are executing in a slow-worker wctx.IncrementPreemptedEvents(); switch (SlowWorkerAction(wctx.PoolId)) { @@ -551,11 +551,11 @@ namespace NActors { wctx.Lease = wctx.Lease.NeverExpire(); wctx.PoolId = MaxPools; idleTimer = nullptr; - break; + break; case Stopped: return false; default: Y_FAIL(); - } - } + } + } } } @@ -576,7 +576,7 @@ namespace NActors { if (AtomicCas(&SlowPoolsMask, slow | WaitPoolsFlag, slow)) { // try set wait flag return RunSlowPool; // wait flag has been successfully set } - } + } } else { // we are about to execute fast pool, token required if (slow & WaitPoolsFlag) { // reset wait flag if required if (AtomicCas(&SlowPoolsMask, slow & ~WaitPoolsFlag, slow)) { // try reset wait flag @@ -649,12 +649,12 @@ namespace NActors { // Lease has been changed just now, no way we need preemption right now, so no retry needed return Standby; } - } else { + } else { // Lease has not expired yet (maybe never expiring lease) return Standby; - } + } } - + EWorkerAction SlowWorkerAction(TPoolId pool) { if (Y_UNLIKELY(United->IsStopped())) { return Stopped; @@ -681,7 +681,7 @@ namespace NActors { } } } - + void SetPoolIsSlowFlag(TPoolId pool) { while (true) { TPoolsMask slow = AtomicLoad(&SlowPoolsMask); @@ -693,9 +693,9 @@ namespace NActors { Y_FAIL("two slow-workers executing the same pool on the same core"); return; // pool is already slow } - } - } - + } + } + bool TryBeginHardPreemption(TLease lease) { return AtomicCas(&CurrentLease, HardPreemptionLease, lease); } @@ -723,7 +723,7 @@ namespace NActors { TPoolsMask slow = AtomicLoad(&SlowPoolsMask); if ((slow & WaitPoolsFlag) == 0) { return; // woken by WakeFast action - } + } ui64 ts = GetCycleCountFast(); if (deadlineTs <= ts) { if (AtomicCas(&SlowPoolsMask, slow & ~WaitPoolsFlag, slow)) { // try reset wait flag @@ -742,13 +742,13 @@ namespace NActors { } } } - + void WakeFastWorker() { #ifdef _linux_ SysFutex(FastWorkerFutex(), FUTEX_WAKE_PRIVATE, 1, nullptr, nullptr, 0); #endif } - + #ifdef _linux_ ui32* FastWorkerFutex() { // Actually we wait on one highest bit, but futex value size is 4 bytes on all platforms @@ -1023,12 +1023,12 @@ namespace NActors { } else { return false; } - } - + } + bool BlockedWait(TPoolId& result, ui64 timeoutNs) { return State.Block(timeoutNs, result); } - + void SwitchPool(TPoolId pool) { return State.SwitchPool(pool); } @@ -1051,9 +1051,9 @@ namespace NActors { case TCpuState::Stopped: return CpuStopped; } - } + } }; - + TUnitedWorkers::TUnitedWorkers( const TUnitedWorkersConfig& config, const TVector<TUnitedExecutorPoolConfig>& unitedPools, @@ -1071,14 +1071,14 @@ namespace NActors { } } Pools.Reset(new TPool[PoolCount]); - + // Find max cpu id and initialize cpus CpuCount = 0; for (const TCpuAllocation& cpuAlloc : allocation.Items) { CpuCount = Max<size_t>(CpuCount, cpuAlloc.CpuId + 1); } Cpus.Reset(new TCpu[CpuCount]); - + // Setup allocated cpus // NOTE: leave gaps for not allocated cpus (default-initialized) WorkerCount = 0; @@ -1143,18 +1143,18 @@ namespace NActors { } } } - } - + } + TUnitedWorkers::~TUnitedWorkers() { } - + void TUnitedWorkers::Prepare(TActorSystem* actorSystem, TVector<NSchedulerQueue::TReader*>& scheduleReaders) { // Setup allocated cpus // NOTE: leave gaps for not allocated cpus (default-initialized) TWorkerId workers = 0; for (TCpuId cpuId = 0; cpuId < CpuCount; cpuId++) { TCpu& cpu = Cpus[cpuId]; - + // Setup cpu-local workers if (cpu.LocalManager) { for (size_t i = 0; i < cpu.LocalManager->WorkerCount(); i++) { @@ -1175,9 +1175,9 @@ namespace NActors { scheduleReaders.push_back(&Workers[workerId].SchedulerQueue.Reader); } } - } - } - + } + } + void TUnitedWorkers::Start() { for (TWorkerId workerId = 0; workerId < WorkerCount; workerId++) { Workers[workerId].Thread->Start(); @@ -1207,31 +1207,31 @@ namespace NActors { } void TUnitedWorkers::PrepareStop() { - AtomicStore(&StopFlag, true); + AtomicStore(&StopFlag, true); for (TPoolId pool = 0; pool < PoolCount; pool++) { Pools[pool].Stop(); } for (TCpuId cpuId = 0; cpuId < CpuCount; cpuId++) { Cpus[cpuId].Stop(); } - } - + } + void TUnitedWorkers::Shutdown() { for (TWorkerId workerId = 0; workerId < WorkerCount; workerId++) { Workers[workerId].Thread->Join(); } - } - + } + inline void TUnitedWorkers::PushActivation(TPoolId pool, ui32 activation, ui64 revolvingCounter) { if (Pools[pool].PushActivation(activation, revolvingCounter)) { // token generated TryWake(pool); } } - + inline bool TUnitedWorkers::TryAcquireToken(TPoolId pool) { return Pools[pool].TryAcquireToken(); - } - + } + inline void TUnitedWorkers::TryWake(TPoolId pool) { // Avoid using multiple atomic seq_cst loads in cycle, use barrier once AtomicBarrier(); @@ -1310,7 +1310,7 @@ namespace NActors { while (true) { if (cpu.StartSpinning(this, assignedPool, result)) { break; // token already acquired (or stop) - } + } result = WaitSequence(cpu, wctx, timeTracker); if (Y_UNLIKELY(result == CpuStopped) || TryAcquireToken(result)) { break; // token acquired (or stop) @@ -1319,7 +1319,7 @@ namespace NActors { wctx.AddElapsedCycles(IActor::ACTOR_SYSTEM, timeTracker.Elapsed()); return result; - } + } TPoolId TUnitedWorkers::WaitSequence(TCpu& cpu, TWorkerContext& wctx, TTimeTracker& timeTracker) { TPoolId result; @@ -1425,4 +1425,4 @@ namespace NActors { statsCopy[0].Aggregate(Stats); United->GetCurrentStats(PoolId, statsCopy); } -} +} diff --git a/library/cpp/actors/core/executor_pool_united.h b/library/cpp/actors/core/executor_pool_united.h index 3afd9efa2b..a090ba2466 100644 --- a/library/cpp/actors/core/executor_pool_united.h +++ b/library/cpp/actors/core/executor_pool_united.h @@ -1,9 +1,9 @@ -#pragma once - -#include "actorsystem.h" +#pragma once + +#include "actorsystem.h" #include "balancer.h" -#include "scheduler_queue.h" -#include "executor_pool_base.h" +#include "scheduler_queue.h" +#include "executor_pool_base.h" #include <library/cpp/actors/util/unordered_cache.h> @@ -13,28 +13,28 @@ #include <util/generic/noncopyable.h> -namespace NActors { +namespace NActors { class TMailboxTable; - + class TUnitedWorkers: public TNonCopyable { struct TWorker; struct TPool; struct TCpu; - + size_t WorkerCount; TArrayHolder<TWorker> Workers; // indexed by WorkerId size_t PoolCount; TArrayHolder<TPool> Pools; // indexed by PoolId, so may include not used (not united) pools size_t CpuCount; TArrayHolder<TCpu> Cpus; // indexed by CpuId, so may include not allocated CPUs - + IBalancer* Balancer; // external pool cpu balancer TUnitedWorkersConfig Config; TCpuAllocationConfig Allocation; volatile bool StopFlag = false; - + public: TUnitedWorkers( const TUnitedWorkersConfig& config, @@ -46,18 +46,18 @@ namespace NActors { void Start(); void PrepareStop(); void Shutdown(); - + bool IsStopped() const { return RelaxedLoad(&StopFlag); } - + TWorkerId GetWorkerCount() const { return WorkerCount; } - + // Returns thread id of a worker TThreadId GetWorkerThreadId(TWorkerId workerId) const; - + // Returns per worker schedule writers NSchedulerQueue::TWriter* GetScheduleWriter(TWorkerId workerId) const; @@ -69,20 +69,20 @@ namespace NActors { // Try acquire pending token. Must be done before execution bool TryAcquireToken(TPoolId pool); - + // Try to wake idle cpu waiting for tokens on specified pool void TryWake(TPoolId pool); // Get activation from pool; requires pool's token void BeginExecution(TPoolId pool, ui32& activation, ui64 revolvingCounter); - + // Stop currently active execution and start new one if token is available // NOTE: Reuses token if it's not destroyed bool NextExecution(TPoolId pool, ui32& activation, ui64 revolvingCounter); // Stop active execution void StopExecution(TPoolId pool); - + // Runs balancer to assign pools to cpus void Balance(); @@ -113,10 +113,10 @@ namespace NActors { TUnitedExecutorPool(const TUnitedExecutorPoolConfig& cfg, TUnitedWorkers* united); void Prepare(TActorSystem* actorSystem, NSchedulerQueue::TReader** scheduleReaders, ui32* scheduleSz) override; - void Start() override; - void PrepareStop() override; - void Shutdown() override; - + void Start() override; + void PrepareStop() override; + void Shutdown() override; + TAffinity* Affinity() const override; ui32 GetThreads() const override; ui32 GetReadyActivation(TWorkerContext& wctx, ui64 revolvingReadCounter) override; @@ -128,8 +128,8 @@ namespace NActors { void GetCurrentStats(TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const override; - TString GetName() const override { - return PoolName; - } - }; -} + TString GetName() const override { + return PoolName; + } + }; +} diff --git a/library/cpp/actors/core/executor_thread.cpp b/library/cpp/actors/core/executor_thread.cpp index 2af7b0debb..446b651efd 100644 --- a/library/cpp/actors/core/executor_thread.cpp +++ b/library/cpp/actors/core/executor_thread.cpp @@ -1,9 +1,9 @@ -#include "executor_thread.h" -#include "actorsystem.h" +#include "executor_thread.h" +#include "actorsystem.h" #include "callstack.h" -#include "mailbox.h" -#include "event.h" -#include "events.h" +#include "mailbox.h" +#include "event.h" +#include "events.h" #include <library/cpp/actors/prof/tag.h> #include <library/cpp/actors/util/affinity.h> @@ -13,7 +13,7 @@ #ifdef BALLOC #include <library/cpp/balloc/optional/operators.h> #endif - + #ifdef _linux_ #include <sys/syscall.h> #include <unistd.h> @@ -24,10 +24,10 @@ LWTRACE_USING(ACTORLIB_PROVIDER) -namespace NActors { - constexpr TDuration TExecutorThread::DEFAULT_TIME_PER_MAILBOX; - - TExecutorThread::TExecutorThread( +namespace NActors { + constexpr TDuration TExecutorThread::DEFAULT_TIME_PER_MAILBOX; + + TExecutorThread::TExecutorThread( TWorkerId workerId, TWorkerId cpuId, TActorSystem* actorSystem, @@ -37,9 +37,9 @@ namespace NActors { TDuration timePerMailbox, ui32 eventsPerMailbox) : ActorSystem(actorSystem) - , ExecutorPool(executorPool) + , ExecutorPool(executorPool) , Ctx(workerId, cpuId, actorSystem ? actorSystem->GetMaxActivityType() : 1) - , ThreadName(threadName) + , ThreadName(threadName) { Ctx.Switch( ExecutorPool, @@ -49,24 +49,24 @@ namespace NActors { ui64(-1), // infinite soft deadline &Ctx.WorkerStats); } - + TActorId TExecutorThread::RegisterActor(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId, const TActorId& parentId) { - if (poolId == Max<ui32>()) + if (poolId == Max<ui32>()) return Ctx.Executor->Register(actor, mailboxType, ++RevolvingWriteCounter, parentId ? parentId : CurrentRecipient); - else - return ActorSystem->Register(actor, mailboxType, poolId, ++RevolvingWriteCounter, parentId ? parentId : CurrentRecipient); - } - + else + return ActorSystem->Register(actor, mailboxType, poolId, ++RevolvingWriteCounter, parentId ? parentId : CurrentRecipient); + } + TActorId TExecutorThread::RegisterActor(IActor* actor, TMailboxHeader* mailbox, ui32 hint, const TActorId& parentId) { return Ctx.Executor->Register(actor, mailbox, hint, parentId ? parentId : CurrentRecipient); - } - - void TExecutorThread::UnregisterActor(TMailboxHeader* mailbox, ui64 localActorId) { - IActor* actor = mailbox->DetachActor(localActorId); + } + + void TExecutorThread::UnregisterActor(TMailboxHeader* mailbox, ui64 localActorId) { + IActor* actor = mailbox->DetachActor(localActorId); Ctx.DecrementActorsAliveByActivity(actor->GetActivityType()); DyingActors.push_back(THolder(actor)); - } - + } + void TExecutorThread::DropUnregistered() { DyingActors.clear(); // here is actual destruction of actors } @@ -74,8 +74,8 @@ namespace NActors { void TExecutorThread::Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) { ++CurrentActorScheduledEventsCounter; Ctx.Executor->Schedule(deadline, ev, cookie, Ctx.WorkerId); - } - + } + void TExecutorThread::Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) { ++CurrentActorScheduledEventsCounter; Ctx.Executor->Schedule(deadline, ev, cookie, Ctx.WorkerId); @@ -86,89 +86,89 @@ namespace NActors { Ctx.Executor->Schedule(delta, ev, cookie, Ctx.WorkerId); } - template <class T> - inline TString SafeTypeName(T* t) { - if (t == nullptr) { - return "nullptr"; - } - try { + template <class T> + inline TString SafeTypeName(T* t) { + if (t == nullptr) { + return "nullptr"; + } + try { return TypeName(*t); - } catch (...) { - return "unknown-type"; - } + } catch (...) { + return "unknown-type"; + } } - + inline TString ActorTypeName(const IActor* actor, ui32 activityType) { return actor ? SafeTypeName(actor) : ("activityType_" + ToString(activityType) + " (destroyed)"); } inline void LwTraceSlowDelivery(IEventHandle* ev, const IActor* actor, ui32 poolId, const TActorId& currentRecipient, - double delivMs, double sinceActivationMs, ui32 eventsExecutedBefore) { - const auto baseEv = (ev && ev->HasEvent()) ? ev->GetBase() : nullptr; - LWPROBE(EventSlowDelivery, - poolId, - delivMs, - sinceActivationMs, - eventsExecutedBefore, - baseEv ? SafeTypeName(baseEv) : (ev ? ToString(ev->Type) : TString("nullptr")), - currentRecipient.ToString(), - SafeTypeName(actor)); + double delivMs, double sinceActivationMs, ui32 eventsExecutedBefore) { + const auto baseEv = (ev && ev->HasEvent()) ? ev->GetBase() : nullptr; + LWPROBE(EventSlowDelivery, + poolId, + delivMs, + sinceActivationMs, + eventsExecutedBefore, + baseEv ? SafeTypeName(baseEv) : (ev ? ToString(ev->Type) : TString("nullptr")), + currentRecipient.ToString(), + SafeTypeName(actor)); } - inline void LwTraceSlowEvent(IEventHandle* ev, ui32 evTypeForTracing, const IActor* actor, ui32 poolId, ui32 activityType, + inline void LwTraceSlowEvent(IEventHandle* ev, ui32 evTypeForTracing, const IActor* actor, ui32 poolId, ui32 activityType, const TActorId& currentRecipient, double eventMs) { - // Event could have been destroyed by actor->Receive(); - const auto baseEv = (ev && ev->HasEvent()) ? ev->GetBase() : nullptr; - LWPROBE(SlowEvent, - poolId, - eventMs, - baseEv ? SafeTypeName(baseEv) : ToString(evTypeForTracing), - currentRecipient.ToString(), + // Event could have been destroyed by actor->Receive(); + const auto baseEv = (ev && ev->HasEvent()) ? ev->GetBase() : nullptr; + LWPROBE(SlowEvent, + poolId, + eventMs, + baseEv ? SafeTypeName(baseEv) : ToString(evTypeForTracing), + currentRecipient.ToString(), ActorTypeName(actor, activityType)); - } + } - template <typename TMailbox> - void TExecutorThread::Execute(TMailbox* mailbox, ui32 hint) { - Y_VERIFY_DEBUG(DyingActors.empty()); + template <typename TMailbox> + void TExecutorThread::Execute(TMailbox* mailbox, ui32 hint) { + Y_VERIFY_DEBUG(DyingActors.empty()); + + bool reclaimAsFree = false; - bool reclaimAsFree = false; - NHPTimer::STime hpstart = GetCycleCountFast(); - NHPTimer::STime hpprev = hpstart; - + NHPTimer::STime hpprev = hpstart; + IActor* actor = nullptr; ui32 prevActivityType = std::numeric_limits<ui32>::max(); TActorId recipient; for (ui32 executed = 0; executed < Ctx.EventsPerMailbox; ++executed) { - TAutoPtr<IEventHandle> ev(mailbox->Pop()); - if (!!ev) { - NHPTimer::STime hpnow; + TAutoPtr<IEventHandle> ev(mailbox->Pop()); + if (!!ev) { + NHPTimer::STime hpnow; recipient = ev->GetRecipientRewrite(); if (actor = mailbox->FindActor(recipient.LocalId())) { TActorContext ctx(*mailbox, *this, hpprev, recipient); - TlsActivationContext = &ctx; - + TlsActivationContext = &ctx; + #ifdef USE_ACTOR_CALLSTACK - TCallstack::GetTlsCallstack() = ev->Callstack; - TCallstack::GetTlsCallstack().SetLinesToSkip(); + TCallstack::GetTlsCallstack() = ev->Callstack; + TCallstack::GetTlsCallstack().SetLinesToSkip(); #endif - CurrentRecipient = recipient; + CurrentRecipient = recipient; CurrentActorScheduledEventsCounter = 0; - - if (executed == 0) { + + if (executed == 0) { double usec = Ctx.AddActivationStats(AtomicLoad(&mailbox->ScheduleMoment), hpprev); if (usec > 500) { GLOBAL_LWPROBE(ACTORLIB_PROVIDER, SlowActivation, Ctx.PoolId, usec / 1000.0); - } + } } - + i64 usecDeliv = Ctx.AddEventDeliveryStats(ev->SendTime, hpprev); - if (usecDeliv > 5000) { - double sinceActivationMs = NHPTimer::GetSeconds(hpprev - hpstart) * 1000.0; + if (usecDeliv > 5000) { + double sinceActivationMs = NHPTimer::GetSeconds(hpprev - hpstart) * 1000.0; LwTraceSlowDelivery(ev.Get(), actor, Ctx.PoolId, CurrentRecipient, NHPTimer::GetSeconds(hpprev - ev->SendTime) * 1000.0, sinceActivationMs, executed); - } + } - ui32 evTypeForTracing = ev->Type; + ui32 evTypeForTracing = ev->Type; ui32 activityType = actor->GetActivityType(); if (activityType != prevActivityType) { @@ -178,39 +178,39 @@ namespace NActors { actor->Receive(ev, ctx); - size_t dyingActorsCnt = DyingActors.size(); + size_t dyingActorsCnt = DyingActors.size(); Ctx.UpdateActorsStats(dyingActorsCnt); - if (dyingActorsCnt) { + if (dyingActorsCnt) { DropUnregistered(); - actor = nullptr; - } + actor = nullptr; + } - if (mailbox->IsEmpty()) // was not-free and become free, we must reclaim mailbox - reclaimAsFree = true; + if (mailbox->IsEmpty()) // was not-free and become free, we must reclaim mailbox + reclaimAsFree = true; hpnow = GetCycleCountFast(); NHPTimer::STime elapsed = Ctx.AddEventProcessingStats(hpprev, hpnow, activityType, CurrentActorScheduledEventsCounter); if (elapsed > 1000000) { LwTraceSlowEvent(ev.Get(), evTypeForTracing, actor, Ctx.PoolId, activityType, CurrentRecipient, NHPTimer::GetSeconds(elapsed) * 1000.0); } - - // The actor might have been destroyed - if (actor) - actor->AddElapsedTicks(elapsed); + + // The actor might have been destroyed + if (actor) + actor->AddElapsedTicks(elapsed); CurrentRecipient = TActorId(); } else { - TAutoPtr<IEventHandle> nonDelivered = ev->ForwardOnNondelivery(TEvents::TEvUndelivered::ReasonActorUnknown); - if (nonDelivered.Get()) { - ActorSystem->Send(nonDelivered); - } else { + TAutoPtr<IEventHandle> nonDelivered = ev->ForwardOnNondelivery(TEvents::TEvUndelivered::ReasonActorUnknown); + if (nonDelivered.Get()) { + ActorSystem->Send(nonDelivered); + } else { Ctx.IncrementNonDeliveredEvents(); - } + } hpnow = GetCycleCountFast(); } - - hpprev = hpnow; - + + hpprev = hpnow; + // Soft preemption in united pool if (Ctx.SoftDeadlineTs < (ui64)hpnow) { AtomicStore(&mailbox->ScheduleMoment, hpnow); @@ -227,7 +227,7 @@ namespace NActors { break; } - // time limit inside one mailbox passed, let others do some work + // time limit inside one mailbox passed, let others do some work if (hpnow - hpstart > (i64)Ctx.TimePerMailboxTs) { AtomicStore(&mailbox->ScheduleMoment, hpnow); Ctx.IncrementMailboxPushedOutByTime(); @@ -240,7 +240,7 @@ namespace NActors { Ctx.WorkerId, recipient.ToString(), SafeTypeName(actor)); - break; + break; } if (executed + 1 == Ctx.EventsPerMailbox) { @@ -257,8 +257,8 @@ namespace NActors { SafeTypeName(actor)); break; } - } else { - if (executed == 0) + } else { + if (executed == 0) Ctx.IncrementEmptyMailboxActivation(); LWTRACK(MailboxEmpty, Ctx.Orbit, @@ -269,15 +269,15 @@ namespace NActors { Ctx.WorkerId, recipient.ToString(), SafeTypeName(actor)); - break; // empty queue, leave - } + break; // empty queue, leave + } } - + NProfiling::TMemoryTagScope::Reset(0); - TlsActivationContext = nullptr; + TlsActivationContext = nullptr; UnlockFromExecution(mailbox, Ctx.Executor, reclaimAsFree, hint, Ctx.WorkerId, RevolvingWriteCounter); - } - + } + TThreadId TExecutorThread::GetThreadId() const { #ifdef _linux_ while (AtomicLoad(&ThreadId) == UnknownThreadId) { @@ -287,7 +287,7 @@ namespace NActors { return ThreadId; } - void* TExecutorThread::ThreadProc() { + void* TExecutorThread::ThreadProc() { #ifdef _linux_ pid_t tid = syscall(SYS_gettid); AtomicSet(ThreadId, (ui64)tid); @@ -297,267 +297,267 @@ namespace NActors { ThreadDisableBalloc(); #endif - if (ThreadName) { + if (ThreadName) { ::SetCurrentThreadName(ThreadName); - } - - ExecutorPool->SetRealTimeMode(); - TAffinityGuard affinity(ExecutorPool->Affinity()); + } + + ExecutorPool->SetRealTimeMode(); + TAffinityGuard affinity(ExecutorPool->Affinity()); NHPTimer::STime hpnow = GetCycleCountFast(); - NHPTimer::STime hpprev = hpnow; - ui64 execCount = 0; - ui64 readyActivationCount = 0; - i64 execCycles = 0; - i64 nonExecCycles = 0; + NHPTimer::STime hpprev = hpnow; + ui64 execCount = 0; + ui64 readyActivationCount = 0; + i64 execCycles = 0; + i64 nonExecCycles = 0; - for (;;) { + for (;;) { if (ui32 activation = ExecutorPool->GetReadyActivation(Ctx, ++RevolvingReadCounter)) { LWTRACK(ActivationBegin, Ctx.Orbit, Ctx.CpuId, Ctx.PoolId, Ctx.WorkerId, NHPTimer::GetSeconds(Ctx.Lease.GetPreciseExpireTs()) * 1e3); - readyActivationCount++; + readyActivationCount++; if (TMailboxHeader* header = Ctx.MailboxTable->Get(activation)) { - if (header->LockForExecution()) { + if (header->LockForExecution()) { hpnow = GetCycleCountFast(); - nonExecCycles += hpnow - hpprev; - hpprev = hpnow; - switch (header->Type) { - case TMailboxType::Simple: - Execute(static_cast<TMailboxTable::TSimpleMailbox*>(header), activation); - break; - case TMailboxType::Revolving: - Execute(static_cast<TMailboxTable::TRevolvingMailbox*>(header), activation); - break; - case TMailboxType::HTSwap: - Execute(static_cast<TMailboxTable::THTSwapMailbox*>(header), activation); - break; - case TMailboxType::ReadAsFilled: - Execute(static_cast<TMailboxTable::TReadAsFilledMailbox*>(header), activation); - break; - case TMailboxType::TinyReadAsFilled: - Execute(static_cast<TMailboxTable::TTinyReadAsFilledMailbox*>(header), activation); - break; - } + nonExecCycles += hpnow - hpprev; + hpprev = hpnow; + switch (header->Type) { + case TMailboxType::Simple: + Execute(static_cast<TMailboxTable::TSimpleMailbox*>(header), activation); + break; + case TMailboxType::Revolving: + Execute(static_cast<TMailboxTable::TRevolvingMailbox*>(header), activation); + break; + case TMailboxType::HTSwap: + Execute(static_cast<TMailboxTable::THTSwapMailbox*>(header), activation); + break; + case TMailboxType::ReadAsFilled: + Execute(static_cast<TMailboxTable::TReadAsFilledMailbox*>(header), activation); + break; + case TMailboxType::TinyReadAsFilled: + Execute(static_cast<TMailboxTable::TTinyReadAsFilledMailbox*>(header), activation); + break; + } hpnow = GetCycleCountFast(); - execCycles += hpnow - hpprev; - hpprev = hpnow; - execCount++; - if (execCycles + nonExecCycles > 39000000) { // every 15 ms at 2.6GHz, so 1000 items is 15 sec (solomon interval) + execCycles += hpnow - hpprev; + hpprev = hpnow; + execCount++; + if (execCycles + nonExecCycles > 39000000) { // every 15 ms at 2.6GHz, so 1000 items is 15 sec (solomon interval) LWPROBE(ExecutorThreadStats, ExecutorPool->PoolId, ExecutorPool->GetName(), Ctx.WorkerId, - execCount, readyActivationCount, - NHPTimer::GetSeconds(execCycles) * 1000.0, NHPTimer::GetSeconds(nonExecCycles) * 1000.0); - execCount = 0; - readyActivationCount = 0; - execCycles = 0; - nonExecCycles = 0; + execCount, readyActivationCount, + NHPTimer::GetSeconds(execCycles) * 1000.0, NHPTimer::GetSeconds(nonExecCycles) * 1000.0); + execCount = 0; + readyActivationCount = 0; + execCycles = 0; + nonExecCycles = 0; Ctx.UpdateThreadTime(); - } - } - } + } + } + } LWTRACK(ActivationEnd, Ctx.Orbit, Ctx.CpuId, Ctx.PoolId, Ctx.WorkerId); Ctx.Orbit.Reset(); } else { // no activation means PrepareStop was called so thread must terminate - break; + break; } - } - return nullptr; - } - - // there must be barrier and check-read with following cas - // or just cas w/o read. - // or queue unlocks must be performed with exchange and not generic write - // TODO: check performance of those options under contention - - // placed here in hope for better compiler optimization - - bool TMailboxHeader::MarkForSchedule() { - AtomicBarrier(); - for (;;) { - const ui32 state = AtomicLoad(&ExecutionState); - switch (state) { - case TExecutionState::Inactive: - if (AtomicUi32Cas(&ExecutionState, TExecutionState::Scheduled, TExecutionState::Inactive)) - return true; - break; - case TExecutionState::Scheduled: - return false; - case TExecutionState::Leaving: - if (AtomicUi32Cas(&ExecutionState, TExecutionState::LeavingMarked, TExecutionState::Leaving)) - return true; - break; - case TExecutionState::Executing: - case TExecutionState::LeavingMarked: - return false; - case TExecutionState::Free: - if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeScheduled, TExecutionState::Free)) - return true; - break; - case TExecutionState::FreeScheduled: - return false; - case TExecutionState::FreeLeaving: - if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeLeavingMarked, TExecutionState::FreeLeaving)) - return true; - break; - case TExecutionState::FreeExecuting: - case TExecutionState::FreeLeavingMarked: - return false; - default: - Y_FAIL(); - } - } - } - - bool TMailboxHeader::LockForExecution() { - AtomicBarrier(); // strictly speaking here should be AtomicBarrier, but as we got mailboxes from queue - this barrier is already set implicitly and could be removed - for (;;) { - const ui32 state = AtomicLoad(&ExecutionState); - switch (state) { - case TExecutionState::Inactive: - return false; - case TExecutionState::Scheduled: - if (AtomicUi32Cas(&ExecutionState, TExecutionState::Executing, TExecutionState::Scheduled)) - return true; - break; - case TExecutionState::Leaving: - case TExecutionState::Executing: - case TExecutionState::LeavingMarked: - return false; - case TExecutionState::Free: - if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeExecuting, TExecutionState::Free)) - return true; - break; - case TExecutionState::FreeScheduled: - if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeExecuting, TExecutionState::FreeScheduled)) - return true; - break; - case TExecutionState::FreeLeaving: - case TExecutionState::FreeExecuting: - case TExecutionState::FreeLeavingMarked: - return false; - default: - Y_FAIL(); - } - } - } - - bool TMailboxHeader::LockFromFree() { - AtomicBarrier(); - for (;;) { - const ui32 state = AtomicLoad(&ExecutionState); - switch (state) { - case TExecutionState::Inactive: - case TExecutionState::Scheduled: - case TExecutionState::Leaving: - case TExecutionState::Executing: - case TExecutionState::LeavingMarked: - Y_FAIL(); - case TExecutionState::Free: - if (AtomicUi32Cas(&ExecutionState, TExecutionState::Executing, TExecutionState::Free)) - return true; - break; - case TExecutionState::FreeScheduled: - if (AtomicUi32Cas(&ExecutionState, TExecutionState::Executing, TExecutionState::FreeScheduled)) - return true; - break; - case TExecutionState::FreeLeaving: - case TExecutionState::FreeExecuting: - case TExecutionState::FreeLeavingMarked: - return false; - default: - Y_FAIL(); - } - } - } - - void TMailboxHeader::UnlockFromExecution1() { - const ui32 state = AtomicLoad(&ExecutionState); - if (state == TExecutionState::Executing) - AtomicStore(&ExecutionState, (ui32)TExecutionState::Leaving); - else if (state == TExecutionState::FreeExecuting) - AtomicStore(&ExecutionState, (ui32)TExecutionState::FreeLeaving); - else + } + return nullptr; + } + + // there must be barrier and check-read with following cas + // or just cas w/o read. + // or queue unlocks must be performed with exchange and not generic write + // TODO: check performance of those options under contention + + // placed here in hope for better compiler optimization + + bool TMailboxHeader::MarkForSchedule() { + AtomicBarrier(); + for (;;) { + const ui32 state = AtomicLoad(&ExecutionState); + switch (state) { + case TExecutionState::Inactive: + if (AtomicUi32Cas(&ExecutionState, TExecutionState::Scheduled, TExecutionState::Inactive)) + return true; + break; + case TExecutionState::Scheduled: + return false; + case TExecutionState::Leaving: + if (AtomicUi32Cas(&ExecutionState, TExecutionState::LeavingMarked, TExecutionState::Leaving)) + return true; + break; + case TExecutionState::Executing: + case TExecutionState::LeavingMarked: + return false; + case TExecutionState::Free: + if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeScheduled, TExecutionState::Free)) + return true; + break; + case TExecutionState::FreeScheduled: + return false; + case TExecutionState::FreeLeaving: + if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeLeavingMarked, TExecutionState::FreeLeaving)) + return true; + break; + case TExecutionState::FreeExecuting: + case TExecutionState::FreeLeavingMarked: + return false; + default: + Y_FAIL(); + } + } + } + + bool TMailboxHeader::LockForExecution() { + AtomicBarrier(); // strictly speaking here should be AtomicBarrier, but as we got mailboxes from queue - this barrier is already set implicitly and could be removed + for (;;) { + const ui32 state = AtomicLoad(&ExecutionState); + switch (state) { + case TExecutionState::Inactive: + return false; + case TExecutionState::Scheduled: + if (AtomicUi32Cas(&ExecutionState, TExecutionState::Executing, TExecutionState::Scheduled)) + return true; + break; + case TExecutionState::Leaving: + case TExecutionState::Executing: + case TExecutionState::LeavingMarked: + return false; + case TExecutionState::Free: + if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeExecuting, TExecutionState::Free)) + return true; + break; + case TExecutionState::FreeScheduled: + if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeExecuting, TExecutionState::FreeScheduled)) + return true; + break; + case TExecutionState::FreeLeaving: + case TExecutionState::FreeExecuting: + case TExecutionState::FreeLeavingMarked: + return false; + default: + Y_FAIL(); + } + } + } + + bool TMailboxHeader::LockFromFree() { + AtomicBarrier(); + for (;;) { + const ui32 state = AtomicLoad(&ExecutionState); + switch (state) { + case TExecutionState::Inactive: + case TExecutionState::Scheduled: + case TExecutionState::Leaving: + case TExecutionState::Executing: + case TExecutionState::LeavingMarked: + Y_FAIL(); + case TExecutionState::Free: + if (AtomicUi32Cas(&ExecutionState, TExecutionState::Executing, TExecutionState::Free)) + return true; + break; + case TExecutionState::FreeScheduled: + if (AtomicUi32Cas(&ExecutionState, TExecutionState::Executing, TExecutionState::FreeScheduled)) + return true; + break; + case TExecutionState::FreeLeaving: + case TExecutionState::FreeExecuting: + case TExecutionState::FreeLeavingMarked: + return false; + default: + Y_FAIL(); + } + } + } + + void TMailboxHeader::UnlockFromExecution1() { + const ui32 state = AtomicLoad(&ExecutionState); + if (state == TExecutionState::Executing) + AtomicStore(&ExecutionState, (ui32)TExecutionState::Leaving); + else if (state == TExecutionState::FreeExecuting) + AtomicStore(&ExecutionState, (ui32)TExecutionState::FreeLeaving); + else Y_FAIL(); - AtomicBarrier(); - } - - bool TMailboxHeader::UnlockFromExecution2(bool wouldReschedule) { - AtomicBarrier(); - for (;;) { - const ui32 state = AtomicLoad(&ExecutionState); - switch (state) { - case TExecutionState::Inactive: - case TExecutionState::Scheduled: - Y_FAIL(); - case TExecutionState::Leaving: - if (!wouldReschedule) { - if (AtomicUi32Cas(&ExecutionState, TExecutionState::Inactive, TExecutionState::Leaving)) - return false; - } else { - if (AtomicUi32Cas(&ExecutionState, TExecutionState::Scheduled, TExecutionState::Leaving)) - return true; - } - break; - case TExecutionState::Executing: - Y_FAIL(); - case TExecutionState::LeavingMarked: - if (AtomicUi32Cas(&ExecutionState, TExecutionState::Scheduled, TExecutionState::LeavingMarked)) - return true; - break; - case TExecutionState::Free: - case TExecutionState::FreeScheduled: - Y_FAIL(); - case TExecutionState::FreeLeaving: - if (!wouldReschedule) { - if (AtomicUi32Cas(&ExecutionState, TExecutionState::Free, TExecutionState::FreeLeaving)) - return false; - } else { - if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeScheduled, TExecutionState::FreeLeaving)) - return true; - } - break; - case TExecutionState::FreeExecuting: - Y_FAIL(); - case TExecutionState::FreeLeavingMarked: - if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeScheduled, TExecutionState::FreeLeavingMarked)) - return true; - break; - default: - Y_FAIL(); - } - } - } - - bool TMailboxHeader::UnlockAsFree(bool wouldReschedule) { - AtomicBarrier(); - for (;;) { - const ui32 state = AtomicLoad(&ExecutionState); - switch (state) { - case TExecutionState::Inactive: - case TExecutionState::Scheduled: - Y_FAIL(); - case TExecutionState::Leaving: - if (!wouldReschedule) { - if (AtomicUi32Cas(&ExecutionState, TExecutionState::Free, TExecutionState::Leaving)) - return false; - } else { - if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeScheduled, TExecutionState::Leaving)) - return true; - } - break; - case TExecutionState::Executing: - Y_FAIL(); - case TExecutionState::LeavingMarked: - if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeScheduled, TExecutionState::LeavingMarked)) - return true; - break; - case TExecutionState::Free: - case TExecutionState::FreeScheduled: - case TExecutionState::FreeLeaving: - case TExecutionState::FreeExecuting: - case TExecutionState::FreeLeavingMarked: - Y_FAIL(); - default: - Y_FAIL(); - } - } - } -} + AtomicBarrier(); + } + + bool TMailboxHeader::UnlockFromExecution2(bool wouldReschedule) { + AtomicBarrier(); + for (;;) { + const ui32 state = AtomicLoad(&ExecutionState); + switch (state) { + case TExecutionState::Inactive: + case TExecutionState::Scheduled: + Y_FAIL(); + case TExecutionState::Leaving: + if (!wouldReschedule) { + if (AtomicUi32Cas(&ExecutionState, TExecutionState::Inactive, TExecutionState::Leaving)) + return false; + } else { + if (AtomicUi32Cas(&ExecutionState, TExecutionState::Scheduled, TExecutionState::Leaving)) + return true; + } + break; + case TExecutionState::Executing: + Y_FAIL(); + case TExecutionState::LeavingMarked: + if (AtomicUi32Cas(&ExecutionState, TExecutionState::Scheduled, TExecutionState::LeavingMarked)) + return true; + break; + case TExecutionState::Free: + case TExecutionState::FreeScheduled: + Y_FAIL(); + case TExecutionState::FreeLeaving: + if (!wouldReschedule) { + if (AtomicUi32Cas(&ExecutionState, TExecutionState::Free, TExecutionState::FreeLeaving)) + return false; + } else { + if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeScheduled, TExecutionState::FreeLeaving)) + return true; + } + break; + case TExecutionState::FreeExecuting: + Y_FAIL(); + case TExecutionState::FreeLeavingMarked: + if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeScheduled, TExecutionState::FreeLeavingMarked)) + return true; + break; + default: + Y_FAIL(); + } + } + } + + bool TMailboxHeader::UnlockAsFree(bool wouldReschedule) { + AtomicBarrier(); + for (;;) { + const ui32 state = AtomicLoad(&ExecutionState); + switch (state) { + case TExecutionState::Inactive: + case TExecutionState::Scheduled: + Y_FAIL(); + case TExecutionState::Leaving: + if (!wouldReschedule) { + if (AtomicUi32Cas(&ExecutionState, TExecutionState::Free, TExecutionState::Leaving)) + return false; + } else { + if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeScheduled, TExecutionState::Leaving)) + return true; + } + break; + case TExecutionState::Executing: + Y_FAIL(); + case TExecutionState::LeavingMarked: + if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeScheduled, TExecutionState::LeavingMarked)) + return true; + break; + case TExecutionState::Free: + case TExecutionState::FreeScheduled: + case TExecutionState::FreeLeaving: + case TExecutionState::FreeExecuting: + case TExecutionState::FreeLeavingMarked: + Y_FAIL(); + default: + Y_FAIL(); + } + } + } +} diff --git a/library/cpp/actors/core/executor_thread.h b/library/cpp/actors/core/executor_thread.h index 7cea13f6d7..9d3c573f0d 100644 --- a/library/cpp/actors/core/executor_thread.h +++ b/library/cpp/actors/core/executor_thread.h @@ -1,34 +1,34 @@ -#pragma once - -#include "defs.h" -#include "event.h" -#include "actor.h" -#include "actorsystem.h" +#pragma once + +#include "defs.h" +#include "event.h" +#include "actor.h" +#include "actorsystem.h" #include "callstack.h" #include "probes.h" #include "worker_context.h" - + #include <library/cpp/actors/util/datetime.h> -#include <util/system/thread.h> - -namespace NActors { +#include <util/system/thread.h> + +namespace NActors { class TExecutorThread: public ISimpleThread { - public: - static constexpr TDuration DEFAULT_TIME_PER_MAILBOX = - TDuration::MilliSeconds(10); - static constexpr ui32 DEFAULT_EVENTS_PER_MAILBOX = 100; - + public: + static constexpr TDuration DEFAULT_TIME_PER_MAILBOX = + TDuration::MilliSeconds(10); + static constexpr ui32 DEFAULT_EVENTS_PER_MAILBOX = 100; + TExecutorThread(TWorkerId workerId, TWorkerId cpuId, - TActorSystem* actorSystem, - IExecutorPool* executorPool, - TMailboxTable* mailboxTable, - const TString& threadName, - TDuration timePerMailbox = DEFAULT_TIME_PER_MAILBOX, - ui32 eventsPerMailbox = DEFAULT_EVENTS_PER_MAILBOX); - + TActorSystem* actorSystem, + IExecutorPool* executorPool, + TMailboxTable* mailboxTable, + const TString& threadName, + TDuration timePerMailbox = DEFAULT_TIME_PER_MAILBOX, + ui32 eventsPerMailbox = DEFAULT_EVENTS_PER_MAILBOX); + TExecutorThread(TWorkerId workerId, TActorSystem* actorSystem, IExecutorPool* executorPool, @@ -42,7 +42,7 @@ namespace NActors { TActorId RegisterActor(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>(), const TActorId& parentId = TActorId()); TActorId RegisterActor(IActor* actor, TMailboxHeader* mailbox, ui32 hint, const TActorId& parentId = TActorId()); - void UnregisterActor(TMailboxHeader* mailbox, ui64 localActorId); + void UnregisterActor(TMailboxHeader* mailbox, ui64 localActorId); void DropUnregistered(); const std::vector<THolder<IActor>>& GetUnregistered() const { return DyingActors; } @@ -57,28 +57,28 @@ namespace NActors { #endif Ctx.IncrementSentEvents(); return ActorSystem->Send(ev); - } + } void GetCurrentStats(TExecutorThreadStats& statsCopy) const { Ctx.GetCurrentStats(statsCopy); - } + } TThreadId GetThreadId() const; // blocks, must be called after Start() TWorkerId GetWorkerId() const { return Ctx.WorkerId; } - private: - void* ThreadProc(); - - template <typename TMailbox> - void Execute(TMailbox* mailbox, ui32 hint); - - public: - TActorSystem* const ActorSystem; - - private: + private: + void* ThreadProc(); + + template <typename TMailbox> + void Execute(TMailbox* mailbox, ui32 hint); + + public: + TActorSystem* const ActorSystem; + + private: // Pool-specific - IExecutorPool* const ExecutorPool; - + IExecutorPool* const ExecutorPool; + // Event-specific (currently executing) TVector<THolder<IActor>> DyingActors; TActorId CurrentRecipient; @@ -88,25 +88,25 @@ namespace NActors { TWorkerContext Ctx; ui64 RevolvingReadCounter = 0; ui64 RevolvingWriteCounter = 0; - const TString ThreadName; + const TString ThreadName; volatile TThreadId ThreadId = UnknownThreadId; - }; - - template <typename TMailbox> + }; + + template <typename TMailbox> void UnlockFromExecution(TMailbox* mailbox, IExecutorPool* executorPool, bool asFree, ui32 hint, TWorkerId workerId, ui64& revolvingWriteCounter) { - mailbox->UnlockFromExecution1(); - const bool needReschedule1 = (nullptr != mailbox->Head()); - if (!asFree) { - if (mailbox->UnlockFromExecution2(needReschedule1)) { + mailbox->UnlockFromExecution1(); + const bool needReschedule1 = (nullptr != mailbox->Head()); + if (!asFree) { + if (mailbox->UnlockFromExecution2(needReschedule1)) { RelaxedStore<NHPTimer::STime>(&mailbox->ScheduleMoment, GetCycleCountFast()); - executorPool->ScheduleActivationEx(hint, ++revolvingWriteCounter); - } - } else { - if (mailbox->UnlockAsFree(needReschedule1)) { + executorPool->ScheduleActivationEx(hint, ++revolvingWriteCounter); + } + } else { + if (mailbox->UnlockAsFree(needReschedule1)) { RelaxedStore<NHPTimer::STime>(&mailbox->ScheduleMoment, GetCycleCountFast()); - executorPool->ScheduleActivationEx(hint, ++revolvingWriteCounter); - } + executorPool->ScheduleActivationEx(hint, ++revolvingWriteCounter); + } executorPool->ReclaimMailbox(TMailbox::MailboxType, hint, workerId, ++revolvingWriteCounter); - } + } } } diff --git a/library/cpp/actors/core/hfunc.h b/library/cpp/actors/core/hfunc.h index 6922c2aadf..26f3c65013 100644 --- a/library/cpp/actors/core/hfunc.h +++ b/library/cpp/actors/core/hfunc.h @@ -1,45 +1,45 @@ -#pragma once - -#include "actor.h" -#include "executor_thread.h" - +#pragma once + +#include "actor.h" +#include "executor_thread.h" + #include <util/system/defaults.h> -#define HFunc(TEvType, HandleFunc) \ - case TEvType::EventType: { \ - typename TEvType::TPtr* x = reinterpret_cast<typename TEvType::TPtr*>(&ev); \ - HandleFunc(*x, ctx); \ - break; \ - } - -#define hFunc(TEvType, HandleFunc) \ - case TEvType::EventType: { \ - typename TEvType::TPtr* x = reinterpret_cast<typename TEvType::TPtr*>(&ev); \ - HandleFunc(*x); \ - break; \ - } - -#define HFuncTraced(TEvType, HandleFunc) \ - case TEvType::EventType: { \ +#define HFunc(TEvType, HandleFunc) \ + case TEvType::EventType: { \ + typename TEvType::TPtr* x = reinterpret_cast<typename TEvType::TPtr*>(&ev); \ + HandleFunc(*x, ctx); \ + break; \ + } + +#define hFunc(TEvType, HandleFunc) \ + case TEvType::EventType: { \ + typename TEvType::TPtr* x = reinterpret_cast<typename TEvType::TPtr*>(&ev); \ + HandleFunc(*x); \ + break; \ + } + +#define HFuncTraced(TEvType, HandleFunc) \ + case TEvType::EventType: { \ TRACE_EVENT_TYPE(Y_STRINGIZE(TEvType)); \ - TEvType::TPtr* x = reinterpret_cast<TEvType::TPtr*>(&ev); \ - HandleFunc(*x, ctx); \ - break; \ + TEvType::TPtr* x = reinterpret_cast<TEvType::TPtr*>(&ev); \ + HandleFunc(*x, ctx); \ + break; \ } -#define hFuncTraced(TEvType, HandleFunc) \ - case TEvType::EventType: { \ +#define hFuncTraced(TEvType, HandleFunc) \ + case TEvType::EventType: { \ TRACE_EVENT_TYPE(Y_STRINGIZE(TEvType)); \ - typename TEvType::TPtr* x = reinterpret_cast<typename TEvType::TPtr*>(&ev); \ - HandleFunc(*x); \ - break; \ - } - -#define HTemplFunc(TEvType, HandleFunc) \ - case TEvType::EventType: { \ - typename TEvType::TPtr* x = reinterpret_cast<typename TEvType::TPtr*>(&ev); \ - HandleFunc(*x, ctx); \ - break; \ + typename TEvType::TPtr* x = reinterpret_cast<typename TEvType::TPtr*>(&ev); \ + HandleFunc(*x); \ + break; \ + } + +#define HTemplFunc(TEvType, HandleFunc) \ + case TEvType::EventType: { \ + typename TEvType::TPtr* x = reinterpret_cast<typename TEvType::TPtr*>(&ev); \ + HandleFunc(*x, ctx); \ + break; \ } #define hTemplFunc(TEvType, HandleFunc) \ @@ -59,26 +59,26 @@ HandleFunc(); \ break; -#define CFunc(TEventType, HandleFunc) \ - case TEventType: \ - HandleFunc(ctx); \ - break; - +#define CFunc(TEventType, HandleFunc) \ + case TEventType: \ + HandleFunc(ctx); \ + break; + #define cFunc(TEventType, HandleFunc) \ case TEventType: \ HandleFunc(); \ - break; - -#define FFunc(TEventType, HandleFunc) \ - case TEventType: \ - HandleFunc(ev, ctx); \ - break; - + break; + +#define FFunc(TEventType, HandleFunc) \ + case TEventType: \ + HandleFunc(ev, ctx); \ + break; + #define fFunc(TEventType, HandleFunc) \ case TEventType: \ HandleFunc(ev); \ break; -#define IgnoreFunc(TEvType) \ - case TEvType::EventType: \ - break; +#define IgnoreFunc(TEvType) \ + case TEvType::EventType: \ + break; diff --git a/library/cpp/actors/core/interconnect.h b/library/cpp/actors/core/interconnect.h index 93b78c9d27..679a4b8cc6 100644 --- a/library/cpp/actors/core/interconnect.h +++ b/library/cpp/actors/core/interconnect.h @@ -1,14 +1,14 @@ -#pragma once +#pragma once #include "events.h" #include "event_local.h" #include <library/cpp/actors/protos/interconnect.pb.h> #include <util/string/cast.h> #include <util/string/builder.h> - -namespace NActors { + +namespace NActors { class TNodeLocation { - public: + public: struct TKeys { enum E : int { DataCenter = 10, @@ -113,21 +113,21 @@ namespace NActors { friend bool operator <=(const TNodeLocation& x, const TNodeLocation& y) { return x.Compare(y) <= 0; } friend bool operator > (const TNodeLocation& x, const TNodeLocation& y) { return x.Compare(y) > 0; } friend bool operator >=(const TNodeLocation& x, const TNodeLocation& y) { return x.Compare(y) >= 0; } - }; + }; - struct TEvInterconnect { - enum EEv { - EvForward = EventSpaceBegin(TEvents::ES_INTERCONNECT), - EvResolveNode, // resolve info about node (internal) + struct TEvInterconnect { + enum EEv { + EvForward = EventSpaceBegin(TEvents::ES_INTERCONNECT), + EvResolveNode, // resolve info about node (internal) EvNodeAddress, // node info (internal) - EvConnectNode, // request proxy to establish connection (like: we would send something there soon) - EvAcceptIncoming, - EvNodeConnected, // node connected notify - EvNodeDisconnected, // node disconnected notify - EvRegisterNode, - EvRegisterNodeResult, - EvListNodes, - EvNodesInfo, + EvConnectNode, // request proxy to establish connection (like: we would send something there soon) + EvAcceptIncoming, + EvNodeConnected, // node connected notify + EvNodeDisconnected, // node disconnected notify + EvRegisterNode, + EvRegisterNodeResult, + EvListNodes, + EvNodesInfo, EvDisconnect, EvGetNode, EvNodeInfo, @@ -135,48 +135,48 @@ namespace NActors { EvCloseInputSession, EvPoisonSession, EvTerminate, - EvEnd - }; - - enum ESubscribes { - SubConnected, - SubDisconnected, - }; - - static_assert(EvEnd < EventSpaceEnd(TEvents::ES_INTERCONNECT), "expect EvEnd < EventSpaceEnd(TEvents::ES_INTERCONNECT)"); - - struct TEvResolveNode; + EvEnd + }; + + enum ESubscribes { + SubConnected, + SubDisconnected, + }; + + static_assert(EvEnd < EventSpaceEnd(TEvents::ES_INTERCONNECT), "expect EvEnd < EventSpaceEnd(TEvents::ES_INTERCONNECT)"); + + struct TEvResolveNode; struct TEvNodeAddress; - - struct TEvConnectNode: public TEventBase<TEvConnectNode, EvConnectNode> { - DEFINE_SIMPLE_LOCAL_EVENT(TEvConnectNode, "TEvInterconnect::TEvConnectNode") - }; - - struct TEvAcceptIncoming; - - struct TEvNodeConnected: public TEventLocal<TEvNodeConnected, EvNodeConnected> { - DEFINE_SIMPLE_LOCAL_EVENT(TEvNodeConnected, "TEvInterconnect::TEvNodeConnected") - TEvNodeConnected(ui32 node) noexcept - : NodeId(node) - { - } - const ui32 NodeId; - }; - - struct TEvNodeDisconnected: public TEventLocal<TEvNodeDisconnected, EvNodeDisconnected> { - DEFINE_SIMPLE_LOCAL_EVENT(TEvNodeDisconnected, "TEvInterconnect::TEvNodeDisconnected") - TEvNodeDisconnected(ui32 node) noexcept - : NodeId(node) - { - } - const ui32 NodeId; - }; - - struct TEvRegisterNode; - struct TEvRegisterNodeResult; - - struct TEvListNodes: public TEventLocal<TEvListNodes, EvListNodes> { - }; + + struct TEvConnectNode: public TEventBase<TEvConnectNode, EvConnectNode> { + DEFINE_SIMPLE_LOCAL_EVENT(TEvConnectNode, "TEvInterconnect::TEvConnectNode") + }; + + struct TEvAcceptIncoming; + + struct TEvNodeConnected: public TEventLocal<TEvNodeConnected, EvNodeConnected> { + DEFINE_SIMPLE_LOCAL_EVENT(TEvNodeConnected, "TEvInterconnect::TEvNodeConnected") + TEvNodeConnected(ui32 node) noexcept + : NodeId(node) + { + } + const ui32 NodeId; + }; + + struct TEvNodeDisconnected: public TEventLocal<TEvNodeDisconnected, EvNodeDisconnected> { + DEFINE_SIMPLE_LOCAL_EVENT(TEvNodeDisconnected, "TEvInterconnect::TEvNodeDisconnected") + TEvNodeDisconnected(ui32 node) noexcept + : NodeId(node) + { + } + const ui32 NodeId; + }; + + struct TEvRegisterNode; + struct TEvRegisterNodeResult; + + struct TEvListNodes: public TEventLocal<TEvListNodes, EvListNodes> { + }; struct TNodeInfo { ui32 NodeId; @@ -211,13 +211,13 @@ namespace NActors { struct TEvNodesInfo: public TEventLocal<TEvNodesInfo, EvNodesInfo> { TVector<TNodeInfo> Nodes; - - const TNodeInfo* GetNodeInfo(ui32 nodeId) const { - for (const auto& x : Nodes) { - if (x.NodeId == nodeId) - return &x; - } - return nullptr; + + const TNodeInfo* GetNodeInfo(ui32 nodeId) const { + for (const auto& x : Nodes) { + if (x.NodeId == nodeId) + return &x; + } + return nullptr; } }; @@ -252,4 +252,4 @@ namespace NActors { struct TEvTerminate : TEventLocal<TEvTerminate, EvTerminate> {}; }; -} +} diff --git a/library/cpp/actors/core/log.cpp b/library/cpp/actors/core/log.cpp index 1d41c649f7..5f63b5af58 100644 --- a/library/cpp/actors/core/log.cpp +++ b/library/cpp/actors/core/log.cpp @@ -209,7 +209,7 @@ namespace NActors { TLoggerActor::~TLoggerActor() { } - void TLoggerActor::Log(TInstant time, NLog::EPriority priority, NLog::EComponent component, const char* c, ...) { + void TLoggerActor::Log(TInstant time, NLog::EPriority priority, NLog::EComponent component, const char* c, ...) { Metrics->IncDirectMsgs(); if (Settings && Settings->Satisfies(priority, component, 0ull)) { va_list params; @@ -235,7 +235,7 @@ namespace NActors { } } - void TLoggerActor::HandleIgnoredEvent(TLogIgnored::TPtr& ev, const NActors::TActorContext& ctx) { + void TLoggerActor::HandleIgnoredEvent(TLogIgnored::TPtr& ev, const NActors::TActorContext& ctx) { Y_UNUSED(ev); LogIgnoredCount(ctx.Now()); IgnoredCount = 0; @@ -254,12 +254,12 @@ namespace NActors { switch (prio) { case ::NActors::NLog::EPrio::Alert: Metrics->IncAlertMsgs(); - break; + break; case ::NActors::NLog::EPrio::Emerg: Metrics->IncEmergMsgs(); - break; - default: - break; + break; + default: + break; } } @@ -273,7 +273,7 @@ namespace NActors { AtomicSet(IsOverflow, 0); // Check if some records have to be dropped - if ((PassedCount > 10 && delayMillisec > (i64)Settings->TimeThresholdMs) || IgnoredCount > 0) { + if ((PassedCount > 10 && delayMillisec > (i64)Settings->TimeThresholdMs) || IgnoredCount > 0) { Metrics->IncIgnoredMsgs(); if (IgnoredCount == 0) { ctx.Send(ctx.SelfID, new TLogIgnored()); @@ -302,7 +302,7 @@ namespace NActors { Schedule(WakeupInterval, new TEvents::TEvWakeup); } - void TLoggerActor::HandleLogComponentLevelRequest(TLogComponentLevelRequest::TPtr& ev, const NActors::TActorContext& ctx) { + void TLoggerActor::HandleLogComponentLevelRequest(TLogComponentLevelRequest::TPtr& ev, const NActors::TActorContext& ctx) { Metrics->IncLevelRequests(); TString explanation; int code = Settings->SetLevel(ev->Get()->Priority, ev->Get()->Component, explanation); @@ -312,24 +312,24 @@ namespace NActors { void TLoggerActor::RenderComponentPriorities(IOutputStream& str) { using namespace NLog; HTML(str) { - H4() { - str << "Priority Settings for the Components"; - } + H4() { + str << "Priority Settings for the Components"; + } TABLE_SORTABLE_CLASS("table") { TABLEHEAD() { TABLER() { - TABLEH() { - str << "Component"; - } - TABLEH() { - str << "Level"; - } - TABLEH() { - str << "Sampling Level"; - } - TABLEH() { - str << "Sampling Rate"; - } + TABLEH() { + str << "Component"; + } + TABLEH() { + str << "Level"; + } + TABLEH() { + str << "Sampling Level"; + } + TABLEH() { + str << "Sampling Rate"; + } } } TABLEBODY() { @@ -340,18 +340,18 @@ namespace NActors { NLog::TComponentSettings componentSettings = Settings->GetComponentSettings(i); TABLER() { - TABLED() { - str << "<a href='logger?c=" << i << "'>" << name << "</a>"; - } - TABLED() { + TABLED() { + str << "<a href='logger?c=" << i << "'>" << name << "</a>"; + } + TABLED() { str << PriorityToString(EPrio(componentSettings.Raw.X.Level)); - } - TABLED() { + } + TABLED() { str << PriorityToString(EPrio(componentSettings.Raw.X.SamplingLevel)); - } - TABLED() { - str << componentSettings.Raw.X.SamplingRate; - } + } + TABLED() { + str << componentSettings.Raw.X.SamplingRate; + } } } } @@ -366,7 +366,7 @@ namespace NActors { * 3. Number of messages per components, per priority * 4. Log level changes (last N changes) */ - void TLoggerActor::HandleMonInfo(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) { + void TLoggerActor::HandleMonInfo(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) { const auto& params = ev->Get()->Request.GetParams(); NLog::EComponent component = NLog::InvalidComponent; NLog::EPriority priority = NLog::PRI_DEBUG; @@ -415,9 +415,9 @@ namespace NActors { HTML(str) { DIV_CLASS("row") { DIV_CLASS("col-md-12") { - H4() { - str << "Current log settings for " << Settings->ComponentName(component) << Endl; - } + H4() { + str << "Current log settings for " << Settings->ComponentName(component) << Endl; + } UL() { LI() { str << "Priority: " @@ -437,9 +437,9 @@ namespace NActors { DIV_CLASS("row") { DIV_CLASS("col-md-12") { - H4() { - str << "Change priority" << Endl; - } + H4() { + str << "Change priority" << Endl; + } UL() { for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) { LI() { @@ -448,9 +448,9 @@ namespace NActors { } } } - H4() { - str << "Change sampling priority" << Endl; - } + H4() { + str << "Change sampling priority" << Endl; + } UL() { for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) { LI() { @@ -459,17 +459,17 @@ namespace NActors { } } } - H4() { - str << "Change sampling rate" << Endl; - } + H4() { + str << "Change sampling rate" << Endl; + } str << "<form method=\"GET\">" << Endl; str << "Rate: <input type=\"number\" name=\"sr\" value=\"" << samplingRate << "\"/>" << Endl; str << "<input type=\"hidden\" name=\"c\" value=\"" << component << "\">" << Endl; str << "<input class=\"btn btn-primary\" type=\"submit\" value=\"Change\"/>" << Endl; str << "</form>" << Endl; - H4() { - str << "<a href='logger'>Cancel</a>" << Endl; - } + H4() { + str << "<a href='logger'>Cancel</a>" << Endl; + } } } } @@ -492,76 +492,76 @@ namespace NActors { HTML(str) { if (!explanation.empty()) { DIV_CLASS("row") { - DIV_CLASS("col-md-12 alert alert-info") { - str << explanation; - } + DIV_CLASS("col-md-12 alert alert-info") { + str << explanation; + } } } DIV_CLASS("row") { DIV_CLASS("col-md-6") { - RenderComponentPriorities(str); - } - DIV_CLASS("col-md-6") { - H4() { - str << "Change priority for all components"; - } + RenderComponentPriorities(str); + } + DIV_CLASS("col-md-6") { + H4() { + str << "Change priority for all components"; + } TABLE_CLASS("table table-condensed") { TABLEHEAD() { TABLER() { - TABLEH() { - str << "Priority"; - } + TABLEH() { + str << "Priority"; + } } } TABLEBODY() { for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) { TABLER() { - TABLED() { - str << "<a href = 'logger?c=-1&p=" << p << "'>" + TABLED() { + str << "<a href = 'logger?c=-1&p=" << p << "'>" << NLog::PriorityToString(NLog::EPrio(p)) << "</a>"; } } } } } - H4() { - str << "Change sampling priority for all components"; - } + H4() { + str << "Change sampling priority for all components"; + } TABLE_CLASS("table table-condensed") { TABLEHEAD() { TABLER() { - TABLEH() { - str << "Priority"; - } + TABLEH() { + str << "Priority"; + } } } TABLEBODY() { for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) { TABLER() { - TABLED() { - str << "<a href = 'logger?c=-1&sp=" << p << "'>" + TABLED() { + str << "<a href = 'logger?c=-1&sp=" << p << "'>" << NLog::PriorityToString(NLog::EPrio(p)) << "</a>"; } } } } } - H4() { - str << "Change sampling rate for all components"; - } + H4() { + str << "Change sampling rate for all components"; + } str << "<form method=\"GET\">" << Endl; str << "Rate: <input type=\"number\" name=\"sr\" value=\"0\"/>" << Endl; str << "<input type=\"hidden\" name=\"c\" value=\"-1\">" << Endl; str << "<input class=\"btn btn-primary\" type=\"submit\" value=\"Change\"/>" << Endl; str << "</form>" << Endl; - H4() { - str << "Drop log entries in case of overflow: " - << (Settings->AllowDrop ? "Enabled" : "Disabled"); - } + H4() { + str << "Drop log entries in case of overflow: " + << (Settings->AllowDrop ? "Enabled" : "Disabled"); + } str << "<form method=\"GET\">" << Endl; - str << "<input type=\"hidden\" name=\"allowdrop\" value=\"" << (Settings->AllowDrop ? "0" : "1") << "\"/>" << Endl; - str << "<input class=\"btn btn-primary\" type=\"submit\" value=\"" << (Settings->AllowDrop ? "Disable" : "Enable") << "\"/>" << Endl; + str << "<input type=\"hidden\" name=\"allowdrop\" value=\"" << (Settings->AllowDrop ? "0" : "1") << "\"/>" << Endl; + str << "<input class=\"btn btn-primary\" type=\"submit\" value=\"" << (Settings->AllowDrop ? "Disable" : "Enable") << "\"/>" << Endl; str << "</form>" << Endl; } } @@ -605,34 +605,34 @@ namespace NActors { TLogRecord(logPrio, logRecord.data(), logRecord.size())); } break; - case NActors::NLog::TSettings::JSON_FORMAT: { - NJsonWriter::TBuf json; - json.BeginObject() - .WriteKey("@timestamp") + case NActors::NLog::TSettings::JSON_FORMAT: { + NJsonWriter::TBuf json; + json.BeginObject() + .WriteKey("@timestamp") .WriteString(Settings->UseLocalTimestamps ? FormatLocalTimestamp(time, buf) : time.ToString().data()) - .WriteKey("microseconds") - .WriteULongLong(time.MicroSeconds()) - .WriteKey("host") - .WriteString(Settings->ShortHostName) - .WriteKey("cluster") - .WriteString(Settings->ClusterName) - .WriteKey("priority") - .WriteString(PriorityToString(priority)) - .WriteKey("npriority") - .WriteInt((int)priority) - .WriteKey("component") - .WriteString(Settings->ComponentName(component)) - .WriteKey("tag") - .WriteString("KIKIMR") - .WriteKey("revision") - .WriteInt(GetProgramSvnRevision()) - .WriteKey("message") - .WriteString(formatted) - .EndObject(); + .WriteKey("microseconds") + .WriteULongLong(time.MicroSeconds()) + .WriteKey("host") + .WriteString(Settings->ShortHostName) + .WriteKey("cluster") + .WriteString(Settings->ClusterName) + .WriteKey("priority") + .WriteString(PriorityToString(priority)) + .WriteKey("npriority") + .WriteInt((int)priority) + .WriteKey("component") + .WriteString(Settings->ComponentName(component)) + .WriteKey("tag") + .WriteString("KIKIMR") + .WriteKey("revision") + .WriteInt(GetProgramSvnRevision()) + .WriteKey("message") + .WriteString(formatted) + .EndObject(); auto logRecord = json.Str(); LogBackend->WriteData( TLogRecord(logPrio, logRecord.data(), logRecord.size())); - } break; + } break; } return true; @@ -657,7 +657,7 @@ namespace NActors { return buf; } - TAutoPtr<TLogBackend> CreateSysLogBackend(const TString& ident, + TAutoPtr<TLogBackend> CreateSysLogBackend(const TString& ident, bool logPError, bool logCons) { int flags = 0; if (logPError) @@ -668,20 +668,20 @@ namespace NActors { return new TSysLogBackend(ident.data(), TSysLogBackend::TSYSLOG_LOCAL1, flags); } - class TStderrBackend: public TLogBackend { + class TStderrBackend: public TLogBackend { public: - TStderrBackend() { - } + TStderrBackend() { + } void WriteData(const TLogRecord& rec) override { -#ifdef _MSC_VER - if (IsDebuggerPresent()) { +#ifdef _MSC_VER + if (IsDebuggerPresent()) { TString x; - x.reserve(rec.Len + 2); - x.append(rec.Data, rec.Len); - x.append('\n'); - OutputDebugString(x.c_str()); - } -#endif + x.reserve(rec.Len + 2); + x.append(rec.Data, rec.Len); + x.append('\n'); + OutputDebugString(x.c_str()); + } +#endif bool isOk = false; do { try { diff --git a/library/cpp/actors/core/log.h b/library/cpp/actors/core/log.h index 3f08af1fc8..c11a7cf3c1 100644 --- a/library/cpp/actors/core/log.h +++ b/library/cpp/actors/core/log.h @@ -1,6 +1,6 @@ #pragma once - -#include "defs.h" + +#include "defs.h" #include "log_iface.h" #include "log_settings.h" @@ -41,12 +41,12 @@ ::NActors::MemLogAdapter( \ actorCtxOrSystem, priority, component, __VA_ARGS__); \ } \ - } while (0) /**/ + } while (0) /**/ -#define LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, priority, component, sampleBy, stream) \ +#define LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, priority, component, sampleBy, stream) \ LOG_LOG_SAMPLED_BY(actorCtxOrSystem, priority, component, sampleBy, "%s", [&]() { \ - TStringBuilder logStringBuilder; \ - logStringBuilder << stream; \ + TStringBuilder logStringBuilder; \ + logStringBuilder << stream; \ return static_cast<TString>(logStringBuilder); \ }().data()) @@ -54,64 +54,64 @@ #define LOG_LOG_S(actorCtxOrSystem, priority, component, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, priority, component, 0ull, stream) // use these macros for logging via actor system or actor context -#define LOG_EMERG(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_EMERG, component, __VA_ARGS__) -#define LOG_ALERT(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_ALERT, component, __VA_ARGS__) -#define LOG_CRIT(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_CRIT, component, __VA_ARGS__) -#define LOG_ERROR(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_ERROR, component, __VA_ARGS__) -#define LOG_WARN(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_WARN, component, __VA_ARGS__) -#define LOG_NOTICE(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_NOTICE, component, __VA_ARGS__) -#define LOG_INFO(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_INFO, component, __VA_ARGS__) -#define LOG_DEBUG(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_DEBUG, component, __VA_ARGS__) -#define LOG_TRACE(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_TRACE, component, __VA_ARGS__) - -#define LOG_EMERG_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_EMERG, component, stream) -#define LOG_ALERT_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_ALERT, component, stream) -#define LOG_CRIT_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_CRIT, component, stream) -#define LOG_ERROR_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_ERROR, component, stream) -#define LOG_WARN_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_WARN, component, stream) +#define LOG_EMERG(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_EMERG, component, __VA_ARGS__) +#define LOG_ALERT(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_ALERT, component, __VA_ARGS__) +#define LOG_CRIT(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_CRIT, component, __VA_ARGS__) +#define LOG_ERROR(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_ERROR, component, __VA_ARGS__) +#define LOG_WARN(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_WARN, component, __VA_ARGS__) +#define LOG_NOTICE(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_NOTICE, component, __VA_ARGS__) +#define LOG_INFO(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_INFO, component, __VA_ARGS__) +#define LOG_DEBUG(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_DEBUG, component, __VA_ARGS__) +#define LOG_TRACE(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_TRACE, component, __VA_ARGS__) + +#define LOG_EMERG_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_EMERG, component, stream) +#define LOG_ALERT_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_ALERT, component, stream) +#define LOG_CRIT_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_CRIT, component, stream) +#define LOG_ERROR_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_ERROR, component, stream) +#define LOG_WARN_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_WARN, component, stream) #define LOG_NOTICE_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_NOTICE, component, stream) -#define LOG_INFO_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_INFO, component, stream) -#define LOG_DEBUG_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_DEBUG, component, stream) -#define LOG_TRACE_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_TRACE, component, stream) - -#define LOG_EMERG_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_EMERG, component, sampleBy, __VA_ARGS__) -#define LOG_ALERT_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_ALERT, component, sampleBy, __VA_ARGS__) -#define LOG_CRIT_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_CRIT, component, sampleBy, __VA_ARGS__) -#define LOG_ERROR_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_ERROR, component, sampleBy, __VA_ARGS__) -#define LOG_WARN_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_WARN, component, sampleBy, __VA_ARGS__) -#define LOG_NOTICE_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_NOTICE, component, sampleBy, __VA_ARGS__) -#define LOG_INFO_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_INFO, component, sampleBy, __VA_ARGS__) -#define LOG_DEBUG_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_DEBUG, component, sampleBy, __VA_ARGS__) -#define LOG_TRACE_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_TRACE, component, sampleBy, __VA_ARGS__) - -#define LOG_EMERG_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_EMERG, component, sampleBy, stream) -#define LOG_ALERT_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_ALERT, component, sampleBy, stream) -#define LOG_CRIT_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_CRIT, component, sampleBy, stream) -#define LOG_ERROR_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_ERROR, component, sampleBy, stream) -#define LOG_WARN_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_WARN, component, sampleBy, stream) +#define LOG_INFO_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_INFO, component, stream) +#define LOG_DEBUG_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_DEBUG, component, stream) +#define LOG_TRACE_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_TRACE, component, stream) + +#define LOG_EMERG_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_EMERG, component, sampleBy, __VA_ARGS__) +#define LOG_ALERT_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_ALERT, component, sampleBy, __VA_ARGS__) +#define LOG_CRIT_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_CRIT, component, sampleBy, __VA_ARGS__) +#define LOG_ERROR_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_ERROR, component, sampleBy, __VA_ARGS__) +#define LOG_WARN_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_WARN, component, sampleBy, __VA_ARGS__) +#define LOG_NOTICE_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_NOTICE, component, sampleBy, __VA_ARGS__) +#define LOG_INFO_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_INFO, component, sampleBy, __VA_ARGS__) +#define LOG_DEBUG_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_DEBUG, component, sampleBy, __VA_ARGS__) +#define LOG_TRACE_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_TRACE, component, sampleBy, __VA_ARGS__) + +#define LOG_EMERG_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_EMERG, component, sampleBy, stream) +#define LOG_ALERT_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_ALERT, component, sampleBy, stream) +#define LOG_CRIT_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_CRIT, component, sampleBy, stream) +#define LOG_ERROR_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_ERROR, component, sampleBy, stream) +#define LOG_WARN_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_WARN, component, sampleBy, stream) #define LOG_NOTICE_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_NOTICE, component, sampleBy, stream) -#define LOG_INFO_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_INFO, component, sampleBy, stream) -#define LOG_DEBUG_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_DEBUG, component, sampleBy, stream) -#define LOG_TRACE_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_TRACE, component, sampleBy, stream) +#define LOG_INFO_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_INFO, component, sampleBy, stream) +#define LOG_DEBUG_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_DEBUG, component, sampleBy, stream) +#define LOG_TRACE_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_TRACE, component, sampleBy, stream) // Log Throttling #define LOG_LOG_THROTTLE(throttler, actorCtxOrSystem, priority, component, ...) \ - do { \ - if ((throttler).Kick()) { \ - LOG_LOG(actorCtxOrSystem, priority, component, __VA_ARGS__); \ - } \ - } while (0) /**/ - -#define TRACE_EVENT(component) \ - const auto& currentTracer = component; \ - if (ev->HasEvent()) { \ - LOG_TRACE(*TlsActivationContext, currentTracer, "%s, received event# %" PRIu32 ", Sender %s, Recipient %s: %s", \ - __FUNCTION__, ev->Type, ev->Sender.ToString().data(), SelfId().ToString().data(), ev->GetBase()->ToString().substr(0, 1000).data()); \ - } else { \ - LOG_TRACE(*TlsActivationContext, currentTracer, "%s, received event# %" PRIu32 ", Sender %s, Recipient %s", \ + do { \ + if ((throttler).Kick()) { \ + LOG_LOG(actorCtxOrSystem, priority, component, __VA_ARGS__); \ + } \ + } while (0) /**/ + +#define TRACE_EVENT(component) \ + const auto& currentTracer = component; \ + if (ev->HasEvent()) { \ + LOG_TRACE(*TlsActivationContext, currentTracer, "%s, received event# %" PRIu32 ", Sender %s, Recipient %s: %s", \ + __FUNCTION__, ev->Type, ev->Sender.ToString().data(), SelfId().ToString().data(), ev->GetBase()->ToString().substr(0, 1000).data()); \ + } else { \ + LOG_TRACE(*TlsActivationContext, currentTracer, "%s, received event# %" PRIu32 ", Sender %s, Recipient %s", \ __FUNCTION__, ev->Type, ev->Sender.ToString().data(), ev->Recipient.ToString().data()); \ } -#define TRACE_EVENT_TYPE(eventType) LOG_TRACE(*TlsActivationContext, currentTracer, "%s, processing event %s", __FUNCTION__, eventType) +#define TRACE_EVENT_TYPE(eventType) LOG_TRACE(*TlsActivationContext, currentTracer, "%s, processing event %s", __FUNCTION__, eventType) class TLog; class TLogBackend; @@ -147,7 +147,7 @@ namespace NActors { class TLogComponentLevelResponse: public TEventLocal<TLogComponentLevelResponse, int(NLog::EEv::LevelResp)> { public: - TLogComponentLevelResponse(int code, const TString& explanation) + TLogComponentLevelResponse(int code, const TString& explanation) : Code(code) , Explanation(explanation) { @@ -157,7 +157,7 @@ namespace NActors { return Code; } - const TString& GetExplanation() const { + const TString& GetExplanation() const { return Explanation; } @@ -190,7 +190,7 @@ namespace NActors { virtual void GetOutputHtml(IOutputStream&) = 0; }; - class TLoggerActor: public TActor<TLoggerActor> { + class TLoggerActor: public TActor<TLoggerActor> { public: static constexpr IActor::EActivityType ActorActivityType() { return IActor::LOG_ACTOR; @@ -210,7 +210,7 @@ namespace NActors { std::shared_ptr<NMonitoring::TMetricRegistry> metrics); ~TLoggerActor(); - void StateFunc(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) { + void StateFunc(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) { switch (ev->GetTypeRewrite()) { HFunc(TLogIgnored, HandleIgnoredEvent); HFunc(NLog::TEvLog, HandleLogEvent); @@ -230,7 +230,7 @@ namespace NActors { } // Directly call logger instead of sending a message - void Log(TInstant time, NLog::EPriority priority, NLog::EComponent component, const char* c, ...); + void Log(TInstant time, NLog::EPriority priority, NLog::EComponent component, const char* c, ...); static void Throttle(const NLog::TSettings& settings); @@ -244,12 +244,12 @@ namespace NActors { std::unique_ptr<ILoggerMetrics> Metrics; void BecomeDefunct(); - void HandleIgnoredEvent(TLogIgnored::TPtr& ev, const NActors::TActorContext& ctx); + void HandleIgnoredEvent(TLogIgnored::TPtr& ev, const NActors::TActorContext& ctx); void HandleIgnoredEventDrop(); void HandleLogEvent(NLog::TEvLog::TPtr& ev, const TActorContext& ctx); void HandleLogEventDrop(const NLog::TEvLog::TPtr& ev); - void HandleLogComponentLevelRequest(TLogComponentLevelRequest::TPtr& ev, const TActorContext& ctx); - void HandleMonInfo(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx); + void HandleLogComponentLevelRequest(TLogComponentLevelRequest::TPtr& ev, const TActorContext& ctx); + void HandleMonInfo(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx); void HandleWakeup(); [[nodiscard]] bool OutputRecord(TInstant time, NLog::EPrio priority, NLog::EComponent component, const TString& formatted) noexcept; void RenderComponentPriorities(IOutputStream& str); @@ -270,8 +270,8 @@ namespace NActors { public: TTrivialLogThrottler(TDuration period) : Period(period) - { - } + { + } // return value: // true -- write to log @@ -294,16 +294,16 @@ namespace NActors { //////////////////////////////////////////////////////////////////////////////// // SYSLOG BACKEND //////////////////////////////////////////////////////////////////////////////// - TAutoPtr<TLogBackend> CreateSysLogBackend(const TString& ident, + TAutoPtr<TLogBackend> CreateSysLogBackend(const TString& ident, bool logPError, bool logCons); TAutoPtr<TLogBackend> CreateStderrBackend(); TAutoPtr<TLogBackend> CreateFileBackend(const TString& fileName); TAutoPtr<TLogBackend> CreateNullBackend(); TAutoPtr<TLogBackend> CreateCompositeLogBackend(TVector<TAutoPtr<TLogBackend>>&& underlyingBackends); - ///////////////////////////////////////////////////////////////////// - // Logging adaptors for memory log and logging into filesystem - ///////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////// + // Logging adaptors for memory log and logging into filesystem + ///////////////////////////////////////////////////////////////////// namespace NDetail { inline void Y_PRINTF_FORMAT(2, 3) PrintfV(TString& dst, const char* format, ...) { @@ -319,18 +319,18 @@ namespace NActors { } // namespace NDetail template <typename TCtx> - inline void DeliverLogMessage(TCtx& ctx, NLog::EPriority mPriority, NLog::EComponent mComponent, TString &&str) - { - const NLog::TSettings *mSettings = ctx.LoggerSettings(); + inline void DeliverLogMessage(TCtx& ctx, NLog::EPriority mPriority, NLog::EComponent mComponent, TString &&str) + { + const NLog::TSettings *mSettings = ctx.LoggerSettings(); TLoggerActor::Throttle(*mSettings); ctx.Send(new IEventHandle(mSettings->LoggerActorId, TActorId(), new NLog::TEvLog(mPriority, mComponent, std::move(str)))); } template <typename TCtx, typename... TArgs> inline void MemLogAdapter( - TCtx& actorCtxOrSystem, - NLog::EPriority mPriority, - NLog::EComponent mComponent, + TCtx& actorCtxOrSystem, + NLog::EPriority mPriority, + NLog::EComponent mComponent, const char* format, TArgs&&... params) { TString Formatted; @@ -346,11 +346,11 @@ namespace NActors { } template <typename TCtx> - Y_WRAPPER inline void MemLogAdapter( - TCtx& actorCtxOrSystem, - NLog::EPriority mPriority, - NLog::EComponent mComponent, - const TString& str) { + Y_WRAPPER inline void MemLogAdapter( + TCtx& actorCtxOrSystem, + NLog::EPriority mPriority, + NLog::EComponent mComponent, + const TString& str) { MemLogWrite(str.data(), str.size(), true); DeliverLogMessage(actorCtxOrSystem, mPriority, mComponent, TString(str)); diff --git a/library/cpp/actors/core/log_settings.cpp b/library/cpp/actors/core/log_settings.cpp index b51519c82a..f52f2fc5d2 100644 --- a/library/cpp/actors/core/log_settings.cpp +++ b/library/cpp/actors/core/log_settings.cpp @@ -5,7 +5,7 @@ namespace NActors { namespace NLog { TSettings::TSettings(const TActorId& loggerActorId, const EComponent loggerComponent, - EComponent minVal, EComponent maxVal, EComponentToStringFunc func, + EComponent minVal, EComponent maxVal, EComponentToStringFunc func, EPriority defPriority, EPriority defSamplingPriority, ui32 defSamplingRate, ui64 timeThresholdMs) : LoggerActorId(loggerActorId) @@ -88,8 +88,8 @@ namespace NActors { } int TSettings::SetLevelImpl( - const TString& name, bool isSampling, - EPriority priority, EComponent component, TString& explanation) { + const TString& name, bool isSampling, + EPriority priority, EComponent component, TString& explanation) { TString titleName(name); titleName.to_title(); @@ -143,17 +143,17 @@ namespace NActors { } } - int TSettings::SetLevel(EPriority priority, EComponent component, TString& explanation) { + int TSettings::SetLevel(EPriority priority, EComponent component, TString& explanation) { return SetLevelImpl("priority", false, - priority, component, explanation); + priority, component, explanation); } - int TSettings::SetSamplingLevel(EPriority priority, EComponent component, TString& explanation) { + int TSettings::SetSamplingLevel(EPriority priority, EComponent component, TString& explanation) { return SetLevelImpl("sampling priority", true, - priority, component, explanation); + priority, component, explanation); } - int TSettings::SetSamplingRate(ui32 sampling, EComponent component, TString& explanation) { + int TSettings::SetSamplingRate(ui32 sampling, EComponent component, TString& explanation) { if (component == InvalidComponent) { for (int i = 0; i < Mask + 1; i++) { TComponentSettings settings = AtomicGet(ComponentInfo[i]); @@ -174,8 +174,8 @@ namespace NActors { AtomicSet(ComponentInfo[component], settings.Raw.Data); TStringStream str; str << "Sampling rate for the component " << ComponentNames[component] - << " has been changed from " << oldSampling - << " to " << sampling; + << " has been changed from " << oldSampling + << " to " << sampling; explanation = str.Str(); } return 0; @@ -192,9 +192,9 @@ namespace NActors { bool TSettings::IsValidPriority(EPriority priority) { return priority == PRI_EMERG || priority == PRI_ALERT || - priority == PRI_CRIT || priority == PRI_ERROR || - priority == PRI_WARN || priority == PRI_NOTICE || - priority == PRI_INFO || priority == PRI_DEBUG || priority == PRI_TRACE; + priority == PRI_CRIT || priority == PRI_ERROR || + priority == PRI_WARN || priority == PRI_NOTICE || + priority == PRI_INFO || priority == PRI_DEBUG || priority == PRI_TRACE; } bool TSettings::IsValidComponent(EComponent component) { diff --git a/library/cpp/actors/core/log_settings.h b/library/cpp/actors/core/log_settings.h index 3bb332319c..7fe4504edd 100644 --- a/library/cpp/actors/core/log_settings.h +++ b/library/cpp/actors/core/log_settings.h @@ -11,25 +11,25 @@ namespace NActors { inline const char* PriorityToString(EPrio priority) { switch (priority) { case EPrio::Emerg: - return "EMERG"; + return "EMERG"; case EPrio::Alert: - return "ALERT"; + return "ALERT"; case EPrio::Crit: - return "CRIT"; + return "CRIT"; case EPrio::Error: - return "ERROR"; + return "ERROR"; case EPrio::Warn: - return "WARN"; + return "WARN"; case EPrio::Notice: - return "NOTICE"; + return "NOTICE"; case EPrio::Info: - return "INFO"; + return "INFO"; case EPrio::Debug: - return "DEBUG"; + return "DEBUG"; case EPrio::Trace: - return "TRACE"; - default: - return "UNKNOWN"; + return "TRACE"; + default: + return "UNKNOWN"; } } @@ -67,7 +67,7 @@ namespace NActors { } }; - struct TSettings: public TThrRefBase { + struct TSettings: public TThrRefBase { public: TActorId LoggerActorId; EComponent LoggerComponent; @@ -99,7 +99,7 @@ namespace NActors { // automatically generates YOURTYPE_MIN, YOURTYPE_MAX and // YOURTYPE_Name for you. TSettings(const TActorId& loggerActorId, const EComponent loggerComponent, - EComponent minVal, EComponent maxVal, EComponentToStringFunc func, + EComponent minVal, EComponent maxVal, EComponentToStringFunc func, EPriority defPriority, EPriority defSamplingPriority = PRI_DEBUG, ui32 defSamplingRate = 0, ui64 timeThresholdMs = 1000); @@ -149,14 +149,14 @@ namespace NActors { return TComponentSettings(AtomicGet(ComponentInfo[component & Mask])); } - const char* ComponentName(EComponent component) const { + const char* ComponentName(EComponent component) const { Y_VERIFY_DEBUG((component & Mask) == component); return ComponentNames[component & Mask].data(); } - int SetLevel(EPriority priority, EComponent component, TString& explanation); - int SetSamplingLevel(EPriority priority, EComponent component, TString& explanation); - int SetSamplingRate(ui32 sampling, EComponent component, TString& explanation); + int SetLevel(EPriority priority, EComponent component, TString& explanation); + int SetSamplingLevel(EPriority priority, EComponent component, TString& explanation); + int SetSamplingRate(ui32 sampling, EComponent component, TString& explanation); EComponent FindComponent(const TStringBuf& componentName) const; static int PowerOf2Mask(int val); static bool IsValidPriority(EPriority priority); @@ -168,7 +168,7 @@ namespace NActors { private: int SetLevelImpl( const TString& name, bool isSampling, - EPriority priority, EComponent component, TString& explanation); + EPriority priority, EComponent component, TString& explanation); }; } diff --git a/library/cpp/actors/core/mailbox.cpp b/library/cpp/actors/core/mailbox.cpp index cf1fca5630..d84b4f9e46 100644 --- a/library/cpp/actors/core/mailbox.cpp +++ b/library/cpp/actors/core/mailbox.cpp @@ -1,381 +1,381 @@ -#include "mailbox.h" -#include "actorsystem.h" - +#include "mailbox.h" +#include "actorsystem.h" + #include <library/cpp/actors/util/datetime.h> #include <util/system/sanitizers.h> -namespace NActors { - TMailboxTable::TMailboxTable() - : LastAllocatedLine(0) - , AllocatedMailboxCount(0) - , CachedSimpleMailboxes(0) - , CachedRevolvingMailboxes(0) - , CachedHTSwapMailboxes(0) - , CachedReadAsFilledMailboxes(0) - , CachedTinyReadAsFilledMailboxes(0) - { - memset((void*)Lines, 0, sizeof(Lines)); - } - - bool IsGoodForCleanup(const TMailboxHeader* header) { - switch (AtomicLoad(&header->ExecutionState)) { - case TMailboxHeader::TExecutionState::Inactive: - case TMailboxHeader::TExecutionState::Scheduled: - return true; - case TMailboxHeader::TExecutionState::Leaving: - case TMailboxHeader::TExecutionState::Executing: - case TMailboxHeader::TExecutionState::LeavingMarked: - return false; - case TMailboxHeader::TExecutionState::Free: - case TMailboxHeader::TExecutionState::FreeScheduled: - return true; - case TMailboxHeader::TExecutionState::FreeLeaving: - case TMailboxHeader::TExecutionState::FreeExecuting: - case TMailboxHeader::TExecutionState::FreeLeavingMarked: - return false; - default: - Y_FAIL(); - } - } - - template <typename TMailbox> - void DestructMailboxLine(ui8* begin, ui8* end) { - const ui32 sx = TMailbox::AlignedSize(); - for (ui8* x = begin; x + sx <= end; x += sx) { - TMailbox* mailbox = reinterpret_cast<TMailbox*>(x); - Y_VERIFY(IsGoodForCleanup(mailbox)); - mailbox->ExecutionState = Max<ui32>(); - mailbox->~TMailbox(); - } - } - - template <typename TMailbox> - bool CleanupMailboxLine(ui8* begin, ui8* end) { - const ui32 sx = TMailbox::AlignedSize(); - bool done = true; - for (ui8* x = begin; x + sx <= end; x += sx) { - TMailbox* mailbox = reinterpret_cast<TMailbox*>(x); - Y_VERIFY(IsGoodForCleanup(mailbox)); - done &= mailbox->CleanupActors() && mailbox->CleanupEvents(); - } - return done; - } - - TMailboxTable::~TMailboxTable() { - // on cleanup we must traverse everything and free stuff - for (ui32 i = 0; i < LastAllocatedLine; ++i) { - if (TMailboxLineHeader* lineHeader = Lines[i]) { - switch (lineHeader->MailboxType) { - case TMailboxType::Simple: - DestructMailboxLine<TSimpleMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); - break; - case TMailboxType::Revolving: - DestructMailboxLine<TRevolvingMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); - break; - case TMailboxType::HTSwap: - DestructMailboxLine<THTSwapMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); - break; - case TMailboxType::ReadAsFilled: - DestructMailboxLine<TReadAsFilledMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); - break; - case TMailboxType::TinyReadAsFilled: - DestructMailboxLine<TTinyReadAsFilledMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); - break; - default: - Y_FAIL(); - } - - lineHeader->~TMailboxLineHeader(); - free(lineHeader); - Lines[i] = nullptr; - } - } - - while (MailboxCacheSimple.Pop(0)) - ; - while (MailboxCacheRevolving.Pop(0)) - ; - while (MailboxCacheHTSwap.Pop(0)) - ; - while (MailboxCacheReadAsFilled.Pop(0)) - ; - while (MailboxCacheTinyReadAsFilled.Pop(0)) - ; - } - - bool TMailboxTable::Cleanup() { - bool done = true; - for (ui32 i = 0; i < LastAllocatedLine; ++i) { - if (TMailboxLineHeader* lineHeader = Lines[i]) { - switch (lineHeader->MailboxType) { - case TMailboxType::Simple: - done &= CleanupMailboxLine<TSimpleMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); - break; - case TMailboxType::Revolving: - done &= CleanupMailboxLine<TRevolvingMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); - break; - case TMailboxType::HTSwap: - done &= CleanupMailboxLine<THTSwapMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); - break; - case TMailboxType::ReadAsFilled: - done &= CleanupMailboxLine<TReadAsFilledMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); - break; - case TMailboxType::TinyReadAsFilled: - done &= CleanupMailboxLine<TTinyReadAsFilledMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); - break; - default: - Y_FAIL(); - } - } - } - return done; - } - - TMailboxHeader* TMailboxTable::Get(ui32 hint) { - // get line - const ui32 lineIndex = (hint & LineIndexMask) >> LineIndexShift; - const ui32 lineHint = hint & LineHintMask; - - Y_VERIFY((lineIndex < MaxLines) && (lineHint < LineSize / 64)); - if (lineHint == 0) - return nullptr; - - if (TMailboxLineHeader* const x = AtomicLoad(Lines + lineIndex)) { - switch (x->MailboxType) { - case TMailboxType::Simple: - return TSimpleMailbox::Get(lineHint, x); - case TMailboxType::Revolving: - return TRevolvingMailbox::Get(lineHint, x); - case TMailboxType::HTSwap: - return THTSwapMailbox::Get(lineHint, x); - case TMailboxType::ReadAsFilled: - return TReadAsFilledMailbox::Get(lineHint, x); - case TMailboxType::TinyReadAsFilled: - return TTinyReadAsFilledMailbox::Get(lineHint, x); - default: - Y_VERIFY_DEBUG(false); - break; - } - } - - return nullptr; - } - - bool TMailboxTable::SendTo(TAutoPtr<IEventHandle>& ev, IExecutorPool* executorPool) { +namespace NActors { + TMailboxTable::TMailboxTable() + : LastAllocatedLine(0) + , AllocatedMailboxCount(0) + , CachedSimpleMailboxes(0) + , CachedRevolvingMailboxes(0) + , CachedHTSwapMailboxes(0) + , CachedReadAsFilledMailboxes(0) + , CachedTinyReadAsFilledMailboxes(0) + { + memset((void*)Lines, 0, sizeof(Lines)); + } + + bool IsGoodForCleanup(const TMailboxHeader* header) { + switch (AtomicLoad(&header->ExecutionState)) { + case TMailboxHeader::TExecutionState::Inactive: + case TMailboxHeader::TExecutionState::Scheduled: + return true; + case TMailboxHeader::TExecutionState::Leaving: + case TMailboxHeader::TExecutionState::Executing: + case TMailboxHeader::TExecutionState::LeavingMarked: + return false; + case TMailboxHeader::TExecutionState::Free: + case TMailboxHeader::TExecutionState::FreeScheduled: + return true; + case TMailboxHeader::TExecutionState::FreeLeaving: + case TMailboxHeader::TExecutionState::FreeExecuting: + case TMailboxHeader::TExecutionState::FreeLeavingMarked: + return false; + default: + Y_FAIL(); + } + } + + template <typename TMailbox> + void DestructMailboxLine(ui8* begin, ui8* end) { + const ui32 sx = TMailbox::AlignedSize(); + for (ui8* x = begin; x + sx <= end; x += sx) { + TMailbox* mailbox = reinterpret_cast<TMailbox*>(x); + Y_VERIFY(IsGoodForCleanup(mailbox)); + mailbox->ExecutionState = Max<ui32>(); + mailbox->~TMailbox(); + } + } + + template <typename TMailbox> + bool CleanupMailboxLine(ui8* begin, ui8* end) { + const ui32 sx = TMailbox::AlignedSize(); + bool done = true; + for (ui8* x = begin; x + sx <= end; x += sx) { + TMailbox* mailbox = reinterpret_cast<TMailbox*>(x); + Y_VERIFY(IsGoodForCleanup(mailbox)); + done &= mailbox->CleanupActors() && mailbox->CleanupEvents(); + } + return done; + } + + TMailboxTable::~TMailboxTable() { + // on cleanup we must traverse everything and free stuff + for (ui32 i = 0; i < LastAllocatedLine; ++i) { + if (TMailboxLineHeader* lineHeader = Lines[i]) { + switch (lineHeader->MailboxType) { + case TMailboxType::Simple: + DestructMailboxLine<TSimpleMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); + break; + case TMailboxType::Revolving: + DestructMailboxLine<TRevolvingMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); + break; + case TMailboxType::HTSwap: + DestructMailboxLine<THTSwapMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); + break; + case TMailboxType::ReadAsFilled: + DestructMailboxLine<TReadAsFilledMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); + break; + case TMailboxType::TinyReadAsFilled: + DestructMailboxLine<TTinyReadAsFilledMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); + break; + default: + Y_FAIL(); + } + + lineHeader->~TMailboxLineHeader(); + free(lineHeader); + Lines[i] = nullptr; + } + } + + while (MailboxCacheSimple.Pop(0)) + ; + while (MailboxCacheRevolving.Pop(0)) + ; + while (MailboxCacheHTSwap.Pop(0)) + ; + while (MailboxCacheReadAsFilled.Pop(0)) + ; + while (MailboxCacheTinyReadAsFilled.Pop(0)) + ; + } + + bool TMailboxTable::Cleanup() { + bool done = true; + for (ui32 i = 0; i < LastAllocatedLine; ++i) { + if (TMailboxLineHeader* lineHeader = Lines[i]) { + switch (lineHeader->MailboxType) { + case TMailboxType::Simple: + done &= CleanupMailboxLine<TSimpleMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); + break; + case TMailboxType::Revolving: + done &= CleanupMailboxLine<TRevolvingMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); + break; + case TMailboxType::HTSwap: + done &= CleanupMailboxLine<THTSwapMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); + break; + case TMailboxType::ReadAsFilled: + done &= CleanupMailboxLine<TReadAsFilledMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); + break; + case TMailboxType::TinyReadAsFilled: + done &= CleanupMailboxLine<TTinyReadAsFilledMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize); + break; + default: + Y_FAIL(); + } + } + } + return done; + } + + TMailboxHeader* TMailboxTable::Get(ui32 hint) { + // get line + const ui32 lineIndex = (hint & LineIndexMask) >> LineIndexShift; + const ui32 lineHint = hint & LineHintMask; + + Y_VERIFY((lineIndex < MaxLines) && (lineHint < LineSize / 64)); + if (lineHint == 0) + return nullptr; + + if (TMailboxLineHeader* const x = AtomicLoad(Lines + lineIndex)) { + switch (x->MailboxType) { + case TMailboxType::Simple: + return TSimpleMailbox::Get(lineHint, x); + case TMailboxType::Revolving: + return TRevolvingMailbox::Get(lineHint, x); + case TMailboxType::HTSwap: + return THTSwapMailbox::Get(lineHint, x); + case TMailboxType::ReadAsFilled: + return TReadAsFilledMailbox::Get(lineHint, x); + case TMailboxType::TinyReadAsFilled: + return TTinyReadAsFilledMailbox::Get(lineHint, x); + default: + Y_VERIFY_DEBUG(false); + break; + } + } + + return nullptr; + } + + bool TMailboxTable::SendTo(TAutoPtr<IEventHandle>& ev, IExecutorPool* executorPool) { const TActorId& recipient = ev->GetRecipientRewrite(); - const ui32 hint = recipient.Hint(); - - // copy-paste from Get to avoid duplicated type-switches - const ui32 lineIndex = (hint & LineIndexMask) >> LineIndexShift; - const ui32 lineHint = hint & LineHintMask; - - Y_VERIFY((lineIndex < MaxLines) && (lineHint < LineSize / 64)); - if (lineHint == 0) - return false; - - if (TMailboxLineHeader* const x = AtomicLoad(Lines + lineIndex)) { - switch (x->MailboxType) { - case TMailboxType::Simple: { - TSimpleMailbox* const mailbox = TSimpleMailbox::Get(lineHint, x); + const ui32 hint = recipient.Hint(); + + // copy-paste from Get to avoid duplicated type-switches + const ui32 lineIndex = (hint & LineIndexMask) >> LineIndexShift; + const ui32 lineHint = hint & LineHintMask; + + Y_VERIFY((lineIndex < MaxLines) && (lineHint < LineSize / 64)); + if (lineHint == 0) + return false; + + if (TMailboxLineHeader* const x = AtomicLoad(Lines + lineIndex)) { + switch (x->MailboxType) { + case TMailboxType::Simple: { + TSimpleMailbox* const mailbox = TSimpleMailbox::Get(lineHint, x); #if (!defined(_tsan_enabled_)) - Y_VERIFY_DEBUG(mailbox->Type == (ui32)x->MailboxType); + Y_VERIFY_DEBUG(mailbox->Type == (ui32)x->MailboxType); #endif - mailbox->Queue.Push(ev.Release()); - if (mailbox->MarkForSchedule()) { + mailbox->Queue.Push(ev.Release()); + if (mailbox->MarkForSchedule()) { RelaxedStore<NHPTimer::STime>(&mailbox->ScheduleMoment, GetCycleCountFast()); - executorPool->ScheduleActivation(hint); - } - } - return true; - case TMailboxType::Revolving: { - // The actorid could be stale and coming from a different machine. If local process has restarted than - // the stale actorid coming from a remote machine might be referencing an actor with simple mailbox - // which is smaller than revolving mailbox. In this cases 'lineHint' index might be greater than actual - // array size. Normally its ok to store stale event to other actor's valid mailbox beacuse Receive will - // compare receiver actor id and discard stale event. But in this case we should discard the event right away - // instead of trying to enque it to a mailbox at invalid address. - // NOTE: lineHint is 1-based - static_assert(TSimpleMailbox::AlignedSize() <= TRevolvingMailbox::AlignedSize(), - "We expect that one line can store more simple mailboxes than revolving mailboxes"); - if (lineHint > TRevolvingMailbox::MaxMailboxesInLine()) - return false; - - TRevolvingMailbox* const mailbox = TRevolvingMailbox::Get(lineHint, x); + executorPool->ScheduleActivation(hint); + } + } + return true; + case TMailboxType::Revolving: { + // The actorid could be stale and coming from a different machine. If local process has restarted than + // the stale actorid coming from a remote machine might be referencing an actor with simple mailbox + // which is smaller than revolving mailbox. In this cases 'lineHint' index might be greater than actual + // array size. Normally its ok to store stale event to other actor's valid mailbox beacuse Receive will + // compare receiver actor id and discard stale event. But in this case we should discard the event right away + // instead of trying to enque it to a mailbox at invalid address. + // NOTE: lineHint is 1-based + static_assert(TSimpleMailbox::AlignedSize() <= TRevolvingMailbox::AlignedSize(), + "We expect that one line can store more simple mailboxes than revolving mailboxes"); + if (lineHint > TRevolvingMailbox::MaxMailboxesInLine()) + return false; + + TRevolvingMailbox* const mailbox = TRevolvingMailbox::Get(lineHint, x); #if (!defined(_tsan_enabled_)) - Y_VERIFY_DEBUG(mailbox->Type == (ui32)x->MailboxType); + Y_VERIFY_DEBUG(mailbox->Type == (ui32)x->MailboxType); #endif - mailbox->QueueWriter.Push(ev.Release()); - if (mailbox->MarkForSchedule()) { + mailbox->QueueWriter.Push(ev.Release()); + if (mailbox->MarkForSchedule()) { RelaxedStore<NHPTimer::STime>(&mailbox->ScheduleMoment, GetCycleCountFast()); - executorPool->ScheduleActivation(hint); - } - } - return true; - case TMailboxType::HTSwap: { - THTSwapMailbox* const mailbox = THTSwapMailbox::Get(lineHint, x); + executorPool->ScheduleActivation(hint); + } + } + return true; + case TMailboxType::HTSwap: { + THTSwapMailbox* const mailbox = THTSwapMailbox::Get(lineHint, x); #if (!defined(_tsan_enabled_)) - Y_VERIFY_DEBUG(mailbox->Type == (ui32)x->MailboxType); + Y_VERIFY_DEBUG(mailbox->Type == (ui32)x->MailboxType); #endif - mailbox->Queue.Push(ev.Release()); - if (mailbox->MarkForSchedule()) { + mailbox->Queue.Push(ev.Release()); + if (mailbox->MarkForSchedule()) { RelaxedStore<NHPTimer::STime>(&mailbox->ScheduleMoment, GetCycleCountFast()); - executorPool->ScheduleActivation(hint); - } + executorPool->ScheduleActivation(hint); + } } - return true; - case TMailboxType::ReadAsFilled: { - if (lineHint > TReadAsFilledMailbox::MaxMailboxesInLine()) - return false; + return true; + case TMailboxType::ReadAsFilled: { + if (lineHint > TReadAsFilledMailbox::MaxMailboxesInLine()) + return false; - TReadAsFilledMailbox* const mailbox = TReadAsFilledMailbox::Get(lineHint, x); + TReadAsFilledMailbox* const mailbox = TReadAsFilledMailbox::Get(lineHint, x); #if (!defined(_tsan_enabled_)) - Y_VERIFY_DEBUG(mailbox->Type == (ui32)x->MailboxType); + Y_VERIFY_DEBUG(mailbox->Type == (ui32)x->MailboxType); #endif - mailbox->Queue.Push(ev.Release()); - if (mailbox->MarkForSchedule()) { + mailbox->Queue.Push(ev.Release()); + if (mailbox->MarkForSchedule()) { RelaxedStore<NHPTimer::STime>(&mailbox->ScheduleMoment, GetCycleCountFast()); - executorPool->ScheduleActivation(hint); - } + executorPool->ScheduleActivation(hint); + } } - return true; - case TMailboxType::TinyReadAsFilled: { - if (lineHint > TTinyReadAsFilledMailbox::MaxMailboxesInLine()) - return false; + return true; + case TMailboxType::TinyReadAsFilled: { + if (lineHint > TTinyReadAsFilledMailbox::MaxMailboxesInLine()) + return false; - TTinyReadAsFilledMailbox* const mailbox = TTinyReadAsFilledMailbox::Get(lineHint, x); + TTinyReadAsFilledMailbox* const mailbox = TTinyReadAsFilledMailbox::Get(lineHint, x); #if (!defined(_tsan_enabled_)) - Y_VERIFY_DEBUG(mailbox->Type == (ui32)x->MailboxType); + Y_VERIFY_DEBUG(mailbox->Type == (ui32)x->MailboxType); #endif - mailbox->Queue.Push(ev.Release()); - if (mailbox->MarkForSchedule()) { + mailbox->Queue.Push(ev.Release()); + if (mailbox->MarkForSchedule()) { RelaxedStore<NHPTimer::STime>(&mailbox->ScheduleMoment, GetCycleCountFast()); - executorPool->ScheduleActivation(hint); - } + executorPool->ScheduleActivation(hint); + } } - return true; - default: - Y_FAIL("unknown mailbox type"); + return true; + default: + Y_FAIL("unknown mailbox type"); } - } - - return false; - } - - ui32 TMailboxTable::AllocateMailbox(TMailboxType::EType type, ui64 revolvingCounter) { - ui32 x = TryAllocateMailbox(type, revolvingCounter); - if (x == 0) - x = AllocateNewLine(type); - return x; - } - - ui32 TMailboxTable::TryAllocateMailbox(TMailboxType::EType type, ui64 revolvingCounter) { - switch (type) { - case TMailboxType::Simple: - do { - if (ui32 ret = MailboxCacheSimple.Pop(revolvingCounter)) { - AtomicDecrement(CachedSimpleMailboxes); - return ret; - } - } while (AtomicGet(CachedSimpleMailboxes) > (MailboxCacheSimple.Concurrency * 512)); - return 0; - case TMailboxType::Revolving: - do { - if (ui32 ret = MailboxCacheRevolving.Pop(revolvingCounter)) { - AtomicDecrement(CachedRevolvingMailboxes); - return ret; - } - } while (AtomicGet(CachedRevolvingMailboxes) > (MailboxCacheRevolving.Concurrency * 512)); - return 0; - case TMailboxType::HTSwap: - do { - if (ui32 ret = MailboxCacheHTSwap.Pop(revolvingCounter)) { - AtomicDecrement(CachedHTSwapMailboxes); - return ret; - } - } while (AtomicGet(CachedHTSwapMailboxes) > (MailboxCacheHTSwap.Concurrency * 512)); - return 0; - case TMailboxType::ReadAsFilled: - do { - if (ui32 ret = MailboxCacheReadAsFilled.Pop(revolvingCounter)) { - AtomicDecrement(CachedReadAsFilledMailboxes); - return ret; - } - } while (AtomicGet(CachedReadAsFilledMailboxes) > (MailboxCacheReadAsFilled.Concurrency * 512)); - return 0; - case TMailboxType::TinyReadAsFilled: - do { - if (ui32 ret = MailboxCacheTinyReadAsFilled.Pop(revolvingCounter)) { - AtomicDecrement(CachedTinyReadAsFilledMailboxes); - return ret; - } - } while (AtomicGet(CachedTinyReadAsFilledMailboxes) > (MailboxCacheTinyReadAsFilled.Concurrency * 512)); - return 0; - default: - Y_FAIL("Unknown mailbox type"); - } - } - - void TMailboxTable::ReclaimMailbox(TMailboxType::EType type, ui32 hint, ui64 revolvingCounter) { - if (hint != 0) { - switch (type) { - case TMailboxType::Simple: - MailboxCacheSimple.Push(hint, revolvingCounter); - AtomicIncrement(CachedSimpleMailboxes); - break; - case TMailboxType::Revolving: - MailboxCacheRevolving.Push(hint, revolvingCounter); - AtomicIncrement(CachedRevolvingMailboxes); - break; - case TMailboxType::HTSwap: - MailboxCacheHTSwap.Push(hint, revolvingCounter); - AtomicIncrement(CachedHTSwapMailboxes); - break; - case TMailboxType::ReadAsFilled: - MailboxCacheReadAsFilled.Push(hint, revolvingCounter); - AtomicIncrement(CachedReadAsFilledMailboxes); - break; - case TMailboxType::TinyReadAsFilled: - MailboxCacheTinyReadAsFilled.Push(hint, revolvingCounter); - AtomicIncrement(CachedTinyReadAsFilledMailboxes); - break; - default: - Y_FAIL(); - } - } - } - - TMailboxHeader::TMailboxHeader(TMailboxType::EType type) - : ExecutionState(TExecutionState::Free) + } + + return false; + } + + ui32 TMailboxTable::AllocateMailbox(TMailboxType::EType type, ui64 revolvingCounter) { + ui32 x = TryAllocateMailbox(type, revolvingCounter); + if (x == 0) + x = AllocateNewLine(type); + return x; + } + + ui32 TMailboxTable::TryAllocateMailbox(TMailboxType::EType type, ui64 revolvingCounter) { + switch (type) { + case TMailboxType::Simple: + do { + if (ui32 ret = MailboxCacheSimple.Pop(revolvingCounter)) { + AtomicDecrement(CachedSimpleMailboxes); + return ret; + } + } while (AtomicGet(CachedSimpleMailboxes) > (MailboxCacheSimple.Concurrency * 512)); + return 0; + case TMailboxType::Revolving: + do { + if (ui32 ret = MailboxCacheRevolving.Pop(revolvingCounter)) { + AtomicDecrement(CachedRevolvingMailboxes); + return ret; + } + } while (AtomicGet(CachedRevolvingMailboxes) > (MailboxCacheRevolving.Concurrency * 512)); + return 0; + case TMailboxType::HTSwap: + do { + if (ui32 ret = MailboxCacheHTSwap.Pop(revolvingCounter)) { + AtomicDecrement(CachedHTSwapMailboxes); + return ret; + } + } while (AtomicGet(CachedHTSwapMailboxes) > (MailboxCacheHTSwap.Concurrency * 512)); + return 0; + case TMailboxType::ReadAsFilled: + do { + if (ui32 ret = MailboxCacheReadAsFilled.Pop(revolvingCounter)) { + AtomicDecrement(CachedReadAsFilledMailboxes); + return ret; + } + } while (AtomicGet(CachedReadAsFilledMailboxes) > (MailboxCacheReadAsFilled.Concurrency * 512)); + return 0; + case TMailboxType::TinyReadAsFilled: + do { + if (ui32 ret = MailboxCacheTinyReadAsFilled.Pop(revolvingCounter)) { + AtomicDecrement(CachedTinyReadAsFilledMailboxes); + return ret; + } + } while (AtomicGet(CachedTinyReadAsFilledMailboxes) > (MailboxCacheTinyReadAsFilled.Concurrency * 512)); + return 0; + default: + Y_FAIL("Unknown mailbox type"); + } + } + + void TMailboxTable::ReclaimMailbox(TMailboxType::EType type, ui32 hint, ui64 revolvingCounter) { + if (hint != 0) { + switch (type) { + case TMailboxType::Simple: + MailboxCacheSimple.Push(hint, revolvingCounter); + AtomicIncrement(CachedSimpleMailboxes); + break; + case TMailboxType::Revolving: + MailboxCacheRevolving.Push(hint, revolvingCounter); + AtomicIncrement(CachedRevolvingMailboxes); + break; + case TMailboxType::HTSwap: + MailboxCacheHTSwap.Push(hint, revolvingCounter); + AtomicIncrement(CachedHTSwapMailboxes); + break; + case TMailboxType::ReadAsFilled: + MailboxCacheReadAsFilled.Push(hint, revolvingCounter); + AtomicIncrement(CachedReadAsFilledMailboxes); + break; + case TMailboxType::TinyReadAsFilled: + MailboxCacheTinyReadAsFilled.Push(hint, revolvingCounter); + AtomicIncrement(CachedTinyReadAsFilledMailboxes); + break; + default: + Y_FAIL(); + } + } + } + + TMailboxHeader::TMailboxHeader(TMailboxType::EType type) + : ExecutionState(TExecutionState::Free) , Reserved(0) - , Type(type) - , ActorPack(TMailboxActorPack::Simple) - , Knobs(0) - { + , Type(type) + , ActorPack(TMailboxActorPack::Simple) + , Knobs(0) + { ActorsInfo.Simple.ActorId = 0; ActorsInfo.Simple.Actor = nullptr; - } - - TMailboxHeader::~TMailboxHeader() { - CleanupActors(); - } - - bool TMailboxHeader::CleanupActors() { - bool done = true; - switch (ActorPack) { + } + + TMailboxHeader::~TMailboxHeader() { + CleanupActors(); + } + + bool TMailboxHeader::CleanupActors() { + bool done = true; + switch (ActorPack) { case TMailboxActorPack::Simple: { if (ActorsInfo.Simple.ActorId != 0) { delete ActorsInfo.Simple.Actor; - done = false; - } - break; + done = false; + } + break; } - case TMailboxActorPack::Map: { + case TMailboxActorPack::Map: { for (auto& [actorId, actor] : *ActorsInfo.Map.ActorsMap) { delete actor; } delete ActorsInfo.Map.ActorsMap; - done = false; + done = false; break; } case TMailboxActorPack::Array: { @@ -386,166 +386,166 @@ namespace NActors { done = false; break; } - } - ActorPack = TMailboxActorPack::Simple; + } + ActorPack = TMailboxActorPack::Simple; ActorsInfo.Simple.ActorId = 0; ActorsInfo.Simple.Actor = nullptr; - return done; - } - - std::pair<ui32, ui32> TMailboxHeader::CountMailboxEvents(ui64 localActorId, ui32 maxTraverse) { - switch (Type) { - case TMailboxType::Simple: - return static_cast<TMailboxTable::TSimpleMailbox*>(this)->CountSimpleMailboxEvents(localActorId, maxTraverse); - case TMailboxType::Revolving: - return static_cast<TMailboxTable::TRevolvingMailbox*>(this)->CountRevolvingMailboxEvents(localActorId, maxTraverse); - default: - return {0, 0}; - } - } - - TMailboxTable::TSimpleMailbox::TSimpleMailbox() - : TMailboxHeader(TMailboxType::Simple) - , ScheduleMoment(0) - { - } - - TMailboxTable::TSimpleMailbox::~TSimpleMailbox() { - CleanupEvents(); - } - - bool TMailboxTable::TSimpleMailbox::CleanupEvents() { - const bool done = (Queue.Head() == nullptr); - while (IEventHandle* ev = Queue.Pop()) - delete ev; - return done; - } - - std::pair<ui32, ui32> TMailboxTable::TSimpleMailbox::CountSimpleMailboxEvents(ui64 localActorId, ui32 maxTraverse) { - ui32 local = 0; - ui32 total = 0; - - auto it = Queue.ReadIterator(); - while (IEventHandle* x = it.Next()) { - ++total; - if (x->GetRecipientRewrite().LocalId() == localActorId) - ++local; - if (total >= maxTraverse) - break; - } - - return std::make_pair(local, total); - } - - TMailboxTable::TRevolvingMailbox::TRevolvingMailbox() - : TMailboxHeader(TMailboxType::Revolving) - , QueueWriter(QueueReader) - , Reserved1(0) - , Reserved2(0) - , ScheduleMoment(0) - { - } - - TMailboxTable::TRevolvingMailbox::~TRevolvingMailbox() { - CleanupEvents(); - } - - bool TMailboxTable::TRevolvingMailbox::CleanupEvents() { - const bool done = (QueueReader.Head() == nullptr); - while (IEventHandle* ev = QueueReader.Pop()) - delete ev; - return done; - } - - std::pair<ui32, ui32> TMailboxTable::TRevolvingMailbox::CountRevolvingMailboxEvents(ui64 localActorId, ui32 maxTraverse) { - ui32 local = 0; - ui32 total = 0; - - auto it = QueueReader.Iterator(); - - while (IEventHandle* x = it.Next()) { - ++total; - if (x->GetRecipientRewrite().LocalId() == localActorId) - ++local; - if (total >= maxTraverse) - break; - } - - return std::make_pair(local, total); - } - - template <typename T> - static ui32 InitNewLine(ui8* x, ui8* end) { - const ui32 sx = T::AlignedSize(); - - for (ui32 index = 1; x + sx <= end; x += sx, ++index) - ::new (x) T(); - - return sx; - } - - ui32 TMailboxTable::AllocateNewLine(TMailboxType::EType type) { - ui8* ptr = (ui8*)malloc(LineSize); - ui8* end = ptr + LineSize; - - const ui32 lineIndex = (ui32)AtomicIncrement(LastAllocatedLine) - 1; - const ui32 lineIndexMask = (lineIndex << LineIndexShift) & LineIndexMask; - - // first 64 bytes is TMailboxLineHeader - TMailboxLineHeader* header = ::new (ptr) TMailboxLineHeader(type, lineIndex); - - ui8* x = ptr + 64; - ui32 sx = 0; - TMailboxCache* cache = nullptr; - TAtomic* counter = nullptr; - - switch (type) { - case TMailboxType::Simple: - sx = InitNewLine<TSimpleMailbox>(x, end); - cache = &MailboxCacheSimple; - counter = &CachedSimpleMailboxes; - break; - case TMailboxType::Revolving: - sx = InitNewLine<TRevolvingMailbox>(x, end); - cache = &MailboxCacheRevolving; - counter = &CachedRevolvingMailboxes; - break; - case TMailboxType::HTSwap: - sx = InitNewLine<THTSwapMailbox>(x, end); - cache = &MailboxCacheHTSwap; - counter = &CachedHTSwapMailboxes; - break; - case TMailboxType::ReadAsFilled: - sx = InitNewLine<TReadAsFilledMailbox>(x, end); - cache = &MailboxCacheReadAsFilled; - counter = &CachedReadAsFilledMailboxes; - break; - case TMailboxType::TinyReadAsFilled: - sx = InitNewLine<TTinyReadAsFilledMailbox>(x, end); - cache = &MailboxCacheTinyReadAsFilled; - counter = &CachedTinyReadAsFilledMailboxes; - break; - default: - Y_FAIL(); - } - + return done; + } + + std::pair<ui32, ui32> TMailboxHeader::CountMailboxEvents(ui64 localActorId, ui32 maxTraverse) { + switch (Type) { + case TMailboxType::Simple: + return static_cast<TMailboxTable::TSimpleMailbox*>(this)->CountSimpleMailboxEvents(localActorId, maxTraverse); + case TMailboxType::Revolving: + return static_cast<TMailboxTable::TRevolvingMailbox*>(this)->CountRevolvingMailboxEvents(localActorId, maxTraverse); + default: + return {0, 0}; + } + } + + TMailboxTable::TSimpleMailbox::TSimpleMailbox() + : TMailboxHeader(TMailboxType::Simple) + , ScheduleMoment(0) + { + } + + TMailboxTable::TSimpleMailbox::~TSimpleMailbox() { + CleanupEvents(); + } + + bool TMailboxTable::TSimpleMailbox::CleanupEvents() { + const bool done = (Queue.Head() == nullptr); + while (IEventHandle* ev = Queue.Pop()) + delete ev; + return done; + } + + std::pair<ui32, ui32> TMailboxTable::TSimpleMailbox::CountSimpleMailboxEvents(ui64 localActorId, ui32 maxTraverse) { + ui32 local = 0; + ui32 total = 0; + + auto it = Queue.ReadIterator(); + while (IEventHandle* x = it.Next()) { + ++total; + if (x->GetRecipientRewrite().LocalId() == localActorId) + ++local; + if (total >= maxTraverse) + break; + } + + return std::make_pair(local, total); + } + + TMailboxTable::TRevolvingMailbox::TRevolvingMailbox() + : TMailboxHeader(TMailboxType::Revolving) + , QueueWriter(QueueReader) + , Reserved1(0) + , Reserved2(0) + , ScheduleMoment(0) + { + } + + TMailboxTable::TRevolvingMailbox::~TRevolvingMailbox() { + CleanupEvents(); + } + + bool TMailboxTable::TRevolvingMailbox::CleanupEvents() { + const bool done = (QueueReader.Head() == nullptr); + while (IEventHandle* ev = QueueReader.Pop()) + delete ev; + return done; + } + + std::pair<ui32, ui32> TMailboxTable::TRevolvingMailbox::CountRevolvingMailboxEvents(ui64 localActorId, ui32 maxTraverse) { + ui32 local = 0; + ui32 total = 0; + + auto it = QueueReader.Iterator(); + + while (IEventHandle* x = it.Next()) { + ++total; + if (x->GetRecipientRewrite().LocalId() == localActorId) + ++local; + if (total >= maxTraverse) + break; + } + + return std::make_pair(local, total); + } + + template <typename T> + static ui32 InitNewLine(ui8* x, ui8* end) { + const ui32 sx = T::AlignedSize(); + + for (ui32 index = 1; x + sx <= end; x += sx, ++index) + ::new (x) T(); + + return sx; + } + + ui32 TMailboxTable::AllocateNewLine(TMailboxType::EType type) { + ui8* ptr = (ui8*)malloc(LineSize); + ui8* end = ptr + LineSize; + + const ui32 lineIndex = (ui32)AtomicIncrement(LastAllocatedLine) - 1; + const ui32 lineIndexMask = (lineIndex << LineIndexShift) & LineIndexMask; + + // first 64 bytes is TMailboxLineHeader + TMailboxLineHeader* header = ::new (ptr) TMailboxLineHeader(type, lineIndex); + + ui8* x = ptr + 64; + ui32 sx = 0; + TMailboxCache* cache = nullptr; + TAtomic* counter = nullptr; + + switch (type) { + case TMailboxType::Simple: + sx = InitNewLine<TSimpleMailbox>(x, end); + cache = &MailboxCacheSimple; + counter = &CachedSimpleMailboxes; + break; + case TMailboxType::Revolving: + sx = InitNewLine<TRevolvingMailbox>(x, end); + cache = &MailboxCacheRevolving; + counter = &CachedRevolvingMailboxes; + break; + case TMailboxType::HTSwap: + sx = InitNewLine<THTSwapMailbox>(x, end); + cache = &MailboxCacheHTSwap; + counter = &CachedHTSwapMailboxes; + break; + case TMailboxType::ReadAsFilled: + sx = InitNewLine<TReadAsFilledMailbox>(x, end); + cache = &MailboxCacheReadAsFilled; + counter = &CachedReadAsFilledMailboxes; + break; + case TMailboxType::TinyReadAsFilled: + sx = InitNewLine<TTinyReadAsFilledMailbox>(x, end); + cache = &MailboxCacheTinyReadAsFilled; + counter = &CachedTinyReadAsFilledMailboxes; + break; + default: + Y_FAIL(); + } + AtomicStore(Lines + lineIndex, header); - - ui32 ret = lineIndexMask | 1; - - ui32 index = 2; - for (ui32 endIndex = LineSize / sx; index != endIndex;) { - const ui32 bufSize = 8; - ui32 buf[bufSize]; - ui32 bufIndex; - for (bufIndex = 0; index != endIndex && bufIndex != bufSize; ++bufIndex, ++index) - buf[bufIndex] = lineIndexMask | index; - cache->PushBulk(buf, bufIndex, index); - AtomicAdd(*counter, bufIndex); - } - - AtomicAdd(AllocatedMailboxCount, index - 1); - - return ret; - } -} + + ui32 ret = lineIndexMask | 1; + + ui32 index = 2; + for (ui32 endIndex = LineSize / sx; index != endIndex;) { + const ui32 bufSize = 8; + ui32 buf[bufSize]; + ui32 bufIndex; + for (bufIndex = 0; index != endIndex && bufIndex != bufSize; ++bufIndex, ++index) + buf[bufIndex] = lineIndexMask | index; + cache->PushBulk(buf, bufIndex, index); + AtomicAdd(*counter, bufIndex); + } + + AtomicAdd(AllocatedMailboxCount, index - 1); + + return ret; + } +} diff --git a/library/cpp/actors/core/mailbox.h b/library/cpp/actors/core/mailbox.h index 3a9f070bc4..0bd9c4d314 100644 --- a/library/cpp/actors/core/mailbox.h +++ b/library/cpp/actors/core/mailbox.h @@ -1,64 +1,64 @@ -#pragma once - -#include "defs.h" -#include "event.h" -#include "actor.h" -#include "mailbox_queue_simple.h" -#include "mailbox_queue_revolving.h" +#pragma once + +#include "defs.h" +#include "event.h" +#include "actor.h" +#include "mailbox_queue_simple.h" +#include "mailbox_queue_revolving.h" #include <library/cpp/actors/util/unordered_cache.h> #include <library/cpp/threading/queue/mpsc_htswap.h> #include <library/cpp/threading/queue/mpsc_read_as_filled.h> #include <util/generic/hash.h> -#include <util/system/hp_timer.h> +#include <util/system/hp_timer.h> #include <util/generic/ptr.h> -// TODO: clean all broken arcadia atomic stuff and replace with intrinsics - -namespace NActors { - class IActor; - class IExecutorPool; - +// TODO: clean all broken arcadia atomic stuff and replace with intrinsics + +namespace NActors { + class IActor; + class IExecutorPool; + const ui64 ARRAY_CAPACITY = 8; - // structure of hint: - // 1 bit: is service or direct hint - // 2 bits: pool index - // 17 bits: line - // 12 bits: index of mailbox inside of line - - struct TMailboxHeader { - struct TMailboxActorPack { - enum EType { - Simple = 0, + // structure of hint: + // 1 bit: is service or direct hint + // 2 bits: pool index + // 17 bits: line + // 12 bits: index of mailbox inside of line + + struct TMailboxHeader { + struct TMailboxActorPack { + enum EType { + Simple = 0, Array = 1, Map = 2 - }; - }; - + }; + }; + using TActorMap = THashMap<ui64, IActor*>; - - struct TExecutionState { - enum EState { - // normal states - Inactive = 0, - Scheduled = 1, - Leaving = 2, - Executing = 3, - LeavingMarked = 4, - // states for free mailboxes (they can still be scheduled so we need duplicates) - Free = 5, - FreeScheduled = 6, - FreeLeaving = 7, - FreeExecuting = 8, - FreeLeavingMarked = 9, - }; - }; - - volatile ui32 ExecutionState; + + struct TExecutionState { + enum EState { + // normal states + Inactive = 0, + Scheduled = 1, + Leaving = 2, + Executing = 3, + LeavingMarked = 4, + // states for free mailboxes (they can still be scheduled so we need duplicates) + Free = 5, + FreeScheduled = 6, + FreeLeaving = 7, + FreeExecuting = 8, + FreeLeavingMarked = 9, + }; + }; + + volatile ui32 ExecutionState; ui32 Reserved : 4; // never changes, always zero - ui32 Type : 4; // never changes - ui32 ActorPack : 2; - ui32 Knobs : 22; - + ui32 Type : 4; // never changes + ui32 ActorPack : 2; + ui32 Knobs : 22; + struct TActorPair { IActor *Actor; ui64 ActorId; @@ -79,26 +79,26 @@ namespace NActors { } Map; } ActorsInfo; - TMailboxHeader(TMailboxType::EType type); - ~TMailboxHeader(); - - bool CleanupActors(); - - // this interface is used exclusively by executor thread, so implementation is there - - bool MarkForSchedule(); // we put something in queue, check should we schedule? - - bool LockForExecution(); // we got activation, try to lock mailbox - bool LockFromFree(); // try to claim mailbox from recycled (could fail if other thread process garbage) - - void UnlockFromExecution1(); // prepare for releasing lock - bool UnlockFromExecution2(bool wouldReschedule); // proceed with releasing lock - bool UnlockAsFree(bool wouldReschedule); // preceed with releasing lock, but mark as free one - + TMailboxHeader(TMailboxType::EType type); + ~TMailboxHeader(); + + bool CleanupActors(); + + // this interface is used exclusively by executor thread, so implementation is there + + bool MarkForSchedule(); // we put something in queue, check should we schedule? + + bool LockForExecution(); // we got activation, try to lock mailbox + bool LockFromFree(); // try to claim mailbox from recycled (could fail if other thread process garbage) + + void UnlockFromExecution1(); // prepare for releasing lock + bool UnlockFromExecution2(bool wouldReschedule); // proceed with releasing lock + bool UnlockAsFree(bool wouldReschedule); // preceed with releasing lock, but mark as free one + bool IsEmpty() const noexcept { return (ActorPack == TMailboxActorPack::Simple && ActorsInfo.Simple.ActorId == 0); - } - + } + template<typename T> void ForEach(T&& callback) noexcept { switch (ActorPack) { @@ -124,16 +124,16 @@ namespace NActors { } IActor* FindActor(ui64 localActorId) noexcept { - switch (ActorPack) { + switch (ActorPack) { case TMailboxActorPack::Simple: { if (ActorsInfo.Simple.ActorId == localActorId) return ActorsInfo.Simple.Actor; - break; + break; } - case TMailboxActorPack::Map: { + case TMailboxActorPack::Map: { TActorMap::iterator it = ActorsInfo.Map.ActorsMap->find(localActorId); if (it != ActorsInfo.Map.ActorsMap->end()) - return it->second; + return it->second; break; } case TMailboxActorPack::Array: { @@ -144,20 +144,20 @@ namespace NActors { } break; } - default: - Y_FAIL(); - } - return nullptr; - } - + default: + Y_FAIL(); + } + return nullptr; + } + void AttachActor(ui64 localActorId, IActor* actor) noexcept { - switch (ActorPack) { + switch (ActorPack) { case TMailboxActorPack::Simple: { if (ActorsInfo.Simple.ActorId == 0) { ActorsInfo.Simple.ActorId = localActorId; ActorsInfo.Simple.Actor = actor; - return; - } else { + return; + } else { auto ar = new TActorArray; ar->Actors[0] = ActorsInfo.Simple; ar->Actors[1] = TActorPair{actor, localActorId}; @@ -184,35 +184,35 @@ namespace NActors { ActorsInfo.Map.ActorsMap = mp; } else { ActorsInfo.Array.ActorsArray->Actors[ActorsInfo.Array.ActorsCount++] = TActorPair{actor, localActorId}; - } - break; + } + break; } - default: - Y_FAIL(); - } - } - + default: + Y_FAIL(); + } + } + IActor* DetachActor(ui64 localActorId) noexcept { - Y_VERIFY_DEBUG(FindActor(localActorId) != nullptr); - - IActor* actorToDestruct = nullptr; - - switch (ActorPack) { + Y_VERIFY_DEBUG(FindActor(localActorId) != nullptr); + + IActor* actorToDestruct = nullptr; + + switch (ActorPack) { case TMailboxActorPack::Simple: { Y_VERIFY(ActorsInfo.Simple.ActorId == localActorId); actorToDestruct = ActorsInfo.Simple.Actor; - + ActorsInfo.Simple.ActorId = 0; ActorsInfo.Simple.Actor = nullptr; - break; + break; } - case TMailboxActorPack::Map: { + case TMailboxActorPack::Map: { TActorMap::iterator it = ActorsInfo.Map.ActorsMap->find(localActorId); Y_VERIFY(it != ActorsInfo.Map.ActorsMap->end()); - - actorToDestruct = it->second; + + actorToDestruct = it->second; ActorsInfo.Map.ActorsMap->erase(it); - + if (ActorsInfo.Map.ActorsMap->size() == ARRAY_CAPACITY) { auto ar = new TActorArray; ui64 i = 0; @@ -242,312 +242,312 @@ namespace NActors { if (ActorsInfo.Array.ActorsCount == 1) { const TActorPair Actor = ActorsInfo.Array.ActorsArray->Actors[0]; delete ActorsInfo.Array.ActorsArray; - ActorPack = TMailboxActorPack::Simple; + ActorPack = TMailboxActorPack::Simple; ActorsInfo.Simple = Actor; - } + } break; } - } - - return actorToDestruct; - } - - std::pair<ui32, ui32> CountMailboxEvents(ui64 localActorId, ui32 maxTraverse); - }; - - class TMailboxTable : TNonCopyable { - private: - struct TMailboxLineHeader { - const TMailboxType::EType MailboxType; - const ui32 Index; - // some more stuff in first cache line, then goes mailboxes - ui8 Padding[52]; - - TMailboxLineHeader(TMailboxType::EType type, ui32 index) - : MailboxType(type) - , Index(index) - { - } - }; - static_assert(sizeof(TMailboxLineHeader) <= 64, "expect sizeof(TMailboxLineHeader) <= 64"); - - constexpr static ui64 MaxLines = 131000; // somewhat less then 2^17. - constexpr static ui64 LineSize = 262144; // 64 * 2^12. - - TAtomic LastAllocatedLine; - TAtomic AllocatedMailboxCount; - + } + + return actorToDestruct; + } + + std::pair<ui32, ui32> CountMailboxEvents(ui64 localActorId, ui32 maxTraverse); + }; + + class TMailboxTable : TNonCopyable { + private: + struct TMailboxLineHeader { + const TMailboxType::EType MailboxType; + const ui32 Index; + // some more stuff in first cache line, then goes mailboxes + ui8 Padding[52]; + + TMailboxLineHeader(TMailboxType::EType type, ui32 index) + : MailboxType(type) + , Index(index) + { + } + }; + static_assert(sizeof(TMailboxLineHeader) <= 64, "expect sizeof(TMailboxLineHeader) <= 64"); + + constexpr static ui64 MaxLines = 131000; // somewhat less then 2^17. + constexpr static ui64 LineSize = 262144; // 64 * 2^12. + + TAtomic LastAllocatedLine; + TAtomic AllocatedMailboxCount; + typedef TUnorderedCache<ui32, 512, 4> TMailboxCache; - TMailboxCache MailboxCacheSimple; - TAtomic CachedSimpleMailboxes; - TMailboxCache MailboxCacheRevolving; - TAtomic CachedRevolvingMailboxes; - TMailboxCache MailboxCacheHTSwap; - TAtomic CachedHTSwapMailboxes; - TMailboxCache MailboxCacheReadAsFilled; - TAtomic CachedReadAsFilledMailboxes; - TMailboxCache MailboxCacheTinyReadAsFilled; - TAtomic CachedTinyReadAsFilledMailboxes; - - // and here goes large chunk of lines - // presented as array of static size to avoid sync on access - TMailboxLineHeader* volatile Lines[MaxLines]; - - ui32 AllocateNewLine(TMailboxType::EType type); - ui32 TryAllocateMailbox(TMailboxType::EType type, ui64 revolvingCounter); - - public: - TMailboxTable(); - ~TMailboxTable(); - - bool Cleanup(); // returns true if nothing found to destruct (so nothing new is possible to be created) - - static const ui32 LineIndexShift = 12; - static const ui32 LineIndexMask = 0x1FFFFu << LineIndexShift; - static const ui32 LineHintMask = 0xFFFu; + TMailboxCache MailboxCacheSimple; + TAtomic CachedSimpleMailboxes; + TMailboxCache MailboxCacheRevolving; + TAtomic CachedRevolvingMailboxes; + TMailboxCache MailboxCacheHTSwap; + TAtomic CachedHTSwapMailboxes; + TMailboxCache MailboxCacheReadAsFilled; + TAtomic CachedReadAsFilledMailboxes; + TMailboxCache MailboxCacheTinyReadAsFilled; + TAtomic CachedTinyReadAsFilledMailboxes; + + // and here goes large chunk of lines + // presented as array of static size to avoid sync on access + TMailboxLineHeader* volatile Lines[MaxLines]; + + ui32 AllocateNewLine(TMailboxType::EType type); + ui32 TryAllocateMailbox(TMailboxType::EType type, ui64 revolvingCounter); + + public: + TMailboxTable(); + ~TMailboxTable(); + + bool Cleanup(); // returns true if nothing found to destruct (so nothing new is possible to be created) + + static const ui32 LineIndexShift = 12; + static const ui32 LineIndexMask = 0x1FFFFu << LineIndexShift; + static const ui32 LineHintMask = 0xFFFu; static const ui32 PoolIndexShift = TActorId::PoolIndexShift; static const ui32 PoolIndexMask = TActorId::PoolIndexMask; - - static ui32 LineIndex(ui32 hint) { - return ((hint & LineIndexMask) >> LineIndexShift); - } - static ui32 PoolIndex(ui32 hint) { + + static ui32 LineIndex(ui32 hint) { + return ((hint & LineIndexMask) >> LineIndexShift); + } + static ui32 PoolIndex(ui32 hint) { return TActorId::PoolIndex(hint); - } - - TMailboxHeader* Get(ui32 hint); - ui32 AllocateMailbox(TMailboxType::EType type, ui64 revolvingCounter); - void ReclaimMailbox(TMailboxType::EType type, ui32 hint, ui64 revolvingCounter); - ui64 GetAllocatedMailboxCount() const { - return RelaxedLoad(&AllocatedMailboxCount); - } - - bool SendTo(TAutoPtr<IEventHandle>& ev, IExecutorPool* executorPool); - - struct TSimpleMailbox: public TMailboxHeader { - // 4 bytes - state - // 4 bytes - knobs - // 8 bytes - actorid - // 8 bytes - actor* - TSimpleMailboxQueue<IEventHandle*, 64> Queue; // 24 + 8 bytes (body, lock) - NHPTimer::STime ScheduleMoment; - - TSimpleMailbox(); - ~TSimpleMailbox(); - - IEventHandle* Pop() { - return Queue.Pop(); - } - IEventHandle* Head() { - return Queue.Head(); - } - - static TSimpleMailbox* Get(ui32 hint, void* line) { - return (TSimpleMailbox*)((ui8*)line + hint * 64); // - } - static const TMailboxType::EType MailboxType = TMailboxType::Simple; - constexpr static ui32 AlignedSize() { - return ((sizeof(TSimpleMailbox) + 63) / 64) * 64; - } - - std::pair<ui32, ui32> CountSimpleMailboxEvents(ui64 localActorId, ui32 maxTraverse); - bool CleanupEvents(); - }; - - static_assert(sizeof(TSimpleMailbox) == 64, "expect sizeof(TSimpleMailbox) == 64"); - - struct TRevolvingMailbox: public TMailboxHeader { - // 4 bytes - state - // 4 bytes - knobs - // 8 bytes - actorid - // 8 bytes - actor* - TRevolvingMailboxQueue<IEventHandle*, 3, 128>::TReader QueueReader; // 8 * 3 + 4 * 3 + (padding): 40 bytes - // here goes next cache-line, so less writers<-> reader interference - TRevolvingMailboxQueue<IEventHandle*, 3, 128>::TWriter QueueWriter; // 8 * 3 + 4 * 3 + 8 : 48 bytes - ui32 Reserved1; - ui32 Reserved2; - NHPTimer::STime ScheduleMoment; - - TRevolvingMailbox(); - ~TRevolvingMailbox(); - - IEventHandle* Pop() { - return QueueReader.Pop(); - } - IEventHandle* Head() { - return QueueReader.Head(); - } - - static TRevolvingMailbox* Get(ui32 hint, void* line) { - return (TRevolvingMailbox*)((ui8*)line + 64 + (hint - 1) * 128); - } - - constexpr static ui64 MaxMailboxesInLine() { - return (LineSize - 64) / AlignedSize(); - } - static const TMailboxType::EType MailboxType = TMailboxType::Revolving; - constexpr static ui32 AlignedSize() { - return ((sizeof(TRevolvingMailbox) + 63) / 64) * 64; - } - - std::pair<ui32, ui32> CountRevolvingMailboxEvents(ui64 localActorId, ui32 maxTraverse); - bool CleanupEvents(); - }; - - static_assert(sizeof(TRevolvingMailbox) == 128, "expect sizeof(TRevolvingMailbox) == 128"); - - struct THTSwapMailbox: public TMailboxHeader { + } + + TMailboxHeader* Get(ui32 hint); + ui32 AllocateMailbox(TMailboxType::EType type, ui64 revolvingCounter); + void ReclaimMailbox(TMailboxType::EType type, ui32 hint, ui64 revolvingCounter); + ui64 GetAllocatedMailboxCount() const { + return RelaxedLoad(&AllocatedMailboxCount); + } + + bool SendTo(TAutoPtr<IEventHandle>& ev, IExecutorPool* executorPool); + + struct TSimpleMailbox: public TMailboxHeader { + // 4 bytes - state + // 4 bytes - knobs + // 8 bytes - actorid + // 8 bytes - actor* + TSimpleMailboxQueue<IEventHandle*, 64> Queue; // 24 + 8 bytes (body, lock) + NHPTimer::STime ScheduleMoment; + + TSimpleMailbox(); + ~TSimpleMailbox(); + + IEventHandle* Pop() { + return Queue.Pop(); + } + IEventHandle* Head() { + return Queue.Head(); + } + + static TSimpleMailbox* Get(ui32 hint, void* line) { + return (TSimpleMailbox*)((ui8*)line + hint * 64); // + } + static const TMailboxType::EType MailboxType = TMailboxType::Simple; + constexpr static ui32 AlignedSize() { + return ((sizeof(TSimpleMailbox) + 63) / 64) * 64; + } + + std::pair<ui32, ui32> CountSimpleMailboxEvents(ui64 localActorId, ui32 maxTraverse); + bool CleanupEvents(); + }; + + static_assert(sizeof(TSimpleMailbox) == 64, "expect sizeof(TSimpleMailbox) == 64"); + + struct TRevolvingMailbox: public TMailboxHeader { + // 4 bytes - state + // 4 bytes - knobs + // 8 bytes - actorid + // 8 bytes - actor* + TRevolvingMailboxQueue<IEventHandle*, 3, 128>::TReader QueueReader; // 8 * 3 + 4 * 3 + (padding): 40 bytes + // here goes next cache-line, so less writers<-> reader interference + TRevolvingMailboxQueue<IEventHandle*, 3, 128>::TWriter QueueWriter; // 8 * 3 + 4 * 3 + 8 : 48 bytes + ui32 Reserved1; + ui32 Reserved2; + NHPTimer::STime ScheduleMoment; + + TRevolvingMailbox(); + ~TRevolvingMailbox(); + + IEventHandle* Pop() { + return QueueReader.Pop(); + } + IEventHandle* Head() { + return QueueReader.Head(); + } + + static TRevolvingMailbox* Get(ui32 hint, void* line) { + return (TRevolvingMailbox*)((ui8*)line + 64 + (hint - 1) * 128); + } + + constexpr static ui64 MaxMailboxesInLine() { + return (LineSize - 64) / AlignedSize(); + } + static const TMailboxType::EType MailboxType = TMailboxType::Revolving; + constexpr static ui32 AlignedSize() { + return ((sizeof(TRevolvingMailbox) + 63) / 64) * 64; + } + + std::pair<ui32, ui32> CountRevolvingMailboxEvents(ui64 localActorId, ui32 maxTraverse); + bool CleanupEvents(); + }; + + static_assert(sizeof(TRevolvingMailbox) == 128, "expect sizeof(TRevolvingMailbox) == 128"); + + struct THTSwapMailbox: public TMailboxHeader { using TQueueType = NThreading::THTSwapQueue<IEventHandle*>; TQueueType Queue; - NHPTimer::STime ScheduleMoment; - char Padding_[16]; + NHPTimer::STime ScheduleMoment; + char Padding_[16]; - THTSwapMailbox() - : TMailboxHeader(TMailboxType::HTSwap) - , ScheduleMoment(0) - { - } + THTSwapMailbox() + : TMailboxHeader(TMailboxType::HTSwap) + , ScheduleMoment(0) + { + } - ~THTSwapMailbox() { - CleanupEvents(); - } + ~THTSwapMailbox() { + CleanupEvents(); + } - IEventHandle* Pop() { - return Queue.Pop(); - } + IEventHandle* Pop() { + return Queue.Pop(); + } - IEventHandle* Head() { - return Queue.Peek(); - } + IEventHandle* Head() { + return Queue.Peek(); + } - static THTSwapMailbox* Get(ui32 hint, void* line) { - return (THTSwapMailbox*)((ui8*)line + 64 + (hint - 1) * 64); - } + static THTSwapMailbox* Get(ui32 hint, void* line) { + return (THTSwapMailbox*)((ui8*)line + 64 + (hint - 1) * 64); + } - constexpr static ui64 MaxMailboxesInLine() { - return (LineSize - 64) / AlignedSize(); - } + constexpr static ui64 MaxMailboxesInLine() { + return (LineSize - 64) / AlignedSize(); + } - static const TMailboxType::EType MailboxType = TMailboxType::HTSwap; + static const TMailboxType::EType MailboxType = TMailboxType::HTSwap; - constexpr static ui32 AlignedSize() { - return ((sizeof(THTSwapMailbox) + 63) / 64) * 64; - } + constexpr static ui32 AlignedSize() { + return ((sizeof(THTSwapMailbox) + 63) / 64) * 64; + } - bool CleanupEvents() { - const bool done = (Queue.Peek() == nullptr); - while (IEventHandle* ev = Queue.Pop()) - delete ev; - return done; - } - }; + bool CleanupEvents() { + const bool done = (Queue.Peek() == nullptr); + while (IEventHandle* ev = Queue.Pop()) + delete ev; + return done; + } + }; - static_assert(sizeof(THTSwapMailbox) == 64, - "expect sizeof(THTSwapMailbox) == 64"); + static_assert(sizeof(THTSwapMailbox) == 64, + "expect sizeof(THTSwapMailbox) == 64"); - struct TReadAsFilledMailbox: public TMailboxHeader { + struct TReadAsFilledMailbox: public TMailboxHeader { using TQueueType = NThreading::TReadAsFilledQueue<IEventHandle>; TQueueType Queue; - NHPTimer::STime ScheduleMoment; - char Padding_[8]; - - TReadAsFilledMailbox() - : TMailboxHeader(TMailboxType::ReadAsFilled) - , ScheduleMoment(0) - { - } - - ~TReadAsFilledMailbox() { - CleanupEvents(); - } - - IEventHandle* Pop() { - return Queue.Pop(); - } - - IEventHandle* Head() { - return Queue.Peek(); - } - - static TReadAsFilledMailbox* Get(ui32 hint, void* line) { - return (TReadAsFilledMailbox*)((ui8*)line + 64 + (hint - 1) * 192); - } - - constexpr static ui64 MaxMailboxesInLine() { - return (LineSize - 64) / AlignedSize(); - } - - static const TMailboxType::EType MailboxType = - TMailboxType::ReadAsFilled; - - constexpr static ui32 AlignedSize() { - return ((sizeof(TReadAsFilledMailbox) + 63) / 64) * 64; - } - - bool CleanupEvents() { - const bool done = (Queue.Peek() == nullptr); - while (IEventHandle* ev = Queue.Pop()) - delete ev; - return done; - } - }; - - static_assert(sizeof(TReadAsFilledMailbox) == 192, - "expect sizeof(TReadAsFilledMailbox) == 192"); - - struct TTinyReadAsFilledMailbox: public TMailboxHeader { + NHPTimer::STime ScheduleMoment; + char Padding_[8]; + + TReadAsFilledMailbox() + : TMailboxHeader(TMailboxType::ReadAsFilled) + , ScheduleMoment(0) + { + } + + ~TReadAsFilledMailbox() { + CleanupEvents(); + } + + IEventHandle* Pop() { + return Queue.Pop(); + } + + IEventHandle* Head() { + return Queue.Peek(); + } + + static TReadAsFilledMailbox* Get(ui32 hint, void* line) { + return (TReadAsFilledMailbox*)((ui8*)line + 64 + (hint - 1) * 192); + } + + constexpr static ui64 MaxMailboxesInLine() { + return (LineSize - 64) / AlignedSize(); + } + + static const TMailboxType::EType MailboxType = + TMailboxType::ReadAsFilled; + + constexpr static ui32 AlignedSize() { + return ((sizeof(TReadAsFilledMailbox) + 63) / 64) * 64; + } + + bool CleanupEvents() { + const bool done = (Queue.Peek() == nullptr); + while (IEventHandle* ev = Queue.Pop()) + delete ev; + return done; + } + }; + + static_assert(sizeof(TReadAsFilledMailbox) == 192, + "expect sizeof(TReadAsFilledMailbox) == 192"); + + struct TTinyReadAsFilledMailbox: public TMailboxHeader { using TQueueType = NThreading::TReadAsFilledQueue< - IEventHandle, - NThreading::TRaFQueueBunchSize<4>>; + IEventHandle, + NThreading::TRaFQueueBunchSize<4>>; TQueueType Queue; - NHPTimer::STime ScheduleMoment; - char Padding_[8]; - - TTinyReadAsFilledMailbox() - : TMailboxHeader(TMailboxType::TinyReadAsFilled) - , ScheduleMoment(0) - { - } - - ~TTinyReadAsFilledMailbox() { - CleanupEvents(); - } - - IEventHandle* Pop() { - return Queue.Pop(); - } - - IEventHandle* Head() { - return Queue.Peek(); - } - - static TTinyReadAsFilledMailbox* Get(ui32 hint, void* line) { - return (TTinyReadAsFilledMailbox*)((ui8*)line + 64 + (hint - 1) * 192); - } - - constexpr static ui64 MaxMailboxesInLine() { - return (LineSize - 64) / AlignedSize(); - } - - static const TMailboxType::EType MailboxType = - TMailboxType::TinyReadAsFilled; - - constexpr static ui32 AlignedSize() { - return ((sizeof(TTinyReadAsFilledMailbox) + 63) / 64) * 64; - } - - bool CleanupEvents() { - const bool done = (Queue.Peek() == nullptr); - while (IEventHandle* ev = Queue.Pop()) - delete ev; - return done; - } - }; - - static_assert(sizeof(TTinyReadAsFilledMailbox) == 192, - "expect sizeof(TTinyReadAsFilledMailbox) == 192"); + NHPTimer::STime ScheduleMoment; + char Padding_[8]; + + TTinyReadAsFilledMailbox() + : TMailboxHeader(TMailboxType::TinyReadAsFilled) + , ScheduleMoment(0) + { + } + + ~TTinyReadAsFilledMailbox() { + CleanupEvents(); + } + + IEventHandle* Pop() { + return Queue.Pop(); + } + + IEventHandle* Head() { + return Queue.Peek(); + } + + static TTinyReadAsFilledMailbox* Get(ui32 hint, void* line) { + return (TTinyReadAsFilledMailbox*)((ui8*)line + 64 + (hint - 1) * 192); + } + + constexpr static ui64 MaxMailboxesInLine() { + return (LineSize - 64) / AlignedSize(); + } + + static const TMailboxType::EType MailboxType = + TMailboxType::TinyReadAsFilled; + + constexpr static ui32 AlignedSize() { + return ((sizeof(TTinyReadAsFilledMailbox) + 63) / 64) * 64; + } + + bool CleanupEvents() { + const bool done = (Queue.Peek() == nullptr); + while (IEventHandle* ev = Queue.Pop()) + delete ev; + return done; + } + }; + + static_assert(sizeof(TTinyReadAsFilledMailbox) == 192, + "expect sizeof(TTinyReadAsFilledMailbox) == 192"); }; -} +} diff --git a/library/cpp/actors/core/mailbox_queue_revolving.h b/library/cpp/actors/core/mailbox_queue_revolving.h index 49eed7ad7c..b0e78a18db 100644 --- a/library/cpp/actors/core/mailbox_queue_revolving.h +++ b/library/cpp/actors/core/mailbox_queue_revolving.h @@ -1,214 +1,214 @@ -#pragma once - -#include "defs.h" +#pragma once + +#include "defs.h" #include <library/cpp/actors/util/queue_chunk.h> - -namespace NActors { - // add some concurrency to basic queue to avoid hangs under contention (we pay with memory, so use only when really expect contention) - // ordering: every completed push guarantied to seen before any not-yet-initiated push. parallel pushes could reorder (and that is natural for concurrent queues). - // try to place reader/writer on different cache-lines to avoid congestion b/w reader and writers. - // if strict ordering does not matter - look at TManyOneQueue. - - template <typename T, ui32 TWriteConcurrency = 3, ui32 TSize = 128> - class TRevolvingMailboxQueue { - static_assert(std::is_integral<T>::value || std::is_pointer<T>::value, "expect std::is_integral<T>::value || std::is_pointer<T>::value"); - - struct TValTagPair { - volatile T Value; - volatile ui64 Tag; - }; - - typedef TQueueChunk<TValTagPair, TSize> TChunk; - - static_assert(sizeof(TAtomic) == sizeof(TChunk*), "expect sizeof(TAtomic) == sizeof(TChunk*)"); - static_assert(sizeof(TAtomic) == sizeof(ui64), "expect sizeof(TAtomic) == sizeof(ui64)"); - - public: - class TWriter; - - class TReader { - TChunk* ReadFrom[TWriteConcurrency]; - ui32 ReadPosition[TWriteConcurrency]; - - friend class TRevolvingMailboxQueue<T, TWriteConcurrency, TSize>::TWriter; // for access to ReadFrom in constructor - - bool ChunkHead(ui32 idx, ui64* tag, T* value) { - TChunk* head = ReadFrom[idx]; - const ui32 pos = ReadPosition[idx]; - if (pos != TChunk::EntriesCount) { - if (const T xval = AtomicLoad(&head->Entries[pos].Value)) { - const ui64 xtag = head->Entries[pos].Tag; - if (xtag < *tag) { - *value = xval; - *tag = xtag; - return true; - } - } - } else if (TChunk* next = AtomicLoad(&head->Next)) { - ReadFrom[idx] = next; - delete head; - ReadPosition[idx] = 0; - return ChunkHead(idx, tag, value); - } - - return false; - } - - T Head(bool pop) { - ui64 tag = Max<ui64>(); + +namespace NActors { + // add some concurrency to basic queue to avoid hangs under contention (we pay with memory, so use only when really expect contention) + // ordering: every completed push guarantied to seen before any not-yet-initiated push. parallel pushes could reorder (and that is natural for concurrent queues). + // try to place reader/writer on different cache-lines to avoid congestion b/w reader and writers. + // if strict ordering does not matter - look at TManyOneQueue. + + template <typename T, ui32 TWriteConcurrency = 3, ui32 TSize = 128> + class TRevolvingMailboxQueue { + static_assert(std::is_integral<T>::value || std::is_pointer<T>::value, "expect std::is_integral<T>::value || std::is_pointer<T>::value"); + + struct TValTagPair { + volatile T Value; + volatile ui64 Tag; + }; + + typedef TQueueChunk<TValTagPair, TSize> TChunk; + + static_assert(sizeof(TAtomic) == sizeof(TChunk*), "expect sizeof(TAtomic) == sizeof(TChunk*)"); + static_assert(sizeof(TAtomic) == sizeof(ui64), "expect sizeof(TAtomic) == sizeof(ui64)"); + + public: + class TWriter; + + class TReader { + TChunk* ReadFrom[TWriteConcurrency]; + ui32 ReadPosition[TWriteConcurrency]; + + friend class TRevolvingMailboxQueue<T, TWriteConcurrency, TSize>::TWriter; // for access to ReadFrom in constructor + + bool ChunkHead(ui32 idx, ui64* tag, T* value) { + TChunk* head = ReadFrom[idx]; + const ui32 pos = ReadPosition[idx]; + if (pos != TChunk::EntriesCount) { + if (const T xval = AtomicLoad(&head->Entries[pos].Value)) { + const ui64 xtag = head->Entries[pos].Tag; + if (xtag < *tag) { + *value = xval; + *tag = xtag; + return true; + } + } + } else if (TChunk* next = AtomicLoad(&head->Next)) { + ReadFrom[idx] = next; + delete head; + ReadPosition[idx] = 0; + return ChunkHead(idx, tag, value); + } + + return false; + } + + T Head(bool pop) { + ui64 tag = Max<ui64>(); T ret = T{}; - ui32 idx = 0; - - for (ui32 i = 0; i < TWriteConcurrency; ++i) - if (ChunkHead(i, &tag, &ret)) - idx = i; - - // w/o second pass we could reorder updates with 'already scanned' range - if (ret) { - for (ui32 i = 0; i < TWriteConcurrency; ++i) - if (ChunkHead(i, &tag, &ret)) - idx = i; - } - - if (pop && ret) - ++ReadPosition[idx]; - - return ret; - } - - public: - TReader() { - for (ui32 i = 0; i != TWriteConcurrency; ++i) { - ReadFrom[i] = new TChunk(); - ReadPosition[i] = 0; - } - } - - ~TReader() { - Y_VERIFY_DEBUG(Head() == 0); - for (ui32 i = 0; i < TWriteConcurrency; ++i) - delete ReadFrom[i]; - } - - T Pop() { - return Head(true); - } - - T Head() { - return Head(false); - } - - class TReadIterator { - TChunk* ReadFrom[TWriteConcurrency]; - ui32 ReadPosition[TWriteConcurrency]; - - bool ChunkHead(ui32 idx, ui64* tag, T* value) { - TChunk* head = ReadFrom[idx]; - const ui32 pos = ReadPosition[idx]; - if (pos != TChunk::EntriesCount) { - if (const T xval = AtomicLoad(&head->Entries[pos].Value)) { - const ui64 xtag = head->Entries[pos].Tag; - if (xtag < *tag) { - *value = xval; - *tag = xtag; - return true; - } - } - } else if (TChunk* next = AtomicLoad(&head->Next)) { - ReadFrom[idx] = next; - ReadPosition[idx] = 0; - return ChunkHead(idx, tag, value); - } - - return false; - } - - public: - TReadIterator(TChunk* const* readFrom, const ui32* readPosition) { - memcpy(ReadFrom, readFrom, TWriteConcurrency * sizeof(TChunk*)); - memcpy(ReadPosition, readPosition, TWriteConcurrency * sizeof(ui32)); - } - - T Next() { - ui64 tag = Max<ui64>(); - T ret = T{}; - ui32 idx = 0; - - for (ui32 i = 0; i < TWriteConcurrency; ++i) - if (ChunkHead(i, &tag, &ret)) - idx = i; - - // w/o second pass we could reorder updates with 'already scanned' range - if (ret) { - for (ui32 i = 0; i < TWriteConcurrency; ++i) - if (ChunkHead(i, &tag, &ret)) - idx = i; - } - - if (ret) - ++ReadPosition[idx]; - - return ret; - } - }; - - TReadIterator Iterator() const { - return TReadIterator(ReadFrom, ReadPosition); - } - }; - - class TWriter { - TChunk* volatile WriteTo[TWriteConcurrency]; - volatile ui64 Tag; - ui32 WritePosition[TWriteConcurrency]; - - public: - TWriter(const TReader& reader) - : Tag(0) - { - for (ui32 i = 0; i != TWriteConcurrency; ++i) { - WriteTo[i] = reader.ReadFrom[i]; - WritePosition[i] = 0; - } - } - - bool TryPush(T x) { - Y_VERIFY(x != 0); - - for (ui32 i = 0; i != TWriteConcurrency; ++i) { - if (RelaxedLoad(&WriteTo[i]) != nullptr) { - if (TChunk* writeTo = AtomicSwap(&WriteTo[i], nullptr)) { - const ui64 nextTag = AtomicIncrement(Tag); - Y_VERIFY_DEBUG(nextTag < Max<ui64>()); - const ui32 writePosition = WritePosition[i]; - if (writePosition != TChunk::EntriesCount) { - writeTo->Entries[writePosition].Tag = nextTag; - AtomicStore(&writeTo->Entries[writePosition].Value, x); - ++WritePosition[i]; - } else { - TChunk* next = new TChunk(); - next->Entries[0].Tag = nextTag; - next->Entries[0].Value = x; - AtomicStore(&writeTo->Next, next); - writeTo = next; - WritePosition[i] = 1; - } - AtomicStore(WriteTo + i, writeTo); - return true; - } - } - } - return false; - } - - ui32 Push(T x) { - ui32 spins = 0; - while (!TryPush(x)) { - ++spins; - SpinLockPause(); - } - return spins; - } - }; - }; -} + ui32 idx = 0; + + for (ui32 i = 0; i < TWriteConcurrency; ++i) + if (ChunkHead(i, &tag, &ret)) + idx = i; + + // w/o second pass we could reorder updates with 'already scanned' range + if (ret) { + for (ui32 i = 0; i < TWriteConcurrency; ++i) + if (ChunkHead(i, &tag, &ret)) + idx = i; + } + + if (pop && ret) + ++ReadPosition[idx]; + + return ret; + } + + public: + TReader() { + for (ui32 i = 0; i != TWriteConcurrency; ++i) { + ReadFrom[i] = new TChunk(); + ReadPosition[i] = 0; + } + } + + ~TReader() { + Y_VERIFY_DEBUG(Head() == 0); + for (ui32 i = 0; i < TWriteConcurrency; ++i) + delete ReadFrom[i]; + } + + T Pop() { + return Head(true); + } + + T Head() { + return Head(false); + } + + class TReadIterator { + TChunk* ReadFrom[TWriteConcurrency]; + ui32 ReadPosition[TWriteConcurrency]; + + bool ChunkHead(ui32 idx, ui64* tag, T* value) { + TChunk* head = ReadFrom[idx]; + const ui32 pos = ReadPosition[idx]; + if (pos != TChunk::EntriesCount) { + if (const T xval = AtomicLoad(&head->Entries[pos].Value)) { + const ui64 xtag = head->Entries[pos].Tag; + if (xtag < *tag) { + *value = xval; + *tag = xtag; + return true; + } + } + } else if (TChunk* next = AtomicLoad(&head->Next)) { + ReadFrom[idx] = next; + ReadPosition[idx] = 0; + return ChunkHead(idx, tag, value); + } + + return false; + } + + public: + TReadIterator(TChunk* const* readFrom, const ui32* readPosition) { + memcpy(ReadFrom, readFrom, TWriteConcurrency * sizeof(TChunk*)); + memcpy(ReadPosition, readPosition, TWriteConcurrency * sizeof(ui32)); + } + + T Next() { + ui64 tag = Max<ui64>(); + T ret = T{}; + ui32 idx = 0; + + for (ui32 i = 0; i < TWriteConcurrency; ++i) + if (ChunkHead(i, &tag, &ret)) + idx = i; + + // w/o second pass we could reorder updates with 'already scanned' range + if (ret) { + for (ui32 i = 0; i < TWriteConcurrency; ++i) + if (ChunkHead(i, &tag, &ret)) + idx = i; + } + + if (ret) + ++ReadPosition[idx]; + + return ret; + } + }; + + TReadIterator Iterator() const { + return TReadIterator(ReadFrom, ReadPosition); + } + }; + + class TWriter { + TChunk* volatile WriteTo[TWriteConcurrency]; + volatile ui64 Tag; + ui32 WritePosition[TWriteConcurrency]; + + public: + TWriter(const TReader& reader) + : Tag(0) + { + for (ui32 i = 0; i != TWriteConcurrency; ++i) { + WriteTo[i] = reader.ReadFrom[i]; + WritePosition[i] = 0; + } + } + + bool TryPush(T x) { + Y_VERIFY(x != 0); + + for (ui32 i = 0; i != TWriteConcurrency; ++i) { + if (RelaxedLoad(&WriteTo[i]) != nullptr) { + if (TChunk* writeTo = AtomicSwap(&WriteTo[i], nullptr)) { + const ui64 nextTag = AtomicIncrement(Tag); + Y_VERIFY_DEBUG(nextTag < Max<ui64>()); + const ui32 writePosition = WritePosition[i]; + if (writePosition != TChunk::EntriesCount) { + writeTo->Entries[writePosition].Tag = nextTag; + AtomicStore(&writeTo->Entries[writePosition].Value, x); + ++WritePosition[i]; + } else { + TChunk* next = new TChunk(); + next->Entries[0].Tag = nextTag; + next->Entries[0].Value = x; + AtomicStore(&writeTo->Next, next); + writeTo = next; + WritePosition[i] = 1; + } + AtomicStore(WriteTo + i, writeTo); + return true; + } + } + } + return false; + } + + ui32 Push(T x) { + ui32 spins = 0; + while (!TryPush(x)) { + ++spins; + SpinLockPause(); + } + return spins; + } + }; + }; +} diff --git a/library/cpp/actors/core/mailbox_queue_simple.h b/library/cpp/actors/core/mailbox_queue_simple.h index e600854f55..2e44c21adb 100644 --- a/library/cpp/actors/core/mailbox_queue_simple.h +++ b/library/cpp/actors/core/mailbox_queue_simple.h @@ -1,34 +1,34 @@ -#pragma once - -#include "defs.h" +#pragma once + +#include "defs.h" #include <library/cpp/actors/util/ticket_lock.h> #include <library/cpp/actors/util/queue_oneone_inplace.h> - -namespace NActors { - // dead-simple one-one queue, based on serializability guaranties of x64 and ticket lock to ensure writer unicity. - template <typename T, ui32 TSize> - class TSimpleMailboxQueue { - TOneOneQueueInplace<T, TSize> Queue; - TTicketLock Lock; - - public: + +namespace NActors { + // dead-simple one-one queue, based on serializability guaranties of x64 and ticket lock to ensure writer unicity. + template <typename T, ui32 TSize> + class TSimpleMailboxQueue { + TOneOneQueueInplace<T, TSize> Queue; + TTicketLock Lock; + + public: ui32 Push(T x) noexcept { - const ui32 spins = Lock.Acquire(); - Queue.Push(x); - Lock.Release(); - return spins; - } - - T Head() { - return Queue.Head(); - } - - T Pop() { - return Queue.Pop(); - } - - typename TOneOneQueueInplace<T, TSize>::TReadIterator ReadIterator() { - return Queue.Iterator(); - } - }; -} + const ui32 spins = Lock.Acquire(); + Queue.Push(x); + Lock.Release(); + return spins; + } + + T Head() { + return Queue.Head(); + } + + T Pop() { + return Queue.Pop(); + } + + typename TOneOneQueueInplace<T, TSize>::TReadIterator ReadIterator() { + return Queue.Iterator(); + } + }; +} diff --git a/library/cpp/actors/core/mon.h b/library/cpp/actors/core/mon.h index 93dfbe28b1..c450f2338e 100644 --- a/library/cpp/actors/core/mon.h +++ b/library/cpp/actors/core/mon.h @@ -20,7 +20,7 @@ namespace NActors { static_assert(End < EventSpaceEnd(NActors::TEvents::ES_MON), "expect End < EventSpaceEnd(NActors::TEvents::ES_MON)"); // request info from an actor in HTML format - struct TEvHttpInfo: public NActors::TEventLocal<TEvHttpInfo, HttpInfo> { + struct TEvHttpInfo: public NActors::TEventLocal<TEvHttpInfo, HttpInfo> { TEvHttpInfo(const NMonitoring::IMonHttpRequest& request, int subReqId = 0) : Request(request) , SubRequestId(subReqId) @@ -41,7 +41,7 @@ namespace NActors { }; // base class for HTTP info response - struct IEvHttpInfoRes: public NActors::TEventLocal<IEvHttpInfoRes, HttpInfoRes> { + struct IEvHttpInfoRes: public NActors::TEventLocal<IEvHttpInfoRes, HttpInfoRes> { enum EContentType { Html, Custom, @@ -58,8 +58,8 @@ namespace NActors { }; // Ready to output HTML in TString - struct TEvHttpInfoRes: public IEvHttpInfoRes { - TEvHttpInfoRes(const TString& answer, int subReqId = 0, EContentType contentType = Html) + struct TEvHttpInfoRes: public IEvHttpInfoRes { + TEvHttpInfoRes(const TString& answer, int subReqId = 0, EContentType contentType = Html) : Answer(answer) , SubRequestId(subReqId) , ContentType(contentType) @@ -79,14 +79,14 @@ namespace NActors { const EContentType ContentType; }; - struct TEvRemoteHttpInfo: public NActors::TEventBase<TEvRemoteHttpInfo, RemoteHttpInfo> { - TEvRemoteHttpInfo() { - } + struct TEvRemoteHttpInfo: public NActors::TEventBase<TEvRemoteHttpInfo, RemoteHttpInfo> { + TEvRemoteHttpInfo() { + } TEvRemoteHttpInfo(const TString& query) : Query(query) - { - } + { + } TEvRemoteHttpInfo(const TString& query, HTTP_METHOD method) : Query(query) @@ -133,14 +133,14 @@ namespace NActors { } }; - struct TEvRemoteHttpInfoRes: public NActors::TEventBase<TEvRemoteHttpInfoRes, RemoteHttpInfoRes> { - TEvRemoteHttpInfoRes() { - } + struct TEvRemoteHttpInfoRes: public NActors::TEventBase<TEvRemoteHttpInfoRes, RemoteHttpInfoRes> { + TEvRemoteHttpInfoRes() { + } TEvRemoteHttpInfoRes(const TString& html) : Html(html) - { - } + { + } TString Html; @@ -165,14 +165,14 @@ namespace NActors { } }; - struct TEvRemoteJsonInfoRes: public NActors::TEventBase<TEvRemoteJsonInfoRes, RemoteJsonInfoRes> { - TEvRemoteJsonInfoRes() { - } + struct TEvRemoteJsonInfoRes: public NActors::TEventBase<TEvRemoteJsonInfoRes, RemoteJsonInfoRes> { + TEvRemoteJsonInfoRes() { + } TEvRemoteJsonInfoRes(const TString& json) : Json(json) - { - } + { + } TString Json; @@ -197,14 +197,14 @@ namespace NActors { } }; - struct TEvRemoteBinaryInfoRes: public NActors::TEventBase<TEvRemoteBinaryInfoRes, RemoteBinaryInfoRes> { - TEvRemoteBinaryInfoRes() { - } + struct TEvRemoteBinaryInfoRes: public NActors::TEventBase<TEvRemoteBinaryInfoRes, RemoteBinaryInfoRes> { + TEvRemoteBinaryInfoRes() { + } TEvRemoteBinaryInfoRes(const TString& blob) : Blob(blob) - { - } + { + } TString Blob; diff --git a/library/cpp/actors/core/mon_stats.h b/library/cpp/actors/core/mon_stats.h index 0f691d5125..d55552af0c 100644 --- a/library/cpp/actors/core/mon_stats.h +++ b/library/cpp/actors/core/mon_stats.h @@ -7,33 +7,33 @@ namespace NActors { struct TLogHistogram : public NMonitoring::IHistogramSnapshot { - TLogHistogram() { + TLogHistogram() { memset(Buckets, 0, sizeof(Buckets)); - } + } - inline void Add(ui64 val, ui64 inc = 1) { - size_t ind = 0; + inline void Add(ui64 val, ui64 inc = 1) { + size_t ind = 0; #if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ == 7 - asm volatile("" :: - : "memory"); + asm volatile("" :: + : "memory"); #endif if (val > 1) { ind = GetValueBitCount(val - 1); - } + } #if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ == 7 - asm volatile("" :: - : "memory"); + asm volatile("" :: + : "memory"); #endif - RelaxedStore(&TotalSamples, RelaxedLoad(&TotalSamples) + inc); - RelaxedStore(&Buckets[ind], RelaxedLoad(&Buckets[ind]) + inc); - } - - void Aggregate(const TLogHistogram& other) { - const ui64 inc = RelaxedLoad(&other.TotalSamples); - RelaxedStore(&TotalSamples, RelaxedLoad(&TotalSamples) + inc); - for (size_t i = 0; i < Y_ARRAY_SIZE(Buckets); ++i) { - Buckets[i] += RelaxedLoad(&other.Buckets[i]); - } + RelaxedStore(&TotalSamples, RelaxedLoad(&TotalSamples) + inc); + RelaxedStore(&Buckets[ind], RelaxedLoad(&Buckets[ind]) + inc); + } + + void Aggregate(const TLogHistogram& other) { + const ui64 inc = RelaxedLoad(&other.TotalSamples); + RelaxedStore(&TotalSamples, RelaxedLoad(&TotalSamples) + inc); + for (size_t i = 0; i < Y_ARRAY_SIZE(Buckets); ++i) { + Buckets[i] += RelaxedLoad(&other.Buckets[i]); + } } // IHistogramSnapshot @@ -55,14 +55,14 @@ namespace NActors { } ui64 TotalSamples = 0; - ui64 Buckets[65]; - }; - - struct TExecutorPoolStats { - ui64 MaxUtilizationTime = 0; - }; - - struct TExecutorThreadStats { + ui64 Buckets[65]; + }; + + struct TExecutorPoolStats { + ui64 MaxUtilizationTime = 0; + }; + + struct TExecutorThreadStats { ui64 SentEvents = 0; ui64 ReceivedEvents = 0; ui64 PreemptedEvents = 0; // Number of events experienced hard preemption @@ -72,10 +72,10 @@ namespace NActors { NHPTimer::STime ElapsedTicks = 0; NHPTimer::STime ParkedTicks = 0; NHPTimer::STime BlockedTicks = 0; - TLogHistogram ActivationTimeHistogram; - TLogHistogram EventDeliveryTimeHistogram; - TLogHistogram EventProcessingCountHistogram; - TLogHistogram EventProcessingTimeHistogram; + TLogHistogram ActivationTimeHistogram; + TLogHistogram EventDeliveryTimeHistogram; + TLogHistogram EventProcessingCountHistogram; + TLogHistogram EventProcessingTimeHistogram; TVector<NHPTimer::STime> ElapsedTicksByActivity; TVector<ui64> ReceivedEventsByActivity; TVector<i64> ActorsAliveByActivity; // the sum should be positive, but per-thread might be negative @@ -87,61 +87,61 @@ namespace NActors { ui64 MailboxPushedOutByTime = 0; ui64 MailboxPushedOutByEventCount = 0; - TExecutorThreadStats(size_t activityVecSize = 1) // must be not empty as 0 used as default + TExecutorThreadStats(size_t activityVecSize = 1) // must be not empty as 0 used as default : ElapsedTicksByActivity(activityVecSize) , ReceivedEventsByActivity(activityVecSize) , ActorsAliveByActivity(activityVecSize) , ScheduledEventsByActivity(activityVecSize) {} - - template <typename T> + + template <typename T> static void AggregateOne(TVector<T>& self, const TVector<T>& other) { - const size_t selfSize = self.size(); - const size_t otherSize = other.size(); - if (selfSize < otherSize) - self.resize(otherSize); - for (size_t at = 0; at < otherSize; ++at) - self[at] += RelaxedLoad(&other[at]); - } - - void Aggregate(const TExecutorThreadStats& other) { - SentEvents += RelaxedLoad(&other.SentEvents); - ReceivedEvents += RelaxedLoad(&other.ReceivedEvents); + const size_t selfSize = self.size(); + const size_t otherSize = other.size(); + if (selfSize < otherSize) + self.resize(otherSize); + for (size_t at = 0; at < otherSize; ++at) + self[at] += RelaxedLoad(&other[at]); + } + + void Aggregate(const TExecutorThreadStats& other) { + SentEvents += RelaxedLoad(&other.SentEvents); + ReceivedEvents += RelaxedLoad(&other.ReceivedEvents); PreemptedEvents += RelaxedLoad(&other.PreemptedEvents); - NonDeliveredEvents += RelaxedLoad(&other.NonDeliveredEvents); - EmptyMailboxActivation += RelaxedLoad(&other.EmptyMailboxActivation); + NonDeliveredEvents += RelaxedLoad(&other.NonDeliveredEvents); + EmptyMailboxActivation += RelaxedLoad(&other.EmptyMailboxActivation); CpuNs += RelaxedLoad(&other.CpuNs); - ElapsedTicks += RelaxedLoad(&other.ElapsedTicks); - ParkedTicks += RelaxedLoad(&other.ParkedTicks); + ElapsedTicks += RelaxedLoad(&other.ElapsedTicks); + ParkedTicks += RelaxedLoad(&other.ParkedTicks); BlockedTicks += RelaxedLoad(&other.BlockedTicks); MailboxPushedOutBySoftPreemption += RelaxedLoad(&other.MailboxPushedOutBySoftPreemption); MailboxPushedOutByTime += RelaxedLoad(&other.MailboxPushedOutByTime); MailboxPushedOutByEventCount += RelaxedLoad(&other.MailboxPushedOutByEventCount); - ActivationTimeHistogram.Aggregate(other.ActivationTimeHistogram); - EventDeliveryTimeHistogram.Aggregate(other.EventDeliveryTimeHistogram); - EventProcessingCountHistogram.Aggregate(other.EventProcessingCountHistogram); - EventProcessingTimeHistogram.Aggregate(other.EventProcessingTimeHistogram); - - AggregateOne(ElapsedTicksByActivity, other.ElapsedTicksByActivity); - AggregateOne(ReceivedEventsByActivity, other.ReceivedEventsByActivity); - AggregateOne(ActorsAliveByActivity, other.ActorsAliveByActivity); + ActivationTimeHistogram.Aggregate(other.ActivationTimeHistogram); + EventDeliveryTimeHistogram.Aggregate(other.EventDeliveryTimeHistogram); + EventProcessingCountHistogram.Aggregate(other.EventProcessingCountHistogram); + EventProcessingTimeHistogram.Aggregate(other.EventProcessingTimeHistogram); + + AggregateOne(ElapsedTicksByActivity, other.ElapsedTicksByActivity); + AggregateOne(ReceivedEventsByActivity, other.ReceivedEventsByActivity); + AggregateOne(ActorsAliveByActivity, other.ActorsAliveByActivity); AggregateOne(ScheduledEventsByActivity, other.ScheduledEventsByActivity); - - RelaxedStore( - &PoolActorRegistrations, - std::max(RelaxedLoad(&PoolActorRegistrations), RelaxedLoad(&other.PoolActorRegistrations))); - RelaxedStore( - &PoolDestroyedActors, - std::max(RelaxedLoad(&PoolDestroyedActors), RelaxedLoad(&other.PoolDestroyedActors))); - RelaxedStore( - &PoolAllocatedMailboxes, - std::max(RelaxedLoad(&PoolAllocatedMailboxes), RelaxedLoad(&other.PoolAllocatedMailboxes))); - } - - size_t MaxActivityType() const { - return ActorsAliveByActivity.size(); - } - }; + + RelaxedStore( + &PoolActorRegistrations, + std::max(RelaxedLoad(&PoolActorRegistrations), RelaxedLoad(&other.PoolActorRegistrations))); + RelaxedStore( + &PoolDestroyedActors, + std::max(RelaxedLoad(&PoolDestroyedActors), RelaxedLoad(&other.PoolDestroyedActors))); + RelaxedStore( + &PoolAllocatedMailboxes, + std::max(RelaxedLoad(&PoolAllocatedMailboxes), RelaxedLoad(&other.PoolAllocatedMailboxes))); + } + + size_t MaxActivityType() const { + return ActorsAliveByActivity.size(); + } + }; } diff --git a/library/cpp/actors/core/probes.h b/library/cpp/actors/core/probes.h index 44abe77d5d..4912d6dd26 100644 --- a/library/cpp/actors/core/probes.h +++ b/library/cpp/actors/core/probes.h @@ -7,22 +7,22 @@ #define LWTYPE_ACTORID ui64, ui64, ui32, ui32 #define LWNAME_ACTORID(n) n "Raw1", n "Raw2", n "NodeId", n "PoolId" -#define ACTORLIB_PROVIDER(PROBE, EVENT, GROUPS, TYPES, NAMES) \ - PROBE(SlowEvent, GROUPS("ActorLibSlow"), \ - TYPES(ui32, double, TString, TString, TString), \ - NAMES("poolId", "eventMs", "eventType", "actorId", "actorType")) \ - PROBE(EventSlowDelivery, GROUPS("ActorLibSlow"), \ - TYPES(ui32, double, double, ui64, TString, TString, TString), \ - NAMES("poolId", "deliveryMs", "sinceActivationMs", "eventProcessedBefore", "eventType", "actorId", "actorType")) \ - PROBE(SlowActivation, GROUPS("ActorLibSlow"), \ - TYPES(ui32, double), \ - NAMES("poolId", "activationMs")) \ - PROBE(SlowRegisterNew, GROUPS("ActorLibSlow"), \ - TYPES(ui32, double), \ - NAMES("poolId", "registerNewMs")) \ - PROBE(SlowRegisterAdd, GROUPS("ActorLibSlow"), \ - TYPES(ui32, double), \ - NAMES("poolId", "registerAddMs")) \ +#define ACTORLIB_PROVIDER(PROBE, EVENT, GROUPS, TYPES, NAMES) \ + PROBE(SlowEvent, GROUPS("ActorLibSlow"), \ + TYPES(ui32, double, TString, TString, TString), \ + NAMES("poolId", "eventMs", "eventType", "actorId", "actorType")) \ + PROBE(EventSlowDelivery, GROUPS("ActorLibSlow"), \ + TYPES(ui32, double, double, ui64, TString, TString, TString), \ + NAMES("poolId", "deliveryMs", "sinceActivationMs", "eventProcessedBefore", "eventType", "actorId", "actorType")) \ + PROBE(SlowActivation, GROUPS("ActorLibSlow"), \ + TYPES(ui32, double), \ + NAMES("poolId", "activationMs")) \ + PROBE(SlowRegisterNew, GROUPS("ActorLibSlow"), \ + TYPES(ui32, double), \ + NAMES("poolId", "registerNewMs")) \ + PROBE(SlowRegisterAdd, GROUPS("ActorLibSlow"), \ + TYPES(ui32, double), \ + NAMES("poolId", "registerAddMs")) \ PROBE(MailboxPushedOutBySoftPreemption, GROUPS("ActorLibMailbox", "ActorLibMailboxPushedOut"), \ TYPES(ui32, TString, ui32, TDuration, ui64, TString, TString), \ NAMES("poolId", "pool", "eventsProcessed", "procTimeMs", "workerId", "actorId", "actorType")) \ @@ -41,32 +41,32 @@ PROBE(ActivationEnd, GROUPS(), \ TYPES(ui32, ui32, ui32), \ NAMES("cpu", "poolId", "workerId")) \ - PROBE(ExecutorThreadStats, GROUPS("ActorLibStats"), \ + PROBE(ExecutorThreadStats, GROUPS("ActorLibStats"), \ TYPES(ui32, TString, ui64, ui64, ui64, double, double), \ NAMES("poolId", "pool", "workerId", "execCount", "readyActivationCount", "execMs", "nonExecMs")) \ - PROBE(SlowICReadLoopAdjustSize, GROUPS("ActorLibSlowIC"), \ - TYPES(double), \ - NAMES("icReadLoopAdjustSizeMs")) \ - PROBE(SlowICReadFromSocket, GROUPS("ActorLibSlowIC"), \ - TYPES(double), \ - NAMES("icReadFromSocketMs")) \ - PROBE(SlowICReadLoopSend, GROUPS("ActorLibSlowIC"), \ - TYPES(double), \ - NAMES("icReadLoopSendMs")) \ - PROBE(SlowICAllocPacketBuffer, GROUPS("ActorLibSlowIC"), \ - TYPES(ui32, double), \ - NAMES("peerId", "icAllocPacketBufferMs")) \ - PROBE(SlowICFillSendingBuffer, GROUPS("ActorLibSlowIC"), \ - TYPES(ui32, double), \ - NAMES("peerId", "icFillSendingBufferMs")) \ - PROBE(SlowICPushSentPackets, GROUPS("ActorLibSlowIC"), \ - TYPES(ui32, double), \ - NAMES("peerId", "icPushSentPacketsMs")) \ - PROBE(SlowICPushSendQueue, GROUPS("ActorLibSlowIC"), \ - TYPES(ui32, double), \ - NAMES("peerId", "icPushSendQueueMs")) \ + PROBE(SlowICReadLoopAdjustSize, GROUPS("ActorLibSlowIC"), \ + TYPES(double), \ + NAMES("icReadLoopAdjustSizeMs")) \ + PROBE(SlowICReadFromSocket, GROUPS("ActorLibSlowIC"), \ + TYPES(double), \ + NAMES("icReadFromSocketMs")) \ + PROBE(SlowICReadLoopSend, GROUPS("ActorLibSlowIC"), \ + TYPES(double), \ + NAMES("icReadLoopSendMs")) \ + PROBE(SlowICAllocPacketBuffer, GROUPS("ActorLibSlowIC"), \ + TYPES(ui32, double), \ + NAMES("peerId", "icAllocPacketBufferMs")) \ + PROBE(SlowICFillSendingBuffer, GROUPS("ActorLibSlowIC"), \ + TYPES(ui32, double), \ + NAMES("peerId", "icFillSendingBufferMs")) \ + PROBE(SlowICPushSentPackets, GROUPS("ActorLibSlowIC"), \ + TYPES(ui32, double), \ + NAMES("peerId", "icPushSentPacketsMs")) \ + PROBE(SlowICPushSendQueue, GROUPS("ActorLibSlowIC"), \ + TYPES(ui32, double), \ + NAMES("peerId", "icPushSendQueueMs")) \ PROBE(SlowICWriteData, GROUPS("ActorLibSlowIC"), \ - TYPES(ui32, double), \ + TYPES(ui32, double), \ NAMES("peerId", "icWriteDataMs")) \ PROBE(SlowICDropConfirmed, GROUPS("ActorLibSlowIC"), \ TYPES(ui32, double), \ diff --git a/library/cpp/actors/core/process_stats.cpp b/library/cpp/actors/core/process_stats.cpp index 3c5fd82afd..0e1dbd0031 100644 --- a/library/cpp/actors/core/process_stats.cpp +++ b/library/cpp/actors/core/process_stats.cpp @@ -13,84 +13,84 @@ #include <util/string/split.h> #ifndef _win_ -#include <sys/user.h> -#include <sys/sysctl.h> +#include <sys/user.h> +#include <sys/sysctl.h> #endif namespace NActors { #ifdef _linux_ - namespace { - template <typename TVal> - static bool ExtractVal(const TString& str, const TString& name, TVal& res) { - if (!str.StartsWith(name)) - return false; + namespace { + template <typename TVal> + static bool ExtractVal(const TString& str, const TString& name, TVal& res) { + if (!str.StartsWith(name)) + return false; size_t pos = name.size(); while (pos < str.size() && (str[pos] == ' ' || str[pos] == '\t')) { - pos++; - } + pos++; + } res = atol(str.data() + pos); - return true; - } + return true; + } - float TicksPerMillisec() { + float TicksPerMillisec() { #ifdef _SC_CLK_TCK - return sysconf(_SC_CLK_TCK) / 1000.0; + return sysconf(_SC_CLK_TCK) / 1000.0; #else - return 1.f; + return 1.f; #endif } - } + } - bool TProcStat::Fill(pid_t pid) { - try { + bool TProcStat::Fill(pid_t pid) { + try { TString strPid(ToString(pid)); TFileInput proc("/proc/" + strPid + "/status"); - TString str; - while (proc.ReadLine(str)) { - if (ExtractVal(str, "VmRSS:", Rss)) - continue; - if (ExtractVal(str, "voluntary_ctxt_switches:", VolCtxSwtch)) - continue; - if (ExtractVal(str, "nonvoluntary_ctxt_switches:", NonvolCtxSwtch)) - continue; - } - // Convert from kB to bytes - Rss *= 1024; - - float tickPerMillisec = TicksPerMillisec(); + TString str; + while (proc.ReadLine(str)) { + if (ExtractVal(str, "VmRSS:", Rss)) + continue; + if (ExtractVal(str, "voluntary_ctxt_switches:", VolCtxSwtch)) + continue; + if (ExtractVal(str, "nonvoluntary_ctxt_switches:", NonvolCtxSwtch)) + continue; + } + // Convert from kB to bytes + Rss *= 1024; + + float tickPerMillisec = TicksPerMillisec(); TFileInput procStat("/proc/" + strPid + "/stat"); - procStat.ReadLine(str); - if (!str.empty()) { + procStat.ReadLine(str); + if (!str.empty()) { sscanf(str.data(), - "%d %*s %c %d %d %d %d %d %u %lu %lu " - "%lu %lu %lu %lu %ld %ld %ld %ld %ld " - "%ld %llu %lu %ld %lu", - &Pid, &State, &Ppid, &Pgrp, &Session, &TtyNr, &TPgid, &Flags, &MinFlt, &CMinFlt, - &MajFlt, &CMajFlt, &Utime, &Stime, &CUtime, &CStime, &Priority, &Nice, &NumThreads, - &ItRealValue, &StartTime, &Vsize, &RssPages, &RssLim); - Utime /= tickPerMillisec; - Stime /= tickPerMillisec; - CUtime /= tickPerMillisec; - CStime /= tickPerMillisec; + "%d %*s %c %d %d %d %d %d %u %lu %lu " + "%lu %lu %lu %lu %ld %ld %ld %ld %ld " + "%ld %llu %lu %ld %lu", + &Pid, &State, &Ppid, &Pgrp, &Session, &TtyNr, &TPgid, &Flags, &MinFlt, &CMinFlt, + &MajFlt, &CMajFlt, &Utime, &Stime, &CUtime, &CStime, &Priority, &Nice, &NumThreads, + &ItRealValue, &StartTime, &Vsize, &RssPages, &RssLim); + Utime /= tickPerMillisec; + Stime /= tickPerMillisec; + CUtime /= tickPerMillisec; + CStime /= tickPerMillisec; SystemUptime = ::Uptime(); Uptime = SystemUptime - TDuration::MilliSeconds(StartTime / TicksPerMillisec()); } - + TFileInput statm("/proc/" + strPid + "/statm"); - statm.ReadLine(str); + statm.ReadLine(str); TVector<TString> fields; StringSplitter(str).Split(' ').SkipEmpty().Collect(&fields); - if (fields.size() >= 7) { - ui64 resident = FromString<ui64>(fields[1]); - ui64 shared = FromString<ui64>(fields[2]); - if (PageSize == 0) { - PageSize = ObtainPageSize(); - } - FileRss = shared * PageSize; - AnonRss = (resident - shared) * PageSize; - } + if (fields.size() >= 7) { + ui64 resident = FromString<ui64>(fields[1]); + ui64 shared = FromString<ui64>(fields[2]); + if (PageSize == 0) { + PageSize = ObtainPageSize(); + } + FileRss = shared * PageSize; + AnonRss = (resident - shared) * PageSize; + } TFileInput cgroup("/proc/" + strPid + "/cgroup"); TString line; @@ -112,70 +112,70 @@ namespace NActors { } } - } catch (...) { - return false; + } catch (...) { + return false; } - return true; + return true; } - long TProcStat::ObtainPageSize() { - long sz = sysconf(_SC_PAGESIZE); - return sz; - } + long TProcStat::ObtainPageSize() { + long sz = sysconf(_SC_PAGESIZE); + return sz; + } #else - bool TProcStat::Fill(pid_t pid) { - Y_UNUSED(pid); - return false; - } + bool TProcStat::Fill(pid_t pid) { + Y_UNUSED(pid); + return false; + } - long TProcStat::ObtainPageSize() { - return 0; - } + long TProcStat::ObtainPageSize() { + return 0; + } #endif namespace { - // Periodically collects process stats and exposes them as mon counters + // Periodically collects process stats and exposes them as mon counters template <typename TDerived> class TProcStatCollectingActor: public TActorBootstrapped<TProcStatCollectingActor<TDerived>> { - public: - static constexpr IActor::EActivityType ActorActivityType() { - return IActor::ACTORLIB_STATS; - } + public: + static constexpr IActor::EActivityType ActorActivityType() { + return IActor::ACTORLIB_STATS; + } TProcStatCollectingActor(TDuration interval) : Interval(interval) - { - } + { + } - void Bootstrap(const TActorContext& ctx) { + void Bootstrap(const TActorContext& ctx) { ctx.Schedule(Interval, new TEvents::TEvWakeup()); Self()->Become(&TDerived::StateWork); - } + } - STFUNC(StateWork) { - switch (ev->GetTypeRewrite()) { - CFunc(TEvents::TSystem::Wakeup, Wakeup); - } - } + STFUNC(StateWork) { + switch (ev->GetTypeRewrite()) { + CFunc(TEvents::TSystem::Wakeup, Wakeup); + } + } - private: - void Wakeup(const TActorContext& ctx) { + private: + void Wakeup(const TActorContext& ctx) { Self()->UpdateCounters(ProcStat); ctx.Schedule(Interval, new TEvents::TEvWakeup()); } TDerived* Self() { - ProcStat.Fill(getpid()); + ProcStat.Fill(getpid()); return static_cast<TDerived*>(this); - } + } private: const TDuration Interval; TProcStat ProcStat; - }; + }; // Periodically collects process stats and exposes them as mon counters class TDynamicCounterCollector: public TProcStatCollectingActor<TDynamicCounterCollector> { diff --git a/library/cpp/actors/core/scheduler_basic.cpp b/library/cpp/actors/core/scheduler_basic.cpp index abba1f818f..fba200e16b 100644 --- a/library/cpp/actors/core/scheduler_basic.cpp +++ b/library/cpp/actors/core/scheduler_basic.cpp @@ -1,6 +1,6 @@ -#include "scheduler_basic.h" -#include "scheduler_queue.h" - +#include "scheduler_basic.h" +#include "scheduler_queue.h" + #include <library/cpp/actors/util/datetime.h> #include <library/cpp/actors/util/thread.h> @@ -8,7 +8,7 @@ #include <library/cpp/balloc/optional/operators.h> #endif -namespace NActors { +namespace NActors { struct TBasicSchedulerThread::TMonCounters { NMonitoring::TDynamicCounters::TCounterPtr TimeDelayMs; @@ -32,144 +32,144 @@ namespace NActors { { } }; - TBasicSchedulerThread::TBasicSchedulerThread(const TSchedulerConfig& config) - : Config(config) + TBasicSchedulerThread::TBasicSchedulerThread(const TSchedulerConfig& config) + : Config(config) , MonCounters(Config.MonCounters ? new TMonCounters(Config.MonCounters) : nullptr) - , ActorSystem(nullptr) - , CurrentTimestamp(nullptr) + , ActorSystem(nullptr) + , CurrentTimestamp(nullptr) , CurrentMonotonic(nullptr) - , TotalReaders(0) - , StopFlag(false) - , ScheduleMap(3600) - { + , TotalReaders(0) + , StopFlag(false) + , ScheduleMap(3600) + { Y_VERIFY(!Config.UseSchedulerActor, "Cannot create scheduler thread because Config.UseSchedulerActor# true"); - } - - TBasicSchedulerThread::~TBasicSchedulerThread() { - Y_VERIFY(!MainCycle); - } - - void TBasicSchedulerThread::CycleFunc() { + } + + TBasicSchedulerThread::~TBasicSchedulerThread() { + Y_VERIFY(!MainCycle); + } + + void TBasicSchedulerThread::CycleFunc() { #ifdef BALLOC ThreadDisableBalloc(); #endif ::SetCurrentThreadName("Scheduler"); - + ui64 currentMonotonic = RelaxedLoad(CurrentMonotonic); ui64 throttledMonotonic = currentMonotonic; ui64 activeTick = AlignUp<ui64>(throttledMonotonic, IntrasecondThreshold); - TAutoPtr<TMomentMap> activeSec; - + TAutoPtr<TMomentMap> activeSec; + NHPTimer::STime hpprev = GetCycleCountFast(); ui64 nextTimestamp = TInstant::Now().MicroSeconds(); ui64 nextMonotonic = Max(currentMonotonic, GetMonotonicMicroSeconds()); - while (!AtomicLoad(&StopFlag)) { - { + while (!AtomicLoad(&StopFlag)) { + { const ui64 delta = nextMonotonic - throttledMonotonic; const ui64 elapsedDelta = nextMonotonic - currentMonotonic; const ui64 threshold = Max(Min(Config.ProgressThreshold, 2 * elapsedDelta), ui64(1)); - + throttledMonotonic = (delta > threshold) ? throttledMonotonic + threshold : nextMonotonic; if (MonCounters) { *MonCounters->TimeDelayMs = (nextMonotonic - throttledMonotonic) / 1000; } - } + } AtomicStore(CurrentTimestamp, nextTimestamp); AtomicStore(CurrentMonotonic, nextMonotonic); currentMonotonic = nextMonotonic; - + if (MonCounters) { ++*MonCounters->Iterations; } - bool somethingDone = false; - - // first step - send everything triggered on schedule + bool somethingDone = false; + + // first step - send everything triggered on schedule ui64 eventsSent = 0; ui64 eventsDropped = 0; - for (;;) { - while (!!activeSec && !activeSec->empty()) { - TMomentMap::iterator it = activeSec->begin(); + for (;;) { + while (!!activeSec && !activeSec->empty()) { + TMomentMap::iterator it = activeSec->begin(); if (it->first <= throttledMonotonic) { if (NSchedulerQueue::TQueueType* q = it->second.Get()) { - while (NSchedulerQueue::TEntry* x = q->Reader.Pop()) { - somethingDone = true; - Y_VERIFY_DEBUG(x->InstantMicroseconds <= activeTick); - IEventHandle* ev = x->Ev; - ISchedulerCookie* cookie = x->Cookie; - // TODO: lazy send with backoff queue to not hang over contended mailboxes - if (cookie) { + while (NSchedulerQueue::TEntry* x = q->Reader.Pop()) { + somethingDone = true; + Y_VERIFY_DEBUG(x->InstantMicroseconds <= activeTick); + IEventHandle* ev = x->Ev; + ISchedulerCookie* cookie = x->Cookie; + // TODO: lazy send with backoff queue to not hang over contended mailboxes + if (cookie) { if (cookie->Detach()) { - ActorSystem->Send(ev); + ActorSystem->Send(ev); ++eventsSent; } else { - delete ev; + delete ev; ++eventsDropped; } - } else { - ActorSystem->Send(ev); + } else { + ActorSystem->Send(ev); ++eventsSent; - } - } - } - activeSec->erase(it); - } else - break; - } - + } + } + } + activeSec->erase(it); + } else + break; + } + if (activeTick <= throttledMonotonic) { - Y_VERIFY_DEBUG(!activeSec || activeSec->empty()); - activeSec.Destroy(); - activeTick += IntrasecondThreshold; - TScheduleMap::iterator it = ScheduleMap.find(activeTick); - if (it != ScheduleMap.end()) { - activeSec = it->second; - ScheduleMap.erase(it); - } - continue; - } - - // ok, if we are here - then nothing is ready, so send step complete - break; - } - - // second step - collect everything from queues - + Y_VERIFY_DEBUG(!activeSec || activeSec->empty()); + activeSec.Destroy(); + activeTick += IntrasecondThreshold; + TScheduleMap::iterator it = ScheduleMap.find(activeTick); + if (it != ScheduleMap.end()) { + activeSec = it->second; + ScheduleMap.erase(it); + } + continue; + } + + // ok, if we are here - then nothing is ready, so send step complete + break; + } + + // second step - collect everything from queues + ui64 eventsAdded = 0; - for (ui32 i = 0; i != TotalReaders; ++i) { - while (NSchedulerQueue::TEntry* x = Readers[i]->Pop()) { - somethingDone = true; - const ui64 instant = AlignUp<ui64>(x->InstantMicroseconds, Config.ResolutionMicroseconds); - IEventHandle* const ev = x->Ev; - ISchedulerCookie* const cookie = x->Cookie; - - // check is cookie still valid? looks like it will hurt performance w/o sagnificant memory save - - if (instant <= activeTick) { - if (!activeSec) - activeSec.Reset(new TMomentMap()); + for (ui32 i = 0; i != TotalReaders; ++i) { + while (NSchedulerQueue::TEntry* x = Readers[i]->Pop()) { + somethingDone = true; + const ui64 instant = AlignUp<ui64>(x->InstantMicroseconds, Config.ResolutionMicroseconds); + IEventHandle* const ev = x->Ev; + ISchedulerCookie* const cookie = x->Cookie; + + // check is cookie still valid? looks like it will hurt performance w/o sagnificant memory save + + if (instant <= activeTick) { + if (!activeSec) + activeSec.Reset(new TMomentMap()); TAutoPtr<NSchedulerQueue::TQueueType>& queue = (*activeSec)[instant]; - if (!queue) + if (!queue) queue.Reset(new NSchedulerQueue::TQueueType()); - queue->Writer.Push(instant, ev, cookie); - } else { - const ui64 intrasecond = AlignUp<ui64>(instant, IntrasecondThreshold); - TAutoPtr<TMomentMap>& msec = ScheduleMap[intrasecond]; - if (!msec) - msec.Reset(new TMomentMap()); + queue->Writer.Push(instant, ev, cookie); + } else { + const ui64 intrasecond = AlignUp<ui64>(instant, IntrasecondThreshold); + TAutoPtr<TMomentMap>& msec = ScheduleMap[intrasecond]; + if (!msec) + msec.Reset(new TMomentMap()); TAutoPtr<NSchedulerQueue::TQueueType>& queue = (*msec)[instant]; - if (!queue) + if (!queue) queue.Reset(new NSchedulerQueue::TQueueType()); - queue->Writer.Push(instant, ev, cookie); - } + queue->Writer.Push(instant, ev, cookie); + } ++eventsAdded; - } - } - + } + } + NHPTimer::STime hpnow = GetCycleCountFast(); if (MonCounters) { @@ -185,46 +185,46 @@ namespace NActors { nextTimestamp = TInstant::Now().MicroSeconds(); nextMonotonic = Max(currentMonotonic, GetMonotonicMicroSeconds()); - // ok complete, if nothing left - sleep - if (!somethingDone) { + // ok complete, if nothing left - sleep + if (!somethingDone) { const ui64 nextInstant = AlignDown<ui64>(throttledMonotonic + Config.ResolutionMicroseconds, Config.ResolutionMicroseconds); if (nextMonotonic >= nextInstant) // already in next time-slice - continue; - + continue; + const ui64 delta = nextInstant - nextMonotonic; - if (delta < Config.SpinThreshold) // not so much time left, just spin - continue; - + if (delta < Config.SpinThreshold) // not so much time left, just spin + continue; + if (MonCounters) { ++*MonCounters->Sleeps; } - NanoSleep(delta * 1000); // ok, looks like we should sleep a bit. + NanoSleep(delta * 1000); // ok, looks like we should sleep a bit. // Don't count sleep in elapsed microseconds hpprev = GetCycleCountFast(); nextTimestamp = TInstant::Now().MicroSeconds(); nextMonotonic = Max(currentMonotonic, GetMonotonicMicroSeconds()); - } - } - // ok, die! - } - + } + } + // ok, die! + } + void TBasicSchedulerThread::Prepare(TActorSystem* actorSystem, volatile ui64* currentTimestamp, volatile ui64* currentMonotonic) { - ActorSystem = actorSystem; - CurrentTimestamp = currentTimestamp; + ActorSystem = actorSystem; + CurrentTimestamp = currentTimestamp; CurrentMonotonic = currentMonotonic; *CurrentTimestamp = TInstant::Now().MicroSeconds(); *CurrentMonotonic = GetMonotonicMicroSeconds(); - } - + } + void TBasicSchedulerThread::PrepareSchedules(NSchedulerQueue::TReader** readers, ui32 scheduleReadersCount) { - Y_VERIFY(scheduleReadersCount > 0); - TotalReaders = scheduleReadersCount; - Readers.Reset(new NSchedulerQueue::TReader*[scheduleReadersCount]); - Copy(readers, readers + scheduleReadersCount, Readers.Get()); - } - + Y_VERIFY(scheduleReadersCount > 0); + TotalReaders = scheduleReadersCount; + Readers.Reset(new NSchedulerQueue::TReader*[scheduleReadersCount]); + Copy(readers, readers + scheduleReadersCount, Readers.Get()); + } + void TBasicSchedulerThread::PrepareStart() { // Called after actor system is initialized, but before executor threads // are started, giving us a chance to update current timestamp with a @@ -235,18 +235,18 @@ namespace NActors { AtomicStore(CurrentMonotonic, Max(RelaxedLoad(CurrentMonotonic), GetMonotonicMicroSeconds())); } - void TBasicSchedulerThread::Start() { - MainCycle.Reset(new NThreading::TLegacyFuture<void, false>(std::bind(&TBasicSchedulerThread::CycleFunc, this))); - } - - void TBasicSchedulerThread::PrepareStop() { - AtomicStore(&StopFlag, true); - } - - void TBasicSchedulerThread::Stop() { - MainCycle->Get(); - MainCycle.Destroy(); - } + void TBasicSchedulerThread::Start() { + MainCycle.Reset(new NThreading::TLegacyFuture<void, false>(std::bind(&TBasicSchedulerThread::CycleFunc, this))); + } + + void TBasicSchedulerThread::PrepareStop() { + AtomicStore(&StopFlag, true); + } + + void TBasicSchedulerThread::Stop() { + MainCycle->Get(); + MainCycle.Destroy(); + } } @@ -269,6 +269,6 @@ namespace NActors { ISchedulerThread* CreateSchedulerThread(const TSchedulerConfig& config) { return new TBasicSchedulerThread(config); } -} +} #endif // __linux__ diff --git a/library/cpp/actors/core/scheduler_basic.h b/library/cpp/actors/core/scheduler_basic.h index f66e784696..2ccde39235 100644 --- a/library/cpp/actors/core/scheduler_basic.h +++ b/library/cpp/actors/core/scheduler_basic.h @@ -1,54 +1,54 @@ -#pragma once - -#include "actorsystem.h" +#pragma once + +#include "actorsystem.h" #include "monotonic.h" -#include "scheduler_queue.h" +#include "scheduler_queue.h" #include <library/cpp/actors/util/queue_chunk.h> #include <library/cpp/threading/future/legacy_future.h> -#include <util/generic/hash.h> -#include <util/generic/map.h> - -namespace NActors { - - class TBasicSchedulerThread: public ISchedulerThread { - // TODO: replace with NUMA-local threads and per-thread schedules - const TSchedulerConfig Config; - +#include <util/generic/hash.h> +#include <util/generic/map.h> + +namespace NActors { + + class TBasicSchedulerThread: public ISchedulerThread { + // TODO: replace with NUMA-local threads and per-thread schedules + const TSchedulerConfig Config; + struct TMonCounters; const THolder<TMonCounters> MonCounters; - TActorSystem* ActorSystem; - volatile ui64* CurrentTimestamp; + TActorSystem* ActorSystem; + volatile ui64* CurrentTimestamp; volatile ui64* CurrentMonotonic; - - ui32 TotalReaders; - TArrayHolder<NSchedulerQueue::TReader*> Readers; - - volatile bool StopFlag; - + + ui32 TotalReaders; + TArrayHolder<NSchedulerQueue::TReader*> Readers; + + volatile bool StopFlag; + typedef TMap<ui64, TAutoPtr<NSchedulerQueue::TQueueType>> TMomentMap; // intrasecond queues typedef THashMap<ui64, TAutoPtr<TMomentMap>> TScheduleMap; // over-second schedule - - TScheduleMap ScheduleMap; - - THolder<NThreading::TLegacyFuture<void, false>> MainCycle; - - static const ui64 IntrasecondThreshold = 1048576; // ~second - - void CycleFunc(); - - public: - TBasicSchedulerThread(const TSchedulerConfig& config = TSchedulerConfig()); - ~TBasicSchedulerThread(); - + + TScheduleMap ScheduleMap; + + THolder<NThreading::TLegacyFuture<void, false>> MainCycle; + + static const ui64 IntrasecondThreshold = 1048576; // ~second + + void CycleFunc(); + + public: + TBasicSchedulerThread(const TSchedulerConfig& config = TSchedulerConfig()); + ~TBasicSchedulerThread(); + void Prepare(TActorSystem* actorSystem, volatile ui64* currentTimestamp, volatile ui64* currentMonotonic) override; void PrepareSchedules(NSchedulerQueue::TReader** readers, ui32 scheduleReadersCount) override; - + void PrepareStart() override; void Start() override; void PrepareStop() override; void Stop() override; - }; + }; class TMockSchedulerThread: public ISchedulerThread { public: @@ -78,4 +78,4 @@ namespace NActors { ISchedulerThread* CreateSchedulerThread(const TSchedulerConfig& cfg); -} +} diff --git a/library/cpp/actors/core/scheduler_cookie.cpp b/library/cpp/actors/core/scheduler_cookie.cpp index 99717f56e4..0fa6f543a7 100644 --- a/library/cpp/actors/core/scheduler_cookie.cpp +++ b/library/cpp/actors/core/scheduler_cookie.cpp @@ -1,84 +1,84 @@ -#include "scheduler_cookie.h" - -namespace NActors { - class TSchedulerCookie2Way: public ISchedulerCookie { - TAtomic Value; - - public: - TSchedulerCookie2Way() - : Value(2) - { - } - +#include "scheduler_cookie.h" + +namespace NActors { + class TSchedulerCookie2Way: public ISchedulerCookie { + TAtomic Value; + + public: + TSchedulerCookie2Way() + : Value(2) + { + } + bool IsArmed() noexcept override { return (AtomicGet(Value) == 2); - } - + } + bool Detach() noexcept override { - const ui64 x = AtomicDecrement(Value); - if (x == 1) - return true; - - if (x == 0) { - delete this; - return false; - } - - Y_FAIL(); - } - + const ui64 x = AtomicDecrement(Value); + if (x == 1) + return true; + + if (x == 0) { + delete this; + return false; + } + + Y_FAIL(); + } + bool DetachEvent() noexcept override { - Y_FAIL(); - } - }; - - ISchedulerCookie* ISchedulerCookie::Make2Way() { - return new TSchedulerCookie2Way(); - } - - class TSchedulerCookie3Way: public ISchedulerCookie { - TAtomic Value; - - public: - TSchedulerCookie3Way() - : Value(3) - { - } - + Y_FAIL(); + } + }; + + ISchedulerCookie* ISchedulerCookie::Make2Way() { + return new TSchedulerCookie2Way(); + } + + class TSchedulerCookie3Way: public ISchedulerCookie { + TAtomic Value; + + public: + TSchedulerCookie3Way() + : Value(3) + { + } + bool IsArmed() noexcept override { return (AtomicGet(Value) == 3); - } - + } + bool Detach() noexcept override { - const ui64 x = AtomicDecrement(Value); - if (x == 2) - return true; - if (x == 1) - return false; - if (x == 0) { - delete this; - return false; - } - - Y_FAIL(); - } - + const ui64 x = AtomicDecrement(Value); + if (x == 2) + return true; + if (x == 1) + return false; + if (x == 0) { + delete this; + return false; + } + + Y_FAIL(); + } + bool DetachEvent() noexcept override { - const ui64 x = AtomicDecrement(Value); - if (x == 2) - return false; - if (x == 1) - return true; - if (x == 0) { - delete this; - return false; - } - - Y_FAIL(); - } - }; - - ISchedulerCookie* ISchedulerCookie::Make3Way() { - return new TSchedulerCookie3Way(); - } -} + const ui64 x = AtomicDecrement(Value); + if (x == 2) + return false; + if (x == 1) + return true; + if (x == 0) { + delete this; + return false; + } + + Y_FAIL(); + } + }; + + ISchedulerCookie* ISchedulerCookie::Make3Way() { + return new TSchedulerCookie3Way(); + } +} diff --git a/library/cpp/actors/core/scheduler_cookie.h b/library/cpp/actors/core/scheduler_cookie.h index 638c1ab5fe..2c20ca67f3 100644 --- a/library/cpp/actors/core/scheduler_cookie.h +++ b/library/cpp/actors/core/scheduler_cookie.h @@ -1,78 +1,78 @@ -#pragma once - -#include "defs.h" -#include <util/generic/noncopyable.h> - -namespace NActors { - class ISchedulerCookie : TNonCopyable { - protected: - virtual ~ISchedulerCookie() { - } - - public: +#pragma once + +#include "defs.h" +#include <util/generic/noncopyable.h> + +namespace NActors { + class ISchedulerCookie : TNonCopyable { + protected: + virtual ~ISchedulerCookie() { + } + + public: virtual bool Detach() noexcept = 0; virtual bool DetachEvent() noexcept = 0; virtual bool IsArmed() noexcept = 0; - - static ISchedulerCookie* Make2Way(); - static ISchedulerCookie* Make3Way(); - }; - + + static ISchedulerCookie* Make2Way(); + static ISchedulerCookie* Make3Way(); + }; + class TSchedulerCookieHolder : TNonCopyable { - ISchedulerCookie* Cookie; - - public: - TSchedulerCookieHolder() + ISchedulerCookie* Cookie; + + public: + TSchedulerCookieHolder() : Cookie(nullptr) - { - } - - TSchedulerCookieHolder(ISchedulerCookie* x) - : Cookie(x) - { - } - - ~TSchedulerCookieHolder() { - Detach(); - } - + { + } + + TSchedulerCookieHolder(ISchedulerCookie* x) + : Cookie(x) + { + } + + ~TSchedulerCookieHolder() { + Detach(); + } + bool operator==(const TSchedulerCookieHolder& x) const noexcept { - return (Cookie == x.Cookie); - } - + return (Cookie == x.Cookie); + } + ISchedulerCookie* Get() const { - return Cookie; - } - + return Cookie; + } + ISchedulerCookie* Release() { ISchedulerCookie* result = Cookie; Cookie = nullptr; return result; } - void Reset(ISchedulerCookie* cookie) { - Detach(); - Cookie = cookie; - } - + void Reset(ISchedulerCookie* cookie) { + Detach(); + Cookie = cookie; + } + bool Detach() noexcept { - if (Cookie) { - const bool res = Cookie->Detach(); + if (Cookie) { + const bool res = Cookie->Detach(); Cookie = nullptr; - return res; - } else { - return false; - } - } - + return res; + } else { + return false; + } + } + bool DetachEvent() noexcept { - if (Cookie) { - const bool res = Cookie->DetachEvent(); + if (Cookie) { + const bool res = Cookie->DetachEvent(); Cookie = nullptr; - return res; - } else { - return false; - } - } - }; -} + return res; + } else { + return false; + } + } + }; +} diff --git a/library/cpp/actors/core/scheduler_queue.h b/library/cpp/actors/core/scheduler_queue.h index 4d353096d2..3b8fac28f0 100644 --- a/library/cpp/actors/core/scheduler_queue.h +++ b/library/cpp/actors/core/scheduler_queue.h @@ -1,120 +1,120 @@ -#pragma once - +#pragma once + #include <library/cpp/actors/util/queue_chunk.h> - -namespace NActors { - class IEventHandle; - class ISchedulerCookie; - - namespace NSchedulerQueue { - struct TEntry { - ui64 InstantMicroseconds; - IEventHandle* Ev; - ISchedulerCookie* Cookie; - }; - + +namespace NActors { + class IEventHandle; + class ISchedulerCookie; + + namespace NSchedulerQueue { + struct TEntry { + ui64 InstantMicroseconds; + IEventHandle* Ev; + ISchedulerCookie* Cookie; + }; + struct TChunk : TQueueChunkDerived<TEntry, 512, TChunk> {}; - - class TReader; - class TWriter; - class TWriterWithPadding; - - class TReader : ::TNonCopyable { - TChunk* ReadFrom; - ui32 ReadPosition; - - friend class TWriter; - - public: - TReader() - : ReadFrom(new TChunk()) - , ReadPosition(0) - { - } - - ~TReader() { - while (TEntry* x = Pop()) { - if (x->Cookie) - x->Cookie->Detach(); - delete x->Ev; - } - delete ReadFrom; - } - - TEntry* Pop() { - TChunk* head = ReadFrom; - if (ReadPosition != TChunk::EntriesCount) { - if (AtomicLoad(&head->Entries[ReadPosition].InstantMicroseconds) != 0) - return const_cast<TEntry*>(&head->Entries[ReadPosition++]); - else - return nullptr; - } else if (TChunk* next = AtomicLoad(&head->Next)) { - ReadFrom = next; - delete head; - ReadPosition = 0; - return Pop(); - } - - return nullptr; - } - }; - - class TWriter : ::TNonCopyable { - TChunk* WriteTo; - ui32 WritePosition; - - public: - TWriter() - : WriteTo(nullptr) - , WritePosition(0) - { - } - - void Init(const TReader& reader) { - WriteTo = reader.ReadFrom; - WritePosition = 0; - } - - void Push(ui64 instantMicrosends, IEventHandle* ev, ISchedulerCookie* cookie) { + + class TReader; + class TWriter; + class TWriterWithPadding; + + class TReader : ::TNonCopyable { + TChunk* ReadFrom; + ui32 ReadPosition; + + friend class TWriter; + + public: + TReader() + : ReadFrom(new TChunk()) + , ReadPosition(0) + { + } + + ~TReader() { + while (TEntry* x = Pop()) { + if (x->Cookie) + x->Cookie->Detach(); + delete x->Ev; + } + delete ReadFrom; + } + + TEntry* Pop() { + TChunk* head = ReadFrom; + if (ReadPosition != TChunk::EntriesCount) { + if (AtomicLoad(&head->Entries[ReadPosition].InstantMicroseconds) != 0) + return const_cast<TEntry*>(&head->Entries[ReadPosition++]); + else + return nullptr; + } else if (TChunk* next = AtomicLoad(&head->Next)) { + ReadFrom = next; + delete head; + ReadPosition = 0; + return Pop(); + } + + return nullptr; + } + }; + + class TWriter : ::TNonCopyable { + TChunk* WriteTo; + ui32 WritePosition; + + public: + TWriter() + : WriteTo(nullptr) + , WritePosition(0) + { + } + + void Init(const TReader& reader) { + WriteTo = reader.ReadFrom; + WritePosition = 0; + } + + void Push(ui64 instantMicrosends, IEventHandle* ev, ISchedulerCookie* cookie) { if (Y_UNLIKELY(instantMicrosends == 0)) { // Protect against Pop() getting stuck forever instantMicrosends = 1; } - if (WritePosition != TChunk::EntriesCount) { - volatile TEntry& entry = WriteTo->Entries[WritePosition]; - entry.Cookie = cookie; - entry.Ev = ev; - AtomicStore(&entry.InstantMicroseconds, instantMicrosends); - ++WritePosition; - } else { - TChunk* next = new TChunk(); - volatile TEntry& entry = next->Entries[0]; - entry.Cookie = cookie; - entry.Ev = ev; - entry.InstantMicroseconds = instantMicrosends; - AtomicStore(&WriteTo->Next, next); - WriteTo = next; - WritePosition = 1; - } - } - }; - - class TWriterWithPadding: public TWriter { - private: - ui8 CacheLinePadding[64 - sizeof(TWriter)]; - - void UnusedCacheLinePadding() { - Y_UNUSED(CacheLinePadding); - } - }; - + if (WritePosition != TChunk::EntriesCount) { + volatile TEntry& entry = WriteTo->Entries[WritePosition]; + entry.Cookie = cookie; + entry.Ev = ev; + AtomicStore(&entry.InstantMicroseconds, instantMicrosends); + ++WritePosition; + } else { + TChunk* next = new TChunk(); + volatile TEntry& entry = next->Entries[0]; + entry.Cookie = cookie; + entry.Ev = ev; + entry.InstantMicroseconds = instantMicrosends; + AtomicStore(&WriteTo->Next, next); + WriteTo = next; + WritePosition = 1; + } + } + }; + + class TWriterWithPadding: public TWriter { + private: + ui8 CacheLinePadding[64 - sizeof(TWriter)]; + + void UnusedCacheLinePadding() { + Y_UNUSED(CacheLinePadding); + } + }; + struct TQueueType { - TReader Reader; - TWriter Writer; - + TReader Reader; + TWriter Writer; + TQueueType() { - Writer.Init(Reader); - } - }; - } -} + Writer.Init(Reader); + } + }; + } +} diff --git a/library/cpp/actors/core/servicemap.h b/library/cpp/actors/core/servicemap.h index ac879b53ad..d72e50cae5 100644 --- a/library/cpp/actors/core/servicemap.h +++ b/library/cpp/actors/core/servicemap.h @@ -1,168 +1,168 @@ -#pragma once - -#include "defs.h" - -namespace NActors { - // wait-free one writer multi reader hash-tree for service mapping purposes - // on fast updates on same key - could lead to false-negatives, we don't care as such cases are broken from service-map app logic - - template <typename TKey, typename TValue, typename THash, ui64 BaseSize = 256 * 1024, ui64 ExtCount = 4, ui64 ExtBranching = 4> - class TServiceMap : TNonCopyable { - struct TEntry : TNonCopyable { - ui32 CounterIn; - ui32 CounterOut; - TKey Key; - TValue Value; - - TEntry() - : CounterIn(0) - , CounterOut(0) - , Key() - , Value() - { - } - }; - - struct TBranch : TNonCopyable { - TEntry Entries[ExtCount]; - TBranch* Branches[ExtBranching]; - - TBranch() { - Fill(Branches, Branches + ExtBranching, (TBranch*)nullptr); - } - }; - - ui32 Counter; - TBranch* Line[BaseSize]; - - bool ScanBranch(TBranch* branch, const TKey& key, ui64 hash, TValue& ret) { - for (ui32 i = 0; i != ExtCount; ++i) { - const TEntry& entry = branch->Entries[i]; - const ui32 counterIn = AtomicLoad(&entry.CounterIn); - if (counterIn != 0 && entry.Key == key) { - ret = entry.Value; - const ui32 counterOut = AtomicLoad(&entry.CounterOut); - if (counterOut == counterIn) - return true; - } - } - - const ui64 hash0 = hash % ExtBranching; - if (TBranch* next = AtomicLoad(branch->Branches + hash0)) - return ScanBranch(next, key, hash / ExtBranching, ret); - - return false; - } - - void ScanZeroOld(TBranch* branch, const TKey& key, ui64 hash, TEntry** zeroEntry, TEntry*& oldEntry) { - for (ui32 i = 0; i != ExtCount; ++i) { - TEntry& entry = branch->Entries[i]; - if (entry.CounterIn == 0) { - if (zeroEntry && !*zeroEntry) { - *zeroEntry = &entry; - if (oldEntry != nullptr) - return; - } - } else { - if (entry.Key == key) { - oldEntry = &entry; - if (!zeroEntry || *zeroEntry) - return; - } - } - } - - const ui64 hash0 = hash % ExtBranching; - if (TBranch* next = branch->Branches[hash0]) { - ScanZeroOld(next, key, hash / ExtBranching, zeroEntry, oldEntry); - } else { // found tail, if zeroEntry requested, but not yet found - insert one - if (zeroEntry && !*zeroEntry) { - TBranch* next = new TBranch(); - *zeroEntry = next->Entries; - AtomicStore(branch->Branches + hash0, next); - } - } - } - - public: - TServiceMap() - : Counter(0) - { - Fill(Line, Line + BaseSize, (TBranch*)nullptr); - } - - ~TServiceMap() { - for (ui64 i = 0; i < BaseSize; ++i) { - delete Line[i]; - } - } - - TValue Find(const TKey& key) { - THash hashOp; - const ui64 hash = hashOp(key); - const ui64 hash0 = hash % BaseSize; - - if (TBranch* branch = AtomicLoad(Line + hash0)) { - TValue ret; - if (ScanBranch(branch, key, hash / BaseSize, ret)) - return ret; - } - - return TValue(); - } - - // returns true on update, false on insert - TValue Update(const TKey& key, const TValue& value) { - THash hashOp; - const ui64 hash = hashOp(key); - const ui64 hash0 = hash % BaseSize; - - TEntry* zeroEntry = nullptr; - TEntry* oldEntry = nullptr; - - if (TBranch* branch = Line[hash0]) { - ScanZeroOld(branch, key, hash / BaseSize, &zeroEntry, oldEntry); - } else { - TBranch* next = new TBranch(); - zeroEntry = next->Entries; - AtomicStore(Line + hash0, next); - } - - // now we got both entries, first - push new one - const ui32 counter = AtomicUi32Increment(&Counter); - AtomicStore(&zeroEntry->CounterOut, counter); - zeroEntry->Key = key; - zeroEntry->Value = value; - AtomicStore(&zeroEntry->CounterIn, counter); - - if (oldEntry != nullptr) { - const TValue ret = oldEntry->Value; - AtomicStore<ui32>(&oldEntry->CounterOut, 0); - AtomicStore<ui32>(&oldEntry->CounterIn, 0); - return ret; - } else { - return TValue(); - } - } - - bool Erase(const TKey& key) { - THash hashOp; - const ui64 hash = hashOp(key); - const ui64 hash0 = hash % BaseSize; - - TEntry* oldEntry = 0; - - if (TBranch* branch = Line[hash0]) { - ScanZeroOld(branch, key, hash / BaseSize, 0, oldEntry); - } - - if (oldEntry != 0) { - AtomicStore<ui32>(&oldEntry->CounterOut, 0); - AtomicStore<ui32>(&oldEntry->CounterIn, 0); - return true; - } else { - return false; - } - } - }; -} +#pragma once + +#include "defs.h" + +namespace NActors { + // wait-free one writer multi reader hash-tree for service mapping purposes + // on fast updates on same key - could lead to false-negatives, we don't care as such cases are broken from service-map app logic + + template <typename TKey, typename TValue, typename THash, ui64 BaseSize = 256 * 1024, ui64 ExtCount = 4, ui64 ExtBranching = 4> + class TServiceMap : TNonCopyable { + struct TEntry : TNonCopyable { + ui32 CounterIn; + ui32 CounterOut; + TKey Key; + TValue Value; + + TEntry() + : CounterIn(0) + , CounterOut(0) + , Key() + , Value() + { + } + }; + + struct TBranch : TNonCopyable { + TEntry Entries[ExtCount]; + TBranch* Branches[ExtBranching]; + + TBranch() { + Fill(Branches, Branches + ExtBranching, (TBranch*)nullptr); + } + }; + + ui32 Counter; + TBranch* Line[BaseSize]; + + bool ScanBranch(TBranch* branch, const TKey& key, ui64 hash, TValue& ret) { + for (ui32 i = 0; i != ExtCount; ++i) { + const TEntry& entry = branch->Entries[i]; + const ui32 counterIn = AtomicLoad(&entry.CounterIn); + if (counterIn != 0 && entry.Key == key) { + ret = entry.Value; + const ui32 counterOut = AtomicLoad(&entry.CounterOut); + if (counterOut == counterIn) + return true; + } + } + + const ui64 hash0 = hash % ExtBranching; + if (TBranch* next = AtomicLoad(branch->Branches + hash0)) + return ScanBranch(next, key, hash / ExtBranching, ret); + + return false; + } + + void ScanZeroOld(TBranch* branch, const TKey& key, ui64 hash, TEntry** zeroEntry, TEntry*& oldEntry) { + for (ui32 i = 0; i != ExtCount; ++i) { + TEntry& entry = branch->Entries[i]; + if (entry.CounterIn == 0) { + if (zeroEntry && !*zeroEntry) { + *zeroEntry = &entry; + if (oldEntry != nullptr) + return; + } + } else { + if (entry.Key == key) { + oldEntry = &entry; + if (!zeroEntry || *zeroEntry) + return; + } + } + } + + const ui64 hash0 = hash % ExtBranching; + if (TBranch* next = branch->Branches[hash0]) { + ScanZeroOld(next, key, hash / ExtBranching, zeroEntry, oldEntry); + } else { // found tail, if zeroEntry requested, but not yet found - insert one + if (zeroEntry && !*zeroEntry) { + TBranch* next = new TBranch(); + *zeroEntry = next->Entries; + AtomicStore(branch->Branches + hash0, next); + } + } + } + + public: + TServiceMap() + : Counter(0) + { + Fill(Line, Line + BaseSize, (TBranch*)nullptr); + } + + ~TServiceMap() { + for (ui64 i = 0; i < BaseSize; ++i) { + delete Line[i]; + } + } + + TValue Find(const TKey& key) { + THash hashOp; + const ui64 hash = hashOp(key); + const ui64 hash0 = hash % BaseSize; + + if (TBranch* branch = AtomicLoad(Line + hash0)) { + TValue ret; + if (ScanBranch(branch, key, hash / BaseSize, ret)) + return ret; + } + + return TValue(); + } + + // returns true on update, false on insert + TValue Update(const TKey& key, const TValue& value) { + THash hashOp; + const ui64 hash = hashOp(key); + const ui64 hash0 = hash % BaseSize; + + TEntry* zeroEntry = nullptr; + TEntry* oldEntry = nullptr; + + if (TBranch* branch = Line[hash0]) { + ScanZeroOld(branch, key, hash / BaseSize, &zeroEntry, oldEntry); + } else { + TBranch* next = new TBranch(); + zeroEntry = next->Entries; + AtomicStore(Line + hash0, next); + } + + // now we got both entries, first - push new one + const ui32 counter = AtomicUi32Increment(&Counter); + AtomicStore(&zeroEntry->CounterOut, counter); + zeroEntry->Key = key; + zeroEntry->Value = value; + AtomicStore(&zeroEntry->CounterIn, counter); + + if (oldEntry != nullptr) { + const TValue ret = oldEntry->Value; + AtomicStore<ui32>(&oldEntry->CounterOut, 0); + AtomicStore<ui32>(&oldEntry->CounterIn, 0); + return ret; + } else { + return TValue(); + } + } + + bool Erase(const TKey& key) { + THash hashOp; + const ui64 hash = hashOp(key); + const ui64 hash0 = hash % BaseSize; + + TEntry* oldEntry = 0; + + if (TBranch* branch = Line[hash0]) { + ScanZeroOld(branch, key, hash / BaseSize, 0, oldEntry); + } + + if (oldEntry != 0) { + AtomicStore<ui32>(&oldEntry->CounterOut, 0); + AtomicStore<ui32>(&oldEntry->CounterIn, 0); + return true; + } else { + return false; + } + } + }; +} diff --git a/library/cpp/actors/core/ya.make b/library/cpp/actors/core/ya.make index fef4811b53..880a9d00db 100644 --- a/library/cpp/actors/core/ya.make +++ b/library/cpp/actors/core/ya.make @@ -1,10 +1,10 @@ -LIBRARY() - +LIBRARY() + OWNER( ddoarn g:kikimr ) - + NO_WSHADOW() IF (PROFILE_MEMORY_ALLOCATIONS) @@ -18,16 +18,16 @@ IF (ALLOCATOR == "B" OR ALLOCATOR == "BS" OR ALLOCATOR == "C") ) ENDIF() -SRCS( - actor_bootstrapped.h +SRCS( + actor_bootstrapped.h actor_coroutine.cpp actor_coroutine.h actor.cpp actor.h actorid.cpp - actorid.h + actorid.h actorsystem.cpp - actorsystem.h + actorsystem.h ask.cpp ask.h balancer.h @@ -40,29 +40,29 @@ SRCS( cpu_manager.cpp cpu_manager.h cpu_state.h - defs.h + defs.h event.cpp - event.h + event.h event_load.h event_local.h event_pb.cpp - event_pb.h - events.h - events_undelivered.cpp + event_pb.h + events.h + events_undelivered.cpp executelater.h - executor_pool_base.cpp - executor_pool_base.h - executor_pool_basic.cpp - executor_pool_basic.h - executor_pool_io.cpp - executor_pool_io.h + executor_pool_base.cpp + executor_pool_base.h + executor_pool_basic.cpp + executor_pool_basic.h + executor_pool_io.cpp + executor_pool_io.h executor_pool_united.cpp executor_pool_united.h - executor_thread.cpp - executor_thread.h - hfunc.h + executor_thread.cpp + executor_thread.h + hfunc.h interconnect.cpp - interconnect.h + interconnect.h invoke.h io_dispatcher.cpp io_dispatcher.h @@ -72,9 +72,9 @@ SRCS( log_settings.cpp log_settings.h mailbox.cpp - mailbox.h - mailbox_queue_revolving.h - mailbox_queue_simple.h + mailbox.h + mailbox_queue_revolving.h + mailbox_queue_simple.h memory_track.cpp memory_track.h memory_tracker.cpp @@ -91,18 +91,18 @@ SRCS( process_stats.h scheduler_actor.cpp scheduler_actor.h - scheduler_basic.cpp - scheduler_basic.h - scheduler_cookie.cpp - scheduler_cookie.h - scheduler_queue.h - servicemap.h -) - + scheduler_basic.cpp + scheduler_basic.h + scheduler_cookie.cpp + scheduler_cookie.h + scheduler_queue.h + servicemap.h +) + GENERATE_ENUM_SERIALIZATION(defs.h) GENERATE_ENUM_SERIALIZATION(actor.h) -PEERDIR( +PEERDIR( library/cpp/actors/memory_log library/cpp/actors/prof library/cpp/actors/protos @@ -114,9 +114,9 @@ PEERDIR( library/cpp/monlib/dynamic_counters library/cpp/svnversion library/cpp/threading/future -) - -END() +) + +END() RECURSE_FOR_TESTS( ut diff --git a/library/cpp/actors/dnscachelib/dnscache.cpp b/library/cpp/actors/dnscachelib/dnscache.cpp index 4114b8023e..649339ddb2 100644 --- a/library/cpp/actors/dnscachelib/dnscache.cpp +++ b/library/cpp/actors/dnscachelib/dnscache.cpp @@ -12,7 +12,7 @@ LWTRACE_USING(DNSCACHELIB_PROVIDER); static_assert(sizeof(ares_channel) == sizeof(void*), "expect sizeof(ares_channel) == sizeof(void *)"); -TDnsCache::TDnsCache(bool allowIpv4, bool allowIpv6, time_t lifetime, time_t neg, ui32 timeout) +TDnsCache::TDnsCache(bool allowIpv4, bool allowIpv6, time_t lifetime, time_t neg, ui32 timeout) : EntryLifetime(lifetime) , NegativeLifetime(neg) , Timeout(TDuration::MicroSeconds(timeout)) @@ -24,12 +24,12 @@ TDnsCache::TDnsCache(bool allowIpv4, bool allowIpv6, time_t lifetime, time_t neg , PtrCacheMisses(0) { #ifdef _win_ - if (ares_library_init(ARES_LIB_INIT_WIN32) != ARES_SUCCESS) { - LWPROBE(AresInitFailed); - ythrow yexception() << "ares_init() failed"; - } + if (ares_library_init(ARES_LIB_INIT_WIN32) != ARES_SUCCESS) { + LWPROBE(AresInitFailed); + ythrow yexception() << "ares_init() failed"; + } #endif - + ares_channel chan; if (ares_init(&chan) != ARES_SUCCESS) { @@ -46,9 +46,9 @@ TDnsCache::~TDnsCache(void) { ares_cancel(chan); ares_destroy(chan); LWPROBE(Destroyed); - + #ifdef _win_ - ares_library_cleanup(); + ares_library_cleanup(); #endif } diff --git a/library/cpp/actors/dnscachelib/dnscache.h b/library/cpp/actors/dnscachelib/dnscache.h index 2c7686cec5..3313a251a1 100644 --- a/library/cpp/actors/dnscachelib/dnscache.h +++ b/library/cpp/actors/dnscachelib/dnscache.h @@ -15,17 +15,17 @@ * 3) most of the time IP addresses do not change * 4) it's OK to return old IP address when DNS server not responding in time */ - + class TDnsCache { public: - TDnsCache(bool allowIpv4 = true, bool allowIpv6 = true, time_t entry_lifetime = 1800, time_t neg_lifetime = 1, ui32 request_timeout = 500000); + TDnsCache(bool allowIpv4 = true, bool allowIpv6 = true, time_t entry_lifetime = 1800, time_t neg_lifetime = 1, ui32 request_timeout = 500000); ~TDnsCache(); TString GetHostByAddr(const NAddr::IRemoteAddr&); // ip in network byte order TIpHost Get(const TString& host); - + /* use with AF_INET, AF_INET6 or AF_UNSPEC */ NAddr::IRemoteAddrPtr GetAddr(const TString& host, int family, @@ -113,8 +113,8 @@ private: const time_t EntryLifetime; const time_t NegativeLifetime; const TDuration Timeout; - const bool AllowIpV4; - const bool AllowIpV6; + const bool AllowIpV4; + const bool AllowIpV6; TMutex CacheMtx; THostCache HostCache; diff --git a/library/cpp/actors/helpers/flow_controlled_queue.cpp b/library/cpp/actors/helpers/flow_controlled_queue.cpp index 81d26c3e55..d75cc54023 100644 --- a/library/cpp/actors/helpers/flow_controlled_queue.cpp +++ b/library/cpp/actors/helpers/flow_controlled_queue.cpp @@ -1,215 +1,215 @@ -#include "flow_controlled_queue.h" - +#include "flow_controlled_queue.h" + #include <library/cpp/actors/core/interconnect.h> #include <library/cpp/actors/core/hfunc.h> #include <library/cpp/actors/util/datetime.h> - -#include <util/generic/deque.h> -#include <util/datetime/cputimer.h> -#include <util/generic/algorithm.h> - -namespace NActors { - -class TFlowControlledRequestQueue; - -class TFlowControlledRequestActor : public IActor { - TFlowControlledRequestQueue * const QueueActor; - - void HandleReply(TAutoPtr<IEventHandle> &ev); - void HandleUndelivered(TEvents::TEvUndelivered::TPtr &ev); -public: + +#include <util/generic/deque.h> +#include <util/datetime/cputimer.h> +#include <util/generic/algorithm.h> + +namespace NActors { + +class TFlowControlledRequestQueue; + +class TFlowControlledRequestActor : public IActor { + TFlowControlledRequestQueue * const QueueActor; + + void HandleReply(TAutoPtr<IEventHandle> &ev); + void HandleUndelivered(TEvents::TEvUndelivered::TPtr &ev); +public: const TActorId Source; - const ui64 Cookie; - const ui32 Flags; - const ui64 StartCounter; - + const ui64 Cookie; + const ui32 Flags; + const ui64 StartCounter; + TFlowControlledRequestActor(ui32 activity, TFlowControlledRequestQueue *queue, TActorId source, ui64 cookie, ui32 flags) - : IActor(static_cast<TReceiveFunc>(&TFlowControlledRequestActor::StateWait), activity) - , QueueActor(queue) - , Source(source) - , Cookie(cookie) - , Flags(flags) + : IActor(static_cast<TReceiveFunc>(&TFlowControlledRequestActor::StateWait), activity) + , QueueActor(queue) + , Source(source) + , Cookie(cookie) + , Flags(flags) , StartCounter(GetCycleCountFast()) - {} - - STATEFN(StateWait) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvents::TEvUndelivered, HandleUndelivered); - default: - HandleReply(ev); - } - } - - TDuration AccumulatedLatency() const { + {} + + STATEFN(StateWait) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvents::TEvUndelivered, HandleUndelivered); + default: + HandleReply(ev); + } + } + + TDuration AccumulatedLatency() const { const ui64 cc = GetCycleCountFast() - StartCounter; - return CyclesToDuration(cc); - } - - using IActor::PassAway; -}; - -class TFlowControlledRequestQueue : public IActor { + return CyclesToDuration(cc); + } + + using IActor::PassAway; +}; + +class TFlowControlledRequestQueue : public IActor { const TActorId Target; - const TFlowControlledQueueConfig Config; - - TDeque<THolder<IEventHandle>> UnhandledRequests; - TDeque<TFlowControlledRequestActor *> RegisteredRequests; - - bool Subscribed = false; - - TDuration MinimalSeenLatency; - - bool CanRegister() { - const ui64 inFly = RegisteredRequests.size(); - if (inFly <= Config.MinAllowedInFly) // <= for handling minAllowed == 0 - return true; - - if (inFly >= Config.MaxAllowedInFly) - return false; - - if (Config.TargetDynamicRate) { - if (const ui64 dynMax = MinimalSeenLatency.MicroSeconds() * Config.TargetDynamicRate / 1000000) { - if (inFly >= dynMax) - return false; - } - } - - const TDuration currentLatency = RegisteredRequests.front()->AccumulatedLatency(); - if (currentLatency <= Config.MinTrackedLatency) - return true; - - if (currentLatency <= MinimalSeenLatency * Config.LatencyFactor) - return true; - - return false; - } - - void HandleForwardedEvent(TAutoPtr<IEventHandle> &ev) { - if (CanRegister()) { - RegisterReqActor(ev); - } else { - UnhandledRequests.emplace_back(ev.Release()); - } - } - - void RegisterReqActor(THolder<IEventHandle> ev) { - TFlowControlledRequestActor *reqActor = new TFlowControlledRequestActor(ActivityType, this, ev->Sender, ev->Cookie, ev->Flags); + const TFlowControlledQueueConfig Config; + + TDeque<THolder<IEventHandle>> UnhandledRequests; + TDeque<TFlowControlledRequestActor *> RegisteredRequests; + + bool Subscribed = false; + + TDuration MinimalSeenLatency; + + bool CanRegister() { + const ui64 inFly = RegisteredRequests.size(); + if (inFly <= Config.MinAllowedInFly) // <= for handling minAllowed == 0 + return true; + + if (inFly >= Config.MaxAllowedInFly) + return false; + + if (Config.TargetDynamicRate) { + if (const ui64 dynMax = MinimalSeenLatency.MicroSeconds() * Config.TargetDynamicRate / 1000000) { + if (inFly >= dynMax) + return false; + } + } + + const TDuration currentLatency = RegisteredRequests.front()->AccumulatedLatency(); + if (currentLatency <= Config.MinTrackedLatency) + return true; + + if (currentLatency <= MinimalSeenLatency * Config.LatencyFactor) + return true; + + return false; + } + + void HandleForwardedEvent(TAutoPtr<IEventHandle> &ev) { + if (CanRegister()) { + RegisterReqActor(ev); + } else { + UnhandledRequests.emplace_back(ev.Release()); + } + } + + void RegisterReqActor(THolder<IEventHandle> ev) { + TFlowControlledRequestActor *reqActor = new TFlowControlledRequestActor(ActivityType, this, ev->Sender, ev->Cookie, ev->Flags); const TActorId reqActorId = RegisterWithSameMailbox(reqActor); - RegisteredRequests.emplace_back(reqActor); - - if (!Subscribed && (Target.NodeId() != SelfId().NodeId())) { - Send(TActivationContext::InterconnectProxy(Target.NodeId()), new TEvents::TEvSubscribe(), IEventHandle::FlagTrackDelivery); - Subscribed = true; - } - - TActivationContext::Send(new IEventHandle(Target, reqActorId, ev->ReleaseBase().Release(), IEventHandle::FlagTrackDelivery, ev->Cookie)); - } - - void PumpQueue() { - while (RegisteredRequests && RegisteredRequests.front() == nullptr) - RegisteredRequests.pop_front(); - - while (UnhandledRequests && CanRegister()) { - RegisterReqActor(std::move(UnhandledRequests.front())); - UnhandledRequests.pop_front(); - } - } - - void HandleDisconnected() { - Subscribed = false; - - const ui32 nodeid = Target.NodeId(); - for (TFlowControlledRequestActor *reqActor : RegisteredRequests) { - if (reqActor) { - if (reqActor->Flags & IEventHandle::FlagSubscribeOnSession) { - TActivationContext::Send( + RegisteredRequests.emplace_back(reqActor); + + if (!Subscribed && (Target.NodeId() != SelfId().NodeId())) { + Send(TActivationContext::InterconnectProxy(Target.NodeId()), new TEvents::TEvSubscribe(), IEventHandle::FlagTrackDelivery); + Subscribed = true; + } + + TActivationContext::Send(new IEventHandle(Target, reqActorId, ev->ReleaseBase().Release(), IEventHandle::FlagTrackDelivery, ev->Cookie)); + } + + void PumpQueue() { + while (RegisteredRequests && RegisteredRequests.front() == nullptr) + RegisteredRequests.pop_front(); + + while (UnhandledRequests && CanRegister()) { + RegisterReqActor(std::move(UnhandledRequests.front())); + UnhandledRequests.pop_front(); + } + } + + void HandleDisconnected() { + Subscribed = false; + + const ui32 nodeid = Target.NodeId(); + for (TFlowControlledRequestActor *reqActor : RegisteredRequests) { + if (reqActor) { + if (reqActor->Flags & IEventHandle::FlagSubscribeOnSession) { + TActivationContext::Send( new IEventHandle(reqActor->Source, TActorId(), new TEvInterconnect::TEvNodeDisconnected(nodeid), 0, reqActor->Cookie) - ); - } - reqActor->PassAway(); - } - } - - RegisteredRequests.clear(); - - for (auto &ev : UnhandledRequests) { - const auto reason = TEvents::TEvUndelivered::Disconnected; - if (ev->Flags & IEventHandle::FlagTrackDelivery) { - TActivationContext::Send( - new IEventHandle(ev->Sender, ev->Recipient, new TEvents::TEvUndelivered(ev->GetTypeRewrite(), reason), 0, ev->Cookie) - ); - } - } - - UnhandledRequests.clear(); - } - - void HandlePoison() { - HandleDisconnected(); - - if (SelfId().NodeId() != Target.NodeId()) - Send(TActivationContext::InterconnectProxy(Target.NodeId()), new TEvents::TEvUnsubscribe()); - - PassAway(); - } -public: + ); + } + reqActor->PassAway(); + } + } + + RegisteredRequests.clear(); + + for (auto &ev : UnhandledRequests) { + const auto reason = TEvents::TEvUndelivered::Disconnected; + if (ev->Flags & IEventHandle::FlagTrackDelivery) { + TActivationContext::Send( + new IEventHandle(ev->Sender, ev->Recipient, new TEvents::TEvUndelivered(ev->GetTypeRewrite(), reason), 0, ev->Cookie) + ); + } + } + + UnhandledRequests.clear(); + } + + void HandlePoison() { + HandleDisconnected(); + + if (SelfId().NodeId() != Target.NodeId()) + Send(TActivationContext::InterconnectProxy(Target.NodeId()), new TEvents::TEvUnsubscribe()); + + PassAway(); + } +public: TFlowControlledRequestQueue(TActorId target, ui32 activity, const TFlowControlledQueueConfig &config) - : IActor(static_cast<TReceiveFunc>(&TFlowControlledRequestQueue::StateWork), activity) - , Target(target) - , Config(config) - , MinimalSeenLatency(TDuration::Seconds(1)) - {} - - STATEFN(StateWork) { - switch (ev->GetTypeRewrite()) { - cFunc(TEvInterconnect::TEvNodeDisconnected::EventType, HandleDisconnected); - IgnoreFunc(TEvInterconnect::TEvNodeConnected); - cFunc(TEvents::TEvUndelivered::EventType, HandleDisconnected); - cFunc(TEvents::TEvPoison::EventType, HandlePoison); - default: - HandleForwardedEvent(ev); - } - } - - void HandleRequestReply(TAutoPtr<IEventHandle> &ev, TFlowControlledRequestActor *reqActor) { - auto it = Find(RegisteredRequests, reqActor); - if (it == RegisteredRequests.end()) - return; - - TActivationContext::Send(ev->Forward(reqActor->Source)); - const TDuration reqLatency = reqActor->AccumulatedLatency(); - if (reqLatency < MinimalSeenLatency) - MinimalSeenLatency = reqLatency; - - *it = nullptr; - PumpQueue(); - } - - void HandleRequestUndelivered(TEvents::TEvUndelivered::TPtr &ev, TFlowControlledRequestActor *reqActor) { - auto it = Find(RegisteredRequests, reqActor); - if (it == RegisteredRequests.end()) - return; - - TActivationContext::Send(ev->Forward(reqActor->Source)); - - *it = nullptr; - PumpQueue(); - } -}; - -void TFlowControlledRequestActor::HandleReply(TAutoPtr<IEventHandle> &ev) { - QueueActor->HandleRequestReply(ev, this); - PassAway(); -} - -void TFlowControlledRequestActor::HandleUndelivered(TEvents::TEvUndelivered::TPtr &ev) { - QueueActor->HandleRequestUndelivered(ev, this); - PassAway(); -} - - + : IActor(static_cast<TReceiveFunc>(&TFlowControlledRequestQueue::StateWork), activity) + , Target(target) + , Config(config) + , MinimalSeenLatency(TDuration::Seconds(1)) + {} + + STATEFN(StateWork) { + switch (ev->GetTypeRewrite()) { + cFunc(TEvInterconnect::TEvNodeDisconnected::EventType, HandleDisconnected); + IgnoreFunc(TEvInterconnect::TEvNodeConnected); + cFunc(TEvents::TEvUndelivered::EventType, HandleDisconnected); + cFunc(TEvents::TEvPoison::EventType, HandlePoison); + default: + HandleForwardedEvent(ev); + } + } + + void HandleRequestReply(TAutoPtr<IEventHandle> &ev, TFlowControlledRequestActor *reqActor) { + auto it = Find(RegisteredRequests, reqActor); + if (it == RegisteredRequests.end()) + return; + + TActivationContext::Send(ev->Forward(reqActor->Source)); + const TDuration reqLatency = reqActor->AccumulatedLatency(); + if (reqLatency < MinimalSeenLatency) + MinimalSeenLatency = reqLatency; + + *it = nullptr; + PumpQueue(); + } + + void HandleRequestUndelivered(TEvents::TEvUndelivered::TPtr &ev, TFlowControlledRequestActor *reqActor) { + auto it = Find(RegisteredRequests, reqActor); + if (it == RegisteredRequests.end()) + return; + + TActivationContext::Send(ev->Forward(reqActor->Source)); + + *it = nullptr; + PumpQueue(); + } +}; + +void TFlowControlledRequestActor::HandleReply(TAutoPtr<IEventHandle> &ev) { + QueueActor->HandleRequestReply(ev, this); + PassAway(); +} + +void TFlowControlledRequestActor::HandleUndelivered(TEvents::TEvUndelivered::TPtr &ev) { + QueueActor->HandleRequestUndelivered(ev, this); + PassAway(); +} + + IActor* CreateFlowControlledRequestQueue(TActorId targetId, ui32 activity, const TFlowControlledQueueConfig &config) { - return new TFlowControlledRequestQueue(targetId, activity, config); -} - -} + return new TFlowControlledRequestQueue(targetId, activity, config); +} + +} diff --git a/library/cpp/actors/helpers/flow_controlled_queue.h b/library/cpp/actors/helpers/flow_controlled_queue.h index 0699b35ca6..d250405304 100644 --- a/library/cpp/actors/helpers/flow_controlled_queue.h +++ b/library/cpp/actors/helpers/flow_controlled_queue.h @@ -1,18 +1,18 @@ -#pragma once - +#pragma once + #include <library/cpp/actors/core/actor.h> - -namespace NActors { - - struct TFlowControlledQueueConfig { - ui32 MinAllowedInFly = 20; - ui32 MaxAllowedInFly = 100; - ui32 TargetDynamicRate = 0; - - TDuration MinTrackedLatency = TDuration::MilliSeconds(20); - ui32 LatencyFactor = 4; - }; - + +namespace NActors { + + struct TFlowControlledQueueConfig { + ui32 MinAllowedInFly = 20; + ui32 MaxAllowedInFly = 100; + ui32 TargetDynamicRate = 0; + + TDuration MinTrackedLatency = TDuration::MilliSeconds(20); + ui32 LatencyFactor = 4; + }; + IActor* CreateFlowControlledRequestQueue(TActorId targetId, ui32 activity = IActor::ACTORLIB_COMMON, const TFlowControlledQueueConfig &config = TFlowControlledQueueConfig()); - -} + +} diff --git a/library/cpp/actors/helpers/mon_histogram_helper.h b/library/cpp/actors/helpers/mon_histogram_helper.h index 35d030b822..a9a57e3823 100644 --- a/library/cpp/actors/helpers/mon_histogram_helper.h +++ b/library/cpp/actors/helpers/mon_histogram_helper.h @@ -1,10 +1,10 @@ -#pragma once - +#pragma once + #include <library/cpp/monlib/dynamic_counters/counters.h> #include <util/string/cast.h> -namespace NActors { +namespace NActors { namespace NMon { class THistogramCounterHelper { public: @@ -13,7 +13,7 @@ namespace NActors { , BucketCount(0) { } - + THistogramCounterHelper(const THistogramCounterHelper&) = default; void Init(NMonitoring::TDynamicCounters* group, const TString& baseName, const TString& unit, @@ -21,7 +21,7 @@ namespace NActors { { Y_ASSERT(FirstBucketVal == 0); Y_ASSERT(BucketCount == 0); - + FirstBucketVal = firstBucket; BucketCount = bucketCnt; BucketsHolder.reserve(BucketCount); @@ -33,7 +33,7 @@ namespace NActors { Buckets.push_back(BucketsHolder.back().Get()); } } - + void Add(ui64 val) { Y_ASSERT(FirstBucketVal != 0); Y_ASSERT(BucketCount != 0); @@ -47,7 +47,7 @@ namespace NActors { } Buckets[ind]->Inc(); } - + ui64 GetBucketCount() const { return BucketCount; } @@ -73,8 +73,8 @@ namespace NActors { // Last slot is up to +INF return "INF"; } - } - + } + private: ui64 FirstBucketVal; ui64 BucketCount; @@ -82,5 +82,5 @@ namespace NActors { TVector<NMonitoring::TDeprecatedCounter*> Buckets; }; - } + } } diff --git a/library/cpp/actors/helpers/ya.make b/library/cpp/actors/helpers/ya.make index b6cce2cc23..d8771179de 100644 --- a/library/cpp/actors/helpers/ya.make +++ b/library/cpp/actors/helpers/ya.make @@ -1,23 +1,23 @@ -LIBRARY() - +LIBRARY() + OWNER(g:kikimr) - -SRCS( + +SRCS( activeactors.cpp activeactors.h - flow_controlled_queue.cpp - flow_controlled_queue.h + flow_controlled_queue.cpp + flow_controlled_queue.h future_callback.h mon_histogram_helper.h selfping_actor.cpp -) - -PEERDIR( +) + +PEERDIR( library/cpp/actors/core library/cpp/monlib/dynamic_counters -) - -END() +) + +END() RECURSE_FOR_TESTS( ut diff --git a/library/cpp/actors/interconnect/interconnect_mon.cpp b/library/cpp/actors/interconnect/interconnect_mon.cpp index 75104af8de..cf924ccbf9 100644 --- a/library/cpp/actors/interconnect/interconnect_mon.cpp +++ b/library/cpp/actors/interconnect/interconnect_mon.cpp @@ -20,10 +20,10 @@ namespace NInterconnect { ui32 PendingReplies = 0; public: - static constexpr IActor::EActorActivity ActorActivityType() { - return INTERCONNECT_MONACTOR; - } - + static constexpr IActor::EActorActivity ActorActivityType() { + return INTERCONNECT_MONACTOR; + } + TQueryProcessor(const TActorId& sender, bool json) : Sender(sender) , Json(json) @@ -186,10 +186,10 @@ namespace NInterconnect { TIntrusivePtr<TInterconnectProxyCommon> Common; public: - static constexpr IActor::EActorActivity ActorActivityType() { - return INTERCONNECT_MONACTOR; - } - + static constexpr IActor::EActorActivity ActorActivityType() { + return INTERCONNECT_MONACTOR; + } + TInterconnectMonActor(TIntrusivePtr<TInterconnectProxyCommon> common) : TActor(&TThis::StateFunc) , Common(std::move(common)) diff --git a/library/cpp/actors/interconnect/slowpoke_actor.h b/library/cpp/actors/interconnect/slowpoke_actor.h index 00eb020b07..4b02e5da48 100644 --- a/library/cpp/actors/interconnect/slowpoke_actor.h +++ b/library/cpp/actors/interconnect/slowpoke_actor.h @@ -12,10 +12,10 @@ namespace NActors { const TDuration RescheduleMax; public: - static constexpr NKikimrServices::TActivity::EType ActorActivityType() { - return NKikimrServices::TActivity::INTERCONNECT_COMMON; - } - + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { + return NKikimrServices::TActivity::INTERCONNECT_COMMON; + } + TSlowpokeActor(TDuration duration, TDuration sleepMin, TDuration sleepMax, TDuration rescheduleMin, TDuration rescheduleMax) : Duration(duration) , SleepMin(sleepMin) diff --git a/library/cpp/actors/memory_log/memlog.cpp b/library/cpp/actors/memory_log/memlog.cpp index 9cd7dee0fe..8e6b46727d 100644 --- a/library/cpp/actors/memory_log/memlog.cpp +++ b/library/cpp/actors/memory_log/memlog.cpp @@ -15,11 +15,11 @@ static int (*FastGetCpu)(unsigned* cpu, unsigned* node, void* unused); #endif #if defined(_unix_) -#include <sched.h> +#include <sched.h> #elif defined(_win_) -#include <WinBase.h> +#include <WinBase.h> #else -#error NO IMPLEMENTATION FOR THE PLATFORM +#error NO IMPLEMENTATION FOR THE PLATFORM #endif const char TMemoryLog::DEFAULT_LAST_MARK[16] = { @@ -62,34 +62,34 @@ const char TMemoryLog::CLEAR_MARK[16] = { unsigned TMemoryLog::GetSelfCpu() noexcept { #if defined(_unix_) -#if HAVE_VDSO_GETCPU +#if HAVE_VDSO_GETCPU unsigned cpu; if (Y_LIKELY(FastGetCpu != nullptr)) { auto result = FastGetCpu(&cpu, nullptr, nullptr); Y_VERIFY(result == 0); - return cpu; + return cpu; } else { return 0; } -#elif defined(_x86_64_) || defined(_i386_) +#elif defined(_x86_64_) || defined(_i386_) -#define CPUID(func, eax, ebx, ecx, edx) \ - __asm__ __volatile__( \ - "cpuid" \ - : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) \ - : "a"(func)); +#define CPUID(func, eax, ebx, ecx, edx) \ + __asm__ __volatile__( \ + "cpuid" \ + : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) \ + : "a"(func)); int a = 0, b = 0, c = 0, d = 0; CPUID(0x1, a, b, c, d); int acpiID = (b >> 24); return acpiID; -#elif defined(__CNUC__) +#elif defined(__CNUC__) return sched_getcpu(); -#else +#else return 0; -#endif +#endif #elif defined(_win_) return GetCurrentProcessorNumber(); @@ -99,16 +99,16 @@ unsigned TMemoryLog::GetSelfCpu() noexcept { } TMemoryLog* TMemoryLog::MemLogBuffer = nullptr; -Y_POD_THREAD(TThread::TId) -TMemoryLog::LogThreadId; +Y_POD_THREAD(TThread::TId) +TMemoryLog::LogThreadId; char* TMemoryLog::LastMarkIsHere = nullptr; std::atomic<bool> TMemoryLog::PrintLastMark(true); TMemoryLog::TMemoryLog(size_t totalSize, size_t grainSize) - : GrainSize(grainSize) - , FreeGrains(DEFAULT_TOTAL_SIZE / DEFAULT_GRAIN_SIZE * 2) - , Buf(totalSize) + : GrainSize(grainSize) + , FreeGrains(DEFAULT_TOTAL_SIZE / DEFAULT_GRAIN_SIZE * 2) + , Buf(totalSize) { Y_VERIFY(DEFAULT_TOTAL_SIZE % DEFAULT_GRAIN_SIZE == 0); NumberOfGrains = DEFAULT_TOTAL_SIZE / DEFAULT_GRAIN_SIZE; @@ -266,7 +266,7 @@ bool MemLogWrite(const char* begin, size_t msgSize, bool addLF) noexcept { // alignment required by NoCacheMemcpy // check for format for snprintf constexpr size_t prologSize = 48; - alignas(TMemoryLog::MemcpyAlignment) char prolog[prologSize + 1]; + alignas(TMemoryLog::MemcpyAlignment) char prolog[prologSize + 1]; Y_VERIFY(AlignDown(&prolog, TMemoryLog::MemcpyAlignment) == &prolog); int snprintfResult = snprintf(prolog, prologSize + 1, @@ -291,7 +291,7 @@ bool MemLogWrite(const char* begin, size_t msgSize, bool addLF) noexcept { // warning: copy prolog first to avoid corruption of the message // by prolog tail NoCacheMemcpy(buffer, prolog, prologSize); - if (AlignDown(begin + prologSize, TMemoryLog::MemcpyAlignment) == begin + prologSize) { + if (AlignDown(begin + prologSize, TMemoryLog::MemcpyAlignment) == begin + prologSize) { NoCacheMemcpy(buffer + prologSize, begin, msgSize); } else { NoWCacheMemcpy(buffer + prologSize, begin, msgSize); @@ -335,14 +335,14 @@ bool MemLogVPrintF(const char* format, va_list params) noexcept { auto threadId = TMemoryLog::GetTheadId(); // alignment required by NoCacheMemcpy - alignas(TMemoryLog::MemcpyAlignment) char buf[TMemoryLog::MAX_MESSAGE_SIZE]; + alignas(TMemoryLog::MemcpyAlignment) char buf[TMemoryLog::MAX_MESSAGE_SIZE]; Y_VERIFY(AlignDown(&buf, TMemoryLog::MemcpyAlignment) == &buf); int prologSize = snprintf(buf, - TMemoryLog::MAX_MESSAGE_SIZE - 2, - "TS %020" PRIu64 " TI %020" PRIu64 " ", + TMemoryLog::MAX_MESSAGE_SIZE - 2, + "TS %020" PRIu64 " TI %020" PRIu64 " ", GetCycleCountFast(), - threadId); + threadId); if (Y_UNLIKELY(prologSize < 0)) { return false; diff --git a/library/cpp/actors/memory_log/memlog.h b/library/cpp/actors/memory_log/memlog.h index ffeb1c308d..2aa27272a6 100644 --- a/library/cpp/actors/memory_log/memlog.h +++ b/library/cpp/actors/memory_log/memlog.h @@ -18,14 +18,14 @@ #endif #ifndef NO_SANITIZE_THREAD -#define NO_SANITIZE_THREAD -#if defined(__has_feature) -#if __has_feature(thread_sanitizer) -#undef NO_SANITIZE_THREAD -#define NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) +#define NO_SANITIZE_THREAD +#if defined(__has_feature) +#if __has_feature(thread_sanitizer) +#undef NO_SANITIZE_THREAD +#define NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) +#endif +#endif #endif -#endif -#endif class TMemoryLog { public: @@ -60,8 +60,8 @@ public: } inline static void CreateMemoryLogBuffer( - size_t totalSize = DEFAULT_TOTAL_SIZE, - size_t grainSize = DEFAULT_GRAIN_SIZE) + size_t totalSize = DEFAULT_TOTAL_SIZE, + size_t grainSize = DEFAULT_GRAIN_SIZE) Y_COLD { if (AtomicGet(MemLogBuffer) != nullptr) { return; @@ -193,11 +193,11 @@ bool MemLogWriteStruct(const TObj* obj) noexcept { return MemLogWrite(begin, begin + sizeof(TObj)); } -Y_PRINTF_FORMAT(1, 0) +Y_PRINTF_FORMAT(1, 0) bool MemLogVPrintF(const char* format, va_list params) noexcept; -Y_PRINTF_FORMAT(1, 2) -Y_WRAPPER +Y_PRINTF_FORMAT(1, 2) +Y_WRAPPER inline bool MemLogPrintF(const char* format, ...) noexcept { va_list params; va_start(params, format); diff --git a/library/cpp/actors/memory_log/mmap.cpp b/library/cpp/actors/memory_log/mmap.cpp index 67dfd9a16f..201998d343 100644 --- a/library/cpp/actors/memory_log/mmap.cpp +++ b/library/cpp/actors/memory_log/mmap.cpp @@ -1,11 +1,11 @@ #include "memlog.h" -#if defined(_unix_) -#include <sys/mman.h> -#elif defined(_win_) -#include <util/system/winint.h> +#if defined(_unix_) +#include <sys/mman.h> +#elif defined(_win_) +#include <util/system/winint.h> #else -#error NO IMPLEMENTATION FOR THE PLATFORM +#error NO IMPLEMENTATION FOR THE PLATFORM #endif void TMemoryLog::TMMapArea::MMap(size_t amount) { @@ -44,7 +44,7 @@ void TMemoryLog::TMMapArea::MUnmap() { return; } -#if defined(_unix_) +#if defined(_unix_) int result = ::munmap(BufPtr, Size); Y_VERIFY(result == 0); diff --git a/library/cpp/actors/prof/tag.cpp b/library/cpp/actors/prof/tag.cpp index f97191f94c..9ccf03e1a9 100644 --- a/library/cpp/actors/prof/tag.cpp +++ b/library/cpp/actors/prof/tag.cpp @@ -18,8 +18,8 @@ namespace NProfiling { class TStringAtoms { private: - TMutex Mutex; - atomizer<ci_hash, ci_equal_to> Tags; + TMutex Mutex; + atomizer<ci_hash, ci_equal_to> Tags; public: static TStringAtoms& Instance() { @@ -58,17 +58,17 @@ namespace NProfiling { return Tags.size(); } } - }; + }; - ui32 MakeTag(const char* s) { + ui32 MakeTag(const char* s) { return TStringAtoms::Instance().MakeTag(s); - } + } ui32 MakeTags(const TVector<const char*>& ss) { return TStringAtoms::Instance().MakeTags(ss); - } + } - const char* GetTag(ui32 tag) { + const char* GetTag(ui32 tag) { return TStringAtoms::Instance().GetTag(tag); } diff --git a/library/cpp/actors/prof/tag.h b/library/cpp/actors/prof/tag.h index 7b743ca183..357e264a22 100644 --- a/library/cpp/actors/prof/tag.h +++ b/library/cpp/actors/prof/tag.h @@ -9,65 +9,65 @@ */ namespace NProfiling { - ui32 MakeTag(const char* s); + ui32 MakeTag(const char* s); - // Make only unique tags. Y_VERIFY inside. + // Make only unique tags. Y_VERIFY inside. ui32 MakeTags(const TVector<const char*>& ss); - const char* GetTag(ui32 tag); + const char* GetTag(ui32 tag); size_t GetTagsCount(); using TSetThreadAllocTag = ui32(ui32 tag); extern TSetThreadAllocTag* SetThreadAllocTag; - class TMemoryTagScope { - public: + class TMemoryTagScope { + public: explicit TMemoryTagScope(ui32 tag) : RestoreTag(SetThreadAllocTag(tag)) - { - } + { + } explicit TMemoryTagScope(const char* tagName) { - ui32 newTag = MakeTag(tagName); + ui32 newTag = MakeTag(tagName); RestoreTag = SetThreadAllocTag(newTag); - } + } - TMemoryTagScope(TMemoryTagScope&& move) - : RestoreTag(move.RestoreTag) + TMemoryTagScope(TMemoryTagScope&& move) + : RestoreTag(move.RestoreTag) , Released(move.Released) - { + { move.Released = true; - } + } - TMemoryTagScope& operator=(TMemoryTagScope&& move) { - RestoreTag = move.RestoreTag; + TMemoryTagScope& operator=(TMemoryTagScope&& move) { + RestoreTag = move.RestoreTag; Released = move.Released; move.Released = true; - return *this; - } + return *this; + } static void Reset(ui32 tag) { SetThreadAllocTag(tag); } - void Release() { + void Release() { if (!Released) { SetThreadAllocTag(RestoreTag); Released = true; - } - } + } + } ~TMemoryTagScope() { if (!Released) { SetThreadAllocTag(RestoreTag); } - } - - protected: - TMemoryTagScope(const TMemoryTagScope&) = delete; - void operator=(const TMemoryTagScope&) = delete; - + } + + protected: + TMemoryTagScope(const TMemoryTagScope&) = delete; + void operator=(const TMemoryTagScope&) = delete; + ui32 RestoreTag = 0; bool Released = false; - }; + }; } diff --git a/library/cpp/actors/prof/ut/tag_ut.cpp b/library/cpp/actors/prof/ut/tag_ut.cpp index f40dcc423c..accf3921ab 100644 --- a/library/cpp/actors/prof/ut/tag_ut.cpp +++ b/library/cpp/actors/prof/ut/tag_ut.cpp @@ -15,7 +15,7 @@ private: UNIT_TEST(Test_MakeVector); UNIT_TEST_SUITE_END(); - + public: void Test_MakeTag(); void Test_Make2Tags(); @@ -58,7 +58,7 @@ void TAtomTagsTest::Test_MakeVector() { "vector tag 0", "vector tag 1", "vector tag 3", - "vector tag 4"}; + "vector tag 4"}; ui32 baseTag = MakeTags(strs); UNIT_ASSERT(baseTag != 0); for (ui32 i = 0; i < strs.size(); ++i) { diff --git a/library/cpp/actors/protos/services_common.proto b/library/cpp/actors/protos/services_common.proto index f3e8f3794f..afa0ec0073 100644 --- a/library/cpp/actors/protos/services_common.proto +++ b/library/cpp/actors/protos/services_common.proto @@ -13,7 +13,7 @@ enum EServiceCommon { INTERCONNECT_STATUS = 5; INTERCONNECT_NETWORK = 6; INTERCONNECT_SESSION = 7; - HTTP = 8; + HTTP = 8; // This value is reserved boundary. Is must not be aliased with any values // TODO: use reseved values upon protobuf update diff --git a/library/cpp/actors/protos/ya.make b/library/cpp/actors/protos/ya.make index dafcf64f09..3a1488d78e 100644 --- a/library/cpp/actors/protos/ya.make +++ b/library/cpp/actors/protos/ya.make @@ -1,14 +1,14 @@ -PROTO_LIBRARY() - +PROTO_LIBRARY() + OWNER(g:kikimr) - -SRCS( - actors.proto + +SRCS( + actors.proto interconnect.proto services_common.proto unittests.proto -) - +) + EXCLUDE_TAGS(GO_PROTO) -END() +END() diff --git a/library/cpp/actors/testlib/test_runtime.cpp b/library/cpp/actors/testlib/test_runtime.cpp index 5f5fdb1536..6fa25b9965 100644 --- a/library/cpp/actors/testlib/test_runtime.cpp +++ b/library/cpp/actors/testlib/test_runtime.cpp @@ -65,11 +65,11 @@ namespace NActors { if (Poller) Poller->Stop(); - if (MailboxTable) { - for (ui32 round = 0; !MailboxTable->Cleanup(); ++round) - Y_VERIFY(round < 10, "cyclic event/actor spawn while trying to shutdown actorsystem stub"); - } - + if (MailboxTable) { + for (ui32 round = 0; !MailboxTable->Cleanup(); ++round) + Y_VERIFY(round < 10, "cyclic event/actor spawn while trying to shutdown actorsystem stub"); + } + if (ActorSystem) ActorSystem->Stop(); @@ -427,10 +427,10 @@ namespace NActors { void Shutdown() override { } - bool Cleanup() override { - return true; - } - + bool Cleanup() override { + return true; + } + // generic TAffinity* Affinity() const override { Y_FAIL(); @@ -1574,7 +1574,7 @@ namespace NActors { node->ActorToActorId[recipientActor] = ev->GetRecipientRewrite(); TActorContext ctx(*mailbox, *node->ExecutorThread, GetCycleCountFast(), actorId); TActivationContext *prevTlsActivationContext = TlsActivationContext; - TlsActivationContext = &ctx; + TlsActivationContext = &ctx; CurrentRecipient = actorId; { TInverseGuard<TMutex> inverseGuard(Mutex); diff --git a/library/cpp/actors/util/affinity.cpp b/library/cpp/actors/util/affinity.cpp index aab8219d6f..cc1b6e70ec 100644 --- a/library/cpp/actors/util/affinity.cpp +++ b/library/cpp/actors/util/affinity.cpp @@ -1,41 +1,41 @@ -#include "affinity.h" - -#ifdef _linux_ -#include <sched.h> -#endif - -class TAffinity::TImpl { -#ifdef _linux_ - cpu_set_t Mask; -#endif -public: - TImpl() { -#ifdef _linux_ - int ar = sched_getaffinity(0, sizeof(cpu_set_t), &Mask); +#include "affinity.h" + +#ifdef _linux_ +#include <sched.h> +#endif + +class TAffinity::TImpl { +#ifdef _linux_ + cpu_set_t Mask; +#endif +public: + TImpl() { +#ifdef _linux_ + int ar = sched_getaffinity(0, sizeof(cpu_set_t), &Mask); Y_VERIFY_DEBUG(ar == 0); -#endif - } - +#endif + } + explicit TImpl(const ui8* cpus, ui32 size) { -#ifdef _linux_ - CPU_ZERO(&Mask); +#ifdef _linux_ + CPU_ZERO(&Mask); for (ui32 i = 0; i != size; ++i) { if (cpus[i]) { CPU_SET(i, &Mask); } } -#else +#else Y_UNUSED(cpus); Y_UNUSED(size); -#endif - } - - void Set() const { -#ifdef _linux_ - int ar = sched_setaffinity(0, sizeof(cpu_set_t), &Mask); +#endif + } + + void Set() const { +#ifdef _linux_ + int ar = sched_setaffinity(0, sizeof(cpu_set_t), &Mask); Y_VERIFY_DEBUG(ar == 0); -#endif - } +#endif + } operator TCpuMask() const { TCpuMask result; @@ -48,20 +48,20 @@ public: return result; } -}; - -TAffinity::TAffinity() { -} - -TAffinity::~TAffinity() { -} - -TAffinity::TAffinity(const ui8* x, ui32 sz) { +}; + +TAffinity::TAffinity() { +} + +TAffinity::~TAffinity() { +} + +TAffinity::TAffinity(const ui8* x, ui32 sz) { if (x && sz) { - Impl.Reset(new TImpl(x, sz)); + Impl.Reset(new TImpl(x, sz)); } -} - +} + TAffinity::TAffinity(const TCpuMask& mask) { if (!mask.IsEmpty()) { static_assert(sizeof(ui8) == sizeof(mask.Cpus[0])); @@ -71,19 +71,19 @@ TAffinity::TAffinity(const TCpuMask& mask) { } } -void TAffinity::Current() { - Impl.Reset(new TImpl()); -} - -void TAffinity::Set() const { +void TAffinity::Current() { + Impl.Reset(new TImpl()); +} + +void TAffinity::Set() const { if (!!Impl) { - Impl->Set(); + Impl->Set(); } -} - -bool TAffinity::Empty() const { +} + +bool TAffinity::Empty() const { return !Impl; -} +} TAffinity::operator TCpuMask() const { if (!!Impl) { diff --git a/library/cpp/actors/util/affinity.h b/library/cpp/actors/util/affinity.h index 0a20744240..ae106ed180 100644 --- a/library/cpp/actors/util/affinity.h +++ b/library/cpp/actors/util/affinity.h @@ -1,49 +1,49 @@ -#pragma once - -#include "defs.h" +#pragma once + +#include "defs.h" #include "cpumask.h" - + // Platform-specific class to set or get thread affinity -class TAffinity: public TThrRefBase, TNonCopyable { - class TImpl; - THolder<TImpl> Impl; - -public: - TAffinity(); +class TAffinity: public TThrRefBase, TNonCopyable { + class TImpl; + THolder<TImpl> Impl; + +public: + TAffinity(); TAffinity(const ui8* cpus, ui32 size); explicit TAffinity(const TCpuMask& mask); - ~TAffinity(); - - void Current(); - void Set() const; - bool Empty() const; + ~TAffinity(); + + void Current(); + void Set() const; + bool Empty() const; operator TCpuMask() const; -}; - +}; + // Scoped affinity setter -class TAffinityGuard : TNonCopyable { - bool Stacked; - TAffinity OldAffinity; - -public: - TAffinityGuard(const TAffinity* affinity) { +class TAffinityGuard : TNonCopyable { + bool Stacked; + TAffinity OldAffinity; + +public: + TAffinityGuard(const TAffinity* affinity) { Stacked = false; - if (affinity && !affinity->Empty()) { - OldAffinity.Current(); - affinity->Set(); - Stacked = true; - } - } - - ~TAffinityGuard() { - Release(); - } - - void Release() { - if (Stacked) { - OldAffinity.Set(); - Stacked = false; - } - } -}; + if (affinity && !affinity->Empty()) { + OldAffinity.Current(); + affinity->Set(); + Stacked = true; + } + } + + ~TAffinityGuard() { + Release(); + } + + void Release() { + if (Stacked) { + OldAffinity.Set(); + Stacked = false; + } + } +}; diff --git a/library/cpp/actors/util/defs.h b/library/cpp/actors/util/defs.h index b88ce59ec6..5c3b57665b 100644 --- a/library/cpp/actors/util/defs.h +++ b/library/cpp/actors/util/defs.h @@ -1,16 +1,16 @@ -#pragma once - -// unique tag to fix pragma once gcc glueing: ./library/actors/util/defs.h - -#include <util/system/defaults.h> -#include <util/generic/bt_exception.h> -#include <util/generic/noncopyable.h> -#include <util/generic/ptr.h> -#include <util/generic/string.h> -#include <util/generic/yexception.h> -#include <util/system/atomic.h> -#include <util/system/align.h> -#include <util/generic/vector.h> -#include <util/datetime/base.h> -#include <util/generic/ylimits.h> -#include "intrinsics.h" +#pragma once + +// unique tag to fix pragma once gcc glueing: ./library/actors/util/defs.h + +#include <util/system/defaults.h> +#include <util/generic/bt_exception.h> +#include <util/generic/noncopyable.h> +#include <util/generic/ptr.h> +#include <util/generic/string.h> +#include <util/generic/yexception.h> +#include <util/system/atomic.h> +#include <util/system/align.h> +#include <util/generic/vector.h> +#include <util/datetime/base.h> +#include <util/generic/ylimits.h> +#include "intrinsics.h" diff --git a/library/cpp/actors/util/futex.h b/library/cpp/actors/util/futex.h index 9f8a7b53bc..c193f8d128 100644 --- a/library/cpp/actors/util/futex.h +++ b/library/cpp/actors/util/futex.h @@ -1,13 +1,13 @@ -#pragma once - -#ifdef _linux_ - -#include <linux/futex.h> -#include <unistd.h> -#include <sys/syscall.h> - -static long SysFutex(void* addr1, int op, int val1, struct timespec* timeout, void* addr2, int val3) { - return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3); -} - -#endif +#pragma once + +#ifdef _linux_ + +#include <linux/futex.h> +#include <unistd.h> +#include <sys/syscall.h> + +static long SysFutex(void* addr1, int op, int val1, struct timespec* timeout, void* addr2, int val3) { + return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3); +} + +#endif diff --git a/library/cpp/actors/util/intrinsics.h b/library/cpp/actors/util/intrinsics.h index 983bf4788d..df07e36896 100644 --- a/library/cpp/actors/util/intrinsics.h +++ b/library/cpp/actors/util/intrinsics.h @@ -1,97 +1,97 @@ -#pragma once - -#include <util/system/defaults.h> -#include <util/system/atomic.h> -#include <util/system/spinlock.h> - +#pragma once + +#include <util/system/defaults.h> +#include <util/system/atomic.h> +#include <util/system/spinlock.h> + #include <library/cpp/sse/sse.h> // The header chooses appropriate SSE support - -static_assert(sizeof(TAtomic) == 8, "expect sizeof(TAtomic) == 8"); - -// we need explicit 32 bit operations to keep cache-line friendly packs -// so have to define some atomics additionaly to arcadia one -#ifdef _win_ -#pragma intrinsic(_InterlockedCompareExchange) -#pragma intrinsic(_InterlockedExchangeAdd) -#pragma intrinsic(_InterlockedIncrement) -#pragma intrinsic(_InterlockedDecrement) -#endif - -inline bool AtomicUi32Cas(volatile ui32* a, ui32 exchange, ui32 compare) { -#ifdef _win_ - return _InterlockedCompareExchange((volatile long*)a, exchange, compare) == (long)compare; -#else - ui32 expected = compare; - return __atomic_compare_exchange_n(a, &expected, exchange, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); -#endif -} - -inline ui32 AtomicUi32Add(volatile ui32* a, ui32 add) { -#ifdef _win_ - return _InterlockedExchangeAdd((volatile long*)a, add) + add; -#else - return __atomic_add_fetch(a, add, __ATOMIC_SEQ_CST); -#endif -} - -inline ui32 AtomicUi32Sub(volatile ui32* a, ui32 sub) { -#ifdef _win_ - return _InterlockedExchangeAdd((volatile long*)a, -(long)sub) - sub; -#else - return __atomic_sub_fetch(a, sub, __ATOMIC_SEQ_CST); -#endif -} - -inline ui32 AtomicUi32Increment(volatile ui32* a) { -#ifdef _win_ - return _InterlockedIncrement((volatile long*)a); -#else - return __atomic_add_fetch(a, 1, __ATOMIC_SEQ_CST); -#endif -} - -inline ui32 AtomicUi32Decrement(volatile ui32* a) { -#ifdef _win_ - return _InterlockedDecrement((volatile long*)a); -#else - return __atomic_sub_fetch(a, 1, __ATOMIC_SEQ_CST); -#endif -} - -template <typename T> -inline void AtomicStore(volatile T* a, T x) { - static_assert(std::is_integral<T>::value || std::is_pointer<T>::value, "expect std::is_integral<T>::value || std::is_pointer<T>::value"); -#ifdef _win_ - *a = x; -#else - __atomic_store_n(a, x, __ATOMIC_RELEASE); -#endif -} - -template <typename T> -inline void RelaxedStore(volatile T* a, T x) { - static_assert(std::is_integral<T>::value || std::is_pointer<T>::value, "expect std::is_integral<T>::value || std::is_pointer<T>::value"); -#ifdef _win_ - *a = x; -#else - __atomic_store_n(a, x, __ATOMIC_RELAXED); -#endif -} - -template <typename T> -inline T AtomicLoad(volatile T* a) { -#ifdef _win_ - return *a; -#else - return __atomic_load_n(a, __ATOMIC_ACQUIRE); -#endif -} - -template <typename T> -inline T RelaxedLoad(volatile T* a) { -#ifdef _win_ - return *a; -#else - return __atomic_load_n(a, __ATOMIC_RELAXED); -#endif -} + +static_assert(sizeof(TAtomic) == 8, "expect sizeof(TAtomic) == 8"); + +// we need explicit 32 bit operations to keep cache-line friendly packs +// so have to define some atomics additionaly to arcadia one +#ifdef _win_ +#pragma intrinsic(_InterlockedCompareExchange) +#pragma intrinsic(_InterlockedExchangeAdd) +#pragma intrinsic(_InterlockedIncrement) +#pragma intrinsic(_InterlockedDecrement) +#endif + +inline bool AtomicUi32Cas(volatile ui32* a, ui32 exchange, ui32 compare) { +#ifdef _win_ + return _InterlockedCompareExchange((volatile long*)a, exchange, compare) == (long)compare; +#else + ui32 expected = compare; + return __atomic_compare_exchange_n(a, &expected, exchange, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); +#endif +} + +inline ui32 AtomicUi32Add(volatile ui32* a, ui32 add) { +#ifdef _win_ + return _InterlockedExchangeAdd((volatile long*)a, add) + add; +#else + return __atomic_add_fetch(a, add, __ATOMIC_SEQ_CST); +#endif +} + +inline ui32 AtomicUi32Sub(volatile ui32* a, ui32 sub) { +#ifdef _win_ + return _InterlockedExchangeAdd((volatile long*)a, -(long)sub) - sub; +#else + return __atomic_sub_fetch(a, sub, __ATOMIC_SEQ_CST); +#endif +} + +inline ui32 AtomicUi32Increment(volatile ui32* a) { +#ifdef _win_ + return _InterlockedIncrement((volatile long*)a); +#else + return __atomic_add_fetch(a, 1, __ATOMIC_SEQ_CST); +#endif +} + +inline ui32 AtomicUi32Decrement(volatile ui32* a) { +#ifdef _win_ + return _InterlockedDecrement((volatile long*)a); +#else + return __atomic_sub_fetch(a, 1, __ATOMIC_SEQ_CST); +#endif +} + +template <typename T> +inline void AtomicStore(volatile T* a, T x) { + static_assert(std::is_integral<T>::value || std::is_pointer<T>::value, "expect std::is_integral<T>::value || std::is_pointer<T>::value"); +#ifdef _win_ + *a = x; +#else + __atomic_store_n(a, x, __ATOMIC_RELEASE); +#endif +} + +template <typename T> +inline void RelaxedStore(volatile T* a, T x) { + static_assert(std::is_integral<T>::value || std::is_pointer<T>::value, "expect std::is_integral<T>::value || std::is_pointer<T>::value"); +#ifdef _win_ + *a = x; +#else + __atomic_store_n(a, x, __ATOMIC_RELAXED); +#endif +} + +template <typename T> +inline T AtomicLoad(volatile T* a) { +#ifdef _win_ + return *a; +#else + return __atomic_load_n(a, __ATOMIC_ACQUIRE); +#endif +} + +template <typename T> +inline T RelaxedLoad(volatile T* a) { +#ifdef _win_ + return *a; +#else + return __atomic_load_n(a, __ATOMIC_RELAXED); +#endif +} diff --git a/library/cpp/actors/util/named_tuple.h b/library/cpp/actors/util/named_tuple.h index 5a8999c4ce..67f185bba8 100644 --- a/library/cpp/actors/util/named_tuple.h +++ b/library/cpp/actors/util/named_tuple.h @@ -2,29 +2,29 @@ #include "defs.h" -template <typename TDerived> +template <typename TDerived> struct TNamedTupleBase { - friend bool operator==(const TDerived& x, const TDerived& y) { + friend bool operator==(const TDerived& x, const TDerived& y) { return x.ConvertToTuple() == y.ConvertToTuple(); } - friend bool operator!=(const TDerived& x, const TDerived& y) { + friend bool operator!=(const TDerived& x, const TDerived& y) { return x.ConvertToTuple() != y.ConvertToTuple(); } - friend bool operator<(const TDerived& x, const TDerived& y) { + friend bool operator<(const TDerived& x, const TDerived& y) { return x.ConvertToTuple() < y.ConvertToTuple(); } - friend bool operator<=(const TDerived& x, const TDerived& y) { + friend bool operator<=(const TDerived& x, const TDerived& y) { return x.ConvertToTuple() <= y.ConvertToTuple(); } - friend bool operator>(const TDerived& x, const TDerived& y) { + friend bool operator>(const TDerived& x, const TDerived& y) { return x.ConvertToTuple() > y.ConvertToTuple(); } - friend bool operator>=(const TDerived& x, const TDerived& y) { + friend bool operator>=(const TDerived& x, const TDerived& y) { return x.ConvertToTuple() >= y.ConvertToTuple(); } }; diff --git a/library/cpp/actors/util/queue_chunk.h b/library/cpp/actors/util/queue_chunk.h index 96657ee890..8a4e02d8cb 100644 --- a/library/cpp/actors/util/queue_chunk.h +++ b/library/cpp/actors/util/queue_chunk.h @@ -1,29 +1,29 @@ -#pragma once - -#include "defs.h" - -template <typename T, ui32 TSize, typename TDerived> -struct TQueueChunkDerived { - static const ui32 EntriesCount = (TSize - sizeof(TQueueChunkDerived*)) / sizeof(T); +#pragma once + +#include "defs.h" + +template <typename T, ui32 TSize, typename TDerived> +struct TQueueChunkDerived { + static const ui32 EntriesCount = (TSize - sizeof(TQueueChunkDerived*)) / sizeof(T); static_assert(EntriesCount > 0, "expect EntriesCount > 0"); - - volatile T Entries[EntriesCount]; - TDerived* volatile Next; - - TQueueChunkDerived() { - memset(this, 0, sizeof(TQueueChunkDerived)); - } -}; - -template <typename T, ui32 TSize> -struct TQueueChunk { - static const ui32 EntriesCount = (TSize - sizeof(TQueueChunk*)) / sizeof(T); + + volatile T Entries[EntriesCount]; + TDerived* volatile Next; + + TQueueChunkDerived() { + memset(this, 0, sizeof(TQueueChunkDerived)); + } +}; + +template <typename T, ui32 TSize> +struct TQueueChunk { + static const ui32 EntriesCount = (TSize - sizeof(TQueueChunk*)) / sizeof(T); static_assert(EntriesCount > 0, "expect EntriesCount > 0"); - - volatile T Entries[EntriesCount]; - TQueueChunk* volatile Next; - - TQueueChunk() { - memset(this, 0, sizeof(TQueueChunk)); - } -}; + + volatile T Entries[EntriesCount]; + TQueueChunk* volatile Next; + + TQueueChunk() { + memset(this, 0, sizeof(TQueueChunk)); + } +}; diff --git a/library/cpp/actors/util/queue_oneone_inplace.h b/library/cpp/actors/util/queue_oneone_inplace.h index 48507a5235..d7ec8bb21c 100644 --- a/library/cpp/actors/util/queue_oneone_inplace.h +++ b/library/cpp/actors/util/queue_oneone_inplace.h @@ -1,118 +1,118 @@ -#pragma once - -#include "defs.h" -#include "queue_chunk.h" - -template <typename T, ui32 TSize, typename TChunk = TQueueChunk<T, TSize>> -class TOneOneQueueInplace : TNonCopyable { +#pragma once + +#include "defs.h" +#include "queue_chunk.h" + +template <typename T, ui32 TSize, typename TChunk = TQueueChunk<T, TSize>> +class TOneOneQueueInplace : TNonCopyable { static_assert(std::is_integral<T>::value || std::is_pointer<T>::value, "expect std::is_integral<T>::value || std::is_pointer<T>::valuer"); - - TChunk* ReadFrom; - ui32 ReadPosition; - ui32 WritePosition; - TChunk* WriteTo; - - friend class TReadIterator; - -public: - class TReadIterator { - TChunk* ReadFrom; - ui32 ReadPosition; - - public: - TReadIterator(TChunk* readFrom, ui32 readPosition) - : ReadFrom(readFrom) - , ReadPosition(readPosition) - { - } - - inline T Next() { - TChunk* head = ReadFrom; - if (ReadPosition != TChunk::EntriesCount) { - return AtomicLoad(&head->Entries[ReadPosition++]); - } else if (TChunk* next = AtomicLoad(&head->Next)) { - ReadFrom = next; - ReadPosition = 0; - return Next(); - } + + TChunk* ReadFrom; + ui32 ReadPosition; + ui32 WritePosition; + TChunk* WriteTo; + + friend class TReadIterator; + +public: + class TReadIterator { + TChunk* ReadFrom; + ui32 ReadPosition; + + public: + TReadIterator(TChunk* readFrom, ui32 readPosition) + : ReadFrom(readFrom) + , ReadPosition(readPosition) + { + } + + inline T Next() { + TChunk* head = ReadFrom; + if (ReadPosition != TChunk::EntriesCount) { + return AtomicLoad(&head->Entries[ReadPosition++]); + } else if (TChunk* next = AtomicLoad(&head->Next)) { + ReadFrom = next; + ReadPosition = 0; + return Next(); + } return T{}; - } - }; - - TOneOneQueueInplace() - : ReadFrom(new TChunk()) - , ReadPosition(0) - , WritePosition(0) - , WriteTo(ReadFrom) - { - } - - ~TOneOneQueueInplace() { + } + }; + + TOneOneQueueInplace() + : ReadFrom(new TChunk()) + , ReadPosition(0) + , WritePosition(0) + , WriteTo(ReadFrom) + { + } + + ~TOneOneQueueInplace() { Y_VERIFY_DEBUG(Head() == 0); - delete ReadFrom; - } - - struct TPtrCleanDestructor { + delete ReadFrom; + } + + struct TPtrCleanDestructor { static inline void Destroy(TOneOneQueueInplace<T, TSize>* x) noexcept { - while (T head = x->Pop()) - delete head; - delete x; - } - }; - - struct TCleanDestructor { + while (T head = x->Pop()) + delete head; + delete x; + } + }; + + struct TCleanDestructor { static inline void Destroy(TOneOneQueueInplace<T, TSize>* x) noexcept { while (x->Pop() != nullptr) - continue; - delete x; - } - }; - - struct TPtrCleanInplaceMallocDestructor { - template <typename TPtrVal> + continue; + delete x; + } + }; + + struct TPtrCleanInplaceMallocDestructor { + template <typename TPtrVal> static inline void Destroy(TOneOneQueueInplace<TPtrVal*, TSize>* x) noexcept { - while (TPtrVal* head = x->Pop()) { - head->~TPtrVal(); - free(head); - } - delete x; - } - }; - + while (TPtrVal* head = x->Pop()) { + head->~TPtrVal(); + free(head); + } + delete x; + } + }; + void Push(T x) noexcept { - if (WritePosition != TChunk::EntriesCount) { - AtomicStore(&WriteTo->Entries[WritePosition], x); - ++WritePosition; - } else { - TChunk* next = new TChunk(); - next->Entries[0] = x; - AtomicStore(&WriteTo->Next, next); - WriteTo = next; - WritePosition = 1; - } - } - - T Head() { - TChunk* head = ReadFrom; - if (ReadPosition != TChunk::EntriesCount) { - return AtomicLoad(&head->Entries[ReadPosition]); - } else if (TChunk* next = AtomicLoad(&head->Next)) { - ReadFrom = next; - delete head; - ReadPosition = 0; - return Head(); - } + if (WritePosition != TChunk::EntriesCount) { + AtomicStore(&WriteTo->Entries[WritePosition], x); + ++WritePosition; + } else { + TChunk* next = new TChunk(); + next->Entries[0] = x; + AtomicStore(&WriteTo->Next, next); + WriteTo = next; + WritePosition = 1; + } + } + + T Head() { + TChunk* head = ReadFrom; + if (ReadPosition != TChunk::EntriesCount) { + return AtomicLoad(&head->Entries[ReadPosition]); + } else if (TChunk* next = AtomicLoad(&head->Next)) { + ReadFrom = next; + delete head; + ReadPosition = 0; + return Head(); + } return T{}; - } - - T Pop() { - T ret = Head(); - if (ret) - ++ReadPosition; - return ret; - } - - TReadIterator Iterator() { - return TReadIterator(ReadFrom, ReadPosition); - } -}; + } + + T Pop() { + T ret = Head(); + if (ret) + ++ReadPosition; + return ret; + } + + TReadIterator Iterator() { + return TReadIterator(ReadFrom, ReadPosition); + } +}; diff --git a/library/cpp/actors/util/should_continue.cpp b/library/cpp/actors/util/should_continue.cpp index 38bb6a28b3..258e6a0aff 100644 --- a/library/cpp/actors/util/should_continue.cpp +++ b/library/cpp/actors/util/should_continue.cpp @@ -1,23 +1,23 @@ -#include "should_continue.h" - -void TProgramShouldContinue::ShouldRestart() { - AtomicSet(State, Restart); -} - -void TProgramShouldContinue::ShouldStop(int returnCode) { - AtomicSet(ReturnCode, returnCode); - AtomicSet(State, Stop); -} - -TProgramShouldContinue::EState TProgramShouldContinue::PollState() { - return static_cast<EState>(AtomicGet(State)); -} - -int TProgramShouldContinue::GetReturnCode() { - return static_cast<int>(AtomicGet(ReturnCode)); -} - -void TProgramShouldContinue::Reset() { - AtomicSet(ReturnCode, 0); - AtomicSet(State, Continue); -} +#include "should_continue.h" + +void TProgramShouldContinue::ShouldRestart() { + AtomicSet(State, Restart); +} + +void TProgramShouldContinue::ShouldStop(int returnCode) { + AtomicSet(ReturnCode, returnCode); + AtomicSet(State, Stop); +} + +TProgramShouldContinue::EState TProgramShouldContinue::PollState() { + return static_cast<EState>(AtomicGet(State)); +} + +int TProgramShouldContinue::GetReturnCode() { + return static_cast<int>(AtomicGet(ReturnCode)); +} + +void TProgramShouldContinue::Reset() { + AtomicSet(ReturnCode, 0); + AtomicSet(State, Continue); +} diff --git a/library/cpp/actors/util/should_continue.h b/library/cpp/actors/util/should_continue.h index 8fc7f9dab0..76acc40dc4 100644 --- a/library/cpp/actors/util/should_continue.h +++ b/library/cpp/actors/util/should_continue.h @@ -1,22 +1,22 @@ -#pragma once -#include "defs.h" - -class TProgramShouldContinue { -public: - enum EState { - Continue, - Stop, - Restart, - }; - - void ShouldRestart(); - void ShouldStop(int returnCode = 0); - - EState PollState(); - int GetReturnCode(); - - void Reset(); -private: - TAtomic ReturnCode = 0; - TAtomic State = Continue; -}; +#pragma once +#include "defs.h" + +class TProgramShouldContinue { +public: + enum EState { + Continue, + Stop, + Restart, + }; + + void ShouldRestart(); + void ShouldStop(int returnCode = 0); + + EState PollState(); + int GetReturnCode(); + + void Reset(); +private: + TAtomic ReturnCode = 0; + TAtomic State = Continue; +}; diff --git a/library/cpp/actors/util/thread.h b/library/cpp/actors/util/thread.h index 0afbe10921..d742c8c585 100644 --- a/library/cpp/actors/util/thread.h +++ b/library/cpp/actors/util/thread.h @@ -8,7 +8,7 @@ #include <time.h> inline void SetCurrentThreadName(const TString& name, - const ui32 maxCharsFromProcessName = 8) { + const ui32 maxCharsFromProcessName = 8) { #if defined(_linux_) // linux limits threadname by 15 + \0 diff --git a/library/cpp/actors/util/threadparkpad.cpp b/library/cpp/actors/util/threadparkpad.cpp index 88813e270c..74069ff15b 100644 --- a/library/cpp/actors/util/threadparkpad.cpp +++ b/library/cpp/actors/util/threadparkpad.cpp @@ -1,15 +1,15 @@ -#include "threadparkpad.h" -#include <util/system/winint.h> - -#ifdef _linux_ - -#include "futex.h" - -namespace NActors { +#include "threadparkpad.h" +#include <util/system/winint.h> + +#ifdef _linux_ + +#include "futex.h" + +namespace NActors { class TThreadParkPad::TImpl { volatile bool Interrupted; int Futex; - + public: TImpl() : Interrupted(false) @@ -18,39 +18,39 @@ namespace NActors { } ~TImpl() { } - + bool Park() noexcept { __atomic_fetch_sub(&Futex, 1, __ATOMIC_SEQ_CST); while (__atomic_load_n(&Futex, __ATOMIC_ACQUIRE) == -1) SysFutex(&Futex, FUTEX_WAIT_PRIVATE, -1, nullptr, nullptr, 0); return IsInterrupted(); } - + void Unpark() noexcept { const int old = __atomic_fetch_add(&Futex, 1, __ATOMIC_SEQ_CST); if (old == -1) SysFutex(&Futex, FUTEX_WAKE_PRIVATE, -1, nullptr, nullptr, 0); } - + void Interrupt() noexcept { __atomic_store_n(&Interrupted, true, __ATOMIC_SEQ_CST); Unpark(); } - + bool IsInterrupted() const noexcept { return __atomic_load_n(&Interrupted, __ATOMIC_ACQUIRE); } }; - -#elif defined _win32_ + +#elif defined _win32_ #include <util/generic/bt_exception.h> -#include <util/generic/yexception.h> - -namespace NActors { +#include <util/generic/yexception.h> + +namespace NActors { class TThreadParkPad::TImpl { TAtomic Interrupted; HANDLE EvHandle; - + public: TImpl() : Interrupted(false) @@ -63,35 +63,35 @@ namespace NActors { if (EvHandle) ::CloseHandle(EvHandle); } - + bool Park() noexcept { ::WaitForSingleObject(EvHandle, INFINITE); return AtomicGet(Interrupted); } - + void Unpark() noexcept { ::SetEvent(EvHandle); } - + void Interrupt() noexcept { AtomicSet(Interrupted, true); Unpark(); } - + bool IsInterrupted() const noexcept { return AtomicGet(Interrupted); } }; - -#else - -#include <util/system/event.h> - -namespace NActors { + +#else + +#include <util/system/event.h> + +namespace NActors { class TThreadParkPad::TImpl { TAtomic Interrupted; TSystemEvent Ev; - + public: TImpl() : Interrupted(false) @@ -100,7 +100,7 @@ namespace NActors { } ~TImpl() { } - + bool Park() noexcept { Ev.Wait(); return AtomicGet(Interrupted); @@ -123,26 +123,26 @@ namespace NActors { TThreadParkPad::TThreadParkPad() : Impl(new TThreadParkPad::TImpl()) - { - } + { + } TThreadParkPad::~TThreadParkPad() { - } - + } + bool TThreadParkPad::Park() noexcept { return Impl->Park(); - } - + } + void TThreadParkPad::Unpark() noexcept { Impl->Unpark(); - } - + } + void TThreadParkPad::Interrupt() noexcept { Impl->Interrupt(); - } - + } + bool TThreadParkPad::Interrupted() const noexcept { return Impl->IsInterrupted(); - } - -} + } + +} diff --git a/library/cpp/actors/util/threadparkpad.h b/library/cpp/actors/util/threadparkpad.h index 30f9cffdb9..5b574ccf34 100644 --- a/library/cpp/actors/util/threadparkpad.h +++ b/library/cpp/actors/util/threadparkpad.h @@ -1,21 +1,21 @@ -#pragma once - -#include <util/generic/ptr.h> - -namespace NActors { - class TThreadParkPad { - private: - class TImpl; - THolder<TImpl> Impl; - - public: - TThreadParkPad(); +#pragma once + +#include <util/generic/ptr.h> + +namespace NActors { + class TThreadParkPad { + private: + class TImpl; + THolder<TImpl> Impl; + + public: + TThreadParkPad(); ~TThreadParkPad(); - + bool Park() noexcept; void Unpark() noexcept; void Interrupt() noexcept; bool Interrupted() const noexcept; - }; - -} + }; + +} diff --git a/library/cpp/actors/util/ticket_lock.h b/library/cpp/actors/util/ticket_lock.h index 334922a088..3b1fa80393 100644 --- a/library/cpp/actors/util/ticket_lock.h +++ b/library/cpp/actors/util/ticket_lock.h @@ -1,48 +1,48 @@ -#pragma once - -#include "intrinsics.h" -#include <util/system/guard.h> -#include <util/system/yassert.h> - -class TTicketLock : TNonCopyable { - ui32 TicketIn; - ui32 TicketOut; - -public: - TTicketLock() - : TicketIn(0) - , TicketOut(0) - { - } - +#pragma once + +#include "intrinsics.h" +#include <util/system/guard.h> +#include <util/system/yassert.h> + +class TTicketLock : TNonCopyable { + ui32 TicketIn; + ui32 TicketOut; + +public: + TTicketLock() + : TicketIn(0) + , TicketOut(0) + { + } + void Release() noexcept { - AtomicUi32Increment(&TicketOut); - } - + AtomicUi32Increment(&TicketOut); + } + ui32 Acquire() noexcept { - ui32 revolves = 0; - const ui32 ticket = AtomicUi32Increment(&TicketIn) - 1; - while (ticket != AtomicLoad(&TicketOut)) { + ui32 revolves = 0; + const ui32 ticket = AtomicUi32Increment(&TicketIn) - 1; + while (ticket != AtomicLoad(&TicketOut)) { Y_VERIFY_DEBUG(ticket >= AtomicLoad(&TicketOut)); - SpinLockPause(); - ++revolves; - } - return revolves; - } - + SpinLockPause(); + ++revolves; + } + return revolves; + } + bool TryAcquire() noexcept { - const ui32 x = AtomicLoad(&TicketOut); - if (x == AtomicLoad(&TicketIn) && AtomicUi32Cas(&TicketIn, x + 1, x)) - return true; - else - return false; - } - + const ui32 x = AtomicLoad(&TicketOut); + if (x == AtomicLoad(&TicketIn) && AtomicUi32Cas(&TicketIn, x + 1, x)) + return true; + else + return false; + } + bool IsLocked() noexcept { - const ui32 ticketIn = AtomicLoad(&TicketIn); - const ui32 ticketOut = AtomicLoad(&TicketOut); - return (ticketIn != ticketOut); - } - - typedef ::TGuard<TTicketLock> TGuard; -}; + const ui32 ticketIn = AtomicLoad(&TicketIn); + const ui32 ticketOut = AtomicLoad(&TicketOut); + return (ticketIn != ticketOut); + } + + typedef ::TGuard<TTicketLock> TGuard; +}; diff --git a/library/cpp/actors/util/unordered_cache.h b/library/cpp/actors/util/unordered_cache.h index 57b9c6663d..76f036c0cf 100644 --- a/library/cpp/actors/util/unordered_cache.h +++ b/library/cpp/actors/util/unordered_cache.h @@ -1,22 +1,22 @@ -#pragma once - -#include "defs.h" +#pragma once + +#include "defs.h" #include "queue_chunk.h" - + template <typename T, ui32 Size = 512, ui32 ConcurrencyFactor = 1, typename TChunk = TQueueChunk<T, Size>> -class TUnorderedCache : TNonCopyable { +class TUnorderedCache : TNonCopyable { static_assert(std::is_integral<T>::value || std::is_pointer<T>::value, "expect std::is_integral<T>::value || std::is_pointer<T>::value"); - -public: + +public: static constexpr ui32 Concurrency = ConcurrencyFactor * 4; - -private: + +private: struct TReadSlot { TChunk* volatile ReadFrom; volatile ui32 ReadPosition; char Padding[64 - sizeof(TChunk*) - sizeof(ui32)]; // 1 slot per cache line }; - + struct TWriteSlot { TChunk* volatile WriteTo; volatile ui32 WritePosition; @@ -31,7 +31,7 @@ private: TWriteSlot WriteSlots[Concurrency]; static_assert(sizeof(TChunk*) == sizeof(TAtomic), "expect sizeof(TChunk*) == sizeof(TAtomic)"); - + private: struct TLockedWriter { TWriteSlot* Slot; @@ -82,53 +82,53 @@ private: private: TLockedWriter LockWriter(ui64 writerRotation) { ui32 cycle = 0; - for (;;) { + for (;;) { TWriteSlot* slot = &WriteSlots[writerRotation % Concurrency]; if (AtomicLoad(&slot->WriteTo) != nullptr) { if (TChunk* writeTo = AtomicSwap(&slot->WriteTo, nullptr)) { return TLockedWriter(slot, writeTo); - } - } + } + } ++writerRotation; - + // Do a spinlock pause after a full cycle if (++cycle == Concurrency) { SpinLockPause(); cycle = 0; } } - } - + } + void WriteOne(TLockedWriter& lock, T x) { Y_VERIFY_DEBUG(x != 0); - + const ui32 pos = AtomicLoad(&lock.Slot->WritePosition); - if (pos != TChunk::EntriesCount) { + if (pos != TChunk::EntriesCount) { AtomicStore(&lock.Slot->WritePosition, pos + 1); AtomicStore(&lock.WriteTo->Entries[pos], x); - } else { + } else { TChunk* next = new TChunk(); - AtomicStore(&next->Entries[0], x); + AtomicStore(&next->Entries[0], x); AtomicStore(&lock.Slot->WritePosition, 1u); AtomicStore(&lock.WriteTo->Next, next); lock.WriteTo = next; - } - } - -public: + } + } + +public: TUnorderedCache() { for (ui32 i = 0; i < Concurrency; ++i) { ReadSlots[i].ReadFrom = new TChunk(); ReadSlots[i].ReadPosition = 0; - + WriteSlots[i].WriteTo = ReadSlots[i].ReadFrom; WriteSlots[i].WritePosition = 0; - } - } - + } + } + ~TUnorderedCache() { Y_VERIFY(!Pop(0)); - + for (ui64 i = 0; i < Concurrency; ++i) { if (ReadSlots[i].ReadFrom) { delete ReadSlots[i].ReadFrom; @@ -139,63 +139,63 @@ public: } T Pop(ui64 readerRotation) noexcept { - ui64 readerIndex = readerRotation; - const ui64 endIndex = readerIndex + Concurrency; - for (; readerIndex != endIndex; ++readerIndex) { + ui64 readerIndex = readerRotation; + const ui64 endIndex = readerIndex + Concurrency; + for (; readerIndex != endIndex; ++readerIndex) { TReadSlot* slot = &ReadSlots[readerIndex % Concurrency]; if (AtomicLoad(&slot->ReadFrom) != nullptr) { if (TChunk* readFrom = AtomicSwap(&slot->ReadFrom, nullptr)) { const ui32 pos = AtomicLoad(&slot->ReadPosition); - if (pos != TChunk::EntriesCount) { - if (T ret = AtomicLoad(&readFrom->Entries[pos])) { + if (pos != TChunk::EntriesCount) { + if (T ret = AtomicLoad(&readFrom->Entries[pos])) { AtomicStore(&slot->ReadPosition, pos + 1); AtomicStore(&slot->ReadFrom, readFrom); // release lock with same chunk return ret; // found, return - } else { + } else { AtomicStore(&slot->ReadFrom, readFrom); // release lock with same chunk - } - } else if (TChunk* next = AtomicLoad(&readFrom->Next)) { - if (T ret = AtomicLoad(&next->Entries[0])) { + } + } else if (TChunk* next = AtomicLoad(&readFrom->Next)) { + if (T ret = AtomicLoad(&next->Entries[0])) { AtomicStore(&slot->ReadPosition, 1u); AtomicStore(&slot->ReadFrom, next); // release lock with next chunk - delete readFrom; - return ret; - } else { + delete readFrom; + return ret; + } else { AtomicStore(&slot->ReadPosition, 0u); AtomicStore(&slot->ReadFrom, next); // release lock with new chunk - delete readFrom; - } - } else { + delete readFrom; + } + } else { // nothing in old chunk and no next chunk, just release lock with old chunk AtomicStore(&slot->ReadFrom, readFrom); - } - } - } - } - - return 0; // got nothing after full cycle, return - } - - void Push(T x, ui64 writerRotation) { + } + } + } + } + + return 0; // got nothing after full cycle, return + } + + void Push(T x, ui64 writerRotation) { TLockedWriter lock = LockWriter(writerRotation); WriteOne(lock, x); - } - - void PushBulk(T* x, ui32 xcount, ui64 writerRotation) { + } + + void PushBulk(T* x, ui32 xcount, ui64 writerRotation) { for (;;) { // Fill no more then one queue chunk per round - const ui32 xround = Min(xcount, (ui32)TChunk::EntriesCount); - + const ui32 xround = Min(xcount, (ui32)TChunk::EntriesCount); + { TLockedWriter lock = LockWriter(writerRotation++); for (T* end = x + xround; x != end; ++x) WriteOne(lock, *x); } - - if (xcount <= TChunk::EntriesCount) - break; - - xcount -= TChunk::EntriesCount; - } - } -}; + + if (xcount <= TChunk::EntriesCount) + break; + + xcount -= TChunk::EntriesCount; + } + } +}; diff --git a/library/cpp/actors/util/ya.make b/library/cpp/actors/util/ya.make index a8bc36c769..37488c3962 100644 --- a/library/cpp/actors/util/ya.make +++ b/library/cpp/actors/util/ya.make @@ -1,37 +1,37 @@ -LIBRARY() - +LIBRARY() + OWNER( ddoarn g:kikimr ) - -SRCS( - affinity.cpp - affinity.h + +SRCS( + affinity.cpp + affinity.h cpumask.h datetime.h - defs.h + defs.h funnel_queue.h - futex.h - intrinsics.h + futex.h + intrinsics.h local_process_key.h - named_tuple.h - queue_chunk.h - queue_oneone_inplace.h + named_tuple.h + queue_chunk.h + queue_oneone_inplace.h recentwnd.h rope.h - should_continue.cpp - should_continue.h - thread.h - threadparkpad.cpp - threadparkpad.h - ticket_lock.h + should_continue.cpp + should_continue.h + thread.h + threadparkpad.cpp + threadparkpad.h + ticket_lock.h timerfd.h - unordered_cache.h -) - -PEERDIR( - util -) - -END() + unordered_cache.h +) + +PEERDIR( + util +) + +END() diff --git a/library/cpp/actors/wilson/wilson_event.h b/library/cpp/actors/wilson/wilson_event.h index 0bf0953096..7d89c33b51 100644 --- a/library/cpp/actors/wilson/wilson_event.h +++ b/library/cpp/actors/wilson/wilson_event.h @@ -10,46 +10,46 @@ namespace NWilson { #if !defined(_win_) // works only for those compilers, who trait C++ as ISO IEC 14882, not their own standard -#define __UNROLL_PARAMS_8(N, F, X, ...) \ - F(X, N - 8) \ - __UNROLL_PARAMS_7(N, F, ##__VA_ARGS__) -#define __UNROLL_PARAMS_7(N, F, X, ...) \ - F(X, N - 7) \ - __UNROLL_PARAMS_6(N, F, ##__VA_ARGS__) -#define __UNROLL_PARAMS_6(N, F, X, ...) \ - F(X, N - 6) \ - __UNROLL_PARAMS_5(N, F, ##__VA_ARGS__) -#define __UNROLL_PARAMS_5(N, F, X, ...) \ - F(X, N - 5) \ - __UNROLL_PARAMS_4(N, F, ##__VA_ARGS__) -#define __UNROLL_PARAMS_4(N, F, X, ...) \ - F(X, N - 4) \ - __UNROLL_PARAMS_3(N, F, ##__VA_ARGS__) -#define __UNROLL_PARAMS_3(N, F, X, ...) \ - F(X, N - 3) \ - __UNROLL_PARAMS_2(N, F, ##__VA_ARGS__) -#define __UNROLL_PARAMS_2(N, F, X, ...) \ - F(X, N - 2) \ - __UNROLL_PARAMS_1(N, F, ##__VA_ARGS__) -#define __UNROLL_PARAMS_1(N, F, X) F(X, N - 1) +#define __UNROLL_PARAMS_8(N, F, X, ...) \ + F(X, N - 8) \ + __UNROLL_PARAMS_7(N, F, ##__VA_ARGS__) +#define __UNROLL_PARAMS_7(N, F, X, ...) \ + F(X, N - 7) \ + __UNROLL_PARAMS_6(N, F, ##__VA_ARGS__) +#define __UNROLL_PARAMS_6(N, F, X, ...) \ + F(X, N - 6) \ + __UNROLL_PARAMS_5(N, F, ##__VA_ARGS__) +#define __UNROLL_PARAMS_5(N, F, X, ...) \ + F(X, N - 5) \ + __UNROLL_PARAMS_4(N, F, ##__VA_ARGS__) +#define __UNROLL_PARAMS_4(N, F, X, ...) \ + F(X, N - 4) \ + __UNROLL_PARAMS_3(N, F, ##__VA_ARGS__) +#define __UNROLL_PARAMS_3(N, F, X, ...) \ + F(X, N - 3) \ + __UNROLL_PARAMS_2(N, F, ##__VA_ARGS__) +#define __UNROLL_PARAMS_2(N, F, X, ...) \ + F(X, N - 2) \ + __UNROLL_PARAMS_1(N, F, ##__VA_ARGS__) +#define __UNROLL_PARAMS_1(N, F, X) F(X, N - 1) #define __UNROLL_PARAMS_0(N, F) #define __EX(...) __VA_ARGS__ #define __NUM_PARAMS(...) __NUM_PARAMS_SELECT_N(__VA_ARGS__, __NUM_PARAMS_SEQ) #define __NUM_PARAMS_SELECT_N(...) __EX(__NUM_PARAMS_SELECT(__VA_ARGS__)) #define __NUM_PARAMS_SELECT(X, _1, _2, _3, _4, _5, _6, _7, _8, N, ...) N #define __NUM_PARAMS_SEQ 8, 7, 6, 5, 4, 3, 2, 1, 0, ERROR -#define __CAT(X, Y) X##Y +#define __CAT(X, Y) X##Y #define __UNROLL_PARAMS_N(N, F, ...) __EX(__CAT(__UNROLL_PARAMS_, N)(N, F, ##__VA_ARGS__)) #define __UNROLL_PARAMS(F, ...) __UNROLL_PARAMS_N(__NUM_PARAMS(X, ##__VA_ARGS__), F, ##__VA_ARGS__) #define __EX2(F, X, INDEX) __INVOKE(F, __EX X, INDEX) #define __INVOKE(F, ...) F(__VA_ARGS__) #define __DECLARE_PARAM(X, INDEX) __EX2(__DECLARE_PARAM_X, X, INDEX) -#define __DECLARE_PARAM_X(TYPE, NAME, INDEX) \ - static const struct T##NAME##Param \ - : ::NWilson::TParamBinder<INDEX, TYPE> { \ - T##NAME##Param() { \ - } \ +#define __DECLARE_PARAM_X(TYPE, NAME, INDEX) \ + static const struct T##NAME##Param \ + : ::NWilson::TParamBinder<INDEX, TYPE> { \ + T##NAME##Param() { \ + } \ using ::NWilson::TParamBinder<INDEX, TYPE>::operator=; \ } NAME; @@ -59,70 +59,70 @@ namespace NWilson { #define __OUTPUT_PARAM(X, INDEX) __EX2(__OUTPUT_PARAM_X, X, INDEX) #define __OUTPUT_PARAM_X(TYPE, NAME, INDEX) str << (INDEX ? ", " : "") << #NAME << "# " << std::get<INDEX>(ParamPack); -#define __FILL_PARAM(P, INDEX) \ - do { \ - const auto& boundParam = (NParams::P); \ - boundParam.Apply(event.ParamPack); \ - } while (false); - -#define DECLARE_WILSON_EVENT(EVENT_NAME, ...) \ - namespace N##EVENT_NAME##Params { \ - __UNROLL_PARAMS(__DECLARE_PARAM, ##__VA_ARGS__) \ - \ - using TParamPack = std::tuple< \ - __UNROLL_PARAMS(__TUPLE_PARAM, ##__VA_ARGS__) char>; \ - } \ - struct T##EVENT_NAME { \ - using TParamPack = N##EVENT_NAME##Params::TParamPack; \ - TParamPack ParamPack; \ - \ +#define __FILL_PARAM(P, INDEX) \ + do { \ + const auto& boundParam = (NParams::P); \ + boundParam.Apply(event.ParamPack); \ + } while (false); + +#define DECLARE_WILSON_EVENT(EVENT_NAME, ...) \ + namespace N##EVENT_NAME##Params { \ + __UNROLL_PARAMS(__DECLARE_PARAM, ##__VA_ARGS__) \ + \ + using TParamPack = std::tuple< \ + __UNROLL_PARAMS(__TUPLE_PARAM, ##__VA_ARGS__) char>; \ + } \ + struct T##EVENT_NAME { \ + using TParamPack = N##EVENT_NAME##Params::TParamPack; \ + TParamPack ParamPack; \ + \ void Output(IOutputStream& str) { \ - str << #EVENT_NAME << "{"; \ - __UNROLL_PARAMS(__OUTPUT_PARAM, ##__VA_ARGS__) \ - str << "}"; \ - } \ + str << #EVENT_NAME << "{"; \ + __UNROLL_PARAMS(__OUTPUT_PARAM, ##__VA_ARGS__) \ + str << "}"; \ + } \ }; - template <size_t INDEX, typename T> + template <size_t INDEX, typename T> class TBoundParam { mutable T Value; public: TBoundParam(T&& value) : Value(std::move(value)) - { - } + { + } - template <typename TParamPack> + template <typename TParamPack> void Apply(TParamPack& pack) const { std::get<INDEX>(pack) = std::move(Value); } }; - template <size_t INDEX, typename T> + template <size_t INDEX, typename T> struct TParamBinder { - template <typename TValue> + template <typename TValue> TBoundParam<INDEX, T> operator=(const TValue& value) const { return TBoundParam<INDEX, T>(TValue(value)); } - template <typename TValue> + template <typename TValue> TBoundParam<INDEX, T> operator=(TValue&& value) const { return TBoundParam<INDEX, T>(std::move(value)); } }; // generate wilson event having parent TRACE_ID and span TRACE_ID to become parent of logged event -#define WILSON_TRACE(CTX, TRACE_ID, EVENT_NAME, ...) \ +#define WILSON_TRACE(CTX, TRACE_ID, EVENT_NAME, ...) \ if (::NWilson::TraceEnabled(CTX)) { \ - ::NWilson::TTraceId* __traceId = (TRACE_ID); \ - if (__traceId && *__traceId) { \ - TInstant now = Now(); \ - T##EVENT_NAME event; \ - namespace NParams = N##EVENT_NAME##Params; \ - __UNROLL_PARAMS(__FILL_PARAM, ##__VA_ARGS__) \ + ::NWilson::TTraceId* __traceId = (TRACE_ID); \ + if (__traceId && *__traceId) { \ + TInstant now = Now(); \ + T##EVENT_NAME event; \ + namespace NParams = N##EVENT_NAME##Params; \ + __UNROLL_PARAMS(__FILL_PARAM, ##__VA_ARGS__) \ ::NWilson::TraceEvent((CTX), __traceId, event, now); \ - } \ + } \ } inline ui32 GetNodeId(const NActors::TActorSystem& actorSystem) { @@ -140,8 +140,8 @@ namespace NWilson { return loggerSettings && loggerSettings->Satisfies(NActors::NLog::PRI_DEBUG, WilsonComponentId); } - template <typename TActorSystem, typename TEvent> - void TraceEvent(const TActorSystem& actorSystem, TTraceId* traceId, TEvent&& event, TInstant timestamp) { + template <typename TActorSystem, typename TEvent> + void TraceEvent(const TActorSystem& actorSystem, TTraceId* traceId, TEvent&& event, TInstant timestamp) { // ensure that we are not using obsolete TraceId traceId->CheckConsistency(); @@ -153,7 +153,7 @@ namespace NWilson { const ui64 timestampValue = timestamp.GetValue(); const size_t base64size = Base64EncodeBufSize(sizeof(timestampValue)); char base64[base64size]; - char* end = Base64Encode(base64, reinterpret_cast<const ui8*>(×tampValue), sizeof(timestampValue)); + char* end = Base64Encode(base64, reinterpret_cast<const ui8*>(×tampValue), sizeof(timestampValue)); // cut trailing padding character to save some space Y_VERIFY(end > base64 && end[-1] == '='); diff --git a/library/cpp/actors/wilson/wilson_trace.h b/library/cpp/actors/wilson/wilson_trace.h index 3f5bbbafa3..3d1ca50562 100644 --- a/library/cpp/actors/wilson/wilson_trace.h +++ b/library/cpp/actors/wilson/wilson_trace.h @@ -16,8 +16,8 @@ namespace NWilson { TTraceId(ui64 traceId, ui64 spanId) : TraceId(traceId) , SpanId(spanId) - { - } + { + } static ui64 GenerateTraceId() { ui64 traceId = 0; @@ -38,8 +38,8 @@ namespace NWilson { TTraceId() : TraceId(0) , SpanId(0) - { - } + { + } explicit TTraceId(ui64 traceId) : TraceId(traceId) @@ -48,10 +48,10 @@ namespace NWilson { } TTraceId(const TSerializedTraceId& in) - : TraceId(reinterpret_cast<const ui64*>(in)[0]) - , SpanId(reinterpret_cast<const ui64*>(in)[1]) - { - } + : TraceId(reinterpret_cast<const ui64*>(in)[0]) + , SpanId(reinterpret_cast<const ui64*>(in)[1]) + { + } // allow move semantic TTraceId(TTraceId&& other) @@ -62,7 +62,7 @@ namespace NWilson { other.SpanId = 1; // explicitly mark invalid } - TTraceId& operator=(TTraceId&& other) { + TTraceId& operator=(TTraceId&& other) { TraceId = other.TraceId; SpanId = other.SpanId; other.TraceId = 0; @@ -72,7 +72,7 @@ namespace NWilson { // do not allow implicit copy of trace id TTraceId(const TTraceId& other) = delete; - TTraceId& operator=(const TTraceId& other) = delete; + TTraceId& operator=(const TTraceId& other) = delete; static TTraceId NewTraceId() { return TTraceId(GenerateTraceId(), 0); @@ -117,7 +117,7 @@ namespace NWilson { const size_t base64size = Base64EncodeBufSize(sizeof(x)); char base64[base64size]; - char* end = Base64Encode(base64, buffer, sizeof(x)); + char* end = Base64Encode(base64, buffer, sizeof(x)); s << TStringBuf(base64, end); } @@ -125,7 +125,7 @@ namespace NWilson { void OutputSpanId(IOutputStream& s) const { const size_t base64size = Base64EncodeBufSize(sizeof(SpanId)); char base64[base64size]; - char* end = Base64Encode(base64, reinterpret_cast<const ui8*>(&SpanId), sizeof(SpanId)); + char* end = Base64Encode(base64, reinterpret_cast<const ui8*>(&SpanId), sizeof(SpanId)); // cut trailing padding character Y_VERIFY(end > base64 && end[-1] == '='); @@ -139,7 +139,7 @@ namespace NWilson { Y_VERIFY_DEBUG(*this || !SpanId); } - friend bool operator==(const TTraceId& x, const TTraceId& y) { + friend bool operator==(const TTraceId& x, const TTraceId& y) { return x.TraceId == y.TraceId && x.SpanId == y.SpanId; } @@ -151,8 +151,8 @@ namespace NWilson { return TraceId == other.TraceId; } - void Serialize(TSerializedTraceId* out) { - ui64* p = reinterpret_cast<ui64*>(*out); + void Serialize(TSerializedTraceId* out) { + ui64* p = reinterpret_cast<ui64*>(*out); p[0] = TraceId; p[1] = SpanId; } diff --git a/library/cpp/actors/wilson/ya.make b/library/cpp/actors/wilson/ya.make index 177884ad69..e371f5061d 100644 --- a/library/cpp/actors/wilson/ya.make +++ b/library/cpp/actors/wilson/ya.make @@ -1,9 +1,9 @@ LIBRARY() - + PEERDIR( library/cpp/string_utils/base64 ) - + OWNER(alexvru) SRCS( diff --git a/library/cpp/actors/ya.make b/library/cpp/actors/ya.make index 95655c27ce..737c7fbc18 100644 --- a/library/cpp/actors/ya.make +++ b/library/cpp/actors/ya.make @@ -1,16 +1,16 @@ RECURSE_FOR_TESTS(ut) -RECURSE( +RECURSE( log_backend - core + core dnsresolver - examples - memory_log + examples + memory_log helpers - prof - protos - util - wilson + prof + protos + util + wilson testlib http -) +) diff --git a/library/cpp/digest/crc32c/ya.make b/library/cpp/digest/crc32c/ya.make index e324c587e5..d6faf16c9c 100644 --- a/library/cpp/digest/crc32c/ya.make +++ b/library/cpp/digest/crc32c/ya.make @@ -1,5 +1,5 @@ -LIBRARY() - +LIBRARY() + #!!! OWNER( ddoarn @@ -15,8 +15,8 @@ PEERDIR( contrib/libs/crcutil ) -SRCS( +SRCS( crc32c.cpp -) - -END() +) + +END() diff --git a/library/cpp/malloc/ya.make b/library/cpp/malloc/ya.make index bacc38d54e..0ec9db71d2 100644 --- a/library/cpp/malloc/ya.make +++ b/library/cpp/malloc/ya.make @@ -6,7 +6,7 @@ RECURSE( galloc jemalloc lockless - nalf + nalf sample-client system mimalloc diff --git a/library/cpp/threading/queue/mpsc_read_as_filled.h b/library/cpp/threading/queue/mpsc_read_as_filled.h index 7670fc4c6f..be33ba5a58 100644 --- a/library/cpp/threading/queue/mpsc_read_as_filled.h +++ b/library/cpp/threading/queue/mpsc_read_as_filled.h @@ -4,14 +4,14 @@ Completely wait-free queue, multiple producers - one consumer. Strict order. The queue algorithm is using concept of virtual infinite array. - A producer takes a number from a counter and atomically increments the counter. + A producer takes a number from a counter and atomically increments the counter. The number taken is a number of a slot for the producer to put a new message into infinite array. Then producer constructs a virtual infinite array by bidirectional linked list of blocks. Each block contains several slots. - There is a hint pointer which optimistically points to the last block + There is a hint pointer which optimistically points to the last block of the list and never goes backward. Consumer exploits the property of the hint pointer always going forward @@ -25,7 +25,7 @@ Consumer can't stop the progress for producers. Consumer can skip not-yet-filled slots and read them later. Thus no producer can stop the progress for consumer. - The algorithm is virtually strictly ordered because it skips slots only + The algorithm is virtually strictly ordered because it skips slots only if it is really does not matter in which order the slots were produced and consumed. @@ -35,7 +35,7 @@ WARNING: though the algorithm itself is completely wait-free but producers and consumer could be blocked by memory allocator - WARNING: copy constructors of the queue are not thread-safe + WARNING: copy constructors of the queue are not thread-safe */ #include <util/generic/deque.h> diff --git a/util/datetime/cputimer.cpp b/util/datetime/cputimer.cpp index 69e888e79e..516d372c37 100644 --- a/util/datetime/cputimer.cpp +++ b/util/datetime/cputimer.cpp @@ -36,7 +36,7 @@ static ui64 GetCyclesPerSecond() { if (ManuallySetCyclesPerSecond != 0) { return ManuallySetCyclesPerSecond; } else { - return NHPTimer::GetCyclesPerSecond(); + return NHPTimer::GetCyclesPerSecond(); } } diff --git a/util/folder/fts.cpp b/util/folder/fts.cpp index 9f18f8bd14..0e6a6f86eb 100644 --- a/util/folder/fts.cpp +++ b/util/folder/fts.cpp @@ -161,7 +161,7 @@ dird get_dird(char* path) { WCHAR* ret = _wfullpath(0, buf, 0); free(buf); - return ret; + return ret; } #endif // ndef _win_ diff --git a/util/generic/vector.h b/util/generic/vector.h index 7135d0af48..a5b258955a 100644 --- a/util/generic/vector.h +++ b/util/generic/vector.h @@ -68,7 +68,7 @@ public: } inline TVector(const TSelf& src) - : TBase(src) + : TBase(src) { } @@ -83,10 +83,10 @@ public: { } - inline TSelf& operator=(const TSelf& src) { - TBase::operator=(src); - return *this; - } + inline TSelf& operator=(const TSelf& src) { + TBase::operator=(src); + return *this; + } inline TSelf& operator=(TSelf&& src) noexcept { TBase::operator=(std::forward<TSelf>(src)); diff --git a/util/system/event.cpp b/util/system/event.cpp index d7cc5caaa0..79b3cdb291 100644 --- a/util/system/event.cpp +++ b/util/system/event.cpp @@ -43,7 +43,7 @@ public: return WaitForSingleObject(cond, (deadLine - now).MilliSeconds()) == WAIT_OBJECT_0; } - return (WaitForSingleObject(cond, 0) == WAIT_OBJECT_0); + return (WaitForSingleObject(cond, 0) == WAIT_OBJECT_0); } #else inline TEvImpl(ResetMode rmode) diff --git a/util/system/hp_timer.cpp b/util/system/hp_timer.cpp index a0bae5d50c..e4c3f21e6b 100644 --- a/util/system/hp_timer.cpp +++ b/util/system/hp_timer.cpp @@ -10,8 +10,8 @@ namespace { struct TFreq { inline TFreq() : Freq(InitHPTimer()) - , Rate(1.0 / Freq) - , CyclesPerSecond(static_cast<ui64>(Rate)) + , Rate(1.0 / Freq) + , CyclesPerSecond(static_cast<ui64>(Rate)) { } @@ -80,16 +80,16 @@ namespace { } inline double GetClockRate() const { - return Rate; + return Rate; + } + + inline ui64 GetCyclesPerSecond() const { + return CyclesPerSecond; } - inline ui64 GetCyclesPerSecond() const { - return CyclesPerSecond; - } - const double Freq; - const double Rate; - const ui64 CyclesPerSecond; + const double Rate; + const ui64 CyclesPerSecond; }; } @@ -102,9 +102,9 @@ double NHPTimer::GetClockRate() noexcept { } ui64 NHPTimer::GetCyclesPerSecond() noexcept { - return TFreq::Instance().GetCyclesPerSecond(); -} - + return TFreq::Instance().GetCyclesPerSecond(); +} + void NHPTimer::GetTime(STime* pTime) noexcept { *pTime = GetCycleCount(); } diff --git a/util/system/tls.h b/util/system/tls.h index 1f08352e50..3c4f56dbeb 100644 --- a/util/system/tls.h +++ b/util/system/tls.h @@ -193,7 +193,7 @@ namespace NTls { T* Construct(void* ptr) const override { //memset(ptr, 0, sizeof(T)); - return ::new (ptr) T(); + return ::new (ptr) T(); } }; @@ -208,7 +208,7 @@ namespace NTls { ~TCopyConstructor() override = default; T* Construct(void* ptr) const override { - return ::new (ptr) T(Value); + return ::new (ptr) T(Value); } private: diff --git a/ydb/core/actorlib_impl/long_timer.cpp b/ydb/core/actorlib_impl/long_timer.cpp index 8482b704f6..e3b139579f 100644 --- a/ydb/core/actorlib_impl/long_timer.cpp +++ b/ydb/core/actorlib_impl/long_timer.cpp @@ -1,61 +1,61 @@ -#include "long_timer.h" +#include "long_timer.h" #include <library/cpp/actors/core/hfunc.h> #include <library/cpp/actors/core/events.h> #include <ydb/core/protos/services.pb.h> - -namespace NActors { - -class TLongTimer : public TActor<TLongTimer> { - const static ui64 ThresholdSec = 15; - + +namespace NActors { + +class TLongTimer : public TActor<TLongTimer> { + const static ui64 ThresholdSec = 15; + TMonotonic StartTime; TMonotonic SignalTime; - TAutoPtr<IEventHandle> Ev; - TSchedulerCookieHolder Cookie; - - void PoisonPill(const TActorContext &ctx) { - return Die(ctx); - } - - void Round(const TActorContext &ctx) { - if (Cookie.Get() && !Cookie.Get()->IsArmed()) - return Die(ctx); - + TAutoPtr<IEventHandle> Ev; + TSchedulerCookieHolder Cookie; + + void PoisonPill(const TActorContext &ctx) { + return Die(ctx); + } + + void Round(const TActorContext &ctx) { + if (Cookie.Get() && !Cookie.Get()->IsArmed()) + return Die(ctx); + const TMonotonic now = ctx.Monotonic(); - if (SignalTime <= now) { - if (!Cookie.Get() || Cookie.Detach()) - ctx.ExecutorThread.Send(Ev); - return Die(ctx); - } - - const TDuration delta = SignalTime - now; - if (delta <= TDuration::Seconds(ThresholdSec)) { + if (SignalTime <= now) { + if (!Cookie.Get() || Cookie.Detach()) + ctx.ExecutorThread.Send(Ev); + return Die(ctx); + } + + const TDuration delta = SignalTime - now; + if (delta <= TDuration::Seconds(ThresholdSec)) { ctx.ExecutorThread.Schedule(SignalTime, Ev, Cookie.Release()); - return Die(ctx); - } - - ctx.Schedule(TDuration::Seconds(ThresholdSec), new TEvents::TEvWakeup()); - } -public: + return Die(ctx); + } + + ctx.Schedule(TDuration::Seconds(ThresholdSec), new TEvents::TEvWakeup()); + } +public: static constexpr auto ActorActivityType() { return NKikimrServices::TActivity::ACTORLIB_LONG_TIMER; } TLongTimer(TMonotonic startTime, TMonotonic signalTime, TAutoPtr<IEventHandle> ev, ISchedulerCookie *cookie) - : TActor(&TThis::StateFunc) - , StartTime(startTime) - , SignalTime(signalTime) - , Ev(ev) - , Cookie(cookie) - {} - - STFUNC(StateFunc) { - switch (ev->GetTypeRewrite()) { - CFunc(TEvents::TEvPoisonPill::EventType, PoisonPill); - CFunc(TEvents::TEvWakeup::EventType, Round); - } - } - + : TActor(&TThis::StateFunc) + , StartTime(startTime) + , SignalTime(signalTime) + , Ev(ev) + , Cookie(cookie) + {} + + STFUNC(StateFunc) { + switch (ev->GetTypeRewrite()) { + CFunc(TEvents::TEvPoisonPill::EventType, PoisonPill); + CFunc(TEvents::TEvWakeup::EventType, Round); + } + } + static TActorId Create( const TActivationContext &ctx, TDuration delta, @@ -64,19 +64,19 @@ public: ISchedulerCookie *cookie, const TActorId& parentId) { - if (delta.Seconds() < ThresholdSec) { // direct scheduling w/o creating actor + if (delta.Seconds() < ThresholdSec) { // direct scheduling w/o creating actor ctx.ExecutorThread.Schedule(delta, ev, cookie); return TActorId(); - } - + } + TMonotonic now = ctx.Monotonic(); TMonotonic signalTime = now + delta; ui64 semirandomNumber = parentId.LocalId(); const TActorId timerActorID = ctx.ExecutorThread.ActorSystem->Register(new TLongTimer(now, signalTime, ev, cookie), TMailboxType::HTSwap, poolId, semirandomNumber, parentId); ctx.ExecutorThread.Schedule(TDuration::Seconds(ThresholdSec), new IEventHandle(timerActorID, timerActorID, new TEvents::TEvWakeup())); - - return timerActorID; - } + + return timerActorID; + } static TActorId Create( TDuration delta, @@ -96,14 +96,14 @@ public: return timerActorID; } -}; - +}; + TActorId CreateLongTimer(const TActorContext &ctx, TDuration delta, TAutoPtr<IEventHandle> ev, ui32 poolId, ISchedulerCookie *cookie) { return TLongTimer::Create(ctx, delta, ev, poolId, cookie, ctx.SelfID); -} - +} + TActorId CreateLongTimer(TDuration delta, TAutoPtr<IEventHandle> ev, ui32 poolId, ISchedulerCookie *cookie) { return TLongTimer::Create(delta, ev, poolId, cookie); -} +} } diff --git a/ydb/core/actorlib_impl/long_timer.h b/ydb/core/actorlib_impl/long_timer.h index 4bab3edaad..9b04c30121 100644 --- a/ydb/core/actorlib_impl/long_timer.h +++ b/ydb/core/actorlib_impl/long_timer.h @@ -1,11 +1,11 @@ -#pragma once +#pragma once #include <library/cpp/actors/core/actor.h> - -namespace NActors { - + +namespace NActors { + TActorId CreateLongTimer(const TActorContext &ctx, TDuration delta, TAutoPtr<IEventHandle> ev, ui32 poolId = 0, ISchedulerCookie *cookie = nullptr); - + // uses TlsActivationContext, note that by default we use current pool TActorId CreateLongTimer(TDuration delta, TAutoPtr<IEventHandle> ev, ui32 poolId = Max<ui32>(), ISchedulerCookie *cookie = nullptr); -} +} diff --git a/ydb/core/actorlib_impl/mad_squirrel.cpp b/ydb/core/actorlib_impl/mad_squirrel.cpp index d6105e7639..3f9629d099 100644 --- a/ydb/core/actorlib_impl/mad_squirrel.cpp +++ b/ydb/core/actorlib_impl/mad_squirrel.cpp @@ -1,31 +1,31 @@ -#include "mad_squirrel.h" +#include "mad_squirrel.h" #include <library/cpp/actors/core/events.h> #include <library/cpp/actors/core/hfunc.h> - -namespace NActors { - -class TMadSquirrel : public TActor<TMadSquirrel> { + +namespace NActors { + +class TMadSquirrel : public TActor<TMadSquirrel> { TAutoPtr<IEventHandle> AfterRegister(const TActorId &self, const TActorId &) override { - return new IEventHandle(self, self, new TEvents::TEvWakeup()); - } - -public: + return new IEventHandle(self, self, new TEvents::TEvWakeup()); + } + +public: static constexpr auto ActorActivityType() { - return ACTORLIB_COMMON; + return ACTORLIB_COMMON; } - TMadSquirrel() - : TActor(&TThis::StateFunc) - {} - - STFUNC(StateFunc) { + TMadSquirrel() + : TActor(&TThis::StateFunc) + {} + + STFUNC(StateFunc) { Y_UNUSED(ev); - ctx.Send(ctx.SelfID, new TEvents::TEvWakeup()); - } -}; - -IActor* CreateMadSquirrel() { - return new TMadSquirrel(); -} - -} + ctx.Send(ctx.SelfID, new TEvents::TEvWakeup()); + } +}; + +IActor* CreateMadSquirrel() { + return new TMadSquirrel(); +} + +} diff --git a/ydb/core/actorlib_impl/mad_squirrel.h b/ydb/core/actorlib_impl/mad_squirrel.h index 22949d7acd..cce45d4aaa 100644 --- a/ydb/core/actorlib_impl/mad_squirrel.h +++ b/ydb/core/actorlib_impl/mad_squirrel.h @@ -1,10 +1,10 @@ -#pragma once +#pragma once #include <library/cpp/actors/core/actor.h> - -namespace NActors { - -IActor* CreateMadSquirrel(); // will send messages to itself in round + +namespace NActors { + +IActor* CreateMadSquirrel(); // will send messages to itself in round IActor* CreateMelancholicGopher(double surveyForSeconds, const TActorId &reportTo); // will spin for survey period and then wakeup next in line IActor* CreateGopherMother(const TVector<std::pair<ui32, double>> &lineProfile, ui32 lines, ui32 shotsInRound); // would spawn gophers according to profile (poolid, period) in lines number - -} + +} diff --git a/ydb/core/actorlib_impl/melancholic_gopher.cpp b/ydb/core/actorlib_impl/melancholic_gopher.cpp index 4eaae8b24f..52a895aae4 100644 --- a/ydb/core/actorlib_impl/melancholic_gopher.cpp +++ b/ydb/core/actorlib_impl/melancholic_gopher.cpp @@ -1,113 +1,113 @@ -#include "mad_squirrel.h" +#include "mad_squirrel.h" #include <library/cpp/actors/core/events.h> #include <library/cpp/actors/core/log.h> #include <library/cpp/actors/core/hfunc.h> #include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/actors/protos/services_common.pb.h> -#include <util/system/hp_timer.h> -#include <util/system/spinlock.h> - -namespace NActors { - -class TMelancholicGopher : public TActor<TMelancholicGopher> { - const double SurveyForSeconds; +#include <util/system/hp_timer.h> +#include <util/system/spinlock.h> + +namespace NActors { + +class TMelancholicGopher : public TActor<TMelancholicGopher> { + const double SurveyForSeconds; const TActorId ReportTo; - - void Round(const TActorContext &ctx) { - if (SurveyForSeconds > 0.0) { - THPTimer timer; - while (timer.Passed() < SurveyForSeconds) - SpinLockPause(); - } - ctx.Send(ReportTo, new TEvents::TEvWakeup()); - } -public: - static constexpr EActivityType ActorActivityType() { - return ACTORLIB_COMMON; + + void Round(const TActorContext &ctx) { + if (SurveyForSeconds > 0.0) { + THPTimer timer; + while (timer.Passed() < SurveyForSeconds) + SpinLockPause(); + } + ctx.Send(ReportTo, new TEvents::TEvWakeup()); + } +public: + static constexpr EActivityType ActorActivityType() { + return ACTORLIB_COMMON; } TMelancholicGopher(double surveyForSeconds, const TActorId &reportTo) - : TActor(&TThis::StateFunc) - , SurveyForSeconds(surveyForSeconds) - , ReportTo(reportTo) - {} - - STFUNC(StateFunc) { - switch (ev->GetTypeRewrite()) { - CFunc(TEvents::TEvWakeup::EventType, Round); - } - } - -}; - -class TGopherMother : public TActorBootstrapped<TGopherMother> { + : TActor(&TThis::StateFunc) + , SurveyForSeconds(surveyForSeconds) + , ReportTo(reportTo) + {} + + STFUNC(StateFunc) { + switch (ev->GetTypeRewrite()) { + CFunc(TEvents::TEvWakeup::EventType, Round); + } + } + +}; + +class TGopherMother : public TActorBootstrapped<TGopherMother> { const TVector<std::pair<ui32, double>> LineProfile; - const ui32 Lines; - const ui32 ShotsInRound; + const ui32 Lines; + const ui32 ShotsInRound; TVector<TActorId> HeadGophers; - ui32 WaitFor; - - TInstant RoundStart; - - void Round(const TActorContext &ctx) { - RoundStart = ctx.Now(); - - for (const auto &head : HeadGophers) - for (ui32 i = ShotsInRound; i > 0; --i) { - ctx.Send(head, new TEvents::TEvWakeup()); - ++WaitFor; - } - } - - void Response(const TActorContext &ctx) { - if (--WaitFor == 0) { - const TDuration roundTime = ctx.Now() - RoundStart; - LOG_INFO_S(ctx, NActorsServices::EServiceCommon::TEST, "Gopher Mother round for " << roundTime.ToString()); - Round(ctx); - } - } -public: - static constexpr EActivityType ActorActivityType() { - return ACTORLIB_COMMON; + ui32 WaitFor; + + TInstant RoundStart; + + void Round(const TActorContext &ctx) { + RoundStart = ctx.Now(); + + for (const auto &head : HeadGophers) + for (ui32 i = ShotsInRound; i > 0; --i) { + ctx.Send(head, new TEvents::TEvWakeup()); + ++WaitFor; + } + } + + void Response(const TActorContext &ctx) { + if (--WaitFor == 0) { + const TDuration roundTime = ctx.Now() - RoundStart; + LOG_INFO_S(ctx, NActorsServices::EServiceCommon::TEST, "Gopher Mother round for " << roundTime.ToString()); + Round(ctx); + } + } +public: + static constexpr EActivityType ActorActivityType() { + return ACTORLIB_COMMON; } TGopherMother(const TVector<std::pair<ui32, double>> &lineProfile, ui32 lines, ui32 shotsInRound) - : LineProfile(lineProfile) - , Lines(lines) - , ShotsInRound(shotsInRound) - , WaitFor(0) - { + : LineProfile(lineProfile) + , Lines(lines) + , ShotsInRound(shotsInRound) + , WaitFor(0) + { Y_VERIFY(!LineProfile.empty()); - } - - void Bootstrap(const TActorContext &ctx) { - HeadGophers.reserve(Lines); - for (ui32 lines = Lines; lines > 0; --lines) { + } + + void Bootstrap(const TActorContext &ctx) { + HeadGophers.reserve(Lines); + for (ui32 lines = Lines; lines > 0; --lines) { HeadGophers.push_back(TActorId()); TActorId &head = HeadGophers.back(); - head = ctx.SelfID; - for (const auto &xpair : LineProfile) - head = ctx.ExecutorThread.ActorSystem->Register(CreateMelancholicGopher(xpair.second, head), TMailboxType::Simple, xpair.first); - } - - Round(ctx); - Become(&TThis::StateWork); - } - - STFUNC(StateWork) { - switch (ev->GetTypeRewrite()) { - CFunc(TEvents::TEvWakeup::EventType, Response); - } - } -}; - + head = ctx.SelfID; + for (const auto &xpair : LineProfile) + head = ctx.ExecutorThread.ActorSystem->Register(CreateMelancholicGopher(xpair.second, head), TMailboxType::Simple, xpair.first); + } + + Round(ctx); + Become(&TThis::StateWork); + } + + STFUNC(StateWork) { + switch (ev->GetTypeRewrite()) { + CFunc(TEvents::TEvWakeup::EventType, Response); + } + } +}; + IActor* CreateMelancholicGopher(double surveyForSeconds, const TActorId &reportTo) { - return new TMelancholicGopher(surveyForSeconds, reportTo); -} - - + return new TMelancholicGopher(surveyForSeconds, reportTo); +} + + IActor* CreateGopherMother(const TVector<std::pair<ui32, double>> &lineProfile, ui32 lines, ui32 shotsInRound) { - return new TGopherMother(lineProfile, lines, shotsInRound); -} - -} + return new TGopherMother(lineProfile, lines, shotsInRound); +} + +} diff --git a/ydb/core/actorlib_impl/proto_ready_actor.h b/ydb/core/actorlib_impl/proto_ready_actor.h index 83627ff1f4..f0b29ec65f 100644 --- a/ydb/core/actorlib_impl/proto_ready_actor.h +++ b/ydb/core/actorlib_impl/proto_ready_actor.h @@ -70,7 +70,7 @@ public: template <typename T> void Become(T stateFunc, const char* hint = "undef") noexcept { - Y_UNUSED(hint); + Y_UNUSED(hint); DerivedActorFunc = static_cast<IActor::TReceiveFunc>(stateFunc); } diff --git a/ydb/core/actorlib_impl/test_interconnect_ut.cpp b/ydb/core/actorlib_impl/test_interconnect_ut.cpp index 7bf4b9700e..0d9d3535ef 100644 --- a/ydb/core/actorlib_impl/test_interconnect_ut.cpp +++ b/ydb/core/actorlib_impl/test_interconnect_ut.cpp @@ -80,7 +80,7 @@ Y_UNIT_TEST_SUITE(TInterconnectTest) { void OnStart(const NActors::TActorContext &ctx) noexcept { Become(&TThis::WaitFunc); - ctx.Send(TActivationContext::InterconnectProxy(Peer.NodeId()), new TEvInterconnect::TEvConnectNode, true); + ctx.Send(TActivationContext::InterconnectProxy(Peer.NodeId()), new TEvInterconnect::TEvConnectNode, true); } void OnConnect(const NActors::TActorContext &ctx) noexcept { diff --git a/ydb/core/actorlib_impl/ya.make b/ydb/core/actorlib_impl/ya.make index 28a9d482a6..ba63f39617 100644 --- a/ydb/core/actorlib_impl/ya.make +++ b/ydb/core/actorlib_impl/ya.make @@ -1,12 +1,12 @@ -LIBRARY() - +LIBRARY() + OWNER( a-romanov ddoarn g:kikimr ) -SRCS( +SRCS( actor_tracker.cpp actor_tracker.h async_destroyer.h @@ -17,11 +17,11 @@ SRCS( http_request_protocol.h load_network.cpp load_network.h - long_timer.cpp - long_timer.h + long_timer.cpp + long_timer.h mad_squirrel.cpp - mad_squirrel.h - melancholic_gopher.cpp + mad_squirrel.h + melancholic_gopher.cpp name_service_client_protocol.cpp name_service_client_protocol.h node_identifier.cpp @@ -31,12 +31,12 @@ SRCS( read_data_protocol.h read_http_reply_protocol.cpp read_http_reply_protocol.h - router_rr.h + router_rr.h send_data_protocol.cpp send_data_protocol.h -) - -PEERDIR( +) + +PEERDIR( library/cpp/actors/core library/cpp/actors/dnscachelib library/cpp/actors/protos @@ -55,11 +55,11 @@ PEERDIR( ydb/core/node_whiteboard ydb/core/protos ydb/core/util -) - +) + YQL_LAST_ABI_VERSION() -END() +END() RECURSE_FOR_TESTS( ut diff --git a/ydb/core/base/appdata.cpp b/ydb/core/base/appdata.cpp index e54e08cbab..f9e517fc42 100644 --- a/ydb/core/base/appdata.cpp +++ b/ydb/core/base/appdata.cpp @@ -9,7 +9,7 @@ TAppData::TAppData( const NScheme::TTypeRegistry* typeRegistry, const NMiniKQL::IFunctionRegistry* functionRegistry, const TFormatFactory* formatFactory, - TProgramShouldContinue *kikimrShouldContinue) + TProgramShouldContinue *kikimrShouldContinue) : Magic(MagicTag) , SystemPoolId(sysPoolId) , UserPoolId(userPoolId) @@ -19,12 +19,12 @@ TAppData::TAppData( , TypeRegistry(typeRegistry) , FunctionRegistry(functionRegistry) , FormatFactory(formatFactory) - , ProxySchemeCacheNodes(Max<ui64>() / 4) - , ProxySchemeCacheDistrNodes(Max<ui64>() / 4) - , CompilerSchemeCachePaths(Max<ui64>() / 4) - , CompilerSchemeCacheTables(Max<ui64>() / 4) + , ProxySchemeCacheNodes(Max<ui64>() / 4) + , ProxySchemeCacheDistrNodes(Max<ui64>() / 4) + , CompilerSchemeCachePaths(Max<ui64>() / 4) + , CompilerSchemeCacheTables(Max<ui64>() / 4) , Mon(nullptr) - , BusMonPage(nullptr) + , BusMonPage(nullptr) , Icb(new TControlBoard()) , InFlightLimiterRegistry(new NGRpcService::TInFlightLimiterRegistry(Icb)) , StaticBlobStorageConfig(new NKikimrBlobStorage::TNodeWardenServiceSet) diff --git a/ydb/core/base/appdata.h b/ydb/core/base/appdata.h index d2da0db584..c666f7468c 100644 --- a/ydb/core/base/appdata.h +++ b/ydb/core/base/appdata.h @@ -1,8 +1,8 @@ -#pragma once +#pragma once -#include "defs.h" +#include "defs.h" #include "channel_profiles.h" -#include "domain.h" +#include "domain.h" #include "feature_flags.h" #include "nameservice.h" #include "tablet_types.h" @@ -25,21 +25,21 @@ #include <library/cpp/random_provider/random_provider.h> #include <library/cpp/time_provider/time_provider.h> #include <library/cpp/monlib/dynamic_counters/counters.h> - + namespace NActors { class TMon; } -namespace NMonitoring { - class TBusNgMonPage; -} - +namespace NMonitoring { + class TBusNgMonPage; +} + namespace NYdb { class TDriver; } -namespace NKikimr { - +namespace NKikimr { + namespace NScheme { class TTypeRegistry; } @@ -63,16 +63,16 @@ namespace NPQ { class TFormatFactory; -struct TAppData { - static const ui32 MagicTag = 0x2991AAF8; - const ui32 Magic; - - const ui32 SystemPoolId; - const ui32 UserPoolId; - const ui32 IOPoolId; - const ui32 BatchPoolId; +struct TAppData { + static const ui32 MagicTag = 0x2991AAF8; + const ui32 Magic; + + const ui32 SystemPoolId; + const ui32 UserPoolId; + const ui32 IOPoolId; + const ui32 BatchPoolId; TMap<TString, ui32> ServicePools; - + const NScheme::TTypeRegistry* TypeRegistry = nullptr; const NMiniKQL::IFunctionRegistry* FunctionRegistry = nullptr; const NDataShard::IExportFactory *DataShardExportFactory = nullptr; @@ -103,7 +103,7 @@ struct TAppData { TTabletTypes::EType TestShard; TTabletTypes::EType SequenceShard; TTabletTypes::EType ReplicationController; - + TDefaultTabletTypes(); }; @@ -111,19 +111,19 @@ struct TAppData { static TIntrusivePtr<IRandomProvider> RandomProvider; static TIntrusivePtr<ITimeProvider> TimeProvider; - TIntrusivePtr<TDomainsInfo> DomainsInfo; + TIntrusivePtr<TDomainsInfo> DomainsInfo; TIntrusivePtr<TChannelProfiles> ChannelProfiles; TIntrusivePtr<TDynamicNameserviceConfig> DynamicNameserviceConfig; - ui64 ProxySchemeCacheNodes; - ui64 ProxySchemeCacheDistrNodes; - - ui64 CompilerSchemeCachePaths; - ui64 CompilerSchemeCacheTables; - + ui64 ProxySchemeCacheNodes; + ui64 ProxySchemeCacheDistrNodes; + + ui64 CompilerSchemeCachePaths; + ui64 CompilerSchemeCacheTables; + NActors::TMon* Mon; NMonitoring::TDynamicCounterPtr Counters; - NMonitoring::TBusNgMonPage* BusMonPage; + NMonitoring::TBusNgMonPage* BusMonPage; TIntrusivePtr<NKikimr::TControlBoard> Icb; TIntrusivePtr<NGRpcService::TInFlightLimiterRegistry> InFlightLimiterRegistry; @@ -156,9 +156,9 @@ struct TAppData { TString AllAuthenticatedUsers; TResourceProfilesPtr ResourceProfiles; - TProgramShouldContinue * const KikimrShouldContinue; + TProgramShouldContinue * const KikimrShouldContinue; bool EnableIntrospection = true; - + // Used to allow column families for testing bool AllowColumnFamiliesForTest = false; bool AllowPrivateTableDescribeForTest = false; @@ -177,22 +177,22 @@ struct TAppData { const NScheme::TTypeRegistry* typeRegistry, const NMiniKQL::IFunctionRegistry* functionRegistry, const TFormatFactory* formatFactory, - TProgramShouldContinue *kikimrShouldContinue); -}; - + TProgramShouldContinue *kikimrShouldContinue); +}; + inline TAppData* AppData(TActorSystem* actorSystem) { Y_VERIFY_DEBUG(actorSystem); TAppData * const x = actorSystem->AppData<TAppData>(); Y_VERIFY_DEBUG(x && x->Magic == TAppData::MagicTag); - return x; -} - + return x; +} + inline TAppData* AppData() { return AppData(TlsActivationContext->ExecutorThread.ActorSystem); } -inline TAppData* AppData(const TActorContext &ctx) { +inline TAppData* AppData(const TActorContext &ctx) { return AppData(ctx.ActorSystem()); -} - +} + } // NKikimr diff --git a/ydb/core/base/blobstorage.h b/ydb/core/base/blobstorage.h index c68e771e76..a2faee326e 100644 --- a/ydb/core/base/blobstorage.h +++ b/ydb/core/base/blobstorage.h @@ -1,11 +1,11 @@ -#pragma once +#pragma once #include "defs.h" #include "blobstorage_pdisk_category.h" #include "events.h" #include "tablet_types.h" #include "logoblob.h" -#include "pathid.h" +#include "pathid.h" #include <ydb/core/base/services/blobstorage_service_id.h> #include <ydb/core/base/blobstorage_grouptype.h> @@ -13,16 +13,16 @@ #include <ydb/core/protos/blobstorage.pb.h> #include <ydb/core/protos/blobstorage_config.pb.h> #include <ydb/core/util/yverify_stream.h> - + #include <ydb/library/wilson/wilson_event.h> #include <library/cpp/lwtrace/shuttle.h> #include <util/stream/str.h> -#include <util/generic/xrange.h> +#include <util/generic/xrange.h> + +namespace NKikimr { -namespace NKikimr { - static constexpr ui32 MaxProtobufSize = 67108000; static constexpr ui32 MaxVDiskBlobSize = 10 << 20; // 10 megabytes static constexpr ui64 MaxCollectGarbageFlagsPerMessage = 10000; @@ -62,8 +62,8 @@ struct TStorageStatusFlags { bool Check(NKikimrBlobStorage::EStatusFlags statusToCheck) const { return (Raw & ui32(NKikimrBlobStorage::StatusIsValid)) && (Raw & ui32(statusToCheck)); - } - + } + TString ToString() const { TStringStream str; Output(str); @@ -88,25 +88,25 @@ NKikimrBlobStorage::EPDiskType PDiskTypeToPDiskType(const TPDiskCategory::EDevic TPDiskCategory::EDeviceType PDiskTypeToPDiskType(const NKikimrBlobStorage::EPDiskType type); -enum EGroupConfigurationType { - GroupConfigurationTypeStatic = 0, - GroupConfigurationTypeDynamic = 1 -}; - -struct TGroupID { +enum EGroupConfigurationType { + GroupConfigurationTypeStatic = 0, + GroupConfigurationTypeDynamic = 1 +}; + +struct TGroupID { TGroupID() { Set((EGroupConfigurationType)0x1, 0x3f, InvalidLocalId); } TGroupID(EGroupConfigurationType configurationType, ui32 dataCenterId, ui32 groupLocalId) { - Set(configurationType, dataCenterId, groupLocalId); - } + Set(configurationType, dataCenterId, groupLocalId); + } TGroupID(const TGroupID& group) { Raw.X = group.GetRaw(); } - explicit TGroupID(ui32 raw) { Raw.X = raw; } - EGroupConfigurationType ConfigurationType() const { return (EGroupConfigurationType)Raw.N.ConfigurationType; } - ui32 AvailabilityDomainID() const { return Raw.N.AvailabilityDomainID; } - ui32 GroupLocalID() const { return Raw.N.GroupLocalID; } - ui32 GetRaw() const { return Raw.X; } - bool operator==(const TGroupID &x) const { return GetRaw() == x.GetRaw(); } - bool operator!=(const TGroupID &x) const { return GetRaw() != x.GetRaw(); } - + explicit TGroupID(ui32 raw) { Raw.X = raw; } + EGroupConfigurationType ConfigurationType() const { return (EGroupConfigurationType)Raw.N.ConfigurationType; } + ui32 AvailabilityDomainID() const { return Raw.N.AvailabilityDomainID; } + ui32 GroupLocalID() const { return Raw.N.GroupLocalID; } + ui32 GetRaw() const { return Raw.X; } + bool operator==(const TGroupID &x) const { return GetRaw() == x.GetRaw(); } + bool operator!=(const TGroupID &x) const { return GetRaw() != x.GetRaw(); } + TGroupID operator++() { Set(ConfigurationType(), AvailabilityDomainID(), NextValidLocalId()); return *this; @@ -118,25 +118,25 @@ struct TGroupID { } TString ToString() const; -private: - union { - struct { - ui32 GroupLocalID : 25; - ui32 AvailabilityDomainID : 6; - ui32 ConfigurationType : 1; - } N; - - ui32 X; - } Raw; - - void Set(EGroupConfigurationType configurationType, ui32 availabilityDomainID, ui32 groupLocalId) { - Y_VERIFY(ui32(configurationType) < (1 << 2)); - Y_VERIFY(ui32(availabilityDomainID) < (1 << 7)); - Y_VERIFY(ui32(groupLocalId) < (1 << 26)); - Raw.N.ConfigurationType = configurationType; - Raw.N.AvailabilityDomainID = availabilityDomainID; - Raw.N.GroupLocalID = groupLocalId; - } +private: + union { + struct { + ui32 GroupLocalID : 25; + ui32 AvailabilityDomainID : 6; + ui32 ConfigurationType : 1; + } N; + + ui32 X; + } Raw; + + void Set(EGroupConfigurationType configurationType, ui32 availabilityDomainID, ui32 groupLocalId) { + Y_VERIFY(ui32(configurationType) < (1 << 2)); + Y_VERIFY(ui32(availabilityDomainID) < (1 << 7)); + Y_VERIFY(ui32(groupLocalId) < (1 << 26)); + Raw.N.ConfigurationType = configurationType; + Raw.N.AvailabilityDomainID = availabilityDomainID; + Raw.N.GroupLocalID = groupLocalId; + } ui32 NextValidLocalId() { const ui32 localId = GroupLocalID(); @@ -150,51 +150,51 @@ private: } static constexpr ui32 InvalidLocalId = 0x1ffffff; - static_assert(sizeof(decltype(Raw)) == sizeof(ui32), "TGroupID Raw value must be binary compatible with ui32"); -}; - -struct TPDiskID { - TPDiskID() { Set((EGroupConfigurationType)0x1, 0x3f, 0x1ffffff); } - explicit TPDiskID(EGroupConfigurationType configurationType, ui32 availabilityDomainID, ui32 pDiskLocalId) { - Set(configurationType, availabilityDomainID, pDiskLocalId); - } - explicit TPDiskID(ui32 raw) { Raw.X = raw; } - EGroupConfigurationType ConfigurationType() const { return (EGroupConfigurationType)Raw.N.ConfigurationType; } - ui32 AvailabilityDomainID() const { return Raw.N.AvailabilityDomainID; } - ui32 PDiskLocalID() const { return Raw.N.PDiskLocalID; } - ui32 GetRaw() const { return Raw.X; } - bool operator==(const TPDiskID &x) const { return GetRaw() == x.GetRaw(); } - + static_assert(sizeof(decltype(Raw)) == sizeof(ui32), "TGroupID Raw value must be binary compatible with ui32"); +}; + +struct TPDiskID { + TPDiskID() { Set((EGroupConfigurationType)0x1, 0x3f, 0x1ffffff); } + explicit TPDiskID(EGroupConfigurationType configurationType, ui32 availabilityDomainID, ui32 pDiskLocalId) { + Set(configurationType, availabilityDomainID, pDiskLocalId); + } + explicit TPDiskID(ui32 raw) { Raw.X = raw; } + EGroupConfigurationType ConfigurationType() const { return (EGroupConfigurationType)Raw.N.ConfigurationType; } + ui32 AvailabilityDomainID() const { return Raw.N.AvailabilityDomainID; } + ui32 PDiskLocalID() const { return Raw.N.PDiskLocalID; } + ui32 GetRaw() const { return Raw.X; } + bool operator==(const TPDiskID &x) const { return GetRaw() == x.GetRaw(); } + TString ToString() const; -private: - union { - struct { - ui32 PDiskLocalID : 25; - ui32 AvailabilityDomainID : 6; - ui32 ConfigurationType : 1; - } N; - - ui32 X; - } Raw; - - void Set(EGroupConfigurationType configurationType, ui32 availabilityDomainID, ui32 pDiskLocalId) { - Y_VERIFY(ui32(configurationType) < (1 << 2)); - Y_VERIFY(ui32(availabilityDomainID) < (1 << 7)); - Y_VERIFY(ui32(pDiskLocalId) < (1 << 26)); - Raw.N.ConfigurationType = configurationType; - Raw.N.AvailabilityDomainID = availabilityDomainID; - Raw.N.PDiskLocalID = pDiskLocalId; - } - static_assert(sizeof(decltype(Raw)) == sizeof(ui32), "TPDiskID Raw value must be binary compatible with ui32"); -}; - -// channel info for tablet -struct TTabletChannelInfo { - struct THistoryEntry { - ui32 FromGeneration; - ui32 GroupID; +private: + union { + struct { + ui32 PDiskLocalID : 25; + ui32 AvailabilityDomainID : 6; + ui32 ConfigurationType : 1; + } N; + + ui32 X; + } Raw; + + void Set(EGroupConfigurationType configurationType, ui32 availabilityDomainID, ui32 pDiskLocalId) { + Y_VERIFY(ui32(configurationType) < (1 << 2)); + Y_VERIFY(ui32(availabilityDomainID) < (1 << 7)); + Y_VERIFY(ui32(pDiskLocalId) < (1 << 26)); + Raw.N.ConfigurationType = configurationType; + Raw.N.AvailabilityDomainID = availabilityDomainID; + Raw.N.PDiskLocalID = pDiskLocalId; + } + static_assert(sizeof(decltype(Raw)) == sizeof(ui32), "TPDiskID Raw value must be binary compatible with ui32"); +}; + +// channel info for tablet +struct TTabletChannelInfo { + struct THistoryEntry { + ui32 FromGeneration; + ui32 GroupID; TInstant Timestamp; // for diagnostics usage only - + THistoryEntry() : FromGeneration(0) , GroupID(0) @@ -206,11 +206,11 @@ struct TTabletChannelInfo { , Timestamp(timestamp) {} - struct TCmp { - bool operator()(ui32 gen, const THistoryEntry &x) const { - return gen < x.FromGeneration; - } - }; + struct TCmp { + bool operator()(ui32 gen, const THistoryEntry &x) const { + return gen < x.FromGeneration; + } + }; TString ToString() const { TStringStream str; @@ -225,13 +225,13 @@ struct TTabletChannelInfo { return FromGeneration == other.FromGeneration && (GroupID == other.GroupID || GroupID == 0 || other.GroupID == 0); } - }; - - ui32 Channel; - TBlobStorageGroupType Type; + }; + + ui32 Channel; + TBlobStorageGroupType Type; TString StoragePool; TVector<THistoryEntry> History; - + TTabletChannelInfo() : Channel() , Type() @@ -252,38 +252,38 @@ struct TTabletChannelInfo { , Type(TBlobStorageGroupType::ErasureNone) , StoragePool(storagePool) {} - - ui32 GroupForGeneration(ui32 gen) const { - const size_t historySize = History.size(); + + ui32 GroupForGeneration(ui32 gen) const { + const size_t historySize = History.size(); Y_VERIFY(historySize > 0, "empty channel history"); - - const THistoryEntry * const first = &*History.begin(); - if (historySize == 1) { - if (first->FromGeneration <= gen) - return first->GroupID; - return Max<ui32>(); - } - - const THistoryEntry * const end = first + historySize; - const THistoryEntry * const last = end - 1; - if (last->FromGeneration <= gen) { - return last->GroupID; - } - - const THistoryEntry *x = UpperBound(first, end, gen, THistoryEntry::TCmp()); - if (x != first) { - return (x - 1)->GroupID; - } - - return Max<ui32>(); - } - - const THistoryEntry* LatestEntry() const { + + const THistoryEntry * const first = &*History.begin(); + if (historySize == 1) { + if (first->FromGeneration <= gen) + return first->GroupID; + return Max<ui32>(); + } + + const THistoryEntry * const end = first + historySize; + const THistoryEntry * const last = end - 1; + if (last->FromGeneration <= gen) { + return last->GroupID; + } + + const THistoryEntry *x = UpperBound(first, end, gen, THistoryEntry::TCmp()); + if (x != first) { + return (x - 1)->GroupID; + } + + return Max<ui32>(); + } + + const THistoryEntry* LatestEntry() const { if (!History.empty()) - return &History.back(); - else - return nullptr; - } + return &History.back(); + else + return nullptr; + } const THistoryEntry* PreviousEntry() const { if (History.size() > 1) @@ -308,8 +308,8 @@ struct TTabletChannelInfo { str << "}"; return str.Str(); } -}; - +}; + class TTabletStorageInfo : public TThrRefBase { public: // @@ -324,8 +324,8 @@ public: , Version(0) {} virtual ~TTabletStorageInfo() {} - - const TTabletChannelInfo* ChannelInfo(ui32 channel) const { + + const TTabletChannelInfo* ChannelInfo(ui32 channel) const { if (Channels.size() <= channel) { return nullptr; } @@ -333,16 +333,16 @@ public: if (info.History.empty()) { return nullptr; } - return &info; - } + return &info; + } + + ui32 GroupFor(ui32 channel, ui32 recordGen) const { + if (const TTabletChannelInfo *channelInfo = ChannelInfo(channel)) + return channelInfo->GroupForGeneration(recordGen); + else + return Max<ui32>(); + } - ui32 GroupFor(ui32 channel, ui32 recordGen) const { - if (const TTabletChannelInfo *channelInfo = ChannelInfo(channel)) - return channelInfo->GroupForGeneration(recordGen); - else - return Max<ui32>(); - } - TString ToString() const { TStringStream str; str << "{Version# " << Version; @@ -357,48 +357,48 @@ public: str << channelIdx << ":" << Channels[channelIdx].ToString(); } str << "}"; - if (TenantPathId) - str << " Tenant: " << TenantPathId; + if (TenantPathId) + str << " Tenant: " << TenantPathId; return str.Str(); } TActorId BSProxyIDForChannel(ui32 channel, ui32 generation) const; - - bool operator<(const TTabletStorageInfo &other) const noexcept { + + bool operator<(const TTabletStorageInfo &other) const noexcept { if (Version != 0 && other.Version != 0) { return Version < other.Version; } - const size_t selfSize = Channels.size(); - const size_t otherSize = other.Channels.size(); - if (selfSize != otherSize) - return (selfSize < otherSize); - - for (ui64 channelIdx : xrange(selfSize)) { - const ui32 lastInSelf = Channels[channelIdx].History.back().FromGeneration; - const ui32 lastInOther = other.Channels[channelIdx].History.back().FromGeneration; - if (lastInSelf != lastInOther) - return (lastInSelf < lastInOther); - } - - return false; - } - + const size_t selfSize = Channels.size(); + const size_t otherSize = other.Channels.size(); + if (selfSize != otherSize) + return (selfSize < otherSize); + + for (ui64 channelIdx : xrange(selfSize)) { + const ui32 lastInSelf = Channels[channelIdx].History.back().FromGeneration; + const ui32 lastInOther = other.Channels[channelIdx].History.back().FromGeneration; + if (lastInSelf != lastInOther) + return (lastInSelf < lastInOther); + } + + return false; + } + // ui64 TabletID; TVector<TTabletChannelInfo> Channels; TTabletTypes::EType TabletType; ui32 Version; - TPathId TenantPathId; + TPathId TenantPathId; ui64 HiveId = 0; -}; - +}; + inline TActorId TTabletStorageInfo::BSProxyIDForChannel(ui32 channel, ui32 generation) const { const ui32 group = GroupFor(channel, generation); Y_VERIFY(group != Max<ui32>()); const TActorId proxy = MakeBlobStorageProxyID(group); - return proxy; -} - + return proxy; +} + inline ui32 GroupIDFromBlobStorageProxyID(TActorId actorId) { ui32 blobStorageGroup = ui32( ((actorId.RawX1() >> (7 * 8)) & 0xff) | @@ -418,11 +418,11 @@ inline IEventHandle *CreateEventForBSProxy(TActorId sender, TActorId recipient, ptr.release(); return res; } - + inline IEventHandle *CreateEventForBSProxy(TActorId sender, ui32 groupId, IEventBase *ev, ui64 cookie, NWilson::TTraceId traceId = {}) { return CreateEventForBSProxy(sender, MakeBlobStorageProxyID(groupId), ev, cookie, std::move(traceId)); -} - +} + inline bool SendToBSProxy(TActorId sender, TActorId recipient, IEventBase *ev, ui64 cookie = 0, NWilson::TTraceId traceId = {}) { return TActivationContext::Send(CreateEventForBSProxy(sender, recipient, ev, cookie, std::move(traceId))); } @@ -430,49 +430,49 @@ inline bool SendToBSProxy(TActorId sender, TActorId recipient, IEventBase *ev, u inline bool SendToBSProxy(const TActorContext &ctx, TActorId recipient, IEventBase *ev, ui64 cookie = 0, NWilson::TTraceId traceId = {}) { return ctx.Send(CreateEventForBSProxy(ctx.SelfID, recipient, ev, cookie, std::move(traceId))); -} +} inline bool SendToBSProxy(TActorId sender, ui32 groupId, IEventBase *ev, ui64 cookie = 0, NWilson::TTraceId traceId = {}) { return TActivationContext::Send(CreateEventForBSProxy(sender, groupId, ev, cookie, std::move(traceId))); -} - +} + inline bool SendToBSProxy(const TActorContext &ctx, ui32 groupId, IEventBase *ev, ui64 cookie = 0, NWilson::TTraceId traceId = {}) { return ctx.Send(CreateEventForBSProxy(ctx.SelfID, groupId, ev, cookie, std::move(traceId))); -} - -struct TEvBlobStorage { - enum EEv { - // user <-> proxy interface +} + +struct TEvBlobStorage { + enum EEv { + // user <-> proxy interface EvPut = EventSpaceBegin(TKikimrEvents::ES_BLOBSTORAGE), /// 268 632 064 - EvGet, - EvBlock, - EvDiscover, - EvRange, - EvProbe, + EvGet, + EvBlock, + EvDiscover, + EvRange, + EvProbe, EvCollectGarbage, EvStatus, EvVBaldSyncLog, EvPatch, EvInplacePatch, - - // + + // EvPutResult = EvPut + 512, /// 268 632 576 - EvGetResult, - EvBlockResult, - EvDiscoverResult, - EvRangeResult, - EvProbeResult, + EvGetResult, + EvBlockResult, + EvDiscoverResult, + EvRangeResult, + EvProbeResult, EvCollectGarbageResult, EvStatusResult, EvVBaldSyncLogResult, EvPatchResult, EvInplacePatchResult, - - // proxy <-> vdisk interface + + // proxy <-> vdisk interface EvVPut = EvPut + 2 * 512, /// 268 633 088 - EvVGet, - EvVBlock, + EvVGet, + EvVBlock, EvVGetBlock, EvVCollectGarbage, EvVGetBarrier, @@ -488,10 +488,10 @@ struct TEvBlobStorage { EvVPatchXorDiff, EvVDefrag, EvVInplacePatch, - + EvVPutResult = EvPut + 3 * 512, /// 268 633 600 - EvVGetResult, - EvVBlockResult, + EvVGetResult, + EvVBlockResult, EvVGetBlockResult, EvVCollectGarbageResult, EvVGetBarrierResult, @@ -507,29 +507,29 @@ struct TEvBlobStorage { EvVPatchResult, EvVDefragResult, EvVInplacePatchResult, - - // vdisk <-> vdisk interface + + // vdisk <-> vdisk interface EvVDisk = EvPut + 4 * 512, /// 268 634 112 EvVSync, EvVSyncFull, EvVSyncGuid, - + EvVDiskReply = EvPut + 5 * 512, /// 268 634 624 EvVSyncResult, EvVSyncFullResult, EvVSyncGuidResult, - - // vdisk <-> controller interface, + + // vdisk <-> controller interface, EvCnt = EvPut + 6 * 512, /// 268 635 136 EvVGenerationChange, EvRegisterPDiskLoadActor, EvStatusUpdate, EvDropDonor, - + EvCntReply = EvPut + 7 * 512, /// 268 635 648 EvVGenerationChangeResult, EvRegisterPDiskLoadActorResult, - + // internal vdisk interface EvYardInit = EvPut + 8 * 512, /// 268 636 160 EvLog, @@ -842,12 +842,12 @@ struct TEvBlobStorage { EvIncrHugeReadLogResult, EvIncrHugeScanResult, - EvEnd - }; - + EvEnd + }; + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_BLOBSTORAGE), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_BLOBSTORAGE)"); - + struct TEvPutResult; struct TEvGetResult; struct TEvBlockResult; @@ -858,7 +858,7 @@ struct TEvBlobStorage { struct TEvPatchResult; struct TEvInplacePatchResult; - struct TEvPut : public TEventLocal<TEvPut, EvPut> { + struct TEvPut : public TEventLocal<TEvPut, EvPut> { enum ETactic { TacticMaxThroughput = 0, TacticMinLatency, @@ -878,19 +878,19 @@ struct TEvBlobStorage { } }; - const TLogoBlobID Id; + const TLogoBlobID Id; const TString Buffer; const TInstant Deadline; const NKikimrBlobStorage::EPutHandleClass HandleClass; const ETactic Tactic; mutable NLWTrace::TOrbit Orbit; ui32 RestartCounter = 0; - + TEvPut(const TLogoBlobID &id, const TString &buffer, TInstant deadline, NKikimrBlobStorage::EPutHandleClass handleClass = NKikimrBlobStorage::TabletLog, ETactic tactic = TacticDefault) - : Id(id) - , Buffer(buffer) + : Id(id) + , Buffer(buffer) , Deadline(deadline) , HandleClass(handleClass) , Tactic(tactic) @@ -933,25 +933,25 @@ struct TEvBlobStorage { std::unique_ptr<TEvPutResult> MakeErrorResponse(NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 groupId); - }; - - struct TEvPutResult : public TEventLocal<TEvPutResult, EvPutResult> { - NKikimrProto::EReplyStatus Status; - const TLogoBlobID Id; + }; + + struct TEvPutResult : public TEventLocal<TEvPutResult, EvPutResult> { + NKikimrProto::EReplyStatus Status; + const TLogoBlobID Id; const TStorageStatusFlags StatusFlags; const ui32 GroupId; const float ApproximateFreeSpaceShare; // 0.f has special meaning 'data could not be obtained' TString ErrorReason; mutable NLWTrace::TOrbit Orbit; - + TEvPutResult(NKikimrProto::EReplyStatus status, const TLogoBlobID &id, const TStorageStatusFlags statusFlags, ui32 groupId, float approximateFreeSpaceShare) - : Status(status) - , Id(id) + : Status(status) + , Id(id) , StatusFlags(statusFlags) , GroupId(groupId) , ApproximateFreeSpaceShare(approximateFreeSpaceShare) - {} + {} TString Print(bool isFull) const { Y_UNUSED(isFull); @@ -970,29 +970,29 @@ struct TEvBlobStorage { TString ToString() const { return Print(false); } - }; - - struct TEvGet : public TEventLocal<TEvGet, EvGet> { - struct TQuery { - TLogoBlobID Id; - ui32 Shift; - ui32 Size; - - TQuery() - : Shift(0) - , Size(0) - {} - + }; + + struct TEvGet : public TEventLocal<TEvGet, EvGet> { + struct TQuery { + TLogoBlobID Id; + ui32 Shift; + ui32 Size; + + TQuery() + : Shift(0) + , Size(0) + {} + void Set(const TLogoBlobID &id, ui32 sh = 0, ui32 sz = 0) { - Id = id; - Shift = sh; - Size = sz; + Id = id; + Shift = sh; + Size = sz; Y_VERIFY(id.BlobSize() > 0, "Please, don't read/write 0-byte blobs!"); Y_VERIFY(sh < id.BlobSize(), "Please, don't read behind the end of the blob! BlobSize# %" PRIu32 " sh# %" PRIu32, (ui32)id.BlobSize(), (ui32)sh); - } + } TString ToString() const { TStringStream str; @@ -1002,11 +1002,11 @@ struct TEvBlobStorage { str << "}"; return str.Str(); } - }; - - // todo: replace with queue-like thing + }; + + // todo: replace with queue-like thing const ui32 QuerySize; - TArrayHolder<TQuery> Queries; + TArrayHolder<TQuery> Queries; TInstant Deadline; bool MustRestoreFirst; NKikimrBlobStorage::EGetHandleClass GetHandleClass; @@ -1017,19 +1017,19 @@ struct TEvBlobStorage { bool IsVerboseNoDataEnabled; // Debug use only bool IsInternal = false; // set to true if generated by ds proxy bool CollectDebugInfo = false; // collect query debug info and return in response - ui32 ForceBlockedGeneration = 0; + ui32 ForceBlockedGeneration = 0; bool ReportDetailedPartMap = false; ui32 RestartCounter = 0; bool PhantomCheck = false; - + // NKikimrBlobStorage::EGetHandleClass::FastRead TEvGet(TArrayHolder<TQuery> &q, ui32 sz, TInstant deadline, NKikimrBlobStorage::EGetHandleClass getHandleClass, bool mustRestoreFirst = false, bool isIndexOnly = false, ui32 forceBlockedGeneration = 0, bool isInternal = false, bool isVerboseNoDataEnabled = false, bool collectDebugInfo = false, bool reportDetailedPartMap = false) - : QuerySize(sz) - , Queries(q.Release()) + : QuerySize(sz) + , Queries(q.Release()) , Deadline(deadline) , MustRestoreFirst(mustRestoreFirst) , GetHandleClass(getHandleClass) @@ -1037,34 +1037,34 @@ struct TEvBlobStorage { , IsVerboseNoDataEnabled(isVerboseNoDataEnabled) , IsInternal(isInternal) , CollectDebugInfo(collectDebugInfo) - , ForceBlockedGeneration(forceBlockedGeneration) + , ForceBlockedGeneration(forceBlockedGeneration) , ReportDetailedPartMap(reportDetailedPartMap) { Y_VERIFY(QuerySize > 0, "can't execute empty get queries"); VerifySameTabletId(); } - + TEvGet(const TLogoBlobID &id, ui32 shift, ui32 size, TInstant deadline, NKikimrBlobStorage::EGetHandleClass getHandleClass, - bool mustRestoreFirst = false, bool isIndexOnly = false, - ui32 forceBlockedGeneration = 0) - : QuerySize(1) - , Queries(new TQuery[1]) + bool mustRestoreFirst = false, bool isIndexOnly = false, + ui32 forceBlockedGeneration = 0) + : QuerySize(1) + , Queries(new TQuery[1]) , Deadline(deadline) , MustRestoreFirst(mustRestoreFirst) , GetHandleClass(getHandleClass) , IsIndexOnly(isIndexOnly) , IsVerboseNoDataEnabled(false) - , ForceBlockedGeneration(forceBlockedGeneration) - { - Queries[0].Id = id; + , ForceBlockedGeneration(forceBlockedGeneration) + { + Queries[0].Id = id; Queries[0].Shift = shift; Queries[0].Size = size; Y_VERIFY(id.BlobSize() > 0, "Please, don't read/write 0-byte blobs!"); Y_VERIFY(shift < id.BlobSize(), "Please, don't read behind the end of the blob! Id# %s BlobSize# %" PRIu32 " shift# %" PRIu32, id.ToString().c_str(), (ui32)id.BlobSize(), (ui32)shift); - } + } TString Print(bool isFull) const { Y_UNUSED(isFull); @@ -1074,8 +1074,8 @@ struct TEvBlobStorage { str << " IsVerboseNoDataEnabled# " << (IsVerboseNoDataEnabled ? "true" : "false"); str << " Deadline# " << Deadline.MilliSeconds(); str << " QuerySize# " << QuerySize; - if (ForceBlockedGeneration) - str << " ForceBlock: " << ForceBlockedGeneration; + if (ForceBlockedGeneration) + str << " ForceBlock: " << ForceBlockedGeneration; for (ui32 i = 0; i < QuerySize; ++i) { TQuery &query = Queries[i]; str << " {Id# " << query.Id.ToString(); @@ -1110,9 +1110,9 @@ struct TEvBlobStorage { Queries[0].Id.TabletID(), Queries[i].Id.TabletID()); } } - }; - - struct TEvGetResult : public TEventLocal<TEvGetResult, EvGetResult> { + }; + + struct TEvGetResult : public TEventLocal<TEvGetResult, EvGetResult> { struct TPartMapItem { ui32 DiskOrderNumber; ui32 PartIdRequested; @@ -1120,42 +1120,42 @@ struct TEvBlobStorage { ui32 ResponseIndex; TVector<std::pair<ui32, NKikimrProto::EReplyStatus>> Status; }; - struct TResponse { - NKikimrProto::EReplyStatus Status; - - TLogoBlobID Id; - ui32 Shift; + struct TResponse { + NKikimrProto::EReplyStatus Status; + + TLogoBlobID Id; + ui32 Shift; ui32 RequestedSize; TString Buffer; TVector<TPartMapItem> PartMap; - - TResponse() - : Status(NKikimrProto::UNKNOWN) - , Shift(0) + + TResponse() + : Status(NKikimrProto::UNKNOWN) + , Shift(0) , RequestedSize(0) - {} - }; - - NKikimrProto::EReplyStatus Status; - - // todo: replace with queue-like thing - ui32 ResponseSz; - TArrayHolder<TResponse> Responses; + {} + }; + + NKikimrProto::EReplyStatus Status; + + // todo: replace with queue-like thing + ui32 ResponseSz; + TArrayHolder<TResponse> Responses; const ui32 GroupId; ui32 BlockedGeneration = 0; // valid only for requests with non-zero TabletId and true AcquireBlockedGeneration. TString DebugInfo; TString ErrorReason; mutable NLWTrace::TOrbit Orbit; - + // to measure blobstorage->client hop TInstant Sent; TEvGetResult(NKikimrProto::EReplyStatus status, ui32 sz, ui32 groupId) - : Status(status) - , ResponseSz(sz) + : Status(status) + , ResponseSz(sz) , Responses(sz == 0 ? nullptr : new TResponse[sz]) , GroupId(groupId) - {} + {} TString Print(bool isFull) const { TStringStream str; @@ -1198,21 +1198,21 @@ struct TEvBlobStorage { } return size; } - }; - - struct TEvBlock : public TEventLocal<TEvBlock, EvBlock> { - const ui64 TabletId; - const ui32 Generation; + }; + + struct TEvBlock : public TEventLocal<TEvBlock, EvBlock> { + const ui64 TabletId; + const ui32 Generation; const TInstant Deadline; const ui64 IssuerGuid = RandomNumber<ui64>() | 1; bool IsMonitored = true; ui32 RestartCounter = 0; - + TEvBlock(ui64 tabletId, ui32 generation, TInstant deadline) - : TabletId(tabletId) - , Generation(generation) + : TabletId(tabletId) + , Generation(generation) , Deadline(deadline) - {} + {} TEvBlock(ui64 tabletId, ui32 generation, TInstant deadline, ui64 issuerGuid) : TabletId(tabletId) @@ -1242,15 +1242,15 @@ struct TEvBlobStorage { std::unique_ptr<TEvBlockResult> MakeErrorResponse(NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 groupId); - }; - - struct TEvBlockResult : public TEventLocal<TEvBlockResult, EvBlockResult> { - NKikimrProto::EReplyStatus Status; + }; + + struct TEvBlockResult : public TEventLocal<TEvBlockResult, EvBlockResult> { + NKikimrProto::EReplyStatus Status; TString ErrorReason; - - TEvBlockResult(NKikimrProto::EReplyStatus status) - : Status(status) - {} + + TEvBlockResult(NKikimrProto::EReplyStatus status) + : Status(status) + {} TString Print(bool isFull) const { Y_UNUSED(isFull); @@ -1266,8 +1266,8 @@ struct TEvBlobStorage { TString ToString() const { return Print(false); } - }; - + }; + struct TEvPatch : public TEventLocal<TEvPatch, EvPatch> { private: static constexpr ui32 BaseDomainsCount = 8; @@ -1555,25 +1555,25 @@ struct TEvBlobStorage { } }; - // special kind of request, strictly used for tablet discovery - // returns logoblobid of last known control-channel (zero) entry. - struct TEvDiscover : public TEventLocal<TEvDiscover, EvDiscover> { - const ui64 TabletId; + // special kind of request, strictly used for tablet discovery + // returns logoblobid of last known control-channel (zero) entry. + struct TEvDiscover : public TEventLocal<TEvDiscover, EvDiscover> { + const ui64 TabletId; const ui32 MinGeneration; const TInstant Deadline; - const bool ReadBody; + const bool ReadBody; const bool DiscoverBlockedGeneration; - const ui32 ForceBlockedGeneration; + const ui32 ForceBlockedGeneration; ui32 RestartCounter = 0; - - TEvDiscover(ui64 tabletId, ui32 minGeneration, bool readBody, bool discoverBlockedGeneration, TInstant deadline, ui32 forceBlockedGeneration) - : TabletId(tabletId) + + TEvDiscover(ui64 tabletId, ui32 minGeneration, bool readBody, bool discoverBlockedGeneration, TInstant deadline, ui32 forceBlockedGeneration) + : TabletId(tabletId) , MinGeneration(minGeneration) , Deadline(deadline) - , ReadBody(readBody) + , ReadBody(readBody) , DiscoverBlockedGeneration(discoverBlockedGeneration) - , ForceBlockedGeneration(forceBlockedGeneration) - {} + , ForceBlockedGeneration(forceBlockedGeneration) + {} TString Print(bool isFull) const { Y_UNUSED(isFull); @@ -1597,32 +1597,32 @@ struct TEvBlobStorage { std::unique_ptr<TEvDiscoverResult> MakeErrorResponse(NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 groupId); - }; - - struct TEvDiscoverResult : public TEventLocal<TEvDiscoverResult, EvDiscoverResult> { - NKikimrProto::EReplyStatus Status; - - TLogoBlobID Id; + }; + + struct TEvDiscoverResult : public TEventLocal<TEvDiscoverResult, EvDiscoverResult> { + NKikimrProto::EReplyStatus Status; + + TLogoBlobID Id; ui32 MinGeneration; TString Buffer; ui32 BlockedGeneration; TString ErrorReason; - + TEvDiscoverResult(NKikimrProto::EReplyStatus status, ui32 minGeneration, ui32 blockedGeneration) - : Status(status) + : Status(status) , MinGeneration(minGeneration) , BlockedGeneration(blockedGeneration) - { + { Y_VERIFY_DEBUG(status != NKikimrProto::OK); - } - + } + TEvDiscoverResult(const TLogoBlobID &id, ui32 minGeneration, const TString &buffer) - : Status(NKikimrProto::OK) - , Id(id) + : Status(NKikimrProto::OK) + , Id(id) , MinGeneration(minGeneration) - , Buffer(buffer) + , Buffer(buffer) , BlockedGeneration(0) - {} + {} TEvDiscoverResult(const TLogoBlobID &id, ui32 minGeneration, const TString &buffer, ui32 blockedGeneration) : Status(NKikimrProto::OK) @@ -1652,28 +1652,28 @@ struct TEvBlobStorage { TString ToString() const { return Print(false); } - }; - - struct TEvRange : public TEventLocal<TEvRange, EvRange> { - ui64 TabletId; - TLogoBlobID From; - TLogoBlobID To; + }; + + struct TEvRange : public TEventLocal<TEvRange, EvRange> { + ui64 TabletId; + TLogoBlobID From; + TLogoBlobID To; const TInstant Deadline; bool MustRestoreFirst; bool IsIndexOnly; - ui32 ForceBlockedGeneration; + ui32 ForceBlockedGeneration; ui32 RestartCounter = 0; - + TEvRange(ui64 tabletId, const TLogoBlobID &from, const TLogoBlobID &to, const bool mustRestoreFirst, - TInstant deadline, bool isIndexOnly = false, ui32 forceBlockedGeneration = 0) - : TabletId(tabletId) - , From(from) - , To(to) + TInstant deadline, bool isIndexOnly = false, ui32 forceBlockedGeneration = 0) + : TabletId(tabletId) + , From(from) + , To(to) , Deadline(deadline) , MustRestoreFirst(mustRestoreFirst) , IsIndexOnly(isIndexOnly) - , ForceBlockedGeneration(forceBlockedGeneration) - {} + , ForceBlockedGeneration(forceBlockedGeneration) + {} TString Print(bool isFull) const { Y_UNUSED(isFull); @@ -1683,8 +1683,8 @@ struct TEvBlobStorage { str << " To# " << To.ToString(); str << " Deadline# " << Deadline.MilliSeconds(); str << " MustRestoreFirst# " << (MustRestoreFirst ? "true" : "false"); - if (ForceBlockedGeneration) - str << " ForceBlock: " << ForceBlockedGeneration; + if (ForceBlockedGeneration) + str << " ForceBlock: " << ForceBlockedGeneration; str << "}"; return str.Str(); } @@ -1699,36 +1699,36 @@ struct TEvBlobStorage { std::unique_ptr<TEvRangeResult> MakeErrorResponse(NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 groupId); - }; - - struct TEvRangeResult : public TEventLocal<TEvRangeResult, EvRangeResult> { - struct TResponse { - TLogoBlobID Id; + }; + + struct TEvRangeResult : public TEventLocal<TEvRangeResult, EvRangeResult> { + struct TResponse { + TLogoBlobID Id; TString Buffer; - - TResponse() - {} - + + TResponse() + {} + TResponse(const TLogoBlobID &id, const TString &x) - : Id(id) - , Buffer(x) - {} - }; - - NKikimrProto::EReplyStatus Status; - TLogoBlobID From; - TLogoBlobID To; - + : Id(id) + , Buffer(x) + {} + }; + + NKikimrProto::EReplyStatus Status; + TLogoBlobID From; + TLogoBlobID To; + TVector<TResponse> Responses; const ui32 GroupId; TString ErrorReason; - + TEvRangeResult(NKikimrProto::EReplyStatus status, const TLogoBlobID &from, const TLogoBlobID &to, ui32 groupId) - : Status(status) - , From(from) - , To(to) + : Status(status) + , From(from) + , To(to) , GroupId(groupId) - {} + {} TString Print(bool isFull) const { TStringStream str; @@ -1755,8 +1755,8 @@ struct TEvBlobStorage { TString ToString() const { return Print(false); } - }; - + }; + struct TEvCollectGarbage : public TEventLocal<TEvCollectGarbage, EvCollectGarbage> { ui64 TabletId; ui32 RecordGeneration; @@ -1982,20 +1982,20 @@ struct TEvBlobStorage { struct TEvVMovedPatchResult; struct TEvVInplacePatch; struct TEvVInplacePatchResult; - struct TEvVPut; - struct TEvVPutResult; + struct TEvVPut; + struct TEvVPutResult; struct TEvVMultiPut; struct TEvVMultiPutResult; - struct TEvVGet; - struct TEvVGetResult; + struct TEvVGet; + struct TEvVGetResult; struct TEvVPatchStart; struct TEvVPatchFoundParts; struct TEvVPatchDiff; struct TEvVPatchResult; struct TEvVPatchXorDiff; struct TEvVPatchXorDiffResult; - struct TEvVBlock; - struct TEvVBlockResult; + struct TEvVBlock; + struct TEvVBlockResult; struct TEvVGetBlock; struct TEvVGetBlockResult; struct TEvVCollectGarbage; @@ -2063,8 +2063,8 @@ struct TEvBlobStorage { struct TEvAskRestartPDisk; struct TEvRestartPDisk; struct TEvRestartPDiskResult; -}; - +}; + // EPutHandleClass defines BlobStorage queue to a request to static inline NKikimrBlobStorage::EVDiskQueueId HandleClassToQueueId(NKikimrBlobStorage::EPutHandleClass cls) { switch (cls) { @@ -2077,8 +2077,8 @@ static inline NKikimrBlobStorage::EVDiskQueueId HandleClassToQueueId(NKikimrBlob default: Y_FAIL("Unexpected case"); } -} - +} + // EGetHandleClass defines BlobStorage queue to a request to static inline NKikimrBlobStorage::EVDiskQueueId HandleClassToQueueId(NKikimrBlobStorage::EGetHandleClass cls) { switch (cls) { diff --git a/ydb/core/base/blobstorage_grouptype.cpp b/ydb/core/base/blobstorage_grouptype.cpp index 58055c5ff0..66c79ba42c 100644 --- a/ydb/core/base/blobstorage_grouptype.cpp +++ b/ydb/core/base/blobstorage_grouptype.cpp @@ -37,14 +37,14 @@ struct TBlobStorageErasureParameters { static const std::array<TBlobStorageErasureParameters, TErasureType::ErasureSpeciesCount> BlobStorageGroupErasureSpeciesParameters{{ - {0} // 0 = ErasureSpicies::ErasureNone - ,{1} // 1 = ErasureSpicies::ErasureMirror3 - ,{1} // 2 = ErasureSpicies::Erasure3Plus1Block - ,{1} // 3 = ErasureSpicies::Erasure3Plus1Stipe - ,{2} // 4 = ErasureSpicies::Erasure4Plus2Block - ,{2} // 5 = ErasureSpicies::Erasure3Plus2Block - ,{2} // 6 = ErasureSpicies::Erasure4Plus2Stipe - ,{2} // 7 = ErasureSpicies::Erasure3Plus2Stipe + {0} // 0 = ErasureSpicies::ErasureNone + ,{1} // 1 = ErasureSpicies::ErasureMirror3 + ,{1} // 2 = ErasureSpicies::Erasure3Plus1Block + ,{1} // 3 = ErasureSpicies::Erasure3Plus1Stipe + ,{2} // 4 = ErasureSpicies::Erasure4Plus2Block + ,{2} // 5 = ErasureSpicies::Erasure3Plus2Block + ,{2} // 6 = ErasureSpicies::Erasure4Plus2Stipe + ,{2} // 7 = ErasureSpicies::Erasure3Plus2Stipe ,{2} // 8 = ErasureSpicies::ErasureMirror3Plus2 ,{6} // 9 = ErasureSpicies::ErasireMirror3dc ,{3} // 10 = ErasureSpicies::Erasure4Plus3Block diff --git a/ydb/core/base/board_lookup.cpp b/ydb/core/base/board_lookup.cpp index d41feac486..890b88f6b9 100644 --- a/ydb/core/base/board_lookup.cpp +++ b/ydb/core/base/board_lookup.cpp @@ -1,210 +1,210 @@ -#include "statestorage_impl.h" -#include "tabletid.h" +#include "statestorage_impl.h" +#include "tabletid.h" #include <ydb/core/protos/services.pb.h> #include <library/cpp/actors/core/interconnect.h> - + #include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/actors/core/log.h> #include <library/cpp/actors/core/hfunc.h> - -#include <util/generic/xrange.h> - -#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR -#error log macro definition clash -#endif - -#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BOARD_LOOKUP, stream) -#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::BOARD_LOOKUP, stream) -#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::BOARD_LOOKUP, stream) - -namespace NKikimr { - -class TBoardLookupActor : public TActorBootstrapped<TBoardLookupActor> { - const TString Path; + +#include <util/generic/xrange.h> + +#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR +#error log macro definition clash +#endif + +#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BOARD_LOOKUP, stream) +#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::BOARD_LOOKUP, stream) +#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::BOARD_LOOKUP, stream) + +namespace NKikimr { + +class TBoardLookupActor : public TActorBootstrapped<TBoardLookupActor> { + const TString Path; const TActorId Owner; - const EBoardLookupMode Mode; - const ui32 StateStorageGroupId; - - enum class EReplicaState { - Unknown, + const EBoardLookupMode Mode; + const ui32 StateStorageGroupId; + + enum class EReplicaState { + Unknown, NotAvailable, - NoInfo, - Ready, - }; - - struct TReplica { + NoInfo, + Ready, + }; + + struct TReplica { TActorId Replica; - EReplicaState State = EReplicaState::Unknown; - }; - - TVector<TReplica> Replicas; + EReplicaState State = EReplicaState::Unknown; + }; + + TVector<TReplica> Replicas; TMap<TActorId, TEvStateStorage::TEvBoardInfo::TInfoEntry> Info; - - ui32 WaitForReplicasToSuccess; - - struct { - ui32 Replied = 0; - ui32 NoInfo = 0; - ui32 HasInfo = 0; - } Stats; - - void PassAway() override { - for (const auto &replica : Replicas) - if (replica.Replica.NodeId() != SelfId().NodeId()) - Send(TActivationContext::InterconnectProxy(replica.Replica.NodeId()), new TEvents::TEvUnsubscribe()); - TActor::PassAway(); - } - - void NotAvailable() { - Send(Owner, new TEvStateStorage::TEvBoardInfo(TEvStateStorage::TEvBoardInfo::EStatus::NotAvailable, Path)); - return PassAway(); - } - - void CheckCompletion() { - if (Stats.HasInfo == WaitForReplicasToSuccess) { - auto reply = MakeHolder<TEvStateStorage::TEvBoardInfo>(TEvStateStorage::TEvBoardInfo::EStatus::Ok, Path); - reply->InfoEntries = std::move(Info); - Send(Owner, std::move(reply)); - - return PassAway(); - } - - if (Stats.Replied == Replicas.size()) - return NotAvailable(); - } - - void Handle(TEvStateStorage::TEvResolveReplicasList::TPtr &ev) { - auto *msg = ev->Get(); - - if (msg->Replicas.empty()) { - BLOG_ERROR("lookup on unconfigured statestorage board service " << StateStorageGroupId); - return NotAvailable(); - } - - Replicas.resize(msg->Replicas.size()); - for (auto idx : xrange(msg->Replicas.size())) { + + ui32 WaitForReplicasToSuccess; + + struct { + ui32 Replied = 0; + ui32 NoInfo = 0; + ui32 HasInfo = 0; + } Stats; + + void PassAway() override { + for (const auto &replica : Replicas) + if (replica.Replica.NodeId() != SelfId().NodeId()) + Send(TActivationContext::InterconnectProxy(replica.Replica.NodeId()), new TEvents::TEvUnsubscribe()); + TActor::PassAway(); + } + + void NotAvailable() { + Send(Owner, new TEvStateStorage::TEvBoardInfo(TEvStateStorage::TEvBoardInfo::EStatus::NotAvailable, Path)); + return PassAway(); + } + + void CheckCompletion() { + if (Stats.HasInfo == WaitForReplicasToSuccess) { + auto reply = MakeHolder<TEvStateStorage::TEvBoardInfo>(TEvStateStorage::TEvBoardInfo::EStatus::Ok, Path); + reply->InfoEntries = std::move(Info); + Send(Owner, std::move(reply)); + + return PassAway(); + } + + if (Stats.Replied == Replicas.size()) + return NotAvailable(); + } + + void Handle(TEvStateStorage::TEvResolveReplicasList::TPtr &ev) { + auto *msg = ev->Get(); + + if (msg->Replicas.empty()) { + BLOG_ERROR("lookup on unconfigured statestorage board service " << StateStorageGroupId); + return NotAvailable(); + } + + Replicas.resize(msg->Replicas.size()); + for (auto idx : xrange(msg->Replicas.size())) { const TActorId &replica = msg->Replicas[idx]; Send(replica, new TEvStateStorage::TEvReplicaBoardLookup(Path, TActorId(), false), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, idx); - Replicas[idx].Replica = replica; - Replicas[idx].State = EReplicaState::Unknown; - } - - switch (Mode) { - case EBoardLookupMode::First: - case EBoardLookupMode::FirstNonEmptyDoubleTime: - WaitForReplicasToSuccess = 1; - break; - case EBoardLookupMode::Second: - case EBoardLookupMode::SecondNonEmptyDoubleTime: - WaitForReplicasToSuccess = Min<ui32>(2, Replicas.size()); - break; - case EBoardLookupMode::Majority: - case EBoardLookupMode::MajorityDoubleTime: - WaitForReplicasToSuccess = (Replicas.size() / 2 + 1); - break; - default: - Y_FAIL("unsupported mode"); - } - - Become(&TThis::StateLookup); - } - - void Handle(TEvStateStorage::TEvReplicaBoardInfo::TPtr &ev) { - const auto &record = ev->Get()->Record; - const ui32 idx = ev->Cookie; - if (idx >= Replicas.size()) - return; - auto &replica = Replicas[idx]; - if (replica.State != EReplicaState::Unknown) - return; - - ++Stats.Replied; - if (record.GetDropped()) { - replica.State = EReplicaState::NoInfo; - ++Stats.NoInfo; - } else { - Y_VERIFY_DEBUG(record.GetInfo().size()); - replica.State = EReplicaState::Ready; - ++Stats.HasInfo; - - for (auto &x : record.GetInfo()) { + Replicas[idx].Replica = replica; + Replicas[idx].State = EReplicaState::Unknown; + } + + switch (Mode) { + case EBoardLookupMode::First: + case EBoardLookupMode::FirstNonEmptyDoubleTime: + WaitForReplicasToSuccess = 1; + break; + case EBoardLookupMode::Second: + case EBoardLookupMode::SecondNonEmptyDoubleTime: + WaitForReplicasToSuccess = Min<ui32>(2, Replicas.size()); + break; + case EBoardLookupMode::Majority: + case EBoardLookupMode::MajorityDoubleTime: + WaitForReplicasToSuccess = (Replicas.size() / 2 + 1); + break; + default: + Y_FAIL("unsupported mode"); + } + + Become(&TThis::StateLookup); + } + + void Handle(TEvStateStorage::TEvReplicaBoardInfo::TPtr &ev) { + const auto &record = ev->Get()->Record; + const ui32 idx = ev->Cookie; + if (idx >= Replicas.size()) + return; + auto &replica = Replicas[idx]; + if (replica.State != EReplicaState::Unknown) + return; + + ++Stats.Replied; + if (record.GetDropped()) { + replica.State = EReplicaState::NoInfo; + ++Stats.NoInfo; + } else { + Y_VERIFY_DEBUG(record.GetInfo().size()); + replica.State = EReplicaState::Ready; + ++Stats.HasInfo; + + for (auto &x : record.GetInfo()) { const TActorId oid = ActorIdFromProto(x.GetOwner()); - Info[oid].Payload = x.GetPayload(); - } - } - - CheckCompletion(); - } - - void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) { - const ui32 nodeId = ev->Get()->NodeId; - for (auto &replica : Replicas) { - if (replica.Replica.NodeId() == nodeId && replica.State == EReplicaState::Unknown) { + Info[oid].Payload = x.GetPayload(); + } + } + + CheckCompletion(); + } + + void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) { + const ui32 nodeId = ev->Get()->NodeId; + for (auto &replica : Replicas) { + if (replica.Replica.NodeId() == nodeId && replica.State == EReplicaState::Unknown) { replica.State = EReplicaState::NotAvailable; - ++Stats.Replied; - ++Stats.NoInfo; - } - } - - CheckCompletion(); - } - - void Handle(TEvents::TEvUndelivered::TPtr &ev) { - auto *msg = ev->Get(); - if (msg->SourceType != TEvStateStorage::TEvReplicaBoardLookup::EventType) - return; - const ui32 idx = ev->Cookie; - if (idx >= Replicas.size()) - return; - auto &replica = Replicas[idx]; - if (replica.State != EReplicaState::Unknown) - return; + ++Stats.Replied; + ++Stats.NoInfo; + } + } + + CheckCompletion(); + } + + void Handle(TEvents::TEvUndelivered::TPtr &ev) { + auto *msg = ev->Get(); + if (msg->SourceType != TEvStateStorage::TEvReplicaBoardLookup::EventType) + return; + const ui32 idx = ev->Cookie; + if (idx >= Replicas.size()) + return; + auto &replica = Replicas[idx]; + if (replica.State != EReplicaState::Unknown) + return; replica.State = EReplicaState::NotAvailable; - ++Stats.Replied; - ++Stats.NoInfo; - - CheckCompletion(); - } -public: + ++Stats.Replied; + ++Stats.NoInfo; + + CheckCompletion(); + } +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::BOARD_LOOKUP_ACTOR; } TBoardLookupActor(const TString &path, TActorId owner, EBoardLookupMode mode, ui32 groupId) - : Path(path) - , Owner(owner) - , Mode(mode) - , StateStorageGroupId(groupId) - {} - - void Bootstrap() { + : Path(path) + , Owner(owner) + , Mode(mode) + , StateStorageGroupId(groupId) + {} + + void Bootstrap() { const TActorId proxyId = MakeStateStorageProxyID(StateStorageGroupId); - Send(proxyId, new TEvStateStorage::TEvResolveBoard(Path), IEventHandle::FlagTrackDelivery); - Become(&TThis::StateResolve); - } - - STATEFN(StateResolve) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvResolveReplicasList, Handle); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); - cFunc(TEvents::TEvUndelivered::EventType, NotAvailable); - } - } - - STATEFN(StateLookup) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvReplicaBoardInfo, Handle); - hFunc(TEvents::TEvUndelivered, Handle); - hFunc(TEvInterconnect::TEvNodeDisconnected, Handle); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); - } - } -}; - + Send(proxyId, new TEvStateStorage::TEvResolveBoard(Path), IEventHandle::FlagTrackDelivery); + Become(&TThis::StateResolve); + } + + STATEFN(StateResolve) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvResolveReplicasList, Handle); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + cFunc(TEvents::TEvUndelivered::EventType, NotAvailable); + } + } + + STATEFN(StateLookup) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvReplicaBoardInfo, Handle); + hFunc(TEvents::TEvUndelivered, Handle); + hFunc(TEvInterconnect::TEvNodeDisconnected, Handle); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + } + } +}; + IActor* CreateBoardLookupActor(const TString &path, const TActorId &owner, ui32 groupId, EBoardLookupMode mode, bool sub, bool useNodeSubsriptions) { - Y_UNUSED(useNodeSubsriptions); - Y_VERIFY(!sub, "subscribe mode for board lookup not implemented yet"); - return new TBoardLookupActor(path, owner, mode, groupId); -} - -} + Y_UNUSED(useNodeSubsriptions); + Y_VERIFY(!sub, "subscribe mode for board lookup not implemented yet"); + return new TBoardLookupActor(path, owner, mode, groupId); +} + +} diff --git a/ydb/core/base/board_publish.cpp b/ydb/core/base/board_publish.cpp index 58cee89a92..cdd4bf6e48 100644 --- a/ydb/core/base/board_publish.cpp +++ b/ydb/core/base/board_publish.cpp @@ -1,196 +1,196 @@ -#include "statestorage_impl.h" -#include "tabletid.h" +#include "statestorage_impl.h" +#include "tabletid.h" #include <ydb/core/protos/services.pb.h> #include <library/cpp/actors/core/interconnect.h> - + #include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/actors/core/log.h> #include <library/cpp/actors/core/hfunc.h> - -#include <util/generic/map.h> - -#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR -#error log macro definition clash -#endif - -#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BOARD_PUBLISH, stream) -#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::BOARD_PUBLISH, stream) -#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::BOARD_PUBLISH, stream) - -namespace NKikimr { - -class TBoardReplicaPublishActor : public TActorBootstrapped<TBoardReplicaPublishActor> { - const TString Path; - TString Payload; + +#include <util/generic/map.h> + +#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR +#error log macro definition clash +#endif + +#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BOARD_PUBLISH, stream) +#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::BOARD_PUBLISH, stream) +#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::BOARD_PUBLISH, stream) + +namespace NKikimr { + +class TBoardReplicaPublishActor : public TActorBootstrapped<TBoardReplicaPublishActor> { + const TString Path; + TString Payload; const TActorId Replica; const TActorId PublishActor; - - ui64 Round; - - void Cleanup() { - Send(Replica, new TEvStateStorage::TEvReplicaBoardCleanup()); - if (Replica.NodeId() != SelfId().NodeId()) - Send(TActivationContext::InterconnectProxy(Replica.NodeId()), new TEvents::TEvUnsubscribe()); - PassAway(); - } - - void NotAvailable() { - Send(PublishActor, new TEvents::TEvGone()); - PassAway(); - } - - void NotAvailableUnsubscribe() { - if (Replica.NodeId() != SelfId().NodeId()) - Send(TActivationContext::InterconnectProxy(Replica.NodeId()), new TEvents::TEvUnsubscribe()); - Send(PublishActor, new TEvents::TEvGone()); - PassAway(); - } - -public: + + ui64 Round; + + void Cleanup() { + Send(Replica, new TEvStateStorage::TEvReplicaBoardCleanup()); + if (Replica.NodeId() != SelfId().NodeId()) + Send(TActivationContext::InterconnectProxy(Replica.NodeId()), new TEvents::TEvUnsubscribe()); + PassAway(); + } + + void NotAvailable() { + Send(PublishActor, new TEvents::TEvGone()); + PassAway(); + } + + void NotAvailableUnsubscribe() { + if (Replica.NodeId() != SelfId().NodeId()) + Send(TActivationContext::InterconnectProxy(Replica.NodeId()), new TEvents::TEvUnsubscribe()); + Send(PublishActor, new TEvents::TEvGone()); + PassAway(); + } + +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::BOARD_REPLICA_PUBLISH_ACTOR; } TBoardReplicaPublishActor(const TString &path, const TString &payload, TActorId replica, TActorId publishActor) - : Path(path) - , Payload(payload) - , Replica(replica) - , PublishActor(publishActor) - , Round(0) - {} - - void Bootstrap() { - Send(Replica, new TEvStateStorage::TEvReplicaBoardPublish(Path, Payload, 0, true, PublishActor), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, ++Round); - - Become(&TThis::StatePublish); - } - - STATEFN(StatePublish) { - switch (ev->GetTypeRewrite()) { - cFunc(TEvents::TEvPoisonPill::EventType, Cleanup); - cFunc(TEvents::TEvUndelivered::EventType, NotAvailableUnsubscribe); - cFunc(TEvInterconnect::TEvNodeDisconnected::EventType, NotAvailable); // no cleanup on node disconnect - cFunc(TEvStateStorage::TEvReplicaShutdown::EventType, NotAvailableUnsubscribe); - } - } -}; - -class TBoardPublishActor : public TActorBootstrapped<TBoardPublishActor> { - const TString Path; - const TString Payload; + : Path(path) + , Payload(payload) + , Replica(replica) + , PublishActor(publishActor) + , Round(0) + {} + + void Bootstrap() { + Send(Replica, new TEvStateStorage::TEvReplicaBoardPublish(Path, Payload, 0, true, PublishActor), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, ++Round); + + Become(&TThis::StatePublish); + } + + STATEFN(StatePublish) { + switch (ev->GetTypeRewrite()) { + cFunc(TEvents::TEvPoisonPill::EventType, Cleanup); + cFunc(TEvents::TEvUndelivered::EventType, NotAvailableUnsubscribe); + cFunc(TEvInterconnect::TEvNodeDisconnected::EventType, NotAvailable); // no cleanup on node disconnect + cFunc(TEvStateStorage::TEvReplicaShutdown::EventType, NotAvailableUnsubscribe); + } + } +}; + +class TBoardPublishActor : public TActorBootstrapped<TBoardPublishActor> { + const TString Path; + const TString Payload; const TActorId Owner; - const ui32 StateStorageGroupId; - const ui32 TtlMs; - const bool Register; - + const ui32 StateStorageGroupId; + const ui32 TtlMs; + const bool Register; + TMap<TActorId, TActorId> ReplicaPublishActors; // replica -> publish actor - - void PassAway() override { - for (auto &xpair : ReplicaPublishActors) { - if (xpair.second) - Send(xpair.second, new TEvents::TEvPoisonPill()); - } - - TActor::PassAway(); - } - - void HandleUndelivered() { - BLOG_ERROR("publish on unavailable statestorage board service " << StateStorageGroupId); - Become(&TThis::StateCalm); - } - - void Handle(TEvStateStorage::TEvResolveReplicasList::TPtr &ev) { - auto *msg = ev->Get(); - - if (msg->Replicas.empty()) { - BLOG_ERROR("publish on unconfigured statestorage board service " << StateStorageGroupId); - } else { + + void PassAway() override { + for (auto &xpair : ReplicaPublishActors) { + if (xpair.second) + Send(xpair.second, new TEvents::TEvPoisonPill()); + } + + TActor::PassAway(); + } + + void HandleUndelivered() { + BLOG_ERROR("publish on unavailable statestorage board service " << StateStorageGroupId); + Become(&TThis::StateCalm); + } + + void Handle(TEvStateStorage::TEvResolveReplicasList::TPtr &ev) { + auto *msg = ev->Get(); + + if (msg->Replicas.empty()) { + BLOG_ERROR("publish on unconfigured statestorage board service " << StateStorageGroupId); + } else { TMap<TActorId, TActorId> updated; - - for (auto &replicaId : msg->Replicas) { + + for (auto &replicaId : msg->Replicas) { const TActorId *known = ReplicaPublishActors.FindPtr(replicaId); - if (known && *known) - updated[replicaId] = *known; - else + if (known && *known) + updated[replicaId] = *known; + else updated[replicaId] = RegisterWithSameMailbox(new TBoardReplicaPublishActor(Path, Payload, replicaId, SelfId())); - } - - ReplicaPublishActors = std::move(updated); - } - - Become(&TThis::StateCalm); - } - - bool ResolveGone(TEvents::TEvGone::TPtr &ev) { + } + + ReplicaPublishActors = std::move(updated); + } + + Become(&TThis::StateCalm); + } + + bool ResolveGone(TEvents::TEvGone::TPtr &ev) { const TActorId sender = ev->Sender; - - for (auto &xpair : ReplicaPublishActors) { - if (xpair.second == sender) { + + for (auto &xpair : ReplicaPublishActors) { + if (xpair.second == sender) { xpair.second = TActorId(); - return true; - } - } - - return false; - } - - void CalmGone(TEvents::TEvGone::TPtr &ev) { - if (ResolveGone(ev)) { + return true; + } + } + + return false; + } + + void CalmGone(TEvents::TEvGone::TPtr &ev) { + if (ResolveGone(ev)) { const TActorId proxyId = MakeStateStorageProxyID(StateStorageGroupId); - const ui32 flags = IEventHandle::FlagTrackDelivery; - TAutoPtr<IEventHandle> x = new IEventHandle(proxyId, SelfId(), new TEvStateStorage::TEvResolveBoard(Path), flags); - TActivationContext::Schedule(TDuration::MilliSeconds(50), x); - - Become(&TThis::StateResolve); - } - } - -public: + const ui32 flags = IEventHandle::FlagTrackDelivery; + TAutoPtr<IEventHandle> x = new IEventHandle(proxyId, SelfId(), new TEvStateStorage::TEvResolveBoard(Path), flags); + TActivationContext::Schedule(TDuration::MilliSeconds(50), x); + + Become(&TThis::StateResolve); + } + } + +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::BOARD_PUBLISH_ACTOR; } TBoardPublishActor(const TString &path, const TString &payload, const TActorId &owner, ui32 groupId, ui32 ttlMs, bool reg) - : Path(path) - , Payload(payload) - , Owner(owner) - , StateStorageGroupId(groupId) - , TtlMs(ttlMs) - , Register(reg) - { - Y_UNUSED(TtlMs); - Y_UNUSED(Register); - } - - void Bootstrap() { + : Path(path) + , Payload(payload) + , Owner(owner) + , StateStorageGroupId(groupId) + , TtlMs(ttlMs) + , Register(reg) + { + Y_UNUSED(TtlMs); + Y_UNUSED(Register); + } + + void Bootstrap() { const TActorId proxyId = MakeStateStorageProxyID(StateStorageGroupId); - Send(proxyId, new TEvStateStorage::TEvResolveBoard(Path), IEventHandle::FlagTrackDelivery); - Become(&TThis::StateResolve); - } - - STATEFN(StateResolve) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvResolveReplicasList, Handle); - hFunc(TEvents::TEvGone, ResolveGone); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); - cFunc(TEvents::TEvUndelivered::EventType, HandleUndelivered); - } - } - - STATEFN(StateCalm) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvents::TEvGone, CalmGone); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); - } - } -}; - + Send(proxyId, new TEvStateStorage::TEvResolveBoard(Path), IEventHandle::FlagTrackDelivery); + Become(&TThis::StateResolve); + } + + STATEFN(StateResolve) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvResolveReplicasList, Handle); + hFunc(TEvents::TEvGone, ResolveGone); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + cFunc(TEvents::TEvUndelivered::EventType, HandleUndelivered); + } + } + + STATEFN(StateCalm) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvents::TEvGone, CalmGone); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + } + } +}; + IActor* CreateBoardPublishActor(const TString &path, const TString &payload, const TActorId &owner, ui32 groupId, ui32 ttlMs, bool reg) { - return new TBoardPublishActor(path, payload, owner, groupId, ttlMs, reg); -} - -TString MakeEndpointsBoardPath(const TString &database) { - return "gpc+" + database; -} - -} + return new TBoardPublishActor(path, payload, owner, groupId, ttlMs, reg); +} + +TString MakeEndpointsBoardPath(const TString &database) { + return "gpc+" + database; +} + +} diff --git a/ydb/core/base/board_replica.cpp b/ydb/core/base/board_replica.cpp index 3fe56e8735..c38fd20e35 100644 --- a/ydb/core/base/board_replica.cpp +++ b/ydb/core/base/board_replica.cpp @@ -1,229 +1,229 @@ -#include "statestorage_impl.h" +#include "statestorage_impl.h" #include <ydb/core/protos/services.pb.h> #include <library/cpp/actors/core/interconnect.h> - -#include <util/generic/set.h> - + +#include <util/generic/set.h> + #include <library/cpp/actors/core/log.h> #include <library/cpp/actors/core/hfunc.h> - -#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR -#error log macro definition clash -#endif - -#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BOARD_REPLICA, stream) -#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::BOARD_REPLICA, stream) -#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::BOARD_REPLICA, stream) - -namespace NKikimr { - -class TBoardReplicaActor : public TActor<TBoardReplicaActor> { + +#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR +#error log macro definition clash +#endif + +#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BOARD_REPLICA, stream) +#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::BOARD_REPLICA, stream) +#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::BOARD_REPLICA, stream) + +namespace NKikimr { + +class TBoardReplicaActor : public TActor<TBoardReplicaActor> { using TOwnerIndex = TMap<TActorId, ui32, TActorId::TOrderedCmp>; - using TPathIndex = TMap<TString, TSet<ui32>>; - - struct TEntry { - TString Payload; + using TPathIndex = TMap<TString, TSet<ui32>>; + + struct TEntry { + TString Payload; TActorId Owner; - TOwnerIndex::iterator OwnerIt; - TPathIndex::iterator PathIt; - }; - - TVector<TEntry> Entries; - TVector<ui32> AvailableEntries; - - TOwnerIndex IndexOwner; - TPathIndex IndexPath; - - ui32 AllocateEntry() { - ui32 ret; - if (AvailableEntries) { - ret = AvailableEntries.back(); - AvailableEntries.pop_back(); - } - else { - ret = Entries.size(); - Entries.emplace_back(); - } - - return ret; - } - - void Handle(TEvStateStorage::TEvReplicaBoardPublish::TPtr &ev) { - auto &record = ev->Get()->Record; - const TString &path = record.GetPath(); + TOwnerIndex::iterator OwnerIt; + TPathIndex::iterator PathIt; + }; + + TVector<TEntry> Entries; + TVector<ui32> AvailableEntries; + + TOwnerIndex IndexOwner; + TPathIndex IndexPath; + + ui32 AllocateEntry() { + ui32 ret; + if (AvailableEntries) { + ret = AvailableEntries.back(); + AvailableEntries.pop_back(); + } + else { + ret = Entries.size(); + Entries.emplace_back(); + } + + return ret; + } + + void Handle(TEvStateStorage::TEvReplicaBoardPublish::TPtr &ev) { + auto &record = ev->Get()->Record; + const TString &path = record.GetPath(); const TActorId &owner = ev->Sender; - - if (!record.GetRegister()) { - BLOG_ERROR("free floating entries not implemented yet"); - return; - } - - auto ownerIt = IndexOwner.find(owner); - if (ownerIt != IndexOwner.end()) { - const ui32 entryIndex = ownerIt->second; - TEntry &entry = Entries[entryIndex]; - if (entry.PathIt->first != path) { - BLOG_ERROR("unconsistent path for same owner"); - // reply nothing, request suspicious - return; - } - - entry.Payload = record.GetPayload(); + + if (!record.GetRegister()) { + BLOG_ERROR("free floating entries not implemented yet"); + return; + } + + auto ownerIt = IndexOwner.find(owner); + if (ownerIt != IndexOwner.end()) { + const ui32 entryIndex = ownerIt->second; + TEntry &entry = Entries[entryIndex]; + if (entry.PathIt->first != path) { + BLOG_ERROR("unconsistent path for same owner"); + // reply nothing, request suspicious + return; + } + + entry.Payload = record.GetPayload(); Y_VERIFY_DEBUG(entry.Owner == ActorIdFromProto(record.GetOwner())); - } else { - const ui32 entryIndex = AllocateEntry(); - TEntry &entry = Entries[entryIndex]; - - entry.Payload = record.GetPayload(); + } else { + const ui32 entryIndex = AllocateEntry(); + TEntry &entry = Entries[entryIndex]; + + entry.Payload = record.GetPayload(); entry.Owner = ActorIdFromProto(record.GetOwner()); - - auto ownerInsPairIt = IndexOwner.emplace(owner, entryIndex); - entry.OwnerIt = ownerInsPairIt.first; - auto pathInsPairIt = IndexPath.emplace(std::make_pair(path, TSet<ui32>())); - entry.PathIt = pathInsPairIt.first; - entry.PathIt->second.emplace(entryIndex); - - Send(owner, new TEvStateStorage::TEvReplicaBoardPublishAck, IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, ev->Cookie); - } - } - - bool IsLastEntryOnNode(TOwnerIndex::iterator ownerIt) { - const ui32 ownerNodeId = ownerIt->first.NodeId(); - if (ownerIt != IndexOwner.begin()) { - auto x = ownerIt; - --x; - if (x->first.NodeId() == ownerNodeId) - return false; - } - - ++ownerIt; - if (ownerIt != IndexOwner.end()) { - if (ownerIt->first.NodeId() == ownerNodeId) - return false; - } - - return true; - } - - void CleanupEntry(ui32 entryIndex) { - TEntry &entry = Entries[entryIndex]; - entry.PathIt->second.erase(entryIndex); - if (entry.PathIt->second.empty()) { - IndexPath.erase(entry.PathIt); - } - - if (IsLastEntryOnNode(entry.OwnerIt)) { - Send(TActivationContext::InterconnectProxy(entry.OwnerIt->first.NodeId()), new TEvents::TEvUnsubscribe()); - } - IndexOwner.erase(entry.OwnerIt); - - TString().swap(entry.Payload); + + auto ownerInsPairIt = IndexOwner.emplace(owner, entryIndex); + entry.OwnerIt = ownerInsPairIt.first; + auto pathInsPairIt = IndexPath.emplace(std::make_pair(path, TSet<ui32>())); + entry.PathIt = pathInsPairIt.first; + entry.PathIt->second.emplace(entryIndex); + + Send(owner, new TEvStateStorage::TEvReplicaBoardPublishAck, IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, ev->Cookie); + } + } + + bool IsLastEntryOnNode(TOwnerIndex::iterator ownerIt) { + const ui32 ownerNodeId = ownerIt->first.NodeId(); + if (ownerIt != IndexOwner.begin()) { + auto x = ownerIt; + --x; + if (x->first.NodeId() == ownerNodeId) + return false; + } + + ++ownerIt; + if (ownerIt != IndexOwner.end()) { + if (ownerIt->first.NodeId() == ownerNodeId) + return false; + } + + return true; + } + + void CleanupEntry(ui32 entryIndex) { + TEntry &entry = Entries[entryIndex]; + entry.PathIt->second.erase(entryIndex); + if (entry.PathIt->second.empty()) { + IndexPath.erase(entry.PathIt); + } + + if (IsLastEntryOnNode(entry.OwnerIt)) { + Send(TActivationContext::InterconnectProxy(entry.OwnerIt->first.NodeId()), new TEvents::TEvUnsubscribe()); + } + IndexOwner.erase(entry.OwnerIt); + + TString().swap(entry.Payload); entry.Owner = TActorId(); - entry.PathIt = IndexPath.end(); - entry.OwnerIt = IndexOwner.end(); - - AvailableEntries.emplace_back(entryIndex); - } - - void PassAway() override { - ui32 prevNode = 0; - for (auto &xpair : IndexOwner) { - const ui32 nodeId = xpair.first.NodeId(); - if (nodeId != prevNode) { - Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe()); - prevNode = nodeId; - } - - Send(xpair.first, new TEvStateStorage::TEvReplicaShutdown()); - } - - // all cleanup in actor destructor - TActor::PassAway(); - } - - void Handle(TEvStateStorage::TEvReplicaBoardCleanup::TPtr &ev) { - auto ownerIt = IndexOwner.find(ev->Sender); - if (ownerIt == IndexOwner.end()) // do nothing, already removed? - return; - - CleanupEntry(ownerIt->second); - } - - void Handle(TEvStateStorage::TEvReplicaBoardLookup::TPtr &ev) { - auto &record = ev->Get()->Record; - const auto &path = record.GetPath(); - - if (record.GetSubscribe()) { - BLOG_ERROR("trying to subscribe on path, must be not implemented yet"); - // reply nothing, request suspicious - return; - } - - auto pathIt = IndexPath.find(path); - if (pathIt == IndexPath.end()) { - Send(ev->Sender, new TEvStateStorage::TEvReplicaBoardInfo(path, true), 0, ev->Cookie); - return; - } - - auto reply = MakeHolder<TEvStateStorage::TEvReplicaBoardInfo>(path, false); - auto *info = reply->Record.MutableInfo(); - info->Reserve(pathIt->second.size()); - for (ui32 entryIndex : pathIt->second) { - const TEntry &entry = Entries[entryIndex]; - auto *ex = info->Add(); + entry.PathIt = IndexPath.end(); + entry.OwnerIt = IndexOwner.end(); + + AvailableEntries.emplace_back(entryIndex); + } + + void PassAway() override { + ui32 prevNode = 0; + for (auto &xpair : IndexOwner) { + const ui32 nodeId = xpair.first.NodeId(); + if (nodeId != prevNode) { + Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe()); + prevNode = nodeId; + } + + Send(xpair.first, new TEvStateStorage::TEvReplicaShutdown()); + } + + // all cleanup in actor destructor + TActor::PassAway(); + } + + void Handle(TEvStateStorage::TEvReplicaBoardCleanup::TPtr &ev) { + auto ownerIt = IndexOwner.find(ev->Sender); + if (ownerIt == IndexOwner.end()) // do nothing, already removed? + return; + + CleanupEntry(ownerIt->second); + } + + void Handle(TEvStateStorage::TEvReplicaBoardLookup::TPtr &ev) { + auto &record = ev->Get()->Record; + const auto &path = record.GetPath(); + + if (record.GetSubscribe()) { + BLOG_ERROR("trying to subscribe on path, must be not implemented yet"); + // reply nothing, request suspicious + return; + } + + auto pathIt = IndexPath.find(path); + if (pathIt == IndexPath.end()) { + Send(ev->Sender, new TEvStateStorage::TEvReplicaBoardInfo(path, true), 0, ev->Cookie); + return; + } + + auto reply = MakeHolder<TEvStateStorage::TEvReplicaBoardInfo>(path, false); + auto *info = reply->Record.MutableInfo(); + info->Reserve(pathIt->second.size()); + for (ui32 entryIndex : pathIt->second) { + const TEntry &entry = Entries[entryIndex]; + auto *ex = info->Add(); ActorIdToProto(entry.Owner, ex->MutableOwner()); - ex->SetPayload(entry.Payload); - } - - Send(ev->Sender, std::move(reply), 0, ev->Cookie); - } - - void Handle(TEvents::TEvUndelivered::TPtr &ev) { - auto ownerIt = IndexOwner.find(ev->Sender); - if (ownerIt == IndexOwner.end()) - return; - - CleanupEntry(ownerIt->second); - } - - void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) { - auto *msg = ev->Get(); - const ui32 nodeId = msg->NodeId; + ex->SetPayload(entry.Payload); + } + + Send(ev->Sender, std::move(reply), 0, ev->Cookie); + } + + void Handle(TEvents::TEvUndelivered::TPtr &ev) { + auto ownerIt = IndexOwner.find(ev->Sender); + if (ownerIt == IndexOwner.end()) + return; + + CleanupEntry(ownerIt->second); + } + + void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) { + auto *msg = ev->Get(); + const ui32 nodeId = msg->NodeId; auto ownerIt = IndexOwner.lower_bound(TActorId(nodeId, 0, 0, 0)); - while (ownerIt != IndexOwner.end() && ownerIt->first.NodeId() == nodeId) { - const ui32 entryToCleanupIndex = ownerIt->second; - ++ownerIt; - CleanupEntry(entryToCleanupIndex); - } - } -public: + while (ownerIt != IndexOwner.end() && ownerIt->first.NodeId() == nodeId) { + const ui32 entryToCleanupIndex = ownerIt->second; + ++ownerIt; + CleanupEntry(entryToCleanupIndex); + } + } +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::BOARD_REPLICA_ACTOR; - } - - TBoardReplicaActor() - : TActor(&TThis::StateWork) - {} - - STATEFN(StateWork) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvReplicaBoardPublish, Handle); - hFunc(TEvStateStorage::TEvReplicaBoardCleanup, Handle); - hFunc(TEvStateStorage::TEvReplicaBoardLookup, Handle); - hFunc(TEvents::TEvUndelivered, Handle); - cFunc(TEvents::TEvPoison::EventType, PassAway); - hFunc(TEvInterconnect::TEvNodeDisconnected, Handle); - - IgnoreFunc(TEvInterconnect::TEvNodeConnected); - default: - // in debug spam some message - break; - } - } -}; - -IActor* CreateStateStorageBoardReplica(const TIntrusivePtr<TStateStorageInfo> &, ui32) { - return new TBoardReplicaActor(); -} - -} + } + + TBoardReplicaActor() + : TActor(&TThis::StateWork) + {} + + STATEFN(StateWork) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvReplicaBoardPublish, Handle); + hFunc(TEvStateStorage::TEvReplicaBoardCleanup, Handle); + hFunc(TEvStateStorage::TEvReplicaBoardLookup, Handle); + hFunc(TEvents::TEvUndelivered, Handle); + cFunc(TEvents::TEvPoison::EventType, PassAway); + hFunc(TEvInterconnect::TEvNodeDisconnected, Handle); + + IgnoreFunc(TEvInterconnect::TEvNodeConnected); + default: + // in debug spam some message + break; + } + } +}; + +IActor* CreateStateStorageBoardReplica(const TIntrusivePtr<TStateStorageInfo> &, ui32) { + return new TBoardReplicaActor(); +} + +} diff --git a/ydb/core/base/compile_time_flags.h b/ydb/core/base/compile_time_flags.h index 0f807c44b6..4259148ee3 100644 --- a/ydb/core/base/compile_time_flags.h +++ b/ydb/core/base/compile_time_flags.h @@ -44,22 +44,22 @@ #ifndef KIKIMR_SCHEMESHARD_ALLOW_COLUMN_FAMILIES #define KIKIMR_SCHEMESHARD_ALLOW_COLUMN_FAMILIES 1 #endif - -// This feature flag enables use of flow controlled queue in statestorage lookup requests -#ifndef KIKIMR_ALLOW_FLOWCONTROLLED_QUEUE_FOR_SSLOOKUP + +// This feature flag enables use of flow controlled queue in statestorage lookup requests +#ifndef KIKIMR_ALLOW_FLOWCONTROLLED_QUEUE_FOR_SSLOOKUP #define KIKIMR_ALLOW_FLOWCONTROLLED_QUEUE_FOR_SSLOOKUP 0 -#endif - +#endif + // This feature flag enables immediate ReadTable on datashard // Runtime support shipped in 20-2, will be enabled in 20-4 #ifndef KIKIMR_ALLOW_READTABLE_IMMEDIATE #define KIKIMR_ALLOW_READTABLE_IMMEDIATE 1 #endif - -// This feature flag enables statestorage replica probes -#ifndef KIKIMR_ALLOW_SSREPLICA_PROBES -#define KIKIMR_ALLOW_SSREPLICA_PROBES 0 -#endif + +// This feature flag enables statestorage replica probes +#ifndef KIKIMR_ALLOW_SSREPLICA_PROBES +#define KIKIMR_ALLOW_SSREPLICA_PROBES 0 +#endif // This feature enables cutting PDisk's log from the middle of log chunks list #ifndef KIKIMR_PDISK_ENABLE_CUT_LOG_FROM_THE_MIDDLE diff --git a/ydb/core/base/defs.h b/ydb/core/base/defs.h index a1604d4188..bb4eb55689 100644 --- a/ydb/core/base/defs.h +++ b/ydb/core/base/defs.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once // unique tag to fix pragma once gcc glueing: ./ydb/core/base/defs.h #include <library/cpp/actors/core/defs.h> #include <library/cpp/actors/core/actor.h> @@ -8,49 +8,49 @@ #include <ydb/core/debug/valgrind_check.h> #include <util/generic/array_ref.h> #include <util/generic/string.h> - -namespace NKikimr { - // actorlib is organic part of kikimr so we emulate global import by this directive - using namespace NActors; - - struct TPtrHash { - template<typename TSmartPtr> - size_t operator()(const TSmartPtr &x) const { - return THash<intptr_t>()(reinterpret_cast<intptr_t>(&*x)); - } - }; - - struct TPtrEqual { - template<typename TPtrLeft, typename TPtrRight> - bool operator()(const TPtrLeft &left, const TPtrRight &right) const { - return (&*left == &*right); - } - }; - - struct TPtrLess { - template<typename TPtrLeft, typename TPtrRight> - bool operator()(const TPtrLeft &left, const TPtrRight &right) const { - return (&*left < &*right); - } - }; - - inline ui64 Hash64to32(ui64 x) noexcept { - const ui64 x1 = 0x001DFF3D8DC48F5Dull * (x >> 32ull); - const ui64 x2 = 0x179CA10C9242235Dull * (x & 0x00000000FFFFFFFFull); - - const ui64 sum = 0x0F530CAD458B0FB1ull + x1 + x2; - - return (sum >> 32); - } - - inline ui64 Hash128to32(ui64 a, ui64 b) noexcept { - const ui64 x1 = 0x001DFF3D8DC48F5Dull * (a & 0xFFFFFFFFull); - const ui64 x2 = 0x179CA10C9242235Dull * (a >> 32); - const ui64 x3 = 0x0F530CAD458B0FB1ull * (b & 0xFFFFFFFFull); - const ui64 x4 = 0xB5026F5AA96619E9ull * (b >> 32); - - const ui64 sum = 0x06C9C021156EAA1Full + x1 + x2 + x3 + x4; - - return (sum >> 32); - } -} + +namespace NKikimr { + // actorlib is organic part of kikimr so we emulate global import by this directive + using namespace NActors; + + struct TPtrHash { + template<typename TSmartPtr> + size_t operator()(const TSmartPtr &x) const { + return THash<intptr_t>()(reinterpret_cast<intptr_t>(&*x)); + } + }; + + struct TPtrEqual { + template<typename TPtrLeft, typename TPtrRight> + bool operator()(const TPtrLeft &left, const TPtrRight &right) const { + return (&*left == &*right); + } + }; + + struct TPtrLess { + template<typename TPtrLeft, typename TPtrRight> + bool operator()(const TPtrLeft &left, const TPtrRight &right) const { + return (&*left < &*right); + } + }; + + inline ui64 Hash64to32(ui64 x) noexcept { + const ui64 x1 = 0x001DFF3D8DC48F5Dull * (x >> 32ull); + const ui64 x2 = 0x179CA10C9242235Dull * (x & 0x00000000FFFFFFFFull); + + const ui64 sum = 0x0F530CAD458B0FB1ull + x1 + x2; + + return (sum >> 32); + } + + inline ui64 Hash128to32(ui64 a, ui64 b) noexcept { + const ui64 x1 = 0x001DFF3D8DC48F5Dull * (a & 0xFFFFFFFFull); + const ui64 x2 = 0x179CA10C9242235Dull * (a >> 32); + const ui64 x3 = 0x0F530CAD458B0FB1ull * (b & 0xFFFFFFFFull); + const ui64 x4 = 0xB5026F5AA96619E9ull * (b >> 32); + + const ui64 sum = 0x06C9C021156EAA1Full + x1 + x2 + x3 + x4; + + return (sum >> 32); + } +} diff --git a/ydb/core/base/domain.h b/ydb/core/base/domain.h index c7e3e836c8..05346e474a 100644 --- a/ydb/core/base/domain.h +++ b/ydb/core/base/domain.h @@ -1,25 +1,25 @@ -#pragma once -#include "defs.h" -#include "tabletid.h" +#pragma once +#include "defs.h" +#include "tabletid.h" #include "localdb.h" #include <ydb/core/protos/blobstorage_config.pb.h> -#include <util/generic/map.h> +#include <util/generic/map.h> #include <util/generic/hash.h> #include <util/generic/ptr.h> - -namespace NKikimr { - -struct TDomainsInfo : public TThrRefBase { - static const ui32 FirstUserTag = 32; - static const ui32 FakeRootTag = 0xFFFFE; + +namespace NKikimr { + +struct TDomainsInfo : public TThrRefBase { + static const ui32 FirstUserTag = 32; + static const ui32 FakeRootTag = 0xFFFFE; static const ui32 MaxUserTag = 0xFFFFF; static const ui32 BadDomainId = 0xFFFFFFFFu; static const ui64 BadTabletId = 0xFFFFFFFFFFFFFFFFull; static const ui32 DomainBits = 5; static const ui32 MaxDomainId = (1 << DomainBits) - 1; - + // it's very sad mistake // MakeTabletID should be called with hiveUid == 0 for all domain's static tablets // but we do it with hiveUid == domain, and collision with dynamic tablets occurs @@ -70,7 +70,7 @@ struct TDomainsInfo : public TThrRefBase { typedef THashMap<TString, TIntrusiveConstPtr<NLocalDb::TCompactionPolicy>> TNamedCompactionPolicies; - struct TDomain : public TThrRefBase { + struct TDomain : public TThrRefBase { using TPtr = TIntrusivePtr<TDomain>; using TVectorUi64 = TVector<ui64>; @@ -79,8 +79,8 @@ struct TDomainsInfo : public TThrRefBase { const ui32 DomainUid; const ui32 DefaultStateStorageGroup; - const ui32 DefaultSchemeBoardGroup; - const ui64 SchemeRoot; + const ui32 DefaultSchemeBoardGroup; + const ui64 SchemeRoot; const TString Name; const TVector<ui64> Coordinators; const TVector<ui64> Mediators; @@ -88,40 +88,40 @@ struct TDomainsInfo : public TThrRefBase { const TVector<ui32> StateStorageGroups; const ui32 DefaultHiveUid; const TVector<ui32> HiveUids; - const ui64 DomainPlanResolution; + const ui64 DomainPlanResolution; const TStoragePoolKinds StoragePoolTypes; - + static constexpr ui32 TimecastBucketsPerMediator = 2; // <- any sense in making this configurable? may be for debug?.. - + private: //don't reinterpret any data TDomain(const TString &name, ui32 domainUid, ui64 schemeRootId, - ui32 defaultStateStorageGroup, ui32 defaultSchemeBoardGroup, - TVectorUi32 stateStorageGroup, + ui32 defaultStateStorageGroup, ui32 defaultSchemeBoardGroup, + TVectorUi32 stateStorageGroup, TVectorUi64 coordinators, TVectorUi64 mediators, TVectorUi64 allocators, ui32 defaultHiveUid, TVectorUi32 hivesUids, ui64 domainPlanResolution, const TStoragePoolKinds &poolTypes) : DomainUid(domainUid) , DefaultStateStorageGroup(defaultStateStorageGroup) - , DefaultSchemeBoardGroup(defaultSchemeBoardGroup) + , DefaultSchemeBoardGroup(defaultSchemeBoardGroup) , SchemeRoot(schemeRootId) - , Name(name) + , Name(name) , Coordinators(std::move(coordinators)) , Mediators(std::move(mediators)) , TxAllocators(std::move(allocators)) , StateStorageGroups(std::move(stateStorageGroup)) , DefaultHiveUid(defaultHiveUid) , HiveUids(std::move(hivesUids)) - , DomainPlanResolution(domainPlanResolution) + , DomainPlanResolution(domainPlanResolution) , StoragePoolTypes(poolTypes) - {} - + {} + public: //interpret coordinatorUids, mediatorUids and allocatorUids as vector uids and call proper MakeTabletId for each template <typename TUidsContainerUi32, typename TUidsContainerUi64> static TDomain::TPtr ConstructDomain(const TString &name, ui32 domainUid, ui64 schemeRoot, - ui32 defaultStateStorageGroup, ui32 defaultSchemeBoardGroup, - const TUidsContainerUi32 &stateStorageGroups, + ui32 defaultStateStorageGroup, ui32 defaultSchemeBoardGroup, + const TUidsContainerUi32 &stateStorageGroups, ui32 defaultHiveUid,const TUidsContainerUi32 &hiveUids, ui64 planResolution, const TUidsContainerUi64 &coordinatorUids, @@ -130,13 +130,13 @@ struct TDomainsInfo : public TThrRefBase { const TStoragePoolKinds &poolTypes = TStoragePoolKinds()) { return new TDomain(name, domainUid, schemeRoot, - defaultStateStorageGroup, defaultSchemeBoardGroup, - TVectorUi32(stateStorageGroups.begin(), stateStorageGroups.end()), - MakeCoordinatorsIds(TVectorUi64(coordinatorUids.begin(), coordinatorUids.end()), domainUid), - MakeMediatrosIds(TVectorUi64(mediatorUids.begin(), mediatorUids.end()), domainUid), - MakeAllocatorsIds(TVectorUi64(allocatorUids.begin(), allocatorUids.end()), domainUid), - defaultHiveUid, TVectorUi32(hiveUids.begin(), hiveUids.end()), - planResolution, poolTypes); + defaultStateStorageGroup, defaultSchemeBoardGroup, + TVectorUi32(stateStorageGroups.begin(), stateStorageGroups.end()), + MakeCoordinatorsIds(TVectorUi64(coordinatorUids.begin(), coordinatorUids.end()), domainUid), + MakeMediatrosIds(TVectorUi64(mediatorUids.begin(), mediatorUids.end()), domainUid), + MakeAllocatorsIds(TVectorUi64(allocatorUids.begin(), allocatorUids.end()), domainUid), + defaultHiveUid, TVectorUi32(hiveUids.begin(), hiveUids.end()), + planResolution, poolTypes); } //no any tablets setted @@ -147,48 +147,48 @@ struct TDomainsInfo : public TThrRefBase { const ui32 defHiveUid = domainId; ui64 planResolution = 500; return new TDomain(name, domainId, schemeRoot, - stateStorageGroup, stateStorageGroup, - TVectorUi32(1, stateStorageGroup), - TVectorUi64(), - TVectorUi64(), - TVectorUi64(), - defHiveUid, TVectorUi32(1, defHiveUid), - planResolution, TStoragePoolKinds()); + stateStorageGroup, stateStorageGroup, + TVectorUi32(1, stateStorageGroup), + TVectorUi64(), + TVectorUi64(), + TVectorUi64(), + defHiveUid, TVectorUi32(1, defHiveUid), + planResolution, TStoragePoolKinds()); } template <typename TUidsContainerUi32, typename TUidsContainerUi64> static TDomain::TPtr ConstructDomainWithExplicitTabletIds(const TString &name, ui32 domainUid, ui64 schemeRoot, - ui32 defaultStateStorageGroup, ui32 defaultSchemeBoardGroup, - const TUidsContainerUi32 &stateStorageGroups, - ui32 defaultHiveUid,const TUidsContainerUi32 &hiveUids, - ui64 planResolution, - const TUidsContainerUi64 &coordinatorUids, - const TUidsContainerUi64 &mediatorUids, - const TUidsContainerUi64 &allocatorUids, - const TStoragePoolKinds &poolTypes = TStoragePoolKinds()) + ui32 defaultStateStorageGroup, ui32 defaultSchemeBoardGroup, + const TUidsContainerUi32 &stateStorageGroups, + ui32 defaultHiveUid,const TUidsContainerUi32 &hiveUids, + ui64 planResolution, + const TUidsContainerUi64 &coordinatorUids, + const TUidsContainerUi64 &mediatorUids, + const TUidsContainerUi64 &allocatorUids, + const TStoragePoolKinds &poolTypes = TStoragePoolKinds()) { return new TDomain(name, domainUid, schemeRoot, - defaultStateStorageGroup, defaultSchemeBoardGroup, - TVectorUi32(stateStorageGroups.begin(), stateStorageGroups.end()), - TVectorUi64(coordinatorUids.begin(), coordinatorUids.end()), - TVectorUi64(mediatorUids.begin(), mediatorUids.end()), - TVectorUi64(allocatorUids.begin(), allocatorUids.end()), - defaultHiveUid, TVectorUi32(hiveUids.begin(), hiveUids.end()), - planResolution, poolTypes); + defaultStateStorageGroup, defaultSchemeBoardGroup, + TVectorUi32(stateStorageGroups.begin(), stateStorageGroups.end()), + TVectorUi64(coordinatorUids.begin(), coordinatorUids.end()), + TVectorUi64(mediatorUids.begin(), mediatorUids.end()), + TVectorUi64(allocatorUids.begin(), allocatorUids.end()), + defaultHiveUid, TVectorUi32(hiveUids.begin(), hiveUids.end()), + planResolution, poolTypes); } - ui32 DomainRootTag() const { + ui32 DomainRootTag() const { return DomainUid + FirstUserTag; - } - + } + static TVector<ui64> TransformUids(TVector<ui64> &&uids, std::function<ui64 (ui32)> func) { TVector<ui64> result(std::move(uids)); for (ui32 i = 0; i < result.size(); ++i) { result[i] = func(result[i]); } return result; - } - + } + static TVector<ui64> TransformIntoVectorUids(ui32 count) { TVector<ui64> result; result.reserve(count); @@ -196,11 +196,11 @@ struct TDomainsInfo : public TThrRefBase { result.push_back(i); } return result; - } - + } + static TVector<ui64> MakeCoordinatorsIds(TVector<ui64> &&uids, ui32 domainUid) { return TransformUids(std::move(uids), [&domainUid](ui32 uid) { return MakeTxCoordinatorID(domainUid, uid); }); - } + } static TVector<ui64> MakeCoordinatorsIds(ui32 count, ui32 domainUid) { return MakeCoordinatorsIds(TransformIntoVectorUids(count), domainUid); @@ -229,8 +229,8 @@ struct TDomainsInfo : public TThrRefBase { return HiveUids.at(idx); } - }; - + }; + TMap<ui32, TIntrusivePtr<TDomain>> Domains; THashMap<TString, TIntrusivePtr<TDomain>> DomainByName; TMap<ui32, TIntrusivePtr<TDomain>> DomainByStateStorageGroup; @@ -300,27 +300,27 @@ struct TDomainsInfo : public TThrRefBase { return it->second->DomainUid; } - ui32 GetDomainUidByTabletId(ui64 tabletId) const { - const ui32 ssid = StateStorageGroupFromTabletID(tabletId); - if (const auto *x = DomainByStateStorageGroup.FindPtr(ssid)) - return x->Get()->DomainUid; - else + ui32 GetDomainUidByTabletId(ui64 tabletId) const { + const ui32 ssid = StateStorageGroupFromTabletID(tabletId); + if (const auto *x = DomainByStateStorageGroup.FindPtr(ssid)) + return x->Get()->DomainUid; + else return BadDomainId; - } - + } + const TDomain& GetDomain(ui32 domainUid) const { auto it = Domains.find(domainUid); Y_VERIFY(it != Domains.end(), "domainUid = %" PRIu32, domainUid); return *(it->second); } - const TDomain* GetDomainByName(TStringBuf name) const { + const TDomain* GetDomainByName(TStringBuf name) const { auto it = DomainByName.find(name); if (it != DomainByName.end()) return it->second.Get(); - return nullptr; - } - + return nullptr; + } + ui64 GetHive(ui32 hiveUid) const { auto it = HivesByHiveUid.find(hiveUid); if (it != HivesByHiveUid.end()) @@ -336,13 +336,13 @@ struct TDomainsInfo : public TThrRefBase { else return BadDomainId; } - - ui32 GetHiveUidByHiveId(ui64 hiveTabletId) const { - for (const auto &xpair : HivesByHiveUid) - if (xpair.second == hiveTabletId) - return xpair.first; - return Max<ui32>(); - } -}; - -} + + ui32 GetHiveUidByHiveId(ui64 hiveTabletId) const { + for (const auto &xpair : HivesByHiveUid) + if (xpair.second == hiveTabletId) + return xpair.first; + return Max<ui32>(); + } +}; + +} diff --git a/ydb/core/base/events.h b/ydb/core/base/events.h index 77d6661a88..f5fedfe19b 100644 --- a/ydb/core/base/events.h +++ b/ydb/core/base/events.h @@ -1,16 +1,16 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include <library/cpp/actors/core/events.h> #include <library/cpp/actors/core/event_local.h> #include <library/cpp/actors/core/event_pb.h> #include <ydb/library/yql/dq/actors/dq_events_ids.h> - + #include <ydb/core/yq/libs/events/event_ids.h> -namespace NKikimr { - -struct TKikimrEvents : TEvents { - enum EEventSpaceKikimr { +namespace NKikimr { + +struct TKikimrEvents : TEvents { + enum EEventSpaceKikimr { /* WARNING: Please mind that you should never change the order for the following keywords, you should consider @@ -18,57 +18,57 @@ struct TKikimrEvents : TEvents { */ ES_KIKIMR_ES_BEGIN = ES_USERSPACE, //4096 ES_STATESTORAGE, //4097 - ES_DEPRECATED_4098, //4098 + ES_DEPRECATED_4098, //4098 ES_BLOBSTORAGE, //4099 ES_HIVE, //4100 ES_TABLETBASE, //4101 ES_TABLET, //4102 - ES_TABLETRESOLVER, - ES_LOCAL, - ES_DEPRECATED_4105, + ES_TABLETRESOLVER, + ES_LOCAL, + ES_DEPRECATED_4105, ES_TX_PROXY, // generic proxy commands 4106 - ES_TX_COORDINATOR, - ES_TX_MEDIATOR, + ES_TX_COORDINATOR, + ES_TX_MEDIATOR, ES_TX_PROCESSING, // 4109 - ES_DEPRECATED_4110, - ES_DEPRECATED_4111, - ES_DEPRECATED_4112, - ES_TX_DATASHARD, - ES_DEPRECATED_4114, - ES_TX_USERPROXY, // user proxy interface + ES_DEPRECATED_4110, + ES_DEPRECATED_4111, + ES_DEPRECATED_4112, + ES_TX_DATASHARD, + ES_DEPRECATED_4114, + ES_TX_USERPROXY, // user proxy interface ES_SCHEME_CACHE, - ES_TX_PROXY_REQ, + ES_TX_PROXY_REQ, ES_TABLET_PIPE, - ES_DEPRECATED_4118, + ES_DEPRECATED_4118, ES_TABLET_COUNTERS_AGGREGATOR, - ES_DEPRECATED_4121, + ES_DEPRECATED_4121, ES_PROXY_BUS, //4122 - ES_BOOTSTRAPPER, - ES_TX_MEDIATORTIMECAST, - ES_DEPRECATED_4125, - ES_DEPRECATED_4126, - ES_DEPRECATED_4127, - ES_DEPRECATED_4128, - ES_DEPRECATED_4129, - ES_DEPRECATED_4130, - ES_DEPRECATED_4131, + ES_BOOTSTRAPPER, + ES_TX_MEDIATORTIMECAST, + ES_DEPRECATED_4125, + ES_DEPRECATED_4126, + ES_DEPRECATED_4127, + ES_DEPRECATED_4128, + ES_DEPRECATED_4129, + ES_DEPRECATED_4130, + ES_DEPRECATED_4131, ES_KEYVALUE, //4132 ES_MSGBUS_TRACER, - ES_RTMR_TABLET, - ES_FLAT_EXECUTOR, + ES_RTMR_TABLET, + ES_FLAT_EXECUTOR, ES_NODE_WHITEBOARD, ES_FLAT_TX_SCHEMESHARD, // 4137 ES_PQ, ES_YQL_KIKIMR_PROXY, ES_PQ_META_CACHE, - ES_DEPRECATED_4141, + ES_DEPRECATED_4141, ES_PQ_L2_CACHE, //4142 ES_TOKEN_BUILDER, ES_TICKET_PARSER, ES_KQP = NYql::NDq::TDqEvents::ES_DQ_COMPUTE_KQP_COMPATIBLE, // 4145 ES_BLACKBOX_VALIDATOR, ES_SELF_PING, - ES_PIPECACHE, + ES_PIPECACHE, ES_PQ_PROXY, ES_CMS, ES_NODE_BROKER, @@ -98,8 +98,8 @@ struct TKikimrEvents : TEvents { ES_IAM_SERVICE, ES_FOLDER_SERVICE, ES_GRPC_MON, - ES_QUOTA, - ES_COORDINATED_QUOTA, + ES_QUOTA, + ES_COORDINATED_QUOTA, ES_ACCESS_SERVICE, ES_USER_ACCOUNT_SERVICE, ES_PQ_PROXY_NEW, @@ -112,7 +112,7 @@ struct TKikimrEvents : TEvents { ES_PQ_CLUSTER_TRACKER, ES_NET_CLASSIFIER, ES_SYSTEM_VIEW, - ES_TENANT_NODE_ENUMERATOR, + ES_TENANT_NODE_ENUMERATOR, ES_SERVICE_ACCOUNT_SERVICE, ES_INDEX_BUILD, ES_BLOCKSTORE_PRIVATE, @@ -145,7 +145,7 @@ struct TKikimrEvents : TEvents { ES_PQ_PARTITION_WRITER, ES_YDB_PROXY, ES_REPLICATION_CONTROLLER, - }; -}; - -} + }; +}; + +} diff --git a/ydb/core/base/hive.h b/ydb/core/base/hive.h index 6bcce181da..7464c76699 100644 --- a/ydb/core/base/hive.h +++ b/ydb/core/base/hive.h @@ -1,22 +1,22 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include "blobstorage.h" -#include "events.h" +#include "events.h" #include "storage_pools.h" #include "subdomain.h" #include <ydb/core/protos/hive.pb.h> #include <ydb/core/base/tablet.h> #include <util/stream/str.h> - -namespace NKikimr { + +namespace NKikimr { struct TEvHive { - enum EEv { - // requests + enum EEv { + // requests EvBootTablet = EventSpaceBegin(TKikimrEvents::ES_HIVE), - EvCreateTablet, - EvForgetTablet, - EvReconfigureTablet, - EvLookupChannelInfo, + EvCreateTablet, + EvForgetTablet, + EvReconfigureTablet, + EvLookupChannelInfo, EvStopTablet, EvTabletMetrics = EvStopTablet + 7, // review 194375 @@ -44,13 +44,13 @@ namespace NKikimr { EvConfigureHive, EvInitMigration, EvQueryMigration, - - // replies - EvBootTabletReply = EvBootTablet + 512, - EvCreateTabletReply, - EvForgetTabletReply, - EvReconfigureTabletReply, - EvChannelInfo, + + // replies + EvBootTabletReply = EvBootTablet + 512, + EvCreateTabletReply, + EvForgetTabletReply, + EvReconfigureTabletReply, + EvChannelInfo, EvStopTabletResult, EvDeleteTabletReply, EvTabletCreationResult, @@ -74,20 +74,20 @@ namespace NKikimr { EvInitMigrationReply, EvQueryMigrationReply, - EvEnd - }; - + EvEnd + }; + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_HIVE), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_HIVE)"); - + struct TEvBootTablet : public TEventPB<TEvBootTablet, NKikimrHive::TEvBootTablet, EvBootTablet> { - TEvBootTablet() - {} - - TEvBootTablet(ui64 tabletId) - { - Record.SetTabletID(tabletId); - } + TEvBootTablet() + {} + + TEvBootTablet(ui64 tabletId) + { + Record.SetTabletID(tabletId); + } TString ToString() const { TStringStream str; @@ -95,18 +95,18 @@ namespace NKikimr { str << "}"; return str.Str(); } - }; - + }; + struct TEvBootTabletReply : public TEventPB<TEvBootTabletReply, NKikimrHive::TEvBootTabletReply, EvBootTabletReply> { - TEvBootTabletReply() - {} - + TEvBootTabletReply() + {} + TEvBootTabletReply(NKikimrProto::EReplyStatus status, const TString& msg = {}) - { - Record.SetStatus(status); + { + Record.SetStatus(status); Record.SetStatusMsg(msg); - } + } TString ToString() const { TStringStream str; @@ -115,18 +115,18 @@ namespace NKikimr { str << "}"; return str.Str(); } - }; - + }; + struct TEvCreateTablet : public TEventPB<TEvCreateTablet, NKikimrHive::TEvCreateTablet, EvCreateTablet> { - TEvCreateTablet() - {} - + TEvCreateTablet() + {} + TEvCreateTablet(ui64 ownerId, ui64 ownerIdx, TTabletTypes::EType tabletType, const TChannelsBindings& bindedChannels) { - Record.SetOwner(ownerId); - Record.SetOwnerIdx(ownerIdx); - Record.SetTabletType(tabletType); + Record.SetOwner(ownerId); + Record.SetOwnerIdx(ownerIdx); + Record.SetTabletType(tabletType); for (auto& channel : bindedChannels) { *Record.AddBindedChannels() = channel; } @@ -155,7 +155,7 @@ namespace NKikimr { for (auto& channel : bindedChannels) { *Record.AddBindedChannels() = channel; } - } + } TString ToString() const { TStringStream str; @@ -184,29 +184,29 @@ namespace NKikimr { str << "}"; return str.Str(); } - }; - + }; + struct TEvCreateTabletReply : TEventPB<TEvCreateTabletReply, NKikimrHive::TEvCreateTabletReply, EvCreateTabletReply> { TEvCreateTabletReply() = default; - + TEvCreateTabletReply(NKikimrProto::EReplyStatus status, ui64 ownerId, ui64 ownerIdx) { - Record.SetStatus(status); - Record.SetOwner(ownerId); - Record.SetOwnerIdx(ownerIdx); + Record.SetStatus(status); + Record.SetOwner(ownerId); + Record.SetOwnerIdx(ownerIdx); } TEvCreateTabletReply(NKikimrProto::EReplyStatus status, ui64 ownerId, ui64 ownerIdx, ui64 tabletId) : TEvCreateTabletReply(status, ownerId, ownerIdx) { - if (tabletId != 0) - Record.SetTabletID(tabletId); + if (tabletId != 0) + Record.SetTabletID(tabletId); } TEvCreateTabletReply(NKikimrProto::EReplyStatus status, ui64 ownerId, ui64 ownerIdx, ui64 tabletId, ui64 origin) : TEvCreateTabletReply(status, ownerId, ownerIdx, tabletId) { Record.SetOrigin(origin); - } + } TEvCreateTabletReply( NKikimrProto::EReplyStatus status, @@ -236,8 +236,8 @@ namespace NKikimr { str << "}"; return str.Str(); } - }; - + }; + struct TEvTabletCreationResult : public TEventPB< TEvTabletCreationResult, NKikimrHive::TEvTabletCreationResult, EvTabletCreationResult> { TEvTabletCreationResult() @@ -369,12 +369,12 @@ namespace NKikimr { struct TEvReconfigureTablet : public TEventPB<TEvReconfigureTablet, NKikimrHive::TEvReconfigureTablet, EvReconfigureTablet> { - TEvReconfigureTablet() - {} - - TEvReconfigureTablet(ui64 tabletId) { - Record.SetTabletID(tabletId); - } + TEvReconfigureTablet() + {} + + TEvReconfigureTablet(ui64 tabletId) { + Record.SetTabletID(tabletId); + } TString ToString() const { TStringStream str; @@ -382,17 +382,17 @@ namespace NKikimr { str << "}"; return str.Str(); } - }; - + }; + struct TEvReconfigureTabletReply : public TEventPB<TEvReconfigureTabletReply, NKikimrHive::TEvReconfigureTabletReply, EvReconfigureTabletReply> { - TEvReconfigureTabletReply() - {} - + TEvReconfigureTabletReply() + {} + TEvReconfigureTabletReply(NKikimrProto::EReplyStatus status, ui64 tabletId) { - Record.SetStatus(status); - Record.SetTabletID(tabletId); - } + Record.SetStatus(status); + Record.SetTabletID(tabletId); + } TString ToString() const { TStringStream str; @@ -401,8 +401,8 @@ namespace NKikimr { str << "}"; return str.Str(); } - }; - + }; + struct TEvDeleteTablet : public TEventPB<TEvDeleteTablet, NKikimrHive::TEvDeleteTablet, EvDeleteTablet> { TEvDeleteTablet() {} @@ -463,10 +463,10 @@ namespace NKikimr { struct TEvLookupChannelInfo : TEventPB<TEvLookupChannelInfo, NKikimrHive::TEvLookupChannelInfo, EvLookupChannelInfo> { TEvLookupChannelInfo() = default; - + TEvLookupChannelInfo(ui64 tabletId) { - Record.SetTabletID(tabletId); - } + Record.SetTabletID(tabletId); + } TString ToString() const { TStringStream str; @@ -474,15 +474,15 @@ namespace NKikimr { str << "}"; return str.Str(); } - }; - + }; + struct TEvChannelInfo : TEventPB<TEvChannelInfo, NKikimrHive::TEvChannelInfo, EvChannelInfo> { TEvChannelInfo() = default; - + TEvChannelInfo(NKikimrProto::EReplyStatus status, ui64 tabletId) { - Record.SetStatus(status); - Record.SetTabletID(tabletId); - } + Record.SetStatus(status); + Record.SetTabletID(tabletId); + } TString ToString() const { TStringStream str; @@ -491,8 +491,8 @@ namespace NKikimr { str << "}"; return str.Str(); } - }; - + }; + struct TEvTabletMetrics : public TEventPB<TEvTabletMetrics, NKikimrHive::TEvTabletMetrics, EvTabletMetrics> { }; @@ -547,9 +547,9 @@ namespace NKikimr { Record.SetReturnFollowers(returnFollowers); } TEvRequestHiveInfo(ui64 tabletId, bool returnFollowers) { - Record.SetTabletID(tabletId); + Record.SetTabletID(tabletId); Record.SetReturnFollowers(returnFollowers); - } + } }; struct TEvResponseHiveInfo : TEventPB<TEvResponseHiveInfo, NKikimrHive::TEvResponseHiveInfo, EvResponseHiveInfo> {}; @@ -804,7 +804,7 @@ namespace NKikimr { Record.SetMigrationProgress(progress); } }; - }; - + }; + IActor* CreateDefaultHive(const TActorId &tablet, TTabletStorageInfo *info); -} +} diff --git a/ydb/core/base/kikimr_issue.cpp b/ydb/core/base/kikimr_issue.cpp index 425da90d58..80b4ed8203 100644 --- a/ydb/core/base/kikimr_issue.cpp +++ b/ydb/core/base/kikimr_issue.cpp @@ -1,11 +1,11 @@ -#include "kikimr_issue.h" - -namespace NKikimr { - -const char IssueMapResource[] = "kikimr_issue.txt"; - -static_assert(NYql::DEFAULT_ERROR == NKikimrIssues::TIssuesIds::DEFAULT_ERROR, - "value of particular and common error mismatched for \"DEFAULT_ERROR\""); -static_assert(NYql::UNEXPECTED_ERROR == NKikimrIssues::TIssuesIds::UNEXPECTED, - "value of particular and common error mismatched for \"UNEXPECTED_ERROR\""); -} +#include "kikimr_issue.h" + +namespace NKikimr { + +const char IssueMapResource[] = "kikimr_issue.txt"; + +static_assert(NYql::DEFAULT_ERROR == NKikimrIssues::TIssuesIds::DEFAULT_ERROR, + "value of particular and common error mismatched for \"DEFAULT_ERROR\""); +static_assert(NYql::UNEXPECTED_ERROR == NKikimrIssues::TIssuesIds::UNEXPECTED, + "value of particular and common error mismatched for \"UNEXPECTED_ERROR\""); +} diff --git a/ydb/core/base/kikimr_issue.h b/ydb/core/base/kikimr_issue.h index 8b12130622..fd7e232d2c 100644 --- a/ydb/core/base/kikimr_issue.h +++ b/ydb/core/base/kikimr_issue.h @@ -1,56 +1,56 @@ -#pragma once - +#pragma once + #include <ydb/core/protos/issue_id.pb.h> #include <ydb/library/yql/public/issue/yql_issue.h> #include <ydb/library/yql/public/issue/yql_issue_id.h> #include <ydb/library/yql/public/issue/yql_issue_message.h> - -namespace NKikimr { - + +namespace NKikimr { + extern const char IssueMapResource[17]; - -inline NYql::ESeverity GetSeverity(NYql::TIssueCode id) { - return NYql::GetSeverity<NKikimrIssues::TIssuesIds, IssueMapResource>(id); -} - -inline TString GetMessage(NYql::TIssueCode id) { - return NYql::GetMessage<NKikimrIssues::TIssuesIds, IssueMapResource>(id); -} - -inline NYql::TIssue& SetIssueCode(NYql::TIssueCode id, NYql::TIssue& issue) { - issue.SetCode(id, GetSeverity(id)); - return issue; -} - -inline TString IssueCodeToString(NYql::TIssueCode id) { - const TString& message = GetMessage(id); - if (message) { - return message; - } else { - return NYql::IssueCodeToString<NKikimrIssues::TIssuesIds>(id); - } -} - -inline NYql::TIssue MakeIssue(NKikimrIssues::TIssuesIds::EIssueCode id, const TString& message) { - NYql::TIssue issue; - - SetIssueCode(id, issue); - issue.Message = message; - - return issue; -} - -inline NYql::TIssue MakeIssue(NKikimrIssues::TIssuesIds::EIssueCode id) { - return MakeIssue(id, IssueCodeToString(id)); -} - + +inline NYql::ESeverity GetSeverity(NYql::TIssueCode id) { + return NYql::GetSeverity<NKikimrIssues::TIssuesIds, IssueMapResource>(id); +} + +inline TString GetMessage(NYql::TIssueCode id) { + return NYql::GetMessage<NKikimrIssues::TIssuesIds, IssueMapResource>(id); +} + +inline NYql::TIssue& SetIssueCode(NYql::TIssueCode id, NYql::TIssue& issue) { + issue.SetCode(id, GetSeverity(id)); + return issue; +} + +inline TString IssueCodeToString(NYql::TIssueCode id) { + const TString& message = GetMessage(id); + if (message) { + return message; + } else { + return NYql::IssueCodeToString<NKikimrIssues::TIssuesIds>(id); + } +} + +inline NYql::TIssue MakeIssue(NKikimrIssues::TIssuesIds::EIssueCode id, const TString& message) { + NYql::TIssue issue; + + SetIssueCode(id, issue); + issue.Message = message; + + return issue; +} + +inline NYql::TIssue MakeIssue(NKikimrIssues::TIssuesIds::EIssueCode id) { + return MakeIssue(id, IssueCodeToString(id)); +} + inline TString SerializeIssues(const NYql::TIssues& in) { NYql::TIssue rootIssue; for(const auto& i : in) { rootIssue.AddSubIssue(MakeIntrusive<NYql::TIssue>(i)); } return NYql::IssueToBinaryMessage(rootIssue); -} +} inline NYql::TIssues DeserializeIssues(const TString& in) { NYql::TIssues result; diff --git a/ydb/core/base/kikimr_issue.txt b/ydb/core/base/kikimr_issue.txt index c8da213891..56c375080b 100644 --- a/ydb/core/base/kikimr_issue.txt +++ b/ydb/core/base/kikimr_issue.txt @@ -1,33 +1,33 @@ -ids { code: UNEXPECTED severity: S_FATAL } -ids { code: DEFAULT_ERROR severity: S_ERROR } -ids { code: INFO severity: S_INFO } -ids { code: WARNING severity: S_WARNING } -ids { code: SUCCESS severity: S_INFO } - -ids { code: ACCESS_DENIED severity: S_ERROR } - -ids { code: PATH_NOT_EXIST severity: S_ERROR } -ids { code: DATABASE_NOT_EXIST severity: S_ERROR } -ids { code: GENERIC_DATASHARD_ERROR severity: S_ERROR } -ids { code: GENERIC_RESOLVE_ERROR severity: S_ERROR } +ids { code: UNEXPECTED severity: S_FATAL } +ids { code: DEFAULT_ERROR severity: S_ERROR } +ids { code: INFO severity: S_INFO } +ids { code: WARNING severity: S_WARNING } +ids { code: SUCCESS severity: S_INFO } + +ids { code: ACCESS_DENIED severity: S_ERROR } + +ids { code: PATH_NOT_EXIST severity: S_ERROR } +ids { code: DATABASE_NOT_EXIST severity: S_ERROR } +ids { code: GENERIC_DATASHARD_ERROR severity: S_ERROR } +ids { code: GENERIC_RESOLVE_ERROR severity: S_ERROR } ids { code: RESOLVE_LOOKUP_ERROR severity: S_ERROR } -ids { code: GENERIC_TXPROXY_ERROR severity: S_ERROR } -ids { code: KEY_PARSE_ERROR severity: S_ERROR } -ids { code: EMPTY_OP_RANGE severity: S_ERROR } -ids { code: ENGINE_ERROR severity: S_ERROR } -ids { code: DOMAIN_LOCALITY_ERROR severity: S_ERROR } -ids { code: SHARD_NOT_AVAILABLE severity: S_ERROR } -ids { code: TX_STATE_UNKNOWN severity: S_ERROR } -ids { code: TX_DECLINED_BY_COORDINATOR severity: S_ERROR } +ids { code: GENERIC_TXPROXY_ERROR severity: S_ERROR } +ids { code: KEY_PARSE_ERROR severity: S_ERROR } +ids { code: EMPTY_OP_RANGE severity: S_ERROR } +ids { code: ENGINE_ERROR severity: S_ERROR } +ids { code: DOMAIN_LOCALITY_ERROR severity: S_ERROR } +ids { code: SHARD_NOT_AVAILABLE severity: S_ERROR } +ids { code: TX_STATE_UNKNOWN severity: S_ERROR } +ids { code: TX_DECLINED_BY_COORDINATOR severity: S_ERROR } ids { code: TX_DECLINED_IMPLICIT_COORDINATOR severity: S_ERROR } ids { code: SHARD_PROGRAM_SIZE_EXCEEDED severity: S_ERROR } - -ids { code: SCOPE_REQPROXY severity: S_INFO} - -ids { code: SCOPE_TXPROXY_INTERPRET severity: S_INFO} -ids { code: SCOPE_TXPROXY_RESOLVE severity: S_INFO} -ids { code: SCOPE_TXPROXY_PREPARE severity: S_INFO} -ids { code: SCOPE_TXPROXY_EXECUTE severity: S_INFO} + +ids { code: SCOPE_REQPROXY severity: S_INFO} + +ids { code: SCOPE_TXPROXY_INTERPRET severity: S_INFO} +ids { code: SCOPE_TXPROXY_RESOLVE severity: S_INFO} +ids { code: SCOPE_TXPROXY_PREPARE severity: S_INFO} +ids { code: SCOPE_TXPROXY_EXECUTE severity: S_INFO} ids { code: YDB_API_VALIDATION_ERROR severity: S_ERROR } ids { code: YDB_AUTH_UNAVAILABLE severity: S_ERROR } diff --git a/ydb/core/base/localdb.cpp b/ydb/core/base/localdb.cpp index 85e50aa408..d07ee26fc1 100644 --- a/ydb/core/base/localdb.cpp +++ b/ydb/core/base/localdb.cpp @@ -24,9 +24,9 @@ TCompactionPolicy::TBackgroundPolicy::TBackgroundPolicy(ui32 threshold, {} TCompactionPolicy::TBackgroundPolicy::TBackgroundPolicy(const NKikimrSchemeOp::TCompactionPolicy::TBackgroundPolicy &policyPb) - : Threshold(policyPb.HasThreshold() ? policyPb.GetThreshold() : 101) - , PriorityBase(policyPb.HasPriorityBase() ? policyPb.GetPriorityBase() : 100) - , TimeFactor(policyPb.HasTimeFactor() ? policyPb.GetTimeFactor() : 1.0) + : Threshold(policyPb.HasThreshold() ? policyPb.GetThreshold() : 101) + , PriorityBase(policyPb.HasPriorityBase() ? policyPb.GetPriorityBase() : 100) + , TimeFactor(policyPb.HasTimeFactor() ? policyPb.GetTimeFactor() : 1.0) , ResourceBrokerTask(policyPb.HasResourceBrokerTask() ? policyPb.GetResourceBrokerTask() : BackgroundCompactionTaskName) {} @@ -61,14 +61,14 @@ TCompactionPolicy::TGenerationPolicy::TGenerationPolicy(ui64 sizeToCompact, {} TCompactionPolicy::TGenerationPolicy::TGenerationPolicy(const NKikimrSchemeOp::TCompactionPolicy::TGenerationPolicy &policyPb) - : SizeToCompact(policyPb.HasSizeToCompact() ? policyPb.GetSizeToCompact() : 0) - , CountToCompact(policyPb.HasCountToCompact() ? policyPb.GetCountToCompact() : 5) - , ForceCountToCompact(policyPb.HasForceCountToCompact() ? policyPb.GetForceCountToCompact() : 8) - , ForceSizeToCompact(policyPb.HasForceSizeToCompact() ? policyPb.GetForceSizeToCompact() : 0) - , CompactionBrokerQueue(policyPb.HasCompactionBrokerQueue() ? policyPb.GetCompactionBrokerQueue() : 1) - , ResourceBrokerTask(policyPb.HasResourceBrokerTask() ? policyPb.GetResourceBrokerTask() : TString()) - , KeepInCache(policyPb.HasKeepInCache() ? policyPb.GetKeepInCache() : false) - , BackgroundCompactionPolicy(policyPb.HasBackgroundCompactionPolicy() ? policyPb.GetBackgroundCompactionPolicy() : TBackgroundPolicy()) + : SizeToCompact(policyPb.HasSizeToCompact() ? policyPb.GetSizeToCompact() : 0) + , CountToCompact(policyPb.HasCountToCompact() ? policyPb.GetCountToCompact() : 5) + , ForceCountToCompact(policyPb.HasForceCountToCompact() ? policyPb.GetForceCountToCompact() : 8) + , ForceSizeToCompact(policyPb.HasForceSizeToCompact() ? policyPb.GetForceSizeToCompact() : 0) + , CompactionBrokerQueue(policyPb.HasCompactionBrokerQueue() ? policyPb.GetCompactionBrokerQueue() : 1) + , ResourceBrokerTask(policyPb.HasResourceBrokerTask() ? policyPb.GetResourceBrokerTask() : TString()) + , KeepInCache(policyPb.HasKeepInCache() ? policyPb.GetKeepInCache() : false) + , BackgroundCompactionPolicy(policyPb.HasBackgroundCompactionPolicy() ? policyPb.GetBackgroundCompactionPolicy() : TBackgroundPolicy()) , ExtraCompactionPercent(policyPb.HasExtraCompactionPercent() ? policyPb.GetExtraCompactionPercent() : 10) , ExtraCompactionExpPercent(policyPb.HasExtraCompactionExpPercent() ? policyPb.GetExtraCompactionExpPercent() : 110) , ExtraCompactionMinSize(policyPb.HasExtraCompactionMinSize() ? policyPb.GetExtraCompactionMinSize() : 16384) @@ -96,10 +96,10 @@ void TCompactionPolicy::TGenerationPolicy::Serialize(NKikimrSchemeOp::TCompactio policyPb.SetUpliftPartSize(UpliftPartSize); } -TCompactionPolicy::TCompactionPolicy() +TCompactionPolicy::TCompactionPolicy() : InMemSizeToSnapshot(4 * 1024 * 1024) - , InMemStepsToSnapshot(300) - , InMemForceStepsToSnapshot(500) + , InMemStepsToSnapshot(300) + , InMemForceStepsToSnapshot(500) , InMemForceSizeToSnapshot(16 * 1024 * 1024) , InMemCompactionBrokerQueue(0) , InMemResourceBrokerTask(LegacyQueueIdToTaskName(0)) @@ -120,27 +120,27 @@ TCompactionPolicy::TCompactionPolicy() {} TCompactionPolicy::TCompactionPolicy(const NKikimrSchemeOp::TCompactionPolicy& policyPb) - : InMemSizeToSnapshot(policyPb.HasInMemSizeToSnapshot() ? policyPb.GetInMemSizeToSnapshot() : 4 * 1024 * 1024) - , InMemStepsToSnapshot(policyPb.HasInMemStepsToSnapshot() ? policyPb.GetInMemStepsToSnapshot() : 300) - , InMemForceStepsToSnapshot(policyPb.HasInMemForceStepsToSnapshot() ? policyPb.GetInMemForceStepsToSnapshot() : 500) - , InMemForceSizeToSnapshot(policyPb.HasInMemForceSizeToSnapshot() ? policyPb.GetInMemForceSizeToSnapshot() : 16 * 1024 * 1024) - , InMemCompactionBrokerQueue(policyPb.HasInMemCompactionBrokerQueue() ? policyPb.GetInMemCompactionBrokerQueue() : 0) - , InMemResourceBrokerTask(policyPb.HasInMemResourceBrokerTask() ? policyPb.GetInMemResourceBrokerTask() : LegacyQueueIdToTaskName(0)) - , ReadAheadHiThreshold(policyPb.HasReadAheadHiThreshold() ? policyPb.GetReadAheadHiThreshold() : 64 * 1024 * 1024) - , ReadAheadLoThreshold(policyPb.HasReadAheadLoThreshold() ? policyPb.GetReadAheadLoThreshold() : 16 * 1024 * 1024) - , MinDataPageSize(policyPb.HasMinDataPageSize() ? policyPb.GetMinDataPageSize() : 7 * 1024) - , SnapshotCompactionBrokerQueue(policyPb.HasSnapBrokerQueue() ? policyPb.GetSnapBrokerQueue() : 0) - , SnapshotResourceBrokerTask(policyPb.HasSnapshotResourceBrokerTask() ? policyPb.GetSnapshotResourceBrokerTask() : LegacyQueueIdToTaskName(0)) - , BackupCompactionBrokerQueue(policyPb.HasBackupBrokerQueue() ? policyPb.GetBackupBrokerQueue() : 1) + : InMemSizeToSnapshot(policyPb.HasInMemSizeToSnapshot() ? policyPb.GetInMemSizeToSnapshot() : 4 * 1024 * 1024) + , InMemStepsToSnapshot(policyPb.HasInMemStepsToSnapshot() ? policyPb.GetInMemStepsToSnapshot() : 300) + , InMemForceStepsToSnapshot(policyPb.HasInMemForceStepsToSnapshot() ? policyPb.GetInMemForceStepsToSnapshot() : 500) + , InMemForceSizeToSnapshot(policyPb.HasInMemForceSizeToSnapshot() ? policyPb.GetInMemForceSizeToSnapshot() : 16 * 1024 * 1024) + , InMemCompactionBrokerQueue(policyPb.HasInMemCompactionBrokerQueue() ? policyPb.GetInMemCompactionBrokerQueue() : 0) + , InMemResourceBrokerTask(policyPb.HasInMemResourceBrokerTask() ? policyPb.GetInMemResourceBrokerTask() : LegacyQueueIdToTaskName(0)) + , ReadAheadHiThreshold(policyPb.HasReadAheadHiThreshold() ? policyPb.GetReadAheadHiThreshold() : 64 * 1024 * 1024) + , ReadAheadLoThreshold(policyPb.HasReadAheadLoThreshold() ? policyPb.GetReadAheadLoThreshold() : 16 * 1024 * 1024) + , MinDataPageSize(policyPb.HasMinDataPageSize() ? policyPb.GetMinDataPageSize() : 7 * 1024) + , SnapshotCompactionBrokerQueue(policyPb.HasSnapBrokerQueue() ? policyPb.GetSnapBrokerQueue() : 0) + , SnapshotResourceBrokerTask(policyPb.HasSnapshotResourceBrokerTask() ? policyPb.GetSnapshotResourceBrokerTask() : LegacyQueueIdToTaskName(0)) + , BackupCompactionBrokerQueue(policyPb.HasBackupBrokerQueue() ? policyPb.GetBackupBrokerQueue() : 1) , BackupResourceBrokerTask(policyPb.HasBackupResourceBrokerTask() ? policyPb.GetBackupResourceBrokerTask() : ScanTaskName) - , DefaultTaskPriority(policyPb.HasDefaultTaskPriority() ? policyPb.GetDefaultTaskPriority() : 5) - , BackgroundSnapshotPolicy(policyPb.HasBackgroundSnapshotPolicy() ? policyPb.GetBackgroundSnapshotPolicy() : TBackgroundPolicy()) + , DefaultTaskPriority(policyPb.HasDefaultTaskPriority() ? policyPb.GetDefaultTaskPriority() : 5) + , BackgroundSnapshotPolicy(policyPb.HasBackgroundSnapshotPolicy() ? policyPb.GetBackgroundSnapshotPolicy() : TBackgroundPolicy()) , LogOverheadSizeToSnapshot(policyPb.HasLogOverheadSizeToSnapshot() ? policyPb.GetLogOverheadSizeToSnapshot() : 16 * 1024 * 1024) , LogOverheadCountToSnapshot(policyPb.HasLogOverheadCountToSnapshot() ? policyPb.GetLogOverheadCountToSnapshot() : 500) , DroppedRowsPercentToCompact(policyPb.HasDroppedRowsPercentToCompact() ? policyPb.GetDroppedRowsPercentToCompact() : 50) , CompactionStrategy(policyPb.GetCompactionStrategy()) , KeepEraseMarkers(policyPb.HasKeepEraseMarkers() ? policyPb.GetKeepEraseMarkers() : false) -{ +{ if (!InMemResourceBrokerTask) InMemResourceBrokerTask = LegacyQueueIdToTaskName(InMemCompactionBrokerQueue); if (!SnapshotResourceBrokerTask) @@ -156,8 +156,8 @@ TCompactionPolicy::TCompactionPolicy(const NKikimrSchemeOp::TCompactionPolicy& p if (policyPb.HasShardPolicy()) { ShardPolicy.CopyFrom(policyPb.GetShardPolicy()); } -} - +} + void TCompactionPolicy::Serialize(NKikimrSchemeOp::TCompactionPolicy& policyPb) const { policyPb.SetInMemSizeToSnapshot(InMemSizeToSnapshot); policyPb.SetInMemStepsToSnapshot(InMemStepsToSnapshot); @@ -186,7 +186,7 @@ void TCompactionPolicy::Serialize(NKikimrSchemeOp::TCompactionPolicy& policyPb) if (ShardPolicy.ByteSizeLong() > 0) { policyPb.MutableShardPolicy()->CopyFrom(ShardPolicy); } - + for (ui32 i = 0; i < Generations.size(); ++i) { auto &g = *policyPb.AddGeneration(); g.SetGenerationId(i); diff --git a/ydb/core/base/localdb.h b/ydb/core/base/localdb.h index 0643016292..8679cb286f 100644 --- a/ydb/core/base/localdb.h +++ b/ydb/core/base/localdb.h @@ -1,16 +1,16 @@ -#pragma once -#include "defs.h" -#include <util/generic/map.h> +#pragma once +#include "defs.h" +#include <util/generic/map.h> #include <util/generic/hash_set.h> #include <util/generic/list.h> #include <ydb/core/protos/flat_scheme_op.pb.h> #include <ydb/core/util/yverify_stream.h> #include <google/protobuf/util/message_differencer.h> - -namespace NKikimr { + +namespace NKikimr { namespace NLocalDb { - -struct TCompactionPolicy : public TThrRefBase { + +struct TCompactionPolicy : public TThrRefBase { struct TBackgroundPolicy { ui32 Threshold; ui32 PriorityBase; @@ -31,14 +31,14 @@ struct TCompactionPolicy : public TThrRefBase { } }; - struct TGenerationPolicy { - ui64 SizeToCompact; - ui32 CountToCompact; - ui32 ForceCountToCompact; - ui64 ForceSizeToCompact; + struct TGenerationPolicy { + ui64 SizeToCompact; + ui32 CountToCompact; + ui32 ForceCountToCompact; + ui64 ForceSizeToCompact; ui32 CompactionBrokerQueue; // TODO: remove deprecated field TString ResourceBrokerTask; - bool KeepInCache; + bool KeepInCache; TBackgroundPolicy BackgroundCompactionPolicy; ui32 ExtraCompactionPercent; ui32 ExtraCompactionExpPercent; @@ -69,12 +69,12 @@ struct TCompactionPolicy : public TThrRefBase { && ExtraCompactionExpMaxSize == p.ExtraCompactionExpMaxSize && UpliftPartSize == p.UpliftPartSize; } - }; - - ui64 InMemSizeToSnapshot; - ui32 InMemStepsToSnapshot; - ui32 InMemForceStepsToSnapshot; - ui64 InMemForceSizeToSnapshot; + }; + + ui64 InMemSizeToSnapshot; + ui32 InMemStepsToSnapshot; + ui32 InMemForceStepsToSnapshot; + ui64 InMemForceSizeToSnapshot; ui32 InMemCompactionBrokerQueue; // TODO: remove deprecated field TString InMemResourceBrokerTask; ui64 ReadAheadHiThreshold; @@ -92,10 +92,10 @@ struct TCompactionPolicy : public TThrRefBase { NKikimrSchemeOp::ECompactionStrategy CompactionStrategy; NKikimrSchemeOp::TCompactionPolicy::TShardPolicy ShardPolicy; bool KeepEraseMarkers; - + TVector<TGenerationPolicy> Generations; - - TCompactionPolicy(); + + TCompactionPolicy(); explicit TCompactionPolicy(const NKikimrSchemeOp::TCompactionPolicy& policyPb); void Serialize(NKikimrSchemeOp::TCompactionPolicy& policyPb) const; @@ -110,7 +110,7 @@ struct TCompactionPolicy : public TThrRefBase { && ReadAheadHiThreshold == p.ReadAheadHiThreshold && ReadAheadLoThreshold == p.ReadAheadLoThreshold && MinDataPageSize == p.MinDataPageSize - && Generations == p.Generations + && Generations == p.Generations && SnapshotCompactionBrokerQueue == p.SnapshotCompactionBrokerQueue && SnapshotResourceBrokerTask == p.SnapshotResourceBrokerTask && BackupCompactionBrokerQueue == p.BackupCompactionBrokerQueue @@ -124,13 +124,13 @@ struct TCompactionPolicy : public TThrRefBase { && KeepEraseMarkers == p.KeepEraseMarkers && ::google::protobuf::util::MessageDifferencer::Equals(ShardPolicy, p.ShardPolicy); } -}; - +}; + typedef TIntrusivePtr<TCompactionPolicy> TCompactionPolicyPtr; TCompactionPolicyPtr CreateDefaultTablePolicy(); TCompactionPolicyPtr CreateDefaultUserTablePolicy(); - + bool ValidateCompactionPolicyChange(const TCompactionPolicy& oldPolicy, const TCompactionPolicy& newPolicy, TString& err); // Get Resource Broker task type name by Compaction Broker queue ID. @@ -148,4 +148,4 @@ extern const TString KqpResourceManagerTaskName; extern const TString KqpResourceManagerQueue; extern const TString LegacyQueueIdTaskNamePrefix; -}} +}} diff --git a/ydb/core/base/logoblob.cpp b/ydb/core/base/logoblob.cpp index 13242640f8..4bea376f60 100644 --- a/ydb/core/base/logoblob.cpp +++ b/ydb/core/base/logoblob.cpp @@ -1,44 +1,44 @@ -#include "logoblob.h" +#include "logoblob.h" #include <ydb/core/protos/base.pb.h> -#include <util/string/printf.h> - -namespace NKikimr { - +#include <util/string/printf.h> + +namespace NKikimr { + TString TLogoBlobID::ToString() const { return Sprintf( "[%" PRIu64 ":%" PRIu32 ":%" PRIu32 ":%" PRIu32 ":%" PRIu32 ":%" PRIu32 ":%" PRIu32 "]", - TabletID(), - Generation(), - Step(), - Channel(), - Cookie(), - BlobSize(), + TabletID(), + Generation(), + Step(), + Channel(), + Cookie(), + BlobSize(), PartId()).data(); -} - +} + void TLogoBlobID::Out(IOutputStream &o) const { - char buf[240]; - sprintf(buf, + char buf[240]; + sprintf(buf, "[%" PRIu64 ":%" PRIu32 ":%" PRIu32 ":%" PRIu32 ":%" PRIu32 ":%" PRIu32 ":%" PRIu32 "]", - TabletID(), - Generation(), - Step(), - Channel(), - Cookie(), - BlobSize(), + TabletID(), + Generation(), + Step(), + Channel(), + Cookie(), + BlobSize(), PartId() - ); - - o << buf; -} - + ); + + o << buf; +} + void TLogoBlobID::Out(IOutputStream &o, const TVector<TLogoBlobID> &vec) { - o << "[ "; - for (const auto &x : vec) - o << x << ' '; - o << "]"; -} - + o << "[ "; + for (const auto &x : vec) + o << x << ' '; + o << "]"; +} + static const char *SkipSpaces(const char *str) { while (str && *str && *str == ' ') ++str; @@ -66,17 +66,17 @@ bool TLogoBlobID::Parse(TLogoBlobID &out, const TString &buf, TString &errorExpl } ++str; PARSE_NUM(const ui64 tabletID, "tablet id", 10); - PARSE_NUM(const ui64 gen, "generation", 10); - PARSE_NUM(const ui64 step, "step", 10); - PARSE_NUM(const ui64 channel, "channel", 10); - PARSE_NUM(const ui64 cookie, "cookie", 10); - PARSE_NUM(const ui64 blobSize, "blob size", 10); - - const ui64 partid = strtoll(str, &endptr, 10); - + PARSE_NUM(const ui64 gen, "generation", 10); + PARSE_NUM(const ui64 step, "step", 10); + PARSE_NUM(const ui64 channel, "channel", 10); + PARSE_NUM(const ui64 cookie, "cookie", 10); + PARSE_NUM(const ui64 blobSize, "blob size", 10); + + const ui64 partid = strtoll(str, &endptr, 10); + str = SkipSpaces(endptr); if (!(str && *str && *str == ']')) { - errorExplanation = "Can't find trailing ']' after part id"; + errorExplanation = "Can't find trailing ']' after part id"; return false; } str = SkipSpaces(str + 1); @@ -85,32 +85,32 @@ bool TLogoBlobID::Parse(TLogoBlobID &out, const TString &buf, TString &errorExpl return false; } - if (partid) - out = TLogoBlobID(tabletID, gen, step, channel, blobSize, cookie, partid); - else - out = TLogoBlobID(tabletID, gen, step, channel, blobSize, cookie); - + if (partid) + out = TLogoBlobID(tabletID, gen, step, channel, blobSize, cookie, partid); + else + out = TLogoBlobID(tabletID, gen, step, channel, blobSize, cookie); + return true; } -TLogoBlobID LogoBlobIDFromLogoBlobID(const NKikimrProto::TLogoBlobID &proto) { - return TLogoBlobID(proto.GetRawX1(), proto.GetRawX2(), proto.GetRawX3()); -} - -void LogoBlobIDFromLogoBlobID(const TLogoBlobID &id, NKikimrProto::TLogoBlobID *proto) { - const ui64* raw = id.GetRaw(); - proto->SetRawX1(raw[0]); - proto->SetRawX2(raw[1]); - proto->SetRawX3(raw[2]); -} - +TLogoBlobID LogoBlobIDFromLogoBlobID(const NKikimrProto::TLogoBlobID &proto) { + return TLogoBlobID(proto.GetRawX1(), proto.GetRawX2(), proto.GetRawX3()); +} + +void LogoBlobIDFromLogoBlobID(const TLogoBlobID &id, NKikimrProto::TLogoBlobID *proto) { + const ui64* raw = id.GetRaw(); + proto->SetRawX1(raw[0]); + proto->SetRawX2(raw[1]); + proto->SetRawX3(raw[2]); +} + void LogoBlobIDVectorFromLogoBlobIDRepeated( TVector<TLogoBlobID> *to, const ::google::protobuf::RepeatedPtrField<NKikimrProto::TLogoBlobID> &proto) { - to->reserve(proto.size()); - to->clear(); - for (const auto &x : proto) - to->emplace_back(LogoBlobIDFromLogoBlobID(x)); -} - -} + to->reserve(proto.size()); + to->clear(); + for (const auto &x : proto) + to->emplace_back(LogoBlobIDFromLogoBlobID(x)); +} + +} diff --git a/ydb/core/base/logoblob.h b/ydb/core/base/logoblob.h index 558610738a..36eea54393 100644 --- a/ydb/core/base/logoblob.h +++ b/ydb/core/base/logoblob.h @@ -1,56 +1,56 @@ -#pragma once -#include "defs.h" - -namespace NKikimrProto { - class TLogoBlobID; -} - -namespace NKikimr { - - struct TLogoBlobID { +#pragma once +#include "defs.h" + +namespace NKikimrProto { + class TLogoBlobID; +} + +namespace NKikimr { + + struct TLogoBlobID { static const ui32 MaxChannel = 255ul; static const ui32 MaxBlobSize = 67108863ul; static const ui32 MaxCookie = 16777215ul; static const ui32 MaxPartId = 15ul; static const ui32 MaxCrcMode = 3ul; - - TLogoBlobID() - { + + TLogoBlobID() + { Set(0, 0, 0, 0, 0, 0, 0, 0); - } - - explicit TLogoBlobID(const TLogoBlobID &source, ui32 partId) - { + } + + explicit TLogoBlobID(const TLogoBlobID &source, ui32 partId) + { Y_VERIFY_DEBUG(partId < 16); - Raw.X[0] = source.Raw.X[0]; - Raw.X[1] = source.Raw.X[1]; + Raw.X[0] = source.Raw.X[0]; + Raw.X[1] = source.Raw.X[1]; Raw.X[2] = (source.Raw.X[2] & 0xFFFFFFFFFFFFFFF0ull) | partId; - } - - explicit TLogoBlobID(ui64 tabletId, ui32 generation, ui32 step, ui32 channel, ui32 blobSize, ui32 cookie) - { + } + + explicit TLogoBlobID(ui64 tabletId, ui32 generation, ui32 step, ui32 channel, ui32 blobSize, ui32 cookie) + { Set(tabletId, generation, step, channel, blobSize, cookie, 0, 0); - } - - explicit TLogoBlobID(ui64 tabletId, ui32 generation, ui32 step, ui32 channel, ui32 blobSize, ui32 cookie, ui32 partId) - { + } + + explicit TLogoBlobID(ui64 tabletId, ui32 generation, ui32 step, ui32 channel, ui32 blobSize, ui32 cookie, ui32 partId) + { Y_VERIFY_DEBUG(partId != 0); Set(tabletId, generation, step, channel, blobSize, cookie, partId, 0); - } - + } + explicit TLogoBlobID(ui64 tabletId, ui32 generation, ui32 step, ui32 channel, ui32 blobSize, ui32 cookie, ui32 partId, ui32 crcMode) { Set(tabletId, generation, step, channel, blobSize, cookie, partId, crcMode); } - explicit TLogoBlobID(ui64 raw1, ui64 raw2, ui64 raw3) - { - Raw.X[0] = raw1; - Raw.X[1] = raw2; - Raw.X[2] = raw3; - } - + explicit TLogoBlobID(ui64 raw1, ui64 raw2, ui64 raw3) + { + Raw.X[0] = raw1; + Raw.X[1] = raw2; + Raw.X[2] = raw3; + } + explicit TLogoBlobID(const ui64 raw[3]) { memcpy(Raw.X, raw, 3 * sizeof(ui64)); } @@ -77,128 +77,128 @@ namespace NKikimr { return id; } - ui32 Hash() const { + ui32 Hash() const { const ui64 x1 = 0x001DFF3D8DC48F5Dull * (Raw.X[0] & 0xFFFFFFFFull); - const ui64 x2 = 0x179CA10C9242235Dull * (Raw.X[0] >> 32); + const ui64 x2 = 0x179CA10C9242235Dull * (Raw.X[0] >> 32); const ui64 x3 = 0x0F530CAD458B0FB1ull * (Raw.X[1] & 0xFFFFFFFFull); - const ui64 x4 = 0xB5026F5AA96619E9ull * (Raw.X[1] >> 32); - const ui64 x5 = 0x5851F42D4C957F2Dull * (Raw.X[2] >> 32); - + const ui64 x4 = 0xB5026F5AA96619E9ull * (Raw.X[1] >> 32); + const ui64 x5 = 0x5851F42D4C957F2Dull * (Raw.X[2] >> 32); + const ui64 sum = 0x06C9C021156EAA1Full + x1 + x2 + x3 + x4 + x5; - - return (sum >> 32); - } - - ui64 TabletID() const { return Raw.N.TabletID; } - ui32 Generation() const { return Raw.N.Generation; } - ui32 Step() const { return (Raw.N.StepR1 << 8) | Raw.N.StepR2; } - ui32 Channel() const { return Raw.N.Channel; } - ui32 BlobSize() const { return Raw.N.BlobSize; } - ui32 Cookie() const { return Raw.N.Cookie; } - ui32 PartId() const { return Raw.N.PartId; } + + return (sum >> 32); + } + + ui64 TabletID() const { return Raw.N.TabletID; } + ui32 Generation() const { return Raw.N.Generation; } + ui32 Step() const { return (Raw.N.StepR1 << 8) | Raw.N.StepR2; } + ui32 Channel() const { return Raw.N.Channel; } + ui32 BlobSize() const { return Raw.N.BlobSize; } + ui32 Cookie() const { return Raw.N.Cookie; } + ui32 PartId() const { return Raw.N.PartId; } ui32 CrcMode() const { return Raw.N.CrcMode; } - - const ui64* GetRaw() const { return Raw.X; } - + + const ui64* GetRaw() const { return Raw.X; } + TString ToString() const; void Out(IOutputStream &o) const; static bool Parse(TLogoBlobID &out, const TString &buf, TString &errorExplanation); static void Out(IOutputStream &o, const TVector<TLogoBlobID> &vec); - + // Returns -1 if *this < x, 0 if *this == x, 1 if *this > x int Compare(const TLogoBlobID &x) const { const ui64 *r1 = GetRaw(); const ui64 *r2 = x.GetRaw(); return - r1[0] != r2[0] ? (r1[0] < r2[0] ? -1 : 1) : + r1[0] != r2[0] ? (r1[0] < r2[0] ? -1 : 1) : r1[1] != r2[1] ? (r1[1] < r2[1] ? -1 : 1) : r1[2] != r2[2] ? (r1[2] < r2[2] ? -1 : 1) : 0; } - bool operator<(const TLogoBlobID &x) const { - const ui64 *r1 = GetRaw(); - const ui64 *r2 = x.GetRaw(); - - return - r1[0] != r2[0] ? r1[0] < r2[0] : - r1[1] != r2[1] ? r1[1] < r2[1] : - r1[2] < r2[2]; - } - - bool operator>(const TLogoBlobID &x) const { - return (x < *this); - } - - bool operator<=(const TLogoBlobID &x) const { - const ui64 *r1 = GetRaw(); - const ui64 *r2 = x.GetRaw(); - - return - r1[0] != r2[0] ? r1[0] < r2[0] : - r1[1] != r2[1] ? r1[1] < r2[1] : - r1[2] <= r2[2]; - } - - bool operator>=(const TLogoBlobID &x) const { - return (x <= *this); - } - - bool operator==(const TLogoBlobID &x) const { - const ui64 *r1 = GetRaw(); - const ui64 *r2 = x.GetRaw(); - - return + bool operator<(const TLogoBlobID &x) const { + const ui64 *r1 = GetRaw(); + const ui64 *r2 = x.GetRaw(); + + return + r1[0] != r2[0] ? r1[0] < r2[0] : + r1[1] != r2[1] ? r1[1] < r2[1] : + r1[2] < r2[2]; + } + + bool operator>(const TLogoBlobID &x) const { + return (x < *this); + } + + bool operator<=(const TLogoBlobID &x) const { + const ui64 *r1 = GetRaw(); + const ui64 *r2 = x.GetRaw(); + + return + r1[0] != r2[0] ? r1[0] < r2[0] : + r1[1] != r2[1] ? r1[1] < r2[1] : + r1[2] <= r2[2]; + } + + bool operator>=(const TLogoBlobID &x) const { + return (x <= *this); + } + + bool operator==(const TLogoBlobID &x) const { + const ui64 *r1 = GetRaw(); + const ui64 *r2 = x.GetRaw(); + + return r1[2] == r2[2] && r1[1] == r2[1] && r1[0] == r2[0]; - } - - bool operator!=(const TLogoBlobID &x) const { - const ui64 *r1 = GetRaw(); - const ui64 *r2 = x.GetRaw(); - - return + } + + bool operator!=(const TLogoBlobID &x) const { + const ui64 *r1 = GetRaw(); + const ui64 *r2 = x.GetRaw(); + + return r1[2] != r2[2] || r1[1] != r2[1] || r1[0] != r2[0]; - } - - explicit operator bool() const noexcept { - return (Raw.N.TabletID != 0); - } - + } + + explicit operator bool() const noexcept { + return (Raw.N.TabletID != 0); + } + bool IsValid() const noexcept { return (Raw.N.TabletID != 0); } - // compares only main part (without part id) - bool IsSameBlob(const TLogoBlobID &x) const { - const ui64 *r1 = GetRaw(); - const ui64 *r2 = x.GetRaw(); - + // compares only main part (without part id) + bool IsSameBlob(const TLogoBlobID &x) const { + const ui64 *r1 = GetRaw(); + const ui64 *r2 = x.GetRaw(); + return r1[0] == r2[0] && r1[1] == r2[1] && (r1[2] & 0xFFFFFFFFFFFFFFF0ull) == (r2[2] & 0xFFFFFFFFFFFFFFF0ull); - } - - TLogoBlobID FullID() const { - return TLogoBlobID(*this, 0); - } - private: - union { - struct { - ui64 TabletID; // 8 - - ui64 StepR1 : 24; // 8 - ui64 Generation : 32; - ui64 Channel : 8; - - ui64 PartId : 4; // 8 + } + + TLogoBlobID FullID() const { + return TLogoBlobID(*this, 0); + } + private: + union { + struct { + ui64 TabletID; // 8 + + ui64 StepR1 : 24; // 8 + ui64 Generation : 32; + ui64 Channel : 8; + + ui64 PartId : 4; // 8 ui64 BlobSize : 26; ui64 CrcMode : 2; - - ui64 Cookie : 24; - ui64 StepR2 : 8; - } N; - - ui64 X[3]; - } Raw; - + + ui64 Cookie : 24; + ui64 StepR2 : 8; + } N; + + ui64 X[3]; + } Raw; + void Set(ui64 tabletId, ui32 generation, ui32 step, ui32 channel, ui32 blobSize, ui32 cookie, ui32 partId, ui32 crcMode) { Y_VERIFY_DEBUG(channel <= MaxChannel); @@ -206,87 +206,87 @@ namespace NKikimr { Y_VERIFY_DEBUG(cookie <= MaxCookie); Y_VERIFY_DEBUG(partId <= MaxPartId); Y_VERIFY(crcMode <= MaxCrcMode); - - Raw.N.TabletID = tabletId; - Raw.N.Generation = generation; - + + Raw.N.TabletID = tabletId; + Raw.N.Generation = generation; + Raw.N.StepR1 = (step & 0xFFFFFF00ull) >> 8; Raw.N.StepR2 = (step & 0x000000FFull); - - Raw.N.Channel = channel; - Raw.N.Cookie = cookie; - Raw.N.BlobSize = blobSize; + + Raw.N.Channel = channel; + Raw.N.Cookie = cookie; + Raw.N.BlobSize = blobSize; Raw.N.CrcMode = crcMode; - Raw.N.PartId = partId; - } - + Raw.N.PartId = partId; + } + public: struct THash { ui32 operator()(const TLogoBlobID &id) const noexcept { return id.Hash(); } }; - }; - + }; + static_assert(sizeof(TLogoBlobID) == 24, "expect sizeof(TLogoBlobID) == 24"); - - struct TLogoBlob { - TLogoBlobID Id; + + struct TLogoBlob { + TLogoBlobID Id; TString Buffer; - - TLogoBlob() - {} - + + TLogoBlob() + {} + TLogoBlob(const TLogoBlobID &id, const TString &buffer) - : Id(id) - , Buffer(buffer) - {} - }; - - struct TLogoBlobRef { - TLogoBlobID Id; - ui32 Status; - ui32 Shift; + : Id(id) + , Buffer(buffer) + {} + }; + + struct TLogoBlobRef { + TLogoBlobID Id; + ui32 Status; + ui32 Shift; TString Buffer; - + explicit TLogoBlobRef(const TLogoBlobID &id, ui32 status, ui32 shift, const TString &buffer) - : Id(id) - , Status(status) - , Shift(shift) - , Buffer(buffer) - {} - }; - - struct TLogoBlobRequest { - TLogoBlobID Id; - ui32 Shift; - ui32 Size; - - TLogoBlobRequest(const TLogoBlobID &id, ui32 shift, ui32 sz) - : Id(id) - , Shift(shift) - , Size(sz) - {} - }; - - TLogoBlobID LogoBlobIDFromLogoBlobID(const NKikimrProto::TLogoBlobID &proto); - void LogoBlobIDFromLogoBlobID(const TLogoBlobID &id, NKikimrProto::TLogoBlobID *proto); + : Id(id) + , Status(status) + , Shift(shift) + , Buffer(buffer) + {} + }; + + struct TLogoBlobRequest { + TLogoBlobID Id; + ui32 Shift; + ui32 Size; + + TLogoBlobRequest(const TLogoBlobID &id, ui32 shift, ui32 sz) + : Id(id) + , Shift(shift) + , Size(sz) + {} + }; + + TLogoBlobID LogoBlobIDFromLogoBlobID(const NKikimrProto::TLogoBlobID &proto); + void LogoBlobIDFromLogoBlobID(const TLogoBlobID &id, NKikimrProto::TLogoBlobID *proto); void LogoBlobIDVectorFromLogoBlobIDRepeated( TVector<TLogoBlobID> *to, const ::google::protobuf::RepeatedPtrField<NKikimrProto::TLogoBlobID> &proto); - - template<typename TIterator> - void LogoBlobIDRepatedFromLogoBlobIDVector( - ::google::protobuf::RepeatedPtrField<NKikimrProto::TLogoBlobID> *proto, - TIterator begin, TIterator end) - { - proto->Reserve(end - begin); - proto->Clear(); - while (begin != end) { - LogoBlobIDFromLogoBlobID(*begin, proto->Add()); - ++begin; - } - } + + template<typename TIterator> + void LogoBlobIDRepatedFromLogoBlobIDVector( + ::google::protobuf::RepeatedPtrField<NKikimrProto::TLogoBlobID> *proto, + TIterator begin, TIterator end) + { + proto->Reserve(end - begin); + proto->Clear(); + while (begin != end) { + LogoBlobIDFromLogoBlobID(*begin, proto->Add()); + ++begin; + } + } template<typename TContainer> void LogoBlobIDRepatedFromLogoBlobIDUniversal( @@ -302,21 +302,21 @@ namespace NKikimr { ++begin; } } -} - -template<> +} + +template<> inline void Out<NKikimr::TLogoBlobID>(IOutputStream& o, const NKikimr::TLogoBlobID &x) { - return x.Out(o); -} - -template<> + return x.Out(o); +} + +template<> inline void Out<TVector<NKikimr::TLogoBlobID>>(IOutputStream& out, const TVector<NKikimr::TLogoBlobID> &xvec) { - return NKikimr::TLogoBlobID::Out(out, xvec); -} - -template<> -struct THash<NKikimr::TLogoBlobID> { + return NKikimr::TLogoBlobID::Out(out, xvec); +} + +template<> +struct THash<NKikimr::TLogoBlobID> { inline ui64 operator()(const NKikimr::TLogoBlobID& x) const noexcept { - return x.Hash(); - } -}; + return x.Hash(); + } +}; diff --git a/ydb/core/base/logoblob_ut.cpp b/ydb/core/base/logoblob_ut.cpp index 295d51a8c8..75d9d2b833 100644 --- a/ydb/core/base/logoblob_ut.cpp +++ b/ydb/core/base/logoblob_ut.cpp @@ -11,66 +11,66 @@ namespace NKikimr { TString explanation; bool res = false; - res = TLogoBlobID::Parse(id, "[ 0:1:2:0:0:0:0]", explanation); - UNIT_ASSERT(res && id == TLogoBlobID(0, 1, 2, 0, 0, 0)); + res = TLogoBlobID::Parse(id, "[ 0:1:2:0:0:0:0]", explanation); + UNIT_ASSERT(res && id == TLogoBlobID(0, 1, 2, 0, 0, 0)); - res = TLogoBlobID::Parse(id, "[ 0:1:2:0:0:0:0", explanation); - UNIT_ASSERT(!res && explanation == "Can't find trailing ']' after part id"); + res = TLogoBlobID::Parse(id, "[ 0:1:2:0:0:0:0", explanation); + UNIT_ASSERT(!res && explanation == "Can't find trailing ']' after part id"); - res = TLogoBlobID::Parse(id, "[ 0:1:2:0:0 v:0:0", explanation); + res = TLogoBlobID::Parse(id, "[ 0:1:2:0:0 v:0:0", explanation); UNIT_ASSERT(!res && explanation == "Can't find trailing ':' after cookie"); - res = TLogoBlobID::Parse(id, "[ 0:1:2:0:0 :0:0]", explanation); + res = TLogoBlobID::Parse(id, "[ 0:1:2:0:0 :0:0]", explanation); UNIT_ASSERT(res); - } + } Y_UNIT_TEST(LogoBlobCompare) { - bool res = false; - - const TLogoBlobID left(1, 0x30002C2D, 0x50005F6F, 1, 0x3333, 0x0001A01B); - - UNIT_ASSERT(left.TabletID() == 1); - UNIT_ASSERT(left.Channel() == 1); - UNIT_ASSERT(left.Generation() == 0x30002C2D); - UNIT_ASSERT(left.Step() == 0x50005F6F); - UNIT_ASSERT(left.Cookie() == 0x0001A01B); - UNIT_ASSERT(left.BlobSize() == 0x3333); - UNIT_ASSERT(left.PartId() == 0); - - res = left < TLogoBlobID(2, 0x30002C2D, 0x50005F6F, 1, 0x3333, 0x0001A01B); - UNIT_ASSERT(res); - - res = left < TLogoBlobID(2, 0x80008C8D, 0x80008F8F, 8, 0x8333, 0x0001801B); - UNIT_ASSERT(res); - - res = left < TLogoBlobID(1, 0x00002C2D, 0x00005F6F, 2, 0x3333, 0x0001A01B); - UNIT_ASSERT(res); - - res = left < TLogoBlobID(1, 0x40002C2D, 0x20005F6F, 1, 0x3333, 0x0001A01B); - UNIT_ASSERT(res); - - res = left < TLogoBlobID(1, 0x30002C2D, 0x60005F6F, 1, 0x5333, 0x0005A01B); - UNIT_ASSERT(res); - - res = left < TLogoBlobID(1, 0x30002C2D, 0x50005F6F, 1, 0x3333, 0x0001A01C); - UNIT_ASSERT(res); - - res = left == TLogoBlobID(1, 0x30002C2D, 0x50005F6F, 1, 0x3333, 0x0001A01C); - UNIT_ASSERT(!res); - - res = left == TLogoBlobID(1, 0x30002C2D, 0x50005F6F, 1, 0x3333, 0x0001A01B); - UNIT_ASSERT(res); - - res = left < TLogoBlobID(1, 0x30002C2D, 0x50005F6F, 1, 0x3333, 0x0001A01B); - UNIT_ASSERT(!res); - - res = left <= TLogoBlobID(1, 0x30002C2D, 0x50005F6F, 1, 0x3333, 0x0001A01B); - UNIT_ASSERT(res); - - res = left == TLogoBlobID(1, 0x30002C2D, 0x50005F6F, 1, 0x3333, 0x0001A01B, 1).FullID(); - UNIT_ASSERT(res); - - UNIT_ASSERT(left.IsSameBlob(TLogoBlobID(1, 0x30002C2D, 0x50005F6F, 1, 0x3333, 0x0001A01B, 1))); + bool res = false; + + const TLogoBlobID left(1, 0x30002C2D, 0x50005F6F, 1, 0x3333, 0x0001A01B); + + UNIT_ASSERT(left.TabletID() == 1); + UNIT_ASSERT(left.Channel() == 1); + UNIT_ASSERT(left.Generation() == 0x30002C2D); + UNIT_ASSERT(left.Step() == 0x50005F6F); + UNIT_ASSERT(left.Cookie() == 0x0001A01B); + UNIT_ASSERT(left.BlobSize() == 0x3333); + UNIT_ASSERT(left.PartId() == 0); + + res = left < TLogoBlobID(2, 0x30002C2D, 0x50005F6F, 1, 0x3333, 0x0001A01B); + UNIT_ASSERT(res); + + res = left < TLogoBlobID(2, 0x80008C8D, 0x80008F8F, 8, 0x8333, 0x0001801B); + UNIT_ASSERT(res); + + res = left < TLogoBlobID(1, 0x00002C2D, 0x00005F6F, 2, 0x3333, 0x0001A01B); + UNIT_ASSERT(res); + + res = left < TLogoBlobID(1, 0x40002C2D, 0x20005F6F, 1, 0x3333, 0x0001A01B); + UNIT_ASSERT(res); + + res = left < TLogoBlobID(1, 0x30002C2D, 0x60005F6F, 1, 0x5333, 0x0005A01B); + UNIT_ASSERT(res); + + res = left < TLogoBlobID(1, 0x30002C2D, 0x50005F6F, 1, 0x3333, 0x0001A01C); + UNIT_ASSERT(res); + + res = left == TLogoBlobID(1, 0x30002C2D, 0x50005F6F, 1, 0x3333, 0x0001A01C); + UNIT_ASSERT(!res); + + res = left == TLogoBlobID(1, 0x30002C2D, 0x50005F6F, 1, 0x3333, 0x0001A01B); + UNIT_ASSERT(res); + + res = left < TLogoBlobID(1, 0x30002C2D, 0x50005F6F, 1, 0x3333, 0x0001A01B); + UNIT_ASSERT(!res); + + res = left <= TLogoBlobID(1, 0x30002C2D, 0x50005F6F, 1, 0x3333, 0x0001A01B); + UNIT_ASSERT(res); + + res = left == TLogoBlobID(1, 0x30002C2D, 0x50005F6F, 1, 0x3333, 0x0001A01B, 1).FullID(); + UNIT_ASSERT(res); + + UNIT_ASSERT(left.IsSameBlob(TLogoBlobID(1, 0x30002C2D, 0x50005F6F, 1, 0x3333, 0x0001A01B, 1))); } Y_UNIT_TEST(LogoBlobSort) { diff --git a/ydb/core/base/path.cpp b/ydb/core/base/path.cpp index 0b4dfde0af..0cfb16f99d 100644 --- a/ydb/core/base/path.cpp +++ b/ydb/core/base/path.cpp @@ -50,26 +50,26 @@ TString JoinPath(const TVector<TString>& path) { TString CanonizePath(const TString &path) { if (!path) - return TString(); + return TString(); - const auto parts = SplitPath(path); - return CanonizePath(parts); + const auto parts = SplitPath(path); + return CanonizePath(parts); +} + +TString CanonizePath(const TVector<TString>& path) { + if (path.empty()) + return TString(); + + return TString("/") + JoinPath(path); +} + +ui32 CanonizedPathLen(const TVector<TString>& path) { + ui32 ret = path.size(); + for (auto &x : path) + ret += x.size(); + return ret; } -TString CanonizePath(const TVector<TString>& path) { - if (path.empty()) - return TString(); - - return TString("/") + JoinPath(path); -} - -ui32 CanonizedPathLen(const TVector<TString>& path) { - ui32 ret = path.size(); - for (auto &x : path) - ret += x.size(); - return ret; -} - TStringBuf ExtractDomain(const TString& path) noexcept { auto domain = TStringBuf(path); diff --git a/ydb/core/base/path.h b/ydb/core/base/path.h index ba2917a8a2..c2b93d2baf 100644 --- a/ydb/core/base/path.h +++ b/ydb/core/base/path.h @@ -9,8 +9,8 @@ namespace NKikimr { TVector<TString> SplitPath(TString path); TString JoinPath(const TVector<TString>& path); TString CanonizePath(const TString &path); -TString CanonizePath(const TVector<TString>& path); -ui32 CanonizedPathLen(const TVector<TString>& path); +TString CanonizePath(const TVector<TString>& path); +ui32 CanonizedPathLen(const TVector<TString>& path); TStringBuf ExtractDomain(const TString& path) noexcept; TStringBuf ExtractDomain(TStringBuf path) noexcept; TStringBuf ExtractBase(const TString& path) noexcept; diff --git a/ydb/core/base/pathid.h b/ydb/core/base/pathid.h index 2bea368de5..e974f84613 100644 --- a/ydb/core/base/pathid.h +++ b/ydb/core/base/pathid.h @@ -36,7 +36,7 @@ struct TPathId { bool operator>=(const TPathId& x) const; bool operator==(const TPathId& x) const; bool operator!=(const TPathId& x) const; - explicit operator bool() const; + explicit operator bool() const; TPathId NextId() const; TPathId PrevId() const; diff --git a/ydb/core/base/pool_stats_collector.cpp b/ydb/core/base/pool_stats_collector.cpp index f0995a64e5..7dcbf28954 100644 --- a/ydb/core/base/pool_stats_collector.cpp +++ b/ydb/core/base/pool_stats_collector.cpp @@ -9,7 +9,7 @@ #include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/actors/helpers/pool_stats_collector.h> -namespace NKikimr { +namespace NKikimr { // Periodically collects stats from executor threads and exposes them as mon counters class TStatsCollectingActor : public NActors::TStatsCollectingActor { diff --git a/ydb/core/base/pool_stats_collector.h b/ydb/core/base/pool_stats_collector.h index e88954cb5d..cbf06f9f51 100644 --- a/ydb/core/base/pool_stats_collector.h +++ b/ydb/core/base/pool_stats_collector.h @@ -1,17 +1,17 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include <library/cpp/actors/core/actorsystem.h> #include <library/cpp/monlib/dynamic_counters/counters.h> - -namespace NActors { - struct TActorSystemSetup; - -} - -namespace NKikimr { - - IActor* CreateStatsCollector(ui32 intervalSec, - const TActorSystemSetup& setup, + +namespace NActors { + struct TActorSystemSetup; + +} + +namespace NKikimr { + + IActor* CreateStatsCollector(ui32 intervalSec, + const TActorSystemSetup& setup, NMonitoring::TDynamicCounterPtr counters); - -} + +} diff --git a/ydb/core/base/quoter.cpp b/ydb/core/base/quoter.cpp index 4d1af89881..c31333fe56 100644 --- a/ydb/core/base/quoter.cpp +++ b/ydb/core/base/quoter.cpp @@ -1,15 +1,15 @@ -#include "quoter.h" - -namespace NKikimr { - +#include "quoter.h" + +namespace NKikimr { + TActorId MakeQuoterServiceID() { - char x[12] = { 'q', 'u', 'o', 't', 'e', 'r', 's', 'v', 'c' }; + char x[12] = { 'q', 'u', 'o', 't', 'e', 'r', 's', 'v', 'c' }; return TActorId(0, TStringBuf(x, 12)); -} - -ui64 TEvQuota::TResourceLeaf::MakeTaggedRateRes(ui32 tag, ui32 rate) { - Y_VERIFY(rate <= 0x3FFFFFFF); - return (1ULL << 62) | (static_cast<ui64>(tag) << 30) | (static_cast<ui64>(rate) & 0x3FFFFFFF); -} - -} +} + +ui64 TEvQuota::TResourceLeaf::MakeTaggedRateRes(ui32 tag, ui32 rate) { + Y_VERIFY(rate <= 0x3FFFFFFF); + return (1ULL << 62) | (static_cast<ui64>(tag) << 30) | (static_cast<ui64>(rate) & 0x3FFFFFFF); +} + +} diff --git a/ydb/core/base/quoter.h b/ydb/core/base/quoter.h index 849acff050..41a19775bc 100644 --- a/ydb/core/base/quoter.h +++ b/ydb/core/base/quoter.h @@ -1,254 +1,254 @@ -#pragma once -#include "defs.h" -#include "events.h" +#pragma once +#include "defs.h" +#include "events.h" #include <library/cpp/actors/core/event_local.h> -#include <util/generic/deque.h> +#include <util/generic/deque.h> #include <util/generic/vector.h> #include <ydb/core/util/time_series_vec.h> - -namespace NKikimr { - -struct TEvQuota { - enum EEv { - EvRequest = EventSpaceBegin(TKikimrEvents::ES_QUOTA), - EvCancelRequest, - EvClearance, - - EvProxyRequest = EvRequest + 512, - EvProxyStats, - EvProxyCloseSession, - - EvProxySession = EvRequest + 2 * 512, - EvProxyUpdate, - - EvEnd - }; - - static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_QUOTA), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_QUOTA)"); - - struct TResourceLeaf { - static constexpr ui64 QuoterSystem = Max<ui64>(); // use as quoter id for some embedded quoters - static constexpr ui64 ResourceForbid = 0; // never allow, just wait for deadline and forbid - static constexpr ui64 ResourceNocheck = 1; // allow everything, w/o any check - - static ui64 MakeTaggedRateRes(ui32 tag, ui32 rate); - // todo: tagged local rate-limiters - - const ui64 QuoterId; - const ui64 ResourceId; - const TString Quoter; - const TString Resource; - - const ui64 Amount; + +namespace NKikimr { + +struct TEvQuota { + enum EEv { + EvRequest = EventSpaceBegin(TKikimrEvents::ES_QUOTA), + EvCancelRequest, + EvClearance, + + EvProxyRequest = EvRequest + 512, + EvProxyStats, + EvProxyCloseSession, + + EvProxySession = EvRequest + 2 * 512, + EvProxyUpdate, + + EvEnd + }; + + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_QUOTA), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_QUOTA)"); + + struct TResourceLeaf { + static constexpr ui64 QuoterSystem = Max<ui64>(); // use as quoter id for some embedded quoters + static constexpr ui64 ResourceForbid = 0; // never allow, just wait for deadline and forbid + static constexpr ui64 ResourceNocheck = 1; // allow everything, w/o any check + + static ui64 MakeTaggedRateRes(ui32 tag, ui32 rate); + // todo: tagged local rate-limiters + + const ui64 QuoterId; + const ui64 ResourceId; + const TString Quoter; + const TString Resource; + + const ui64 Amount; const bool IsUsedAmount; - + TResourceLeaf(const TResourceLeaf&) = default; TResourceLeaf(ui64 quoterId, ui64 resourceId, ui64 amount, bool isUsedAmount = false) - : QuoterId(quoterId) - , ResourceId(resourceId) - , Amount(amount) + : QuoterId(quoterId) + , ResourceId(resourceId) + , Amount(amount) , IsUsedAmount(isUsedAmount) {} - + TResourceLeaf(const TString "er, const TString &resource, ui64 amount, bool isUsedAmount = false) - : QuoterId(0) - , ResourceId(0) - , Quoter(quoter) - , Resource(resource) - , Amount(amount) + : QuoterId(0) + , ResourceId(0) + , Quoter(quoter) + , Resource(resource) + , Amount(amount) , IsUsedAmount(isUsedAmount) {} - }; - - enum class EResourceOperator { - Unknown, - And, - OrBoth, - OrAny, - }; - - // event cookie + sender actorid would be used as id for cancel requests - struct TEvRequest : public TEventLocal<TEvRequest, EvRequest> { - const EResourceOperator Operator; - const TVector<TResourceLeaf> Reqs; - TDuration Deadline; - - TEvRequest(EResourceOperator op, TVector<TResourceLeaf> &&reqs, TDuration deadline) - : Operator(op) - , Reqs(std::move(reqs)) - , Deadline(deadline) - {} - }; - - struct TEvClearance : public TEventLocal<TEvClearance, EvClearance> { - // clearance result, could be success or deadline, or one of error - enum class EResult { - GenericError, - UnknownResource, - Deadline, - Success = 128 - } Result; - - TEvClearance(EResult result) - : Result(result) - {} - }; - - // when cookie present - cancel one request + }; + + enum class EResourceOperator { + Unknown, + And, + OrBoth, + OrAny, + }; + + // event cookie + sender actorid would be used as id for cancel requests + struct TEvRequest : public TEventLocal<TEvRequest, EvRequest> { + const EResourceOperator Operator; + const TVector<TResourceLeaf> Reqs; + TDuration Deadline; + + TEvRequest(EResourceOperator op, TVector<TResourceLeaf> &&reqs, TDuration deadline) + : Operator(op) + , Reqs(std::move(reqs)) + , Deadline(deadline) + {} + }; + + struct TEvClearance : public TEventLocal<TEvClearance, EvClearance> { + // clearance result, could be success or deadline, or one of error + enum class EResult { + GenericError, + UnknownResource, + Deadline, + Success = 128 + } Result; + + TEvClearance(EResult result) + : Result(result) + {} + }; + + // when cookie present - cancel one request // when cookie omitted - cancel all requests from sender - struct TEvCancelRequest : public TEventLocal<TEvClearance, EvCancelRequest> {}; - - // b/w service and quoter proxy - - // initial request - struct TEvProxyRequest : public TEventLocal<TEvProxyRequest, EvProxyRequest> { - const TString Resource; - - TEvProxyRequest(const TString &resource) - : Resource(resource) - {} - }; - - enum class EStatUpdatePolicy { - Never, - OnActivity, // on queue and on allocation - EveryTick, - EveryActiveTick, - }; - - struct TEvProxySession : public TEventLocal<TEvProxySession, EvProxySession> { - enum EResult { - GenericError, - UnknownResource, - Success = 128 - } Result; - - const ui64 QuoterId; - const ui64 ResourceId; - const TString Resource; - - const TDuration TickSize; - const EStatUpdatePolicy StatUpdatePolicy; - - TEvProxySession(EResult result, ui64 quoterId, ui64 resourceId, const TString &resource, TDuration tickSize, EStatUpdatePolicy statUpdatePolicy) - : Result(result) - , QuoterId(quoterId) - , ResourceId(resourceId) - , Resource(resource) - , TickSize(tickSize) - , StatUpdatePolicy(statUpdatePolicy) - {} - }; - - struct TProxyStat { - const ui64 ResourceId; - const ui64 Tick; - + struct TEvCancelRequest : public TEventLocal<TEvClearance, EvCancelRequest> {}; + + // b/w service and quoter proxy + + // initial request + struct TEvProxyRequest : public TEventLocal<TEvProxyRequest, EvProxyRequest> { + const TString Resource; + + TEvProxyRequest(const TString &resource) + : Resource(resource) + {} + }; + + enum class EStatUpdatePolicy { + Never, + OnActivity, // on queue and on allocation + EveryTick, + EveryActiveTick, + }; + + struct TEvProxySession : public TEventLocal<TEvProxySession, EvProxySession> { + enum EResult { + GenericError, + UnknownResource, + Success = 128 + } Result; + + const ui64 QuoterId; + const ui64 ResourceId; + const TString Resource; + + const TDuration TickSize; + const EStatUpdatePolicy StatUpdatePolicy; + + TEvProxySession(EResult result, ui64 quoterId, ui64 resourceId, const TString &resource, TDuration tickSize, EStatUpdatePolicy statUpdatePolicy) + : Result(result) + , QuoterId(quoterId) + , ResourceId(resourceId) + , Resource(resource) + , TickSize(tickSize) + , StatUpdatePolicy(statUpdatePolicy) + {} + }; + + struct TProxyStat { + const ui64 ResourceId; + const ui64 Tick; + const double Consumed; const TTimeSeriesMap<double> History; - const ui64 QueueSize; + const ui64 QueueSize; const double QueueWeight; const double ExpectedRate; const double Cap; - + TProxyStat(ui64 id, ui64 tick, double consumed, const TTimeSeriesMap<double>& history, ui64 queueSize, double queueWeight, double rate, double cap) - : ResourceId(id) - , Tick(tick) - , Consumed(consumed) + : ResourceId(id) + , Tick(tick) + , Consumed(consumed) , History(history) - , QueueSize(queueSize) + , QueueSize(queueSize) , QueueWeight(queueWeight) - , ExpectedRate(rate) - , Cap(cap) - {} - - TProxyStat(const TProxyStat &x) = default; - }; - - struct TEvProxyStats : public TEventLocal<TEvProxyStats, EvProxyStats> { - const TDeque<TProxyStat> Stats; - - TEvProxyStats(TDeque<TProxyStat> &&stats) + , ExpectedRate(rate) + , Cap(cap) + {} + + TProxyStat(const TProxyStat &x) = default; + }; + + struct TEvProxyStats : public TEventLocal<TEvProxyStats, EvProxyStats> { + const TDeque<TProxyStat> Stats; + + TEvProxyStats(TDeque<TProxyStat> &&stats) : Stats(std::move(stats)) - {} - }; - - struct TEvProxyCloseSession : public TEventLocal<TEvProxyCloseSession, EvProxyCloseSession> { - const TString Resource; - const ui64 ResourceId; - - TEvProxyCloseSession(const TString &resource, ui64 resourceId) - : Resource(resource) - , ResourceId(resourceId) - {} - }; - - enum class ETickPolicy : ui32 { - Front, // all quota could be used right from tick start - Sustained, // quota must be used on sustained rate - Ahead, // sustained + could go negative - }; - - struct TUpdateTick { - ui32 Channel; - ui32 Ticks; + {} + }; + + struct TEvProxyCloseSession : public TEventLocal<TEvProxyCloseSession, EvProxyCloseSession> { + const TString Resource; + const ui64 ResourceId; + + TEvProxyCloseSession(const TString &resource, ui64 resourceId) + : Resource(resource) + , ResourceId(resourceId) + {} + }; + + enum class ETickPolicy : ui32 { + Front, // all quota could be used right from tick start + Sustained, // quota must be used on sustained rate + Ahead, // sustained + could go negative + }; + + struct TUpdateTick { + ui32 Channel; + ui32 Ticks; double Rate; - ETickPolicy Policy; - - TUpdateTick() - : Channel(0) - , Ticks(0) + ETickPolicy Policy; + + TUpdateTick() + : Channel(0) + , Ticks(0) , Rate(0.0) - , Policy(ETickPolicy::Sustained) - {} - + , Policy(ETickPolicy::Sustained) + {} + TUpdateTick(ui32 channel, ui32 ticks, double rate, ETickPolicy policy) - : Channel(channel) - , Ticks(ticks) - , Rate(rate) - , Policy(policy) - {} - - TUpdateTick(const TUpdateTick &) = default; - TUpdateTick& operator=(const TUpdateTick &) noexcept = default; - }; - - enum class EUpdateState { - Normal, - Evict, - Broken - }; - - struct TProxyResourceUpdate { - const ui64 ResourceId; + : Channel(channel) + , Ticks(ticks) + , Rate(rate) + , Policy(policy) + {} + + TUpdateTick(const TUpdateTick &) = default; + TUpdateTick& operator=(const TUpdateTick &) noexcept = default; + }; + + enum class EUpdateState { + Normal, + Evict, + Broken + }; + + struct TProxyResourceUpdate { + const ui64 ResourceId; const double SustainedRate; - const TVector<TUpdateTick> Update; - const EUpdateState ResourceState; - + const TVector<TUpdateTick> Update; + const EUpdateState ResourceState; + TProxyResourceUpdate(ui64 resourceId, double sustainedRate, TVector<TUpdateTick> &&update, EUpdateState resState) - : ResourceId(resourceId) - , SustainedRate(sustainedRate) - , Update(std::move(update)) - , ResourceState(resState) - {} - }; - - struct TEvProxyUpdate : public TEventLocal<TEvProxyUpdate, EvProxyUpdate> { - const ui64 QuoterId; - TVector<TProxyResourceUpdate> Resources; - const EUpdateState QuoterState; - - TEvProxyUpdate(ui64 quoterId, EUpdateState quoterState) - : QuoterId(quoterId) - , QuoterState(quoterState) - {} - }; - - // interface b/w proxy and proxy backend is private, so not defined here -}; - -// + : ResourceId(resourceId) + , SustainedRate(sustainedRate) + , Update(std::move(update)) + , ResourceState(resState) + {} + }; + + struct TEvProxyUpdate : public TEventLocal<TEvProxyUpdate, EvProxyUpdate> { + const ui64 QuoterId; + TVector<TProxyResourceUpdate> Resources; + const EUpdateState QuoterState; + + TEvProxyUpdate(ui64 quoterId, EUpdateState quoterState) + : QuoterId(quoterId) + , QuoterState(quoterState) + {} + }; + + // interface b/w proxy and proxy backend is private, so not defined here +}; + +// TActorId MakeQuoterServiceID(); - -} + +} diff --git a/ydb/core/base/statestorage.cpp b/ydb/core/base/statestorage.cpp index 8be146cc6b..de39a327ae 100644 --- a/ydb/core/base/statestorage.cpp +++ b/ydb/core/base/statestorage.cpp @@ -1,273 +1,273 @@ -#include "statestorage.h" -#include "tabletid.h" -#include <util/generic/xrange.h> -#include <util/generic/mem_copy.h> -#include <util/generic/algorithm.h> - -namespace NKikimr { - -static const ui32 Primes[128] = { - 104743, 105023, 105359, 105613, - 104759, 105031, 105361, 105619, - 104761, 105037, 105367, 105649, - 104773, 105071, 105373, 105653, - 104779, 105097, 105379, 105667, - 104789, 105107, 105389, 105673, - 104801, 105137, 105397, 105683, - 104803, 105143, 105401, 105691, - 104827, 105167, 105407, 105701, - 104831, 105173, 105437, 105727, - 104849, 105199, 105449, 105733, - 104851, 105211, 105467, 105751, - 104869, 105227, 105491, 105761, - 104879, 105229, 105499, 105767, - 104891, 105239, 105503, 105769, - 104911, 105251, 105509, 105817, - 104917, 105253, 105517, 105829, - 104933, 105263, 105527, 105863, - 104947, 105269, 105529, 105871, - 104953, 105277, 105533, 105883, - 104959, 105319, 105541, 105899, - 104971, 105323, 105557, 105907, - 104987, 105331, 105563, 105913, - 104999, 105337, 105601, 105929, - 105019, 105341, 105607, 105943, - 105953, 106261, 106487, 106753, - 105967, 106273, 106501, 106759, - 105971, 106277, 106531, 106781, - 105977, 106279, 106537, 106783, - 105983, 106291, 106541, 106787, - 105997, 106297, 106543, 106801, - 106013, 106303, 106591, 106823, -}; - +#include "statestorage.h" +#include "tabletid.h" +#include <util/generic/xrange.h> +#include <util/generic/mem_copy.h> +#include <util/generic/algorithm.h> + +namespace NKikimr { + +static const ui32 Primes[128] = { + 104743, 105023, 105359, 105613, + 104759, 105031, 105361, 105619, + 104761, 105037, 105367, 105649, + 104773, 105071, 105373, 105653, + 104779, 105097, 105379, 105667, + 104789, 105107, 105389, 105673, + 104801, 105137, 105397, 105683, + 104803, 105143, 105401, 105691, + 104827, 105167, 105407, 105701, + 104831, 105173, 105437, 105727, + 104849, 105199, 105449, 105733, + 104851, 105211, 105467, 105751, + 104869, 105227, 105491, 105761, + 104879, 105229, 105499, 105767, + 104891, 105239, 105503, 105769, + 104911, 105251, 105509, 105817, + 104917, 105253, 105517, 105829, + 104933, 105263, 105527, 105863, + 104947, 105269, 105529, 105871, + 104953, 105277, 105533, 105883, + 104959, 105319, 105541, 105899, + 104971, 105323, 105557, 105907, + 104987, 105331, 105563, 105913, + 104999, 105337, 105601, 105929, + 105019, 105341, 105607, 105943, + 105953, 106261, 106487, 106753, + 105967, 106273, 106501, 106759, + 105971, 106277, 106531, 106781, + 105977, 106279, 106537, 106783, + 105983, 106291, 106541, 106787, + 105997, 106297, 106543, 106801, + 106013, 106303, 106591, 106823, +}; + constexpr ui64 MaxRingCount = 1024; constexpr ui64 MaxNodeCount = 1024; -class TStateStorageRingWalker { - const ui32 Sz; - const ui32 Delta; - ui32 A; -public: - TStateStorageRingWalker(ui32 hash, ui32 sz) - : Sz(sz) - , Delta(Primes[hash % 128]) - , A(hash + Delta) - { +class TStateStorageRingWalker { + const ui32 Sz; + const ui32 Delta; + ui32 A; +public: + TStateStorageRingWalker(ui32 hash, ui32 sz) + : Sz(sz) + , Delta(Primes[hash % 128]) + , A(hash + Delta) + { Y_VERIFY_DEBUG(Delta > Sz); - } - - ui32 Next() { - A += Delta; - return (A % Sz); - } -}; - -void TStateStorageInfo::SelectReplicas(ui64 tabletId, TSelection *selection) const { - const ui32 hash = StateStorageHashFromTabletID(tabletId); - const ui32 total = Rings.size(); - - Y_VERIFY(NToSelect <= total); - - if (selection->Sz < NToSelect) { - selection->Status.Reset(new TStateStorageInfo::TSelection::EStatus[NToSelect]); + } + + ui32 Next() { + A += Delta; + return (A % Sz); + } +}; + +void TStateStorageInfo::SelectReplicas(ui64 tabletId, TSelection *selection) const { + const ui32 hash = StateStorageHashFromTabletID(tabletId); + const ui32 total = Rings.size(); + + Y_VERIFY(NToSelect <= total); + + if (selection->Sz < NToSelect) { + selection->Status.Reset(new TStateStorageInfo::TSelection::EStatus[NToSelect]); selection->SelectedReplicas.Reset(new TActorId[NToSelect]); - } - - selection->Sz = NToSelect; - - Fill(selection->Status.Get(), selection->Status.Get() + NToSelect, TStateStorageInfo::TSelection::StatusUnknown); - - if (NToSelect == total) { - for (ui32 idx : xrange(total)) { - selection->SelectedReplicas[idx] = Rings[idx].SelectReplica(hash); - } - } else { // NToSelect < total, first - select rings with walker, then select concrete node - TStateStorageRingWalker walker(hash, total); - for (ui32 idx : xrange(NToSelect)) - selection->SelectedReplicas[idx] = Rings[walker.Next()].SelectReplica(hash); - } -} - + } + + selection->Sz = NToSelect; + + Fill(selection->Status.Get(), selection->Status.Get() + NToSelect, TStateStorageInfo::TSelection::StatusUnknown); + + if (NToSelect == total) { + for (ui32 idx : xrange(total)) { + selection->SelectedReplicas[idx] = Rings[idx].SelectReplica(hash); + } + } else { // NToSelect < total, first - select rings with walker, then select concrete node + TStateStorageRingWalker walker(hash, total); + for (ui32 idx : xrange(NToSelect)) + selection->SelectedReplicas[idx] = Rings[walker.Next()].SelectReplica(hash); + } +} + TActorId TStateStorageInfo::TRing::SelectReplica(ui32 hash) const { - if (Replicas.size() == 1) - return Replicas[0]; - - Y_VERIFY(!Replicas.empty()); + if (Replicas.size() == 1) + return Replicas[0]; + + Y_VERIFY(!Replicas.empty()); if (UseRingSpecificNodeSelection) { return Replicas[CombineHashes(hash, ContentHash()) % Replicas.size()]; } else { return Replicas[hash % Replicas.size()]; } -} - +} + TList<TActorId> TStateStorageInfo::SelectAllReplicas() const { -// TODO: we really need this method in such way? +// TODO: we really need this method in such way? TList<TActorId> replicas; - - for (auto &ring : Rings) { + + for (auto &ring : Rings) { for (TActorId replica : ring.Replicas) - replicas.push_back(replica); + replicas.push_back(replica); } - + return replicas; } -ui32 TStateStorageInfo::TRing::ContentHash() const { - ui64 hash = 17; +ui32 TStateStorageInfo::TRing::ContentHash() const { + ui64 hash = 17; for (TActorId replica : Replicas) { - hash = Hash64to32((hash << 32) | replica.Hash32()); - } - return static_cast<ui32>(hash); -} - -ui32 TStateStorageInfo::ContentHash() const { - ui64 hash = RelaxedLoad<ui64>(&Hash); - if (Y_UNLIKELY(hash == Max<ui64>())) { - hash = 37; - for (const TRing &ring : Rings) { - hash = Hash64to32((hash << 32) | ring.ContentHash()); - } - RelaxedStore<ui64>(&Hash, static_cast<ui32>(hash)); - } - return static_cast<ui32>(hash); -} - -void TStateStorageInfo::TSelection::MergeReply(EStatus status, EStatus *owner, ui64 targetCookie, bool resetOld) { - ui32 unknown = 0; - ui32 ok = 0; - ui32 noinfo = 0; - ui32 outdated = 0; - - const ui32 majority = Sz / 2 + 1; - - ui32 cookie = 0; - for (ui32 i = 0; i < Sz; ++i) { - EStatus &st = Status[i]; - if (resetOld && st != StatusUnknown) - st = StatusOutdated; - - if (cookie == targetCookie) - st = status; - - ++cookie; - - switch (st) { - case StatusUnknown: - ++unknown; - break; - case StatusOk: - ++ok; - break; - case StatusNoInfo: - ++noinfo; - break; - case StatusOutdated: - ++outdated; - break; - } - } - - if (owner) { - if (ok >= majority) { - *owner = StatusOk; - } else if (outdated >= majority) { - *owner = StatusOutdated; - } else if (ok + unknown < majority) { - if (outdated) - *owner = StatusOutdated; - else - *owner = StatusNoInfo; - } - } -} - -static void CopyStateStorageRingInfo( - const NKikimrConfig::TDomainsConfig::TStateStorage::TRing &source, - TStateStorageInfo *info, - char *serviceId, - ui32 depth -) { - info->NToSelect = source.GetNToSelect(); - - const bool hasRings = source.RingSize() > 0; - const bool hasNodes = source.NodeSize() > 0; - - if (hasRings) { // has explicitely defined rings, use them as info rings - Y_VERIFY(!hasNodes); + hash = Hash64to32((hash << 32) | replica.Hash32()); + } + return static_cast<ui32>(hash); +} + +ui32 TStateStorageInfo::ContentHash() const { + ui64 hash = RelaxedLoad<ui64>(&Hash); + if (Y_UNLIKELY(hash == Max<ui64>())) { + hash = 37; + for (const TRing &ring : Rings) { + hash = Hash64to32((hash << 32) | ring.ContentHash()); + } + RelaxedStore<ui64>(&Hash, static_cast<ui32>(hash)); + } + return static_cast<ui32>(hash); +} + +void TStateStorageInfo::TSelection::MergeReply(EStatus status, EStatus *owner, ui64 targetCookie, bool resetOld) { + ui32 unknown = 0; + ui32 ok = 0; + ui32 noinfo = 0; + ui32 outdated = 0; + + const ui32 majority = Sz / 2 + 1; + + ui32 cookie = 0; + for (ui32 i = 0; i < Sz; ++i) { + EStatus &st = Status[i]; + if (resetOld && st != StatusUnknown) + st = StatusOutdated; + + if (cookie == targetCookie) + st = status; + + ++cookie; + + switch (st) { + case StatusUnknown: + ++unknown; + break; + case StatusOk: + ++ok; + break; + case StatusNoInfo: + ++noinfo; + break; + case StatusOutdated: + ++outdated; + break; + } + } + + if (owner) { + if (ok >= majority) { + *owner = StatusOk; + } else if (outdated >= majority) { + *owner = StatusOutdated; + } else if (ok + unknown < majority) { + if (outdated) + *owner = StatusOutdated; + else + *owner = StatusNoInfo; + } + } +} + +static void CopyStateStorageRingInfo( + const NKikimrConfig::TDomainsConfig::TStateStorage::TRing &source, + TStateStorageInfo *info, + char *serviceId, + ui32 depth +) { + info->NToSelect = source.GetNToSelect(); + + const bool hasRings = source.RingSize() > 0; + const bool hasNodes = source.NodeSize() > 0; + + if (hasRings) { // has explicitely defined rings, use them as info rings + Y_VERIFY(!hasNodes); Y_VERIFY(source.RingSize() < MaxRingCount); - info->Rings.resize(source.RingSize()); - - for (ui32 iring = 0, ering = source.RingSize(); iring != ering; ++iring) { - serviceId[depth] = (iring + 1); - - const NKikimrConfig::TDomainsConfig::TStateStorage::TRing &ring = source.GetRing(iring); + info->Rings.resize(source.RingSize()); + + for (ui32 iring = 0, ering = source.RingSize(); iring != ering; ++iring) { + serviceId[depth] = (iring + 1); + + const NKikimrConfig::TDomainsConfig::TStateStorage::TRing &ring = source.GetRing(iring); info->Rings[iring].UseRingSpecificNodeSelection = ring.GetUseRingSpecificNodeSelection(); if (ring.GetUseSingleNodeActorId()) { Y_VERIFY(ring.NodeSize() == 1); - + const TActorId replicaActorID = TActorId(ring.GetNode(0), TStringBuf(serviceId, serviceId + 12)); - info->Rings[iring].Replicas.push_back(replicaActorID); - } + info->Rings[iring].Replicas.push_back(replicaActorID); + } else { Y_VERIFY(ring.NodeSize() > 0); - + for (ui32 inode = 0, enode = ring.NodeSize(); inode != enode; ++inode) { serviceId[depth + 1] = (inode + 1); const TActorId replicaActorID = TActorId(ring.GetNode(inode), TStringBuf(serviceId, serviceId + 12)); info->Rings[iring].Replicas.push_back(replicaActorID); } } - // reset for next ring - serviceId[depth + 1] = char(); - } - - return; - } - - if (hasNodes) { // has explicitely defined replicas, use nodes as 1-node rings - Y_VERIFY(!hasRings); + // reset for next ring + serviceId[depth + 1] = char(); + } + + return; + } + + if (hasNodes) { // has explicitely defined replicas, use nodes as 1-node rings + Y_VERIFY(!hasRings); Y_VERIFY(source.NodeSize() < MaxNodeCount); - - info->Rings.resize(source.NodeSize()); - for (ui32 inode = 0, enode = source.NodeSize(); inode != enode; ++inode) { - serviceId[depth] = (inode + 1); - + + info->Rings.resize(source.NodeSize()); + for (ui32 inode = 0, enode = source.NodeSize(); inode != enode; ++inode) { + serviceId[depth] = (inode + 1); + const TActorId replicaActorID = TActorId(source.GetNode(inode), TStringBuf(serviceId, serviceId + 12)); - info->Rings[inode].Replicas.push_back(replicaActorID); - } - - return; - } - - Y_FAIL("must have rings or legacy node config"); -} - + info->Rings[inode].Replicas.push_back(replicaActorID); + } + + return; + } + + Y_FAIL("must have rings or legacy node config"); +} + TIntrusivePtr<TStateStorageInfo> BuildStateStorageInfo(char (&namePrefix)[TActorId::MaxServiceIDLength], const NKikimrConfig::TDomainsConfig::TStateStorage& config) { - TIntrusivePtr<TStateStorageInfo> info = new TStateStorageInfo(); - info->StateStorageGroup = config.GetSSId(); - - const size_t offset = FindIndex(namePrefix, char()); + TIntrusivePtr<TStateStorageInfo> info = new TStateStorageInfo(); + info->StateStorageGroup = config.GetSSId(); + + const size_t offset = FindIndex(namePrefix, char()); Y_VERIFY(offset != NPOS && (offset + sizeof(ui32)) < TActorId::MaxServiceIDLength); - - memcpy(namePrefix + offset, reinterpret_cast<const char *>(&info->StateStorageGroup), sizeof(ui32)); - CopyStateStorageRingInfo(config.GetRing(), info.Get(), namePrefix, offset + sizeof(ui32)); - - return info; -} - -void BuildStateStorageInfos(const NKikimrConfig::TDomainsConfig::TStateStorage& config, - TIntrusivePtr<TStateStorageInfo> &stateStorageInfo, - TIntrusivePtr<TStateStorageInfo> &boardInfo, - TIntrusivePtr<TStateStorageInfo> &schemeBoardInfo) -{ + + memcpy(namePrefix + offset, reinterpret_cast<const char *>(&info->StateStorageGroup), sizeof(ui32)); + CopyStateStorageRingInfo(config.GetRing(), info.Get(), namePrefix, offset + sizeof(ui32)); + + return info; +} + +void BuildStateStorageInfos(const NKikimrConfig::TDomainsConfig::TStateStorage& config, + TIntrusivePtr<TStateStorageInfo> &stateStorageInfo, + TIntrusivePtr<TStateStorageInfo> &boardInfo, + TIntrusivePtr<TStateStorageInfo> &schemeBoardInfo) +{ char ssr[TActorId::MaxServiceIDLength] = { 's', 's', 'r' }; // state storage replica char ssb[TActorId::MaxServiceIDLength] = { 's', 's', 'b' }; // state storage board char sbr[TActorId::MaxServiceIDLength] = { 's', 'b', 'r' }; // scheme board replica - - stateStorageInfo = BuildStateStorageInfo(ssr, config); - boardInfo = BuildStateStorageInfo(ssb, config); - schemeBoardInfo = BuildStateStorageInfo(sbr, config); -} - -} + + stateStorageInfo = BuildStateStorageInfo(ssr, config); + boardInfo = BuildStateStorageInfo(ssb, config); + schemeBoardInfo = BuildStateStorageInfo(sbr, config); +} + +} diff --git a/ydb/core/base/statestorage.h b/ydb/core/base/statestorage.h index f008f70902..9b3e3b6b1b 100644 --- a/ydb/core/base/statestorage.h +++ b/ydb/core/base/statestorage.h @@ -1,83 +1,83 @@ -#pragma once -#include "defs.h" -#include "events.h" +#pragma once +#include "defs.h" +#include "events.h" #include <ydb/core/protos/statestorage.pb.h> #include <ydb/core/protos/config.pb.h> #include <library/cpp/actors/interconnect/event_filter.h> #include <util/stream/str.h> #include <util/generic/list.h> -#include <util/generic/map.h> - -namespace NKikimr { - -struct TEvStateStorage { - enum EEv { - // requests (local, to proxy) - EvLookup = EventSpaceBegin(TKikimrEvents::ES_STATESTORAGE), - EvUpdate, - EvLock, - EvResolveReplicas, +#include <util/generic/map.h> + +namespace NKikimr { + +struct TEvStateStorage { + enum EEv { + // requests (local, to proxy) + EvLookup = EventSpaceBegin(TKikimrEvents::ES_STATESTORAGE), + EvUpdate, + EvLock, + EvResolveReplicas, EvRequestReplicasDumps, EvDelete, - EvCleanup, - EvResolveBoard, - EvBoardInfo, + EvCleanup, + EvResolveBoard, + EvBoardInfo, EvResolveSchemeBoard, // subset (by hash) EvListSchemeBoard, // all - EvUpdateGroupConfig, - - // replies (local, from proxy) - EvInfo = EvLookup + 512, - EvUpdateSignature, - EvResolveReplicasList, + EvUpdateGroupConfig, + + // replies (local, from proxy) + EvInfo = EvLookup + 512, + EvUpdateSignature, + EvResolveReplicasList, EvResponseReplicasDumps, EvDeleteResult, EvListSchemeBoardResult, - - // replicas interface - EvReplicaLookup = EvLock + 2 * 512, - EvReplicaUpdate, - EvReplicaLock, + + // replicas interface + EvReplicaLookup = EvLock + 2 * 512, + EvReplicaUpdate, + EvReplicaLock, EvReplicaLeaderDemoted, EvReplicaDumpRequest, EvReplicaDump, EvReplicaRegFollower, EvReplicaUnregFollower, EvReplicaDelete, - EvReplicaCleanup, - - EvReplicaInfo = EvLock + 3 * 512, - EvReplicaShutdown, - - EvReplicaBoardPublish = EvLock + 4 * 512, - EvReplicaBoardLookup, - EvReplicaBoardCleanup, - - EvReplicaBoardPublishAck = EvLock + 5 * 512, - EvReplicaBoardInfo, - - EvReplicaProbeSubscribe = EvLock + 6 * 512, - EvReplicaProbeUnsubscribe, - EvReplicaProbeConnected, - EvReplicaProbeDisconnected, - - EvEnd - }; - + EvReplicaCleanup, + + EvReplicaInfo = EvLock + 3 * 512, + EvReplicaShutdown, + + EvReplicaBoardPublish = EvLock + 4 * 512, + EvReplicaBoardLookup, + EvReplicaBoardCleanup, + + EvReplicaBoardPublishAck = EvLock + 5 * 512, + EvReplicaBoardInfo, + + EvReplicaProbeSubscribe = EvLock + 6 * 512, + EvReplicaProbeUnsubscribe, + EvReplicaProbeConnected, + EvReplicaProbeDisconnected, + + EvEnd + }; + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_STATESTORAGE), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_STATESTORAGE)"); - - struct TProxyOptions { - enum ESigWaitMode { - SigNone, - SigAsync, - SigSync, - }; - - ESigWaitMode SigWaitMode; - - TProxyOptions(ESigWaitMode sigWaitMode = SigNone) - : SigWaitMode(sigWaitMode) - {} + + struct TProxyOptions { + enum ESigWaitMode { + SigNone, + SigAsync, + SigSync, + }; + + ESigWaitMode SigWaitMode; + + TProxyOptions(ESigWaitMode sigWaitMode = SigNone) + : SigWaitMode(sigWaitMode) + {} TString ToString() const { switch (SigWaitMode) { @@ -87,18 +87,18 @@ struct TEvStateStorage { default: return "Unknown"; } } - }; - - struct TEvLookup : public TEventLocal<TEvLookup, EvLookup> { - const ui64 TabletID; - const ui64 Cookie; - const TProxyOptions ProxyOptions; - - TEvLookup(ui64 tabletId, ui64 cookie, const TProxyOptions &proxyOptions = TProxyOptions()) - : TabletID(tabletId) - , Cookie(cookie) - , ProxyOptions(proxyOptions) - {} + }; + + struct TEvLookup : public TEventLocal<TEvLookup, EvLookup> { + const ui64 TabletID; + const ui64 Cookie; + const TProxyOptions ProxyOptions; + + TEvLookup(ui64 tabletId, ui64 cookie, const TProxyOptions &proxyOptions = TProxyOptions()) + : TabletID(tabletId) + , Cookie(cookie) + , ProxyOptions(proxyOptions) + {} TString ToString() const { TStringStream str; @@ -108,32 +108,32 @@ struct TEvStateStorage { str << "}"; return str.Str(); } - }; - - struct TEvUpdate : public TEventLocal<TEvUpdate, EvUpdate> { - const ui64 TabletID; - const ui64 Cookie; + }; + + struct TEvUpdate : public TEventLocal<TEvUpdate, EvUpdate> { + const ui64 TabletID; + const ui64 Cookie; const TActorId ProposedLeader; const TActorId ProposedLeaderTablet; - const ui32 ProposedGeneration; - const ui32 ProposedStep; - const ui32 SignatureSz; - const TArrayHolder<ui64> Signature; - const TProxyOptions ProxyOptions; - + const ui32 ProposedGeneration; + const ui32 ProposedStep; + const ui32 SignatureSz; + const TArrayHolder<ui64> Signature; + const TProxyOptions ProxyOptions; + TEvUpdate(ui64 tabletId, ui64 cookie, const TActorId &leader, const TActorId &leaderTablet, ui32 gen, ui32 step, const ui64 *sig, ui32 sigsz, const TProxyOptions &proxyOptions = TProxyOptions()) - : TabletID(tabletId) - , Cookie(cookie) + : TabletID(tabletId) + , Cookie(cookie) , ProposedLeader(leader) , ProposedLeaderTablet(leaderTablet) - , ProposedGeneration(gen) - , ProposedStep(step) - , SignatureSz(sigsz) - , Signature(new ui64[sigsz]) - , ProxyOptions(proxyOptions) - { - Copy(sig, sig + sigsz, Signature.Get()); - } + , ProposedGeneration(gen) + , ProposedStep(step) + , SignatureSz(sigsz) + , Signature(new ui64[sigsz]) + , ProxyOptions(proxyOptions) + { + Copy(sig, sig + sigsz, Signature.Get()); + } TString ToString() const { TStringStream str; @@ -155,8 +155,8 @@ struct TEvStateStorage { str << "}"; return str.Str(); } - }; - + }; + struct TEvDelete : TEventLocal<TEvDelete, EvDelete> { const ui64 TabletID; const ui64 Cookie; @@ -175,16 +175,16 @@ struct TEvStateStorage { } }; - struct TEvCleanup : TEventLocal<TEvCleanup, EvCleanup> { - const ui64 TabletID; + struct TEvCleanup : TEventLocal<TEvCleanup, EvCleanup> { + const ui64 TabletID; const TActorId ProposedLeader; - + TEvCleanup(ui64 tabletId, TActorId proposedLeader) - : TabletID(tabletId) + : TabletID(tabletId) , ProposedLeader(proposedLeader) - {} - }; - + {} + }; + struct TEvDeleteResult : TEventLocal<TEvDeleteResult, EvDeleteResult> { const ui64 TabletID; const NKikimrProto::EReplyStatus Status; @@ -203,26 +203,26 @@ struct TEvStateStorage { } }; - struct TEvLock : public TEventLocal<TEvLock, EvLock> { - const ui64 TabletID; - const ui64 Cookie; + struct TEvLock : public TEventLocal<TEvLock, EvLock> { + const ui64 TabletID; + const ui64 Cookie; const TActorId ProposedLeader; - const ui32 ProposedGeneration; - const ui32 SignatureSz; - const TArrayHolder<ui64> Signature; - const TProxyOptions ProxyOptions; - + const ui32 ProposedGeneration; + const ui32 SignatureSz; + const TArrayHolder<ui64> Signature; + const TProxyOptions ProxyOptions; + TEvLock(ui64 tabletId, ui64 cookie, const TActorId &leader, ui32 gen, const ui64 *sig, ui32 sigsz, const TProxyOptions &proxyOptions = TProxyOptions()) - : TabletID(tabletId) - , Cookie(cookie) + : TabletID(tabletId) + , Cookie(cookie) , ProposedLeader(leader) - , ProposedGeneration(gen) - , SignatureSz(sigsz) - , Signature(new ui64[sigsz]) - , ProxyOptions(proxyOptions) - { - Copy(sig, sig + sigsz, Signature.Get()); - } + , ProposedGeneration(gen) + , SignatureSz(sigsz) + , Signature(new ui64[sigsz]) + , ProxyOptions(proxyOptions) + { + Copy(sig, sig + sigsz, Signature.Get()); + } TString ToString() const { TStringStream str; @@ -242,47 +242,47 @@ struct TEvStateStorage { str << "}"; return str.Str(); } - }; - - inline static void MakeFilteredSignatureCopy(const ui64 *sig, ui32 sigsz, ui64 *target) { - for (ui32 i = 0; i != sigsz; ++i) { - if (sig[i] != Max<ui64>()) - target[i] = sig[i]; - else - target[i] = 0; - } - } - - struct TEvInfo : public TEventLocal<TEvInfo, EvInfo> { - const NKikimrProto::EReplyStatus Status; - const ui64 TabletID; - const ui64 Cookie; + }; + + inline static void MakeFilteredSignatureCopy(const ui64 *sig, ui32 sigsz, ui64 *target) { + for (ui32 i = 0; i != sigsz; ++i) { + if (sig[i] != Max<ui64>()) + target[i] = sig[i]; + else + target[i] = 0; + } + } + + struct TEvInfo : public TEventLocal<TEvInfo, EvInfo> { + const NKikimrProto::EReplyStatus Status; + const ui64 TabletID; + const ui64 Cookie; const TActorId CurrentLeader; const TActorId CurrentLeaderTablet; - const ui32 CurrentGeneration; - const ui32 CurrentStep; - const bool Locked; - const ui64 LockedFor; - const ui32 SignatureSz; - TArrayHolder<ui64> Signature; + const ui32 CurrentGeneration; + const ui32 CurrentStep; + const bool Locked; + const ui64 LockedFor; + const ui32 SignatureSz; + TArrayHolder<ui64> Signature; TVector<std::pair<TActorId, TActorId>> Followers; - + TEvInfo(NKikimrProto::EReplyStatus status, ui64 tabletId, ui64 cookie, const TActorId &leader, const TActorId &leaderTablet, ui32 gen, ui32 step, bool locked, ui64 lockedFor, const ui64 *sig, ui32 sigsz, const TMap<TActorId, TActorId> &followers) - : Status(status) - , TabletID(tabletId) - , Cookie(cookie) + : Status(status) + , TabletID(tabletId) + , Cookie(cookie) , CurrentLeader(leader) , CurrentLeaderTablet(leaderTablet) - , CurrentGeneration(gen) - , CurrentStep(step) - , Locked(locked) - , LockedFor(lockedFor) - , SignatureSz(sigsz) - , Signature(new ui64[sigsz]) + , CurrentGeneration(gen) + , CurrentStep(step) + , Locked(locked) + , LockedFor(lockedFor) + , SignatureSz(sigsz) + , Signature(new ui64[sigsz]) , Followers(followers.begin(), followers.end()) - { - MakeFilteredSignatureCopy(sig, sigsz, Signature.Get()); - } + { + MakeFilteredSignatureCopy(sig, sigsz, Signature.Get()); + } TString ToString() const { TStringStream str; @@ -316,20 +316,20 @@ struct TEvStateStorage { str << "}"; return str.Str(); } - }; - - struct TEvUpdateSignature : public TEventLocal<TEvUpdateSignature, EvUpdateSignature> { - const ui64 TabletID; - const ui32 Sz; - const TArrayHolder<ui64> Signature; - - TEvUpdateSignature(ui64 tabletId, ui64 *sig, ui32 sigsz) - : TabletID(tabletId) - , Sz(sigsz) - , Signature(new ui64[sigsz]) - { - MakeFilteredSignatureCopy(sig, sigsz, Signature.Get()); - } + }; + + struct TEvUpdateSignature : public TEventLocal<TEvUpdateSignature, EvUpdateSignature> { + const ui64 TabletID; + const ui32 Sz; + const TArrayHolder<ui64> Signature; + + TEvUpdateSignature(ui64 tabletId, ui64 *sig, ui32 sigsz) + : TabletID(tabletId) + , Sz(sigsz) + , Signature(new ui64[sigsz]) + { + MakeFilteredSignatureCopy(sig, sigsz, Signature.Get()); + } TString ToString() const { TStringStream str; @@ -345,43 +345,43 @@ struct TEvStateStorage { str << "}"; return str.Str(); } - }; - + }; + struct TEvReplicaLeaderDemoted : public TEventPB<TEvReplicaLeaderDemoted, NKikimrStateStorage::TEvReplicaLeaderDemoted, EvReplicaLeaderDemoted> { TEvReplicaLeaderDemoted() {} TEvReplicaLeaderDemoted(ui64 tabletId, ui64 signature) - { - Record.SetTabletID(tabletId); - Record.SetSignature(signature); - } - }; - - struct TEvResolveReplicas; - struct TEvResolveBoard; + { + Record.SetTabletID(tabletId); + Record.SetSignature(signature); + } + }; + + struct TEvResolveReplicas; + struct TEvResolveBoard; struct TEvResolveSchemeBoard; - struct TEvResolveReplicasList; - struct TEvReplicaLookup; - struct TEvReplicaInfo; - struct TEvReplicaUpdate; - struct TEvReplicaLock; + struct TEvResolveReplicasList; + struct TEvReplicaLookup; + struct TEvReplicaInfo; + struct TEvReplicaUpdate; + struct TEvReplicaLock; struct TEvReplicaDelete; - struct TEvReplicaCleanup; - struct TEvReplicaBoardPublish; - struct TEvReplicaBoardLookup; - struct TEvReplicaBoardCleanup; - struct TEvReplicaBoardPublishAck; - struct TEvReplicaBoardInfo; + struct TEvReplicaCleanup; + struct TEvReplicaBoardPublish; + struct TEvReplicaBoardLookup; + struct TEvReplicaBoardCleanup; + struct TEvReplicaBoardPublishAck; + struct TEvReplicaBoardInfo; struct TEvListSchemeBoard; struct TEvListSchemeBoardResult; - struct TEvUpdateGroupConfig; - struct TEvReplicaProbeSubscribe; - struct TEvReplicaProbeUnsubscribe; - struct TEvReplicaProbeConnected; - struct TEvReplicaProbeDisconnected; - - struct TEvReplicaShutdown : public TEventPB<TEvStateStorage::TEvReplicaShutdown, NKikimrStateStorage::TEvReplicaShutdown, TEvStateStorage::EvReplicaShutdown> { - }; - + struct TEvUpdateGroupConfig; + struct TEvReplicaProbeSubscribe; + struct TEvReplicaProbeUnsubscribe; + struct TEvReplicaProbeConnected; + struct TEvReplicaProbeDisconnected; + + struct TEvReplicaShutdown : public TEventPB<TEvStateStorage::TEvReplicaShutdown, NKikimrStateStorage::TEvReplicaShutdown, TEvStateStorage::EvReplicaShutdown> { + }; + struct TEvReplicaDumpRequest : public TEventPB<TEvReplicaDumpRequest, NKikimrStateStorage::TEvDumpRequest, EvReplicaDumpRequest> { }; @@ -395,138 +395,138 @@ struct TEvStateStorage { struct TEvResponseReplicasDumps : public TEventLocal<TEvResponseReplicasDumps, EvResponseReplicasDumps> { TVector<std::pair<TActorId, TAutoPtr<TEvReplicaDump>>> ReplicasDumps; }; - + struct TEvReplicaRegFollower : public TEventPB<TEvReplicaRegFollower, NKikimrStateStorage::TEvRegisterFollower, EvReplicaRegFollower> { TEvReplicaRegFollower() - {} - + {} + TEvReplicaRegFollower(ui64 tabletId, TActorId follower, TActorId tablet, bool isCandidate) - { - Record.SetTabletID(tabletId); + { + Record.SetTabletID(tabletId); ActorIdToProto(follower, Record.MutableFollower()); ActorIdToProto(tablet, Record.MutableFollowerTablet()); - Record.SetCandidate(isCandidate); - } - }; - + Record.SetCandidate(isCandidate); + } + }; + struct TEvReplicaUnregFollower : public TEventPB<TEvReplicaUnregFollower, NKikimrStateStorage::TEvUnregisterFollower, EvReplicaUnregFollower> { TEvReplicaUnregFollower() - {} - + {} + TEvReplicaUnregFollower(ui64 tabletId, const TActorId &follower) - { - Record.SetTabletID(tabletId); + { + Record.SetTabletID(tabletId); ActorIdToProto(follower, Record.MutableFollower()); - } - }; - - struct TEvBoardInfo : public TEventLocal<TEvBoardInfo, EvBoardInfo> { - enum class EStatus { - Unknown, - Ok, - NotAvailable, - }; - - struct TInfoEntry { - TString Payload; - }; - - const EStatus Status; - const TString Path; + } + }; + + struct TEvBoardInfo : public TEventLocal<TEvBoardInfo, EvBoardInfo> { + enum class EStatus { + Unknown, + Ok, + NotAvailable, + }; + + struct TInfoEntry { + TString Payload; + }; + + const EStatus Status; + const TString Path; TMap<TActorId, TInfoEntry> InfoEntries; - - TEvBoardInfo(EStatus status, const TString &path) - : Status(status) - , Path(path) - {} - - TEvBoardInfo(const TEvBoardInfo &x) - : Status(x.Status) - , Path(x.Path) - , InfoEntries(x.InfoEntries) - {} - }; -}; - -struct TStateStorageInfo : public TThrRefBase { - struct TSelection { - enum EStatus { - StatusUnknown, - StatusOk, - StatusNoInfo, - StatusOutdated, - }; - - ui32 Sz; + + TEvBoardInfo(EStatus status, const TString &path) + : Status(status) + , Path(path) + {} + + TEvBoardInfo(const TEvBoardInfo &x) + : Status(x.Status) + , Path(x.Path) + , InfoEntries(x.InfoEntries) + {} + }; +}; + +struct TStateStorageInfo : public TThrRefBase { + struct TSelection { + enum EStatus { + StatusUnknown, + StatusOk, + StatusNoInfo, + StatusOutdated, + }; + + ui32 Sz; TArrayHolder<TActorId> SelectedReplicas; - TArrayHolder<EStatus> Status; - - TSelection() - : Sz(0) - {} - - void MergeReply(EStatus status, EStatus *owner, ui64 targetCookie, bool resetOld); - + TArrayHolder<EStatus> Status; + + TSelection() + : Sz(0) + {} + + void MergeReply(EStatus status, EStatus *owner, ui64 targetCookie, bool resetOld); + const TActorId* begin() const { return SelectedReplicas.Get(); } const TActorId* end() const { return SelectedReplicas.Get() + Sz; } - }; - - struct TRing { + }; + + struct TRing { bool UseRingSpecificNodeSelection; TVector<TActorId> Replicas; - + TActorId SelectReplica(ui32 hash) const; - ui32 ContentHash() const; - }; - - ui32 StateStorageGroup; - ui32 NToSelect; - TVector<TRing> Rings; - - void SelectReplicas(ui64 tabletId, TSelection *selection) const; + ui32 ContentHash() const; + }; + + ui32 StateStorageGroup; + ui32 NToSelect; + TVector<TRing> Rings; + + void SelectReplicas(ui64 tabletId, TSelection *selection) const; TList<TActorId> SelectAllReplicas() const; - ui32 ContentHash() const; - - TStateStorageInfo() - : StateStorageGroup(Max<ui32>()) - , NToSelect(0) - , Hash(Max<ui64>()) - {} - -private: - mutable ui64 Hash; -}; - -enum class EBoardLookupMode { - First, - Second, - Majority, - FirstNonEmptyDoubleTime, - SecondNonEmptyDoubleTime, - MajorityDoubleTime, -}; - + ui32 ContentHash() const; + + TStateStorageInfo() + : StateStorageGroup(Max<ui32>()) + , NToSelect(0) + , Hash(Max<ui64>()) + {} + +private: + mutable ui64 Hash; +}; + +enum class EBoardLookupMode { + First, + Second, + Majority, + FirstNonEmptyDoubleTime, + SecondNonEmptyDoubleTime, + MajorityDoubleTime, +}; + TIntrusivePtr<TStateStorageInfo> BuildStateStorageInfo(char (&namePrefix)[TActorId::MaxServiceIDLength], const NKikimrConfig::TDomainsConfig::TStateStorage& config); -void BuildStateStorageInfos(const NKikimrConfig::TDomainsConfig::TStateStorage& config, - TIntrusivePtr<TStateStorageInfo> &stateStorageInfo, - TIntrusivePtr<TStateStorageInfo> &boardInfo, - TIntrusivePtr<TStateStorageInfo> &schemeBoardInfo); - -IActor* CreateStateStorageWarden(const TIntrusivePtr<TStateStorageInfo> &info, const TIntrusivePtr<TStateStorageInfo> &board, const TIntrusivePtr<TStateStorageInfo> &schemeBoard); - +void BuildStateStorageInfos(const NKikimrConfig::TDomainsConfig::TStateStorage& config, + TIntrusivePtr<TStateStorageInfo> &stateStorageInfo, + TIntrusivePtr<TStateStorageInfo> &boardInfo, + TIntrusivePtr<TStateStorageInfo> &schemeBoardInfo); + +IActor* CreateStateStorageWarden(const TIntrusivePtr<TStateStorageInfo> &info, const TIntrusivePtr<TStateStorageInfo> &board, const TIntrusivePtr<TStateStorageInfo> &schemeBoard); + IActor* CreateStateStorageProxy(const TIntrusivePtr<TStateStorageInfo> &info, const TIntrusivePtr<TStateStorageInfo> &board, const TIntrusivePtr<TStateStorageInfo> &schemeBoard); -IActor* CreateStateStorageProxyStub(); -IActor* CreateStateStorageReplica(const TIntrusivePtr<TStateStorageInfo> &info, ui32 replicaIndex); +IActor* CreateStateStorageProxyStub(); +IActor* CreateStateStorageReplica(const TIntrusivePtr<TStateStorageInfo> &info, ui32 replicaIndex); IActor* CreateStateStorageMonitoringActor(ui64 targetTablet, const TActorId &sender, const TString &query); IActor* CreateStateStorageTabletGuardian(ui64 tabletId, const TActorId &leader, const TActorId &tabletLeader, ui32 generation); IActor* CreateStateStorageFollowerGuardian(ui64 tabletId, const TActorId &follower); // created as followerCandidate -IActor* CreateStateStorageBoardReplica(const TIntrusivePtr<TStateStorageInfo> &, ui32); -IActor* CreateSchemeBoardReplica(const TIntrusivePtr<TStateStorageInfo>&, ui32); +IActor* CreateStateStorageBoardReplica(const TIntrusivePtr<TStateStorageInfo> &, ui32); +IActor* CreateSchemeBoardReplica(const TIntrusivePtr<TStateStorageInfo>&, ui32); IActor* CreateBoardLookupActor(const TString &path, const TActorId &owner, ui32 groupId, EBoardLookupMode mode, bool sub, bool useNodeSubscriptions); IActor* CreateBoardPublishActor(const TString &path, const TString &payload, const TActorId &owner, ui32 groupId, ui32 ttlMs, bool reg); - -TString MakeEndpointsBoardPath(const TString &database); - -void RegisterStateStorageEventScopes(const std::shared_ptr<TEventFilter>& filter); - -} + +TString MakeEndpointsBoardPath(const TString &database); + +void RegisterStateStorageEventScopes(const std::shared_ptr<TEventFilter>& filter); + +} diff --git a/ydb/core/base/statestorage_event_filter.cpp b/ydb/core/base/statestorage_event_filter.cpp index 87e58fca07..75d772e3a1 100644 --- a/ydb/core/base/statestorage_event_filter.cpp +++ b/ydb/core/base/statestorage_event_filter.cpp @@ -1,45 +1,45 @@ -#include "statestorage.h" - -namespace NKikimr { - -void RegisterStateStorageEventScopes(const std::shared_ptr<TEventFilter>& filter) { - static const ui32 eventsFromPeerToSystem[] = { - TEvStateStorage::EvReplicaLookup, - TEvStateStorage::EvReplicaUpdate, - TEvStateStorage::EvReplicaLock, - TEvStateStorage::EvReplicaDumpRequest, +#include "statestorage.h" + +namespace NKikimr { + +void RegisterStateStorageEventScopes(const std::shared_ptr<TEventFilter>& filter) { + static const ui32 eventsFromPeerToSystem[] = { + TEvStateStorage::EvReplicaLookup, + TEvStateStorage::EvReplicaUpdate, + TEvStateStorage::EvReplicaLock, + TEvStateStorage::EvReplicaDumpRequest, TEvStateStorage::EvReplicaRegFollower, TEvStateStorage::EvReplicaUnregFollower, - TEvStateStorage::EvReplicaDelete, - TEvStateStorage::EvReplicaCleanup, - - TEvStateStorage::EvReplicaBoardPublish, - TEvStateStorage::EvReplicaBoardLookup, - TEvStateStorage::EvReplicaBoardCleanup, - }; - - static const ui32 eventsFromSystemToPeer[] = { + TEvStateStorage::EvReplicaDelete, + TEvStateStorage::EvReplicaCleanup, + + TEvStateStorage::EvReplicaBoardPublish, + TEvStateStorage::EvReplicaBoardLookup, + TEvStateStorage::EvReplicaBoardCleanup, + }; + + static const ui32 eventsFromSystemToPeer[] = { TEvStateStorage::EvReplicaLeaderDemoted, - TEvStateStorage::EvReplicaDump, - TEvStateStorage::EvReplicaInfo, - - TEvStateStorage::EvReplicaBoardPublishAck, - TEvStateStorage::EvReplicaBoardInfo, - }; - - for (ui32 e : eventsFromPeerToSystem) { - filter->RegisterEvent(e, TEventFilter::MakeRouteMask({ - {ENodeClass::PEER_TENANT, ENodeClass::SYSTEM}, - {ENodeClass::SYSTEM, ENodeClass::SYSTEM} - })); - } - - for (ui32 e : eventsFromSystemToPeer) { - filter->RegisterEvent(e, TEventFilter::MakeRouteMask({ - {ENodeClass::SYSTEM, ENodeClass::PEER_TENANT}, - {ENodeClass::SYSTEM, ENodeClass::SYSTEM} - })); - } -} - -} + TEvStateStorage::EvReplicaDump, + TEvStateStorage::EvReplicaInfo, + + TEvStateStorage::EvReplicaBoardPublishAck, + TEvStateStorage::EvReplicaBoardInfo, + }; + + for (ui32 e : eventsFromPeerToSystem) { + filter->RegisterEvent(e, TEventFilter::MakeRouteMask({ + {ENodeClass::PEER_TENANT, ENodeClass::SYSTEM}, + {ENodeClass::SYSTEM, ENodeClass::SYSTEM} + })); + } + + for (ui32 e : eventsFromSystemToPeer) { + filter->RegisterEvent(e, TEventFilter::MakeRouteMask({ + {ENodeClass::SYSTEM, ENodeClass::PEER_TENANT}, + {ENodeClass::SYSTEM, ENodeClass::SYSTEM} + })); + } +} + +} diff --git a/ydb/core/base/statestorage_guardian.cpp b/ydb/core/base/statestorage_guardian.cpp index 3ef80bc0c2..f1df97896b 100644 --- a/ydb/core/base/statestorage_guardian.cpp +++ b/ydb/core/base/statestorage_guardian.cpp @@ -1,7 +1,7 @@ -#include "statestorage_impl.h" -#include "statestorage_guardian_impl.h" -#include "tabletid.h" -#include "tablet.h" +#include "statestorage_impl.h" +#include "statestorage_guardian_impl.h" +#include "tabletid.h" +#include "tablet.h" #include <ydb/core/base/appdata.h> #include <ydb/core/base/compile_time_flags.h> @@ -12,573 +12,573 @@ #include <library/cpp/actors/core/interconnect.h> #include <util/generic/algorithm.h> -#include <util/generic/xrange.h> - -namespace NKikimr { -namespace NStateStorageGuardian { - -struct TGuardedInfo; +#include <util/generic/xrange.h> + +namespace NKikimr { +namespace NStateStorageGuardian { + +struct TGuardedInfo; struct TFollowerInfo; - -struct TEvPrivate { - enum EEv { + +struct TEvPrivate { + enum EEv { EvRefreshFollowerState = EventSpaceBegin(TKikimrEvents::ES_PRIVATE), - - EvEnd - }; - - static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_PRIVATE), - "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_PRIVATE)"); - + + EvEnd + }; + + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_PRIVATE), + "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_PRIVATE)"); + struct TEvRefreshFollowerState : public TEventLocal<TEvRefreshFollowerState, EvRefreshFollowerState> { TIntrusiveConstPtr<TFollowerInfo> FollowerInfo; - + TEvRefreshFollowerState(const TIntrusivePtr<TFollowerInfo> &info) : FollowerInfo(info) - {} - }; -}; - -struct TGuardedInfo : public TAtomicRefCount<TGuardedInfo> { - const ui64 TabletID; + {} + }; +}; + +struct TGuardedInfo : public TAtomicRefCount<TGuardedInfo> { + const ui64 TabletID; const TActorId Leader; const TActorId TabletLeader; - const ui32 Generation; - + const ui32 Generation; + TGuardedInfo(ui64 tabletId, const TActorId &leader, const TActorId &tabletLeader, ui32 generation) - : TabletID(tabletId) + : TabletID(tabletId) , Leader(leader) , TabletLeader(tabletLeader) - , Generation(generation) - {} -}; - + , Generation(generation) + {} +}; + struct TFollowerInfo : public TAtomicRefCount<TGuardedInfo> { - const ui64 TabletID; + const ui64 TabletID; const TActorId Follower; const TActorId Tablet; - const bool IsCandidate; - + const bool IsCandidate; + TFollowerInfo(ui64 tabletId, TActorId follower, TActorId tablet, bool isCandidate) - : TabletID(tabletId) + : TabletID(tabletId) , Follower(follower) - , Tablet(tablet) - , IsCandidate(isCandidate) - {} -}; - -class TReplicaGuardian : public TActorBootstrapped<TReplicaGuardian> { - TIntrusiveConstPtr<TGuardedInfo> Info; + , Tablet(tablet) + , IsCandidate(isCandidate) + {} +}; + +class TReplicaGuardian : public TActorBootstrapped<TReplicaGuardian> { + TIntrusiveConstPtr<TGuardedInfo> Info; const TActorId Replica; const TActorId Guard; - - ui64 Signature; - TInstant DowntimeFrom; - - void PassAway() override { - if (Replica.NodeId() != SelfId().NodeId()) - Send(TActivationContext::InterconnectProxy(Replica.NodeId()), new TEvents::TEvUnsubscribe); - - if (KIKIMR_ALLOW_SSREPLICA_PROBES) { + + ui64 Signature; + TInstant DowntimeFrom; + + void PassAway() override { + if (Replica.NodeId() != SelfId().NodeId()) + Send(TActivationContext::InterconnectProxy(Replica.NodeId()), new TEvents::TEvUnsubscribe); + + if (KIKIMR_ALLOW_SSREPLICA_PROBES) { const TActorId ssProxyId = MakeStateStorageProxyID(StateStorageGroupFromTabletID(Info->TabletID)); - Send(ssProxyId, new TEvStateStorage::TEvReplicaProbeUnsubscribe(Replica)); - } - - TActor::PassAway(); - } - - void RequestInfo() { - if (KIKIMR_ALLOW_SSREPLICA_PROBES) { + Send(ssProxyId, new TEvStateStorage::TEvReplicaProbeUnsubscribe(Replica)); + } + + TActor::PassAway(); + } + + void RequestInfo() { + if (KIKIMR_ALLOW_SSREPLICA_PROBES) { const TActorId ssProxyId = MakeStateStorageProxyID(StateStorageGroupFromTabletID(Info->TabletID)); - Send(ssProxyId, new TEvStateStorage::TEvReplicaProbeSubscribe(Replica)); - Become(&TThis::StateLookup); - } else { - MakeRequest(); - } - } - - void MakeRequest() { - Send(Replica, new TEvStateStorage::TEvReplicaLookup(Info->TabletID, 0), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession); - Become(&TThis::StateLookup); - } - - void UpdateInfo() { - TAutoPtr<TEvStateStorage::TEvReplicaUpdate> req(new TEvStateStorage::TEvReplicaUpdate()); - req->Record.SetTabletID(Info->TabletID); + Send(ssProxyId, new TEvStateStorage::TEvReplicaProbeSubscribe(Replica)); + Become(&TThis::StateLookup); + } else { + MakeRequest(); + } + } + + void MakeRequest() { + Send(Replica, new TEvStateStorage::TEvReplicaLookup(Info->TabletID, 0), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession); + Become(&TThis::StateLookup); + } + + void UpdateInfo() { + TAutoPtr<TEvStateStorage::TEvReplicaUpdate> req(new TEvStateStorage::TEvReplicaUpdate()); + req->Record.SetTabletID(Info->TabletID); ActorIdToProto(Info->Leader, req->Record.MutableProposedLeader()); ActorIdToProto(Info->TabletLeader, req->Record.MutableProposedLeaderTablet()); - req->Record.SetProposedGeneration(Info->Generation); - req->Record.SetProposedStep(0); - req->Record.SetSignature(Signature); - req->Record.SetIsGuardian(true); - - Send(Replica, req.Release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession); - Become(&TThis::StateUpdate); - } - - void Gone() { - Send(Guard, new TEvents::TEvGone()); - PassAway(); - } - - void SomeSleep() { - const TInstant now = TActivationContext::Now(); - if (DowntimeFrom > now) { - DowntimeFrom = now; - } else if (DowntimeFrom + TDuration::Seconds(15) < now) { - return Gone(); - } - - Become(&TThis::StateSleep, TDuration::MilliSeconds(250), new TEvents::TEvWakeup()); - } - - void Demoted() { + req->Record.SetProposedGeneration(Info->Generation); + req->Record.SetProposedStep(0); + req->Record.SetSignature(Signature); + req->Record.SetIsGuardian(true); + + Send(Replica, req.Release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession); + Become(&TThis::StateUpdate); + } + + void Gone() { + Send(Guard, new TEvents::TEvGone()); + PassAway(); + } + + void SomeSleep() { + const TInstant now = TActivationContext::Now(); + if (DowntimeFrom > now) { + DowntimeFrom = now; + } else if (DowntimeFrom + TDuration::Seconds(15) < now) { + return Gone(); + } + + Become(&TThis::StateSleep, TDuration::MilliSeconds(250), new TEvents::TEvWakeup()); + } + + void Demoted() { Send(Info->Leader, new TEvTablet::TEvDemoted(false)); - return PassAway(); - } - - void Handle(TEvStateStorage::TEvReplicaInfo::TPtr &ev) { - const auto &record = ev->Get()->Record; - const auto status = record.GetStatus(); - Signature = record.GetSignature(); - - DowntimeFrom = TInstant::Max(); - - if (status == NKikimrProto::OK) { - const ui32 gen = record.GetCurrentGeneration(); - - if (gen > Info->Generation) { - return Demoted(); - } else if (gen == Info->Generation) { + return PassAway(); + } + + void Handle(TEvStateStorage::TEvReplicaInfo::TPtr &ev) { + const auto &record = ev->Get()->Record; + const auto status = record.GetStatus(); + Signature = record.GetSignature(); + + DowntimeFrom = TInstant::Max(); + + if (status == NKikimrProto::OK) { + const ui32 gen = record.GetCurrentGeneration(); + + if (gen > Info->Generation) { + return Demoted(); + } else if (gen == Info->Generation) { const TActorId leader = ActorIdFromProto(record.GetCurrentLeader()); const TActorId tabletLeader = ActorIdFromProto(record.GetCurrentLeaderTablet()); if (!leader || leader == Info->Leader && !tabletLeader) { - return UpdateInfo(); + return UpdateInfo(); } else if (leader != Info->Leader || tabletLeader != Info->TabletLeader) { - return Demoted(); // hack around cluster restarts - } else { - Become(&TThis::StateCalm); - Send(Guard, ev->Release().Release()); - return; - } - } else { - return UpdateInfo(); // what about locked-state? - } - } else if (status == NKikimrProto::ERROR) { - return UpdateInfo(); - } else { + return Demoted(); // hack around cluster restarts + } else { + Become(&TThis::StateCalm); + Send(Guard, ev->Release().Release()); + return; + } + } else { + return UpdateInfo(); // what about locked-state? + } + } else if (status == NKikimrProto::ERROR) { + return UpdateInfo(); + } else { Y_FAIL(); - } - } -public: + } + } +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::SS_REPLICA_GUARDIAN; } TReplicaGuardian(TGuardedInfo *info, TActorId replica, TActorId guard) - : Info(info) - , Replica(replica) - , Guard(guard) - , Signature(0) - , DowntimeFrom(TInstant::Max()) + : Info(info) + , Replica(replica) + , Guard(guard) + , Signature(0) + , DowntimeFrom(TInstant::Max()) {} - - void Bootstrap() { - RequestInfo(); - } - - STATEFN(StateLookup) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvReplicaInfo, Handle); - cFunc(TEvStateStorage::TEvReplicaProbeConnected::EventType, MakeRequest); - cFunc(TEvStateStorage::TEvReplicaProbeDisconnected::EventType, Gone); - cFunc(TEvStateStorage::TEvReplicaShutdown::EventType, Gone); - cFunc(TEvents::TEvUndelivered::EventType, SomeSleep); - cFunc(TEvInterconnect::TEvNodeDisconnected::EventType, SomeSleep); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); - } - } - - STATEFN(StateCalm) { // info is correct, wait for disconnect event - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvReplicaInfo, Handle); - cFunc(TEvStateStorage::TEvReplicaShutdown::EventType, Gone); - cFunc(TEvents::TEvUndelivered::EventType, RequestInfo); - cFunc(TEvInterconnect::TEvNodeDisconnected::EventType, RequestInfo); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); - } - } - - STATEFN(StateSleep) { // not-connected, sleeping for retry - switch (ev->GetTypeRewrite()) { - cFunc(TEvStateStorage::TEvReplicaShutdown::EventType, Gone); - cFunc(TEvents::TEvWakeup::EventType, RequestInfo); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); - } - } - - STATEFN(StateUpdate) { // waiting for update result - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvReplicaInfo, Handle); - cFunc(TEvStateStorage::TEvReplicaShutdown::EventType, Gone); - cFunc(TEvents::TEvUndelivered::EventType, SomeSleep); - cFunc(TEvInterconnect::TEvNodeDisconnected::EventType, SomeSleep); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); - } - } -}; - + + void Bootstrap() { + RequestInfo(); + } + + STATEFN(StateLookup) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvReplicaInfo, Handle); + cFunc(TEvStateStorage::TEvReplicaProbeConnected::EventType, MakeRequest); + cFunc(TEvStateStorage::TEvReplicaProbeDisconnected::EventType, Gone); + cFunc(TEvStateStorage::TEvReplicaShutdown::EventType, Gone); + cFunc(TEvents::TEvUndelivered::EventType, SomeSleep); + cFunc(TEvInterconnect::TEvNodeDisconnected::EventType, SomeSleep); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + } + } + + STATEFN(StateCalm) { // info is correct, wait for disconnect event + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvReplicaInfo, Handle); + cFunc(TEvStateStorage::TEvReplicaShutdown::EventType, Gone); + cFunc(TEvents::TEvUndelivered::EventType, RequestInfo); + cFunc(TEvInterconnect::TEvNodeDisconnected::EventType, RequestInfo); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + } + } + + STATEFN(StateSleep) { // not-connected, sleeping for retry + switch (ev->GetTypeRewrite()) { + cFunc(TEvStateStorage::TEvReplicaShutdown::EventType, Gone); + cFunc(TEvents::TEvWakeup::EventType, RequestInfo); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + } + } + + STATEFN(StateUpdate) { // waiting for update result + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvReplicaInfo, Handle); + cFunc(TEvStateStorage::TEvReplicaShutdown::EventType, Gone); + cFunc(TEvents::TEvUndelivered::EventType, SomeSleep); + cFunc(TEvInterconnect::TEvNodeDisconnected::EventType, SomeSleep); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + } + } +}; + class TFollowerGuardian : public TActorBootstrapped<TFollowerGuardian> { TIntrusiveConstPtr<TFollowerInfo> Info; const TActorId Replica; const TActorId Guard; - - TInstant DowntimeFrom; - + + TInstant DowntimeFrom; + void RefreshInfo(TEvPrivate::TEvRefreshFollowerState::TPtr &ev) { Info = ev->Get()->FollowerInfo; - } - + } + void UpdateInfo(TEvPrivate::TEvRefreshFollowerState::TPtr &ev) { - RefreshInfo(ev); - UpdateInfo(); - } - - void UpdateInfo() { - if (KIKIMR_ALLOW_SSREPLICA_PROBES) { + RefreshInfo(ev); + UpdateInfo(); + } + + void UpdateInfo() { + if (KIKIMR_ALLOW_SSREPLICA_PROBES) { const TActorId ssProxyId = MakeStateStorageProxyID(StateStorageGroupFromTabletID(Info->TabletID)); - Send(ssProxyId, new TEvStateStorage::TEvReplicaProbeSubscribe(Replica)); - Become(&TThis::StateCalm); - } else { - MakeRequest(); - } - } - - void MakeRequest() { - Send( - Replica, + Send(ssProxyId, new TEvStateStorage::TEvReplicaProbeSubscribe(Replica)); + Become(&TThis::StateCalm); + } else { + MakeRequest(); + } + } + + void MakeRequest() { + Send( + Replica, new TEvStateStorage::TEvReplicaRegFollower(Info->TabletID, Info->Follower, Info->Tablet, Info->IsCandidate), - IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession); - Become(&TThis::StateCalm); - } - - void SomeSleep() { - const TInstant now = TActivationContext::Now(); - if (DowntimeFrom > now) { - DowntimeFrom = now; - } else if (DowntimeFrom + TDuration::Seconds(15) < now) { - return Gone(); - } - - Become(&TThis::StateSleep, TDuration::MilliSeconds(250), new TEvents::TEvWakeup()); - } - - void PassAway() override { + IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession); + Become(&TThis::StateCalm); + } + + void SomeSleep() { + const TInstant now = TActivationContext::Now(); + if (DowntimeFrom > now) { + DowntimeFrom = now; + } else if (DowntimeFrom + TDuration::Seconds(15) < now) { + return Gone(); + } + + Become(&TThis::StateSleep, TDuration::MilliSeconds(250), new TEvents::TEvWakeup()); + } + + void PassAway() override { Send(Replica, new TEvStateStorage::TEvReplicaUnregFollower(Info->TabletID, Info->Follower)); - if (Replica.NodeId() != SelfId().NodeId()) - Send(TActivationContext::InterconnectProxy(Replica.NodeId()), new TEvents::TEvUnsubscribe()); - - if (KIKIMR_ALLOW_SSREPLICA_PROBES) { + if (Replica.NodeId() != SelfId().NodeId()) + Send(TActivationContext::InterconnectProxy(Replica.NodeId()), new TEvents::TEvUnsubscribe()); + + if (KIKIMR_ALLOW_SSREPLICA_PROBES) { const TActorId ssProxyId = MakeStateStorageProxyID(StateStorageGroupFromTabletID(Info->TabletID)); - Send(ssProxyId, new TEvStateStorage::TEvReplicaProbeUnsubscribe(Replica)); - } - - TActor::PassAway(); - } - - void Gone() { - Send(Guard, new TEvents::TEvGone()); - PassAway(); - } - - void Ping() { - DowntimeFrom = TInstant::Max(); - } -public: + Send(ssProxyId, new TEvStateStorage::TEvReplicaProbeUnsubscribe(Replica)); + } + + TActor::PassAway(); + } + + void Gone() { + Send(Guard, new TEvents::TEvGone()); + PassAway(); + } + + void Ping() { + DowntimeFrom = TInstant::Max(); + } +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::SS_REPLICA_GUARDIAN; } TFollowerGuardian(TFollowerInfo *info, const TActorId replica, const TActorId guard) - : Info(info) - , Replica(replica) - , Guard(guard) - , DowntimeFrom(TInstant::Max()) + : Info(info) + , Replica(replica) + , Guard(guard) + , DowntimeFrom(TInstant::Max()) {} - - void Bootstrap() { - UpdateInfo(); - } - - STATEFN(StateCalm) { - switch (ev->GetTypeRewrite()) { + + void Bootstrap() { + UpdateInfo(); + } + + STATEFN(StateCalm) { + switch (ev->GetTypeRewrite()) { hFunc(TEvPrivate::TEvRefreshFollowerState, UpdateInfo); - cFunc(TEvStateStorage::TEvReplicaProbeConnected::EventType, MakeRequest); - cFunc(TEvStateStorage::TEvReplicaProbeDisconnected::EventType, Gone); - cFunc(TEvents::TEvUndelivered::EventType, SomeSleep); - cFunc(TEvInterconnect::TEvNodeDisconnected::EventType, SomeSleep); - cFunc(TEvTablet::TEvPing::EventType, Ping); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); - cFunc(TEvStateStorage::TEvReplicaShutdown::EventType, Gone); - } - } - - STATEFN(StateSleep) { - switch (ev->GetTypeRewrite()) { + cFunc(TEvStateStorage::TEvReplicaProbeConnected::EventType, MakeRequest); + cFunc(TEvStateStorage::TEvReplicaProbeDisconnected::EventType, Gone); + cFunc(TEvents::TEvUndelivered::EventType, SomeSleep); + cFunc(TEvInterconnect::TEvNodeDisconnected::EventType, SomeSleep); + cFunc(TEvTablet::TEvPing::EventType, Ping); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + cFunc(TEvStateStorage::TEvReplicaShutdown::EventType, Gone); + } + } + + STATEFN(StateSleep) { + switch (ev->GetTypeRewrite()) { hFunc(TEvPrivate::TEvRefreshFollowerState, RefreshInfo); - - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); - cFunc(TEvents::TEvWakeup::EventType, UpdateInfo); - - cFunc(TEvStateStorage::TEvReplicaShutdown::EventType, Gone); - } - } -}; - -class TTabletGuardian : public TActorBootstrapped<TTabletGuardian> { - TIntrusivePtr<TGuardedInfo> Info; + + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + cFunc(TEvents::TEvWakeup::EventType, UpdateInfo); + + cFunc(TEvStateStorage::TEvReplicaShutdown::EventType, Gone); + } + } +}; + +class TTabletGuardian : public TActorBootstrapped<TTabletGuardian> { + TIntrusivePtr<TGuardedInfo> Info; TIntrusivePtr<TFollowerInfo> FollowerInfo; - + TVector<std::pair<TActorId, TActorId>> ReplicaGuardians; // replica -> guardian, position dependant so vector - ui32 ReplicasOnlineThreshold; - + ui32 ReplicasOnlineThreshold; + THolder<TFollowerTracker> FollowerTracker; - + TActorId Launcher() const { return Info ? Info->Leader : FollowerInfo->Follower; - } - - void HandlePoison() { - for (const auto &xpair : ReplicaGuardians) - Send(xpair.second, new TEvents::TEvPoison()); - - return PassAway(); - } - - void Handle(TEvStateStorage::TEvResolveReplicasList::TPtr &ev) { + } + + void HandlePoison() { + for (const auto &xpair : ReplicaGuardians) + Send(xpair.second, new TEvents::TEvPoison()); + + return PassAway(); + } + + void Handle(TEvStateStorage::TEvResolveReplicasList::TPtr &ev) { const TVector<TActorId> &replicasList = ev->Get()->Replicas; Y_VERIFY(!replicasList.empty(), "must not happens, guardian must be created over active tablet"); - - const ui32 replicaSz = replicasList.size(); - + + const ui32 replicaSz = replicasList.size(); + TVector<std::pair<TActorId, TActorId>> updatedReplicaGuardians; - updatedReplicaGuardians.reserve(replicaSz); - - const bool inspectCurrent = (ReplicaGuardians.size() == replicaSz); - if (!inspectCurrent) { - for (const auto &xpair : ReplicaGuardians) { - if (xpair.second) - Send(xpair.second, new TEvents::TEvPoison()); - } - ReplicaGuardians.clear(); - } - - for (ui32 idx : xrange(replicasList.size())) { + updatedReplicaGuardians.reserve(replicaSz); + + const bool inspectCurrent = (ReplicaGuardians.size() == replicaSz); + if (!inspectCurrent) { + for (const auto &xpair : ReplicaGuardians) { + if (xpair.second) + Send(xpair.second, new TEvents::TEvPoison()); + } + ReplicaGuardians.clear(); + } + + for (ui32 idx : xrange(replicasList.size())) { const TActorId replica = replicasList[idx]; - - if (inspectCurrent && ReplicaGuardians[idx].first == replica && ReplicaGuardians[idx].second) { - updatedReplicaGuardians.emplace_back(ReplicaGuardians[idx]); + + if (inspectCurrent && ReplicaGuardians[idx].first == replica && ReplicaGuardians[idx].second) { + updatedReplicaGuardians.emplace_back(ReplicaGuardians[idx]); ReplicaGuardians[idx].second = TActorId(); - } else { - if (Info) + } else { + if (Info) updatedReplicaGuardians.emplace_back(replica, RegisterWithSameMailbox(new TReplicaGuardian(Info.Get(), replica, SelfId()))); - else + else updatedReplicaGuardians.emplace_back(replica, RegisterWithSameMailbox(new TFollowerGuardian(FollowerInfo.Get(), replica, SelfId()))); - } - } - - for (const auto &xpair : ReplicaGuardians) { - if (xpair.second) - Send(xpair.second, new TEvents::TEvPoison()); - } - - ReplicaGuardians.swap(updatedReplicaGuardians); - ReplicasOnlineThreshold = (ReplicaGuardians.size() == 1) ? 0 : 1; - + } + } + + for (const auto &xpair : ReplicaGuardians) { + if (xpair.second) + Send(xpair.second, new TEvents::TEvPoison()); + } + + ReplicaGuardians.swap(updatedReplicaGuardians); + ReplicasOnlineThreshold = (ReplicaGuardians.size() == 1) ? 0 : 1; + if (!FollowerTracker || !inspectCurrent) // would notify on first change FollowerTracker.Reset(new TFollowerTracker(replicaSz)); - - Become(&TThis::StateCalm); - } - - void Handle(TEvents::TEvUndelivered::TPtr &ev) { + + Become(&TThis::StateCalm); + } + + void Handle(TEvents::TEvUndelivered::TPtr &ev) { Y_UNUSED(ev); Y_FAIL("must not happens, guardian must be created over active tablet"); - } - + } + bool ReplicaDown(TActorId guardian) { - ui32 replicasOnline = 0; - bool ret = false; - - for (auto it = ReplicaGuardians.begin(), end = ReplicaGuardians.end(); it != end; ++it) { - if (it->second == guardian) { + ui32 replicasOnline = 0; + bool ret = false; + + for (auto it = ReplicaGuardians.begin(), end = ReplicaGuardians.end(); it != end; ++it) { + if (it->second == guardian) { it->second = TActorId(); - ret = true; - } else if (it->second) { - ++replicasOnline; - } - } - - if (replicasOnline == ReplicasOnlineThreshold) { - Send(Launcher(), new TEvTablet::TEvDemoted(true)); - HandlePoison(); - - // we are dead now - return false; - } - - return ret; // true on erase, false on outdated notify - } - - void SendResolveRequest(TDuration delay) { + ret = true; + } else if (it->second) { + ++replicasOnline; + } + } + + if (replicasOnline == ReplicasOnlineThreshold) { + Send(Launcher(), new TEvTablet::TEvDemoted(true)); + HandlePoison(); + + // we are dead now + return false; + } + + return ret; // true on erase, false on outdated notify + } + + void SendResolveRequest(TDuration delay) { const ui64 tabletId = Info ? Info->TabletID : FollowerInfo->TabletID; - const ui64 stateStorageGroup = StateStorageGroupFromTabletID(tabletId); + const ui64 stateStorageGroup = StateStorageGroupFromTabletID(tabletId); const TActorId proxyActorID = MakeStateStorageProxyID(stateStorageGroup); - - if (delay == TDuration::Zero()) { - Send(proxyActorID, new TEvStateStorage::TEvResolveReplicas(tabletId), IEventHandle::FlagTrackDelivery); - } else { - TActivationContext::Schedule( - delay, - new IEventHandle(proxyActorID, SelfId(), new TEvStateStorage::TEvResolveReplicas(tabletId), IEventHandle::FlagTrackDelivery) - ); - } - - Become(&TThis::StateResolve); - } - - void HandleGoneResolve(TEvents::TEvGone::TPtr &ev) { - // already resolving so no more action needed, just refresh active replica list - ReplicaDown(ev->Sender); - } - - void HandleGoneCalm(TEvents::TEvGone::TPtr &ev) { - if (ReplicaDown(ev->Sender)) { - const ui64 rndDelay = AppData()->RandomProvider->GenRand() % 150; - SendResolveRequest(TDuration::MilliSeconds(150 + rndDelay)); - } - } - - void Handle(TEvStateStorage::TEvReplicaInfo::TPtr &ev) { + + if (delay == TDuration::Zero()) { + Send(proxyActorID, new TEvStateStorage::TEvResolveReplicas(tabletId), IEventHandle::FlagTrackDelivery); + } else { + TActivationContext::Schedule( + delay, + new IEventHandle(proxyActorID, SelfId(), new TEvStateStorage::TEvResolveReplicas(tabletId), IEventHandle::FlagTrackDelivery) + ); + } + + Become(&TThis::StateResolve); + } + + void HandleGoneResolve(TEvents::TEvGone::TPtr &ev) { + // already resolving so no more action needed, just refresh active replica list + ReplicaDown(ev->Sender); + } + + void HandleGoneCalm(TEvents::TEvGone::TPtr &ev) { + if (ReplicaDown(ev->Sender)) { + const ui64 rndDelay = AppData()->RandomProvider->GenRand() % 150; + SendResolveRequest(TDuration::MilliSeconds(150 + rndDelay)); + } + } + + void Handle(TEvStateStorage::TEvReplicaInfo::TPtr &ev) { Y_VERIFY(FollowerTracker); - - const NKikimrStateStorage::TEvInfo &record = ev->Get()->Record; + + const NKikimrStateStorage::TEvInfo &record = ev->Get()->Record; const TActorId guardian = ev->Sender; - for (ui32 idx : xrange(ReplicaGuardians.size())) { - if (ReplicaGuardians[idx].second != guardian) - continue; - + for (ui32 idx : xrange(ReplicaGuardians.size())) { + if (ReplicaGuardians[idx].second != guardian) + continue; + TVector<TActorId> reported; reported.reserve(record.FollowerSize() + record.FollowerCandidatesSize()); for (const auto &x : record.GetFollower()) { reported.emplace_back(ActorIdFromProto(x)); - } - + } + for (const auto &x : record.GetFollowerCandidates()) { reported.emplace_back(ActorIdFromProto(x)); - } - - Sort(reported); + } + + Sort(reported); if (FollowerTracker->Merge(idx, reported)) { const auto &merged = FollowerTracker->GetMerged(); - - // reuse reported so in many cases no allocation happens - reported.clear(); - reported.reserve(merged.size()); - - for (const auto &xpair : merged) { - reported.emplace_back(xpair.first); - } - + + // reuse reported so in many cases no allocation happens + reported.clear(); + reported.reserve(merged.size()); + + for (const auto &xpair : merged) { + reported.emplace_back(xpair.first); + } + Send(Launcher(), new TEvTablet::TEvFollowerListRefresh(std::move(reported))); - } - - break; - } - } - + } + + break; + } + } + bool RefreshFollowerInfo(TEvTablet::TEvFollowerUpdateState::TPtr &ev) { - const auto *msg = ev->Get(); + const auto *msg = ev->Get(); const ui64 tabletId = FollowerInfo->TabletID; - + Y_VERIFY(msg->FollowerActor == FollowerInfo->Follower); - + const bool hasChanges = msg->TabletActor != FollowerInfo->Tablet || msg->IsCandidate != FollowerInfo->IsCandidate; - if (hasChanges) { + if (hasChanges) { FollowerInfo = new TFollowerInfo( - tabletId, + tabletId, msg->FollowerActor, - msg->TabletActor, - msg->IsCandidate - ); - } - - return hasChanges; - } - + msg->TabletActor, + msg->IsCandidate + ); + } + + return hasChanges; + } + void UpdateFollowerInfo(TEvTablet::TEvFollowerUpdateState::TPtr &ev) { if (!RefreshFollowerInfo(ev)) - return; - - for (auto &xpair : ReplicaGuardians) { + return; + + for (auto &xpair : ReplicaGuardians) { const TActorId guardian = xpair.second; Send(guardian, new TEvPrivate::TEvRefreshFollowerState(FollowerInfo)); - } - } -public: + } + } +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::SS_TABLET_GUARDIAN; } - TTabletGuardian(TGuardedInfo *info) - : Info(info) + TTabletGuardian(TGuardedInfo *info) + : Info(info) , ReplicasOnlineThreshold(0) {} - + TTabletGuardian(TFollowerInfo *info) : FollowerInfo(info) , ReplicasOnlineThreshold(0) {} - - void Bootstrap() { - SendResolveRequest(TDuration::Zero()); - } - - STATEFN(StateResolve) { - switch (ev->GetTypeRewrite()) { + + void Bootstrap() { + SendResolveRequest(TDuration::Zero()); + } + + STATEFN(StateResolve) { + switch (ev->GetTypeRewrite()) { hFunc(TEvTablet::TEvFollowerUpdateState, UpdateFollowerInfo); - hFunc(TEvStateStorage::TEvResolveReplicasList, Handle); - hFunc(TEvStateStorage::TEvReplicaInfo, Handle); - hFunc(TEvents::TEvUndelivered, Handle); - hFunc(TEvents::TEvGone, HandleGoneResolve); - cFunc(TEvents::TEvPoisonPill::EventType, HandlePoison); - cFunc(TEvTablet::TEvTabletDead::EventType, HandlePoison); - } - } - - STATEFN(StateCalm) { - switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvResolveReplicasList, Handle); + hFunc(TEvStateStorage::TEvReplicaInfo, Handle); + hFunc(TEvents::TEvUndelivered, Handle); + hFunc(TEvents::TEvGone, HandleGoneResolve); + cFunc(TEvents::TEvPoisonPill::EventType, HandlePoison); + cFunc(TEvTablet::TEvTabletDead::EventType, HandlePoison); + } + } + + STATEFN(StateCalm) { + switch (ev->GetTypeRewrite()) { hFunc(TEvTablet::TEvFollowerUpdateState, UpdateFollowerInfo); - hFunc(TEvStateStorage::TEvResolveReplicasList, Handle); - hFunc(TEvStateStorage::TEvReplicaInfo, Handle); - hFunc(TEvents::TEvUndelivered, Handle); - hFunc(TEvents::TEvGone, HandleGoneCalm); - cFunc(TEvents::TEvPoisonPill::EventType, HandlePoison); - cFunc(TEvTablet::TEvTabletDead::EventType, HandlePoison); - } - } -}; - -} - + hFunc(TEvStateStorage::TEvResolveReplicasList, Handle); + hFunc(TEvStateStorage::TEvReplicaInfo, Handle); + hFunc(TEvents::TEvUndelivered, Handle); + hFunc(TEvents::TEvGone, HandleGoneCalm); + cFunc(TEvents::TEvPoisonPill::EventType, HandlePoison); + cFunc(TEvTablet::TEvTabletDead::EventType, HandlePoison); + } + } +}; + +} + IActor* CreateStateStorageTabletGuardian(ui64 tabletId, const TActorId &leader, const TActorId &tabletLeader, ui32 generation) { TIntrusivePtr<NStateStorageGuardian::TGuardedInfo> info = new NStateStorageGuardian::TGuardedInfo(tabletId, leader, tabletLeader, generation); - return new NStateStorageGuardian::TTabletGuardian(info.Get()); -} - + return new NStateStorageGuardian::TTabletGuardian(info.Get()); +} + IActor* CreateStateStorageFollowerGuardian(ui64 tabletId, const TActorId &follower) { TIntrusivePtr<NStateStorageGuardian::TFollowerInfo> followerInfo = new NStateStorageGuardian::TFollowerInfo(tabletId, follower, TActorId(), true); return new NStateStorageGuardian::TTabletGuardian(followerInfo.Get()); -} - -} +} + +} diff --git a/ydb/core/base/statestorage_guardian_impl.h b/ydb/core/base/statestorage_guardian_impl.h index 60ef793e5d..0bdda91ead 100644 --- a/ydb/core/base/statestorage_guardian_impl.h +++ b/ydb/core/base/statestorage_guardian_impl.h @@ -1,91 +1,91 @@ -#pragma once -#include "defs.h" -#include <util/generic/map.h> -#include <util/generic/algorithm.h> - -namespace NKikimr { -namespace NStateStorageGuardian { - +#pragma once +#include "defs.h" +#include <util/generic/map.h> +#include <util/generic/algorithm.h> + +namespace NKikimr { +namespace NStateStorageGuardian { + struct TFollowerTracker { TVector<TVector<TActorId>> Reported; // reported followers by replica index TMap<TActorId, ui32> Merged; // follower -> referenced by - + bool AddMerged(TActorId x) { - auto itPair = Merged.emplace(x, 1); - if (itPair.second) { - return true; - } else { - itPair.first->second++; - return false; - } - } - + auto itPair = Merged.emplace(x, 1); + if (itPair.second) { + return true; + } else { + itPair.first->second++; + return false; + } + } + bool DelMerged(TActorId x) { - auto it = Merged.find(x); + auto it = Merged.find(x); Y_VERIFY(it != Merged.end(), "follower tracker consistency broken"); - - if (it->second == 1) { - Merged.erase(it); - return true; - } else { - it->second--; - return false; - } - } -public: + + if (it->second == 1) { + Merged.erase(it); + return true; + } else { + it->second--; + return false; + } + } +public: TFollowerTracker(ui32 replicas) - : Reported(replicas) - {} - + : Reported(replicas) + {} + const TMap<TActorId, ui32>& GetMerged() const { - return Merged; - } - - // update reported list for replica, returns true if smth changed - // reported must be sorted + return Merged; + } + + // update reported list for replica, returns true if smth changed + // reported must be sorted bool Merge(ui32 replicaIdx, TVector<TActorId> &reported) { - bool changed = false; - + bool changed = false; + TVector<TActorId> &old = Reported[replicaIdx]; - const ui32 oldSz = old.size(); - bool gotDuplicates = false; - - ui32 oldIdx = 0; + const ui32 oldSz = old.size(); + bool gotDuplicates = false; + + ui32 oldIdx = 0; TActorId prevReported; for (TActorId x : reported) { - if (x == prevReported) { // skip duplicated - gotDuplicates = true; - continue; - } - prevReported = x; - - // every x must be kept in merged - - while (oldIdx < oldSz && old[oldIdx] < x) { - changed |= DelMerged(old[oldIdx]); - ++oldIdx; - } - - if (oldIdx < oldSz && old[oldIdx] == x) { - ++oldIdx; - // do nothing - } else { - // new entries - changed |= AddMerged(x); - } - } - - // erase old tail - for (; oldIdx < oldSz; ++oldIdx) { - changed |= DelMerged(old[oldIdx]); - } - - if (gotDuplicates) - reported.erase(Unique(reported.begin(), reported.end()), reported.end()); - - Reported[replicaIdx].swap(reported); - return changed; - } -}; - -}} + if (x == prevReported) { // skip duplicated + gotDuplicates = true; + continue; + } + prevReported = x; + + // every x must be kept in merged + + while (oldIdx < oldSz && old[oldIdx] < x) { + changed |= DelMerged(old[oldIdx]); + ++oldIdx; + } + + if (oldIdx < oldSz && old[oldIdx] == x) { + ++oldIdx; + // do nothing + } else { + // new entries + changed |= AddMerged(x); + } + } + + // erase old tail + for (; oldIdx < oldSz; ++oldIdx) { + changed |= DelMerged(old[oldIdx]); + } + + if (gotDuplicates) + reported.erase(Unique(reported.begin(), reported.end()), reported.end()); + + Reported[replicaIdx].swap(reported); + return changed; + } +}; + +}} diff --git a/ydb/core/base/statestorage_guardian_impl_ut.cpp b/ydb/core/base/statestorage_guardian_impl_ut.cpp index c750c994c4..00638ab480 100644 --- a/ydb/core/base/statestorage_guardian_impl_ut.cpp +++ b/ydb/core/base/statestorage_guardian_impl_ut.cpp @@ -1,63 +1,63 @@ -#include "defs.h" -#include "statestorage_guardian_impl.h" +#include "defs.h" +#include "statestorage_guardian_impl.h" #include <library/cpp/testing/unittest/registar.h> -#include <util/generic/ptr.h> - -namespace NKikimr { - namespace NStateStorageGuardian { - - Y_UNIT_TEST_SUITE(TGuardianImpl) { +#include <util/generic/ptr.h> + +namespace NKikimr { + namespace NStateStorageGuardian { + + Y_UNIT_TEST_SUITE(TGuardianImpl) { Y_UNIT_TEST(FollowerTracker) { TFollowerTracker tracker(2); - - { + + { TVector<TActorId> followers = { TActorId(1, 1, 1, 1), TActorId(1, 1, 5, 1), TActorId(1, 1, 10, 1) }; UNIT_ASSERT(tracker.Merge(0, followers) == true); - } - { + } + { TVector<TActorId> followers = { TActorId(1, 1, 1, 1), TActorId(1, 1, 5, 1), TActorId(1, 1, 10, 1) }; UNIT_ASSERT(tracker.Merge(1, followers) == false); - } - - { + } + + { TVector<TActorId> followers = { TActorId(1, 1, 1, 1) }; UNIT_ASSERT(tracker.Merge(0, followers) == false); - } - { + } + { TVector<TActorId> followers = { TActorId(1, 1, 1, 1), TActorId(1, 1, 5, 1) }; UNIT_ASSERT(tracker.Merge(1, followers) == true); - } - - auto merged = tracker.GetMerged(); - UNIT_ASSERT(merged.size() == 2); + } + + auto merged = tracker.GetMerged(); + UNIT_ASSERT(merged.size() == 2); UNIT_ASSERT(merged.FindPtr(TActorId(1, 1, 1, 1)) != nullptr); UNIT_ASSERT(merged.FindPtr(TActorId(1, 1, 5, 1)) != nullptr); UNIT_ASSERT(merged.FindPtr(TActorId(1, 1, 10, 1)) == nullptr); - } - + } + Y_UNIT_TEST(FollowerTrackerDuplicates) { TFollowerTracker tracker(1); - - { + + { TVector<TActorId> followers = { TActorId(1, 1, 1, 1), TActorId(1, 1, 5, 1), TActorId(1, 1, 10, 1) }; UNIT_ASSERT(tracker.Merge(0, followers) == true); - } - { + } + { TVector<TActorId> followers = { TActorId(1, 1, 1, 1), TActorId(1, 1, 10, 1), TActorId(1, 1, 10, 1) }; UNIT_ASSERT(tracker.Merge(0, followers) == true); - UNIT_ASSERT(tracker.GetMerged().size() == 2); - } - { + UNIT_ASSERT(tracker.GetMerged().size() == 2); + } + { TVector<TActorId> followers = { TActorId(1, 1, 1, 1), TActorId(1, 1, 11, 1), TActorId(1, 1, 11, 1) }; UNIT_ASSERT(tracker.Merge(0, followers) == true); - UNIT_ASSERT(tracker.GetMerged().size() == 2); - } - { + UNIT_ASSERT(tracker.GetMerged().size() == 2); + } + { TVector<TActorId> followers = { TActorId(1, 1, 1, 1), TActorId(1, 1, 5, 1) }; UNIT_ASSERT(tracker.Merge(0, followers) == true); - UNIT_ASSERT(tracker.GetMerged().size() == 2); - } - } - } - } -} + UNIT_ASSERT(tracker.GetMerged().size() == 2); + } + } + } + } +} diff --git a/ydb/core/base/statestorage_impl.h b/ydb/core/base/statestorage_impl.h index 92c393d254..2a2aa22f6a 100644 --- a/ydb/core/base/statestorage_impl.h +++ b/ydb/core/base/statestorage_impl.h @@ -1,40 +1,40 @@ -#pragma once +#pragma once #include "pathid.h" -#include "statestorage.h" - -namespace NKikimr { - +#include "statestorage.h" + +namespace NKikimr { + inline TActorId MakeStateStorageReplicaID(ui32 node, ui64 stateStorageGroup, ui32 replicaIndex) { - char x[12] = { 's', 't', 's' }; - x[3] = (char)stateStorageGroup; - memcpy(x + 5, &replicaIndex, sizeof(ui32)); + char x[12] = { 's', 't', 's' }; + x[3] = (char)stateStorageGroup; + memcpy(x + 5, &replicaIndex, sizeof(ui32)); return TActorId(node, TStringBuf(x, 12)); -} - -struct TEvStateStorage::TEvReplicaInfo : public TEventPB<TEvStateStorage::TEvReplicaInfo, NKikimrStateStorage::TEvInfo, TEvStateStorage::EvReplicaInfo> { - TEvReplicaInfo() - {} - - TEvReplicaInfo(ui64 tabletId, NKikimrProto::EReplyStatus status) - { - Record.SetTabletID(tabletId); - Record.SetStatus(status); - } - +} + +struct TEvStateStorage::TEvReplicaInfo : public TEventPB<TEvStateStorage::TEvReplicaInfo, NKikimrStateStorage::TEvInfo, TEvStateStorage::EvReplicaInfo> { + TEvReplicaInfo() + {} + + TEvReplicaInfo(ui64 tabletId, NKikimrProto::EReplyStatus status) + { + Record.SetTabletID(tabletId); + Record.SetStatus(status); + } + TEvReplicaInfo(ui64 tabletId, const TActorId ¤tLeader, const TActorId ¤tLeaderTablet, ui32 currentGeneration, ui32 currentStep, bool locked, ui64 lockedFor) - { - Record.SetStatus(NKikimrProto::OK); - - Record.SetTabletID(tabletId); + { + Record.SetStatus(NKikimrProto::OK); + + Record.SetTabletID(tabletId); ActorIdToProto(currentLeader, Record.MutableCurrentLeader()); ActorIdToProto(currentLeaderTablet, Record.MutableCurrentLeaderTablet()); - Record.SetCurrentGeneration(currentGeneration); - Record.SetCurrentStep(currentStep); - if (locked) { - Record.SetLocked(locked); - Record.SetLockedFor(lockedFor); - } - } + Record.SetCurrentGeneration(currentGeneration); + Record.SetCurrentStep(currentStep); + if (locked) { + Record.SetLocked(locked); + Record.SetLockedFor(lockedFor); + } + } TString ToString() const { TStringStream str; @@ -62,71 +62,71 @@ struct TEvStateStorage::TEvReplicaInfo : public TEventPB<TEvStateStorage::TEvRep return str.Str(); } -}; - -struct TEvStateStorage::TEvUpdateGroupConfig : public TEventLocal<TEvUpdateGroupConfig, EvUpdateGroupConfig> { - TIntrusivePtr<TStateStorageInfo> GroupConfig; - TIntrusivePtr<TStateStorageInfo> BoardConfig; - TIntrusivePtr<TStateStorageInfo> SchemeBoardConfig; - - TEvUpdateGroupConfig( - const TIntrusivePtr<TStateStorageInfo> &info, - const TIntrusivePtr<TStateStorageInfo> &board, - const TIntrusivePtr<TStateStorageInfo> &scheme) - : GroupConfig(info) - , BoardConfig(board) - , SchemeBoardConfig(scheme) - {} -}; - -struct TEvStateStorage::TEvReplicaProbeSubscribe : public TEventLocal<TEvReplicaProbeSubscribe, EvReplicaProbeSubscribe> { +}; + +struct TEvStateStorage::TEvUpdateGroupConfig : public TEventLocal<TEvUpdateGroupConfig, EvUpdateGroupConfig> { + TIntrusivePtr<TStateStorageInfo> GroupConfig; + TIntrusivePtr<TStateStorageInfo> BoardConfig; + TIntrusivePtr<TStateStorageInfo> SchemeBoardConfig; + + TEvUpdateGroupConfig( + const TIntrusivePtr<TStateStorageInfo> &info, + const TIntrusivePtr<TStateStorageInfo> &board, + const TIntrusivePtr<TStateStorageInfo> &scheme) + : GroupConfig(info) + , BoardConfig(board) + , SchemeBoardConfig(scheme) + {} +}; + +struct TEvStateStorage::TEvReplicaProbeSubscribe : public TEventLocal<TEvReplicaProbeSubscribe, EvReplicaProbeSubscribe> { const TActorId ReplicaId; - + TEvReplicaProbeSubscribe(TActorId replicaId) - : ReplicaId(replicaId) - {} -}; - -struct TEvStateStorage::TEvReplicaProbeUnsubscribe : public TEventLocal<TEvReplicaProbeUnsubscribe, EvReplicaProbeUnsubscribe> { + : ReplicaId(replicaId) + {} +}; + +struct TEvStateStorage::TEvReplicaProbeUnsubscribe : public TEventLocal<TEvReplicaProbeUnsubscribe, EvReplicaProbeUnsubscribe> { const TActorId ReplicaId; - + TEvReplicaProbeUnsubscribe(TActorId replicaId) - : ReplicaId(replicaId) - {} -}; - -struct TEvStateStorage::TEvReplicaProbeConnected : public TEventLocal<TEvReplicaProbeConnected, EvReplicaProbeConnected> { + : ReplicaId(replicaId) + {} +}; + +struct TEvStateStorage::TEvReplicaProbeConnected : public TEventLocal<TEvReplicaProbeConnected, EvReplicaProbeConnected> { const TActorId ReplicaId; - + TEvReplicaProbeConnected(TActorId replicaId) - : ReplicaId(replicaId) - {} -}; - -struct TEvStateStorage::TEvReplicaProbeDisconnected : public TEventLocal<TEvReplicaProbeDisconnected, EvReplicaProbeDisconnected> { + : ReplicaId(replicaId) + {} +}; + +struct TEvStateStorage::TEvReplicaProbeDisconnected : public TEventLocal<TEvReplicaProbeDisconnected, EvReplicaProbeDisconnected> { const TActorId ReplicaId; - + TEvReplicaProbeDisconnected(TActorId replicaId) - : ReplicaId(replicaId) - {} -}; - -struct TEvStateStorage::TEvResolveReplicas : public TEventLocal<TEvResolveReplicas, EvResolveReplicas> { - const ui64 TabletID; - - TEvResolveReplicas(ui64 tabletId) - : TabletID(tabletId) - {} -}; - -struct TEvStateStorage::TEvResolveBoard : public TEventLocal<TEvResolveBoard, EvResolveBoard> { - const TString Path; - - TEvResolveBoard(const TString &path) - : Path(path) - {} -}; - + : ReplicaId(replicaId) + {} +}; + +struct TEvStateStorage::TEvResolveReplicas : public TEventLocal<TEvResolveReplicas, EvResolveReplicas> { + const ui64 TabletID; + + TEvResolveReplicas(ui64 tabletId) + : TabletID(tabletId) + {} +}; + +struct TEvStateStorage::TEvResolveBoard : public TEventLocal<TEvResolveBoard, EvResolveBoard> { + const TString Path; + + TEvResolveBoard(const TString &path) + : Path(path) + {} +}; + struct TEvStateStorage::TEvResolveSchemeBoard : public TEventLocal<TEvResolveSchemeBoard, EvResolveSchemeBoard> { enum EKeyType { KeyTypePath, @@ -149,43 +149,43 @@ struct TEvStateStorage::TEvResolveSchemeBoard : public TEventLocal<TEvResolveSch {} }; -struct TEvStateStorage::TEvResolveReplicasList : public TEventLocal<TEvResolveReplicasList, EvResolveReplicasList> { +struct TEvStateStorage::TEvResolveReplicasList : public TEventLocal<TEvResolveReplicasList, EvResolveReplicasList> { TVector<TActorId> Replicas; - ui32 ConfigContentHash = Max<ui32>(); -}; - + ui32 ConfigContentHash = Max<ui32>(); +}; + struct TEvStateStorage::TEvListSchemeBoard : public TEventLocal<TEvListSchemeBoard, EvListSchemeBoard> { }; struct TEvStateStorage::TEvListSchemeBoardResult : public TEventLocal<TEvListSchemeBoardResult, EvListSchemeBoardResult> { - TIntrusiveConstPtr<TStateStorageInfo> Info; - - TEvListSchemeBoardResult(const TIntrusiveConstPtr<TStateStorageInfo> &info) - : Info(info) - {} + TIntrusiveConstPtr<TStateStorageInfo> Info; + + TEvListSchemeBoardResult(const TIntrusiveConstPtr<TStateStorageInfo> &info) + : Info(info) + {} }; -struct TEvStateStorage::TEvReplicaLookup : public TEventPB<TEvStateStorage::TEvReplicaLookup, NKikimrStateStorage::TEvLookup, TEvStateStorage::EvReplicaLookup>{ - struct TActualityCounter : public TRefCounted<TActualityCounter, TAtomicCounter> {}; - using TActualityCounterPtr = TIntrusivePtr<TActualityCounter>; - TActualityCounterPtr ActualityRefCounter; - - TEvReplicaLookup() - {} - - TEvReplicaLookup(ui64 tabletId, ui64 cookie) - { - Record.SetTabletID(tabletId); - Record.SetCookie(cookie); - } - - TEvReplicaLookup(ui64 tabletId, ui64 cookie, TActualityCounterPtr &actualityRefCounter) - : ActualityRefCounter(actualityRefCounter) - { - Record.SetTabletID(tabletId); - Record.SetCookie(cookie); - } - +struct TEvStateStorage::TEvReplicaLookup : public TEventPB<TEvStateStorage::TEvReplicaLookup, NKikimrStateStorage::TEvLookup, TEvStateStorage::EvReplicaLookup>{ + struct TActualityCounter : public TRefCounted<TActualityCounter, TAtomicCounter> {}; + using TActualityCounterPtr = TIntrusivePtr<TActualityCounter>; + TActualityCounterPtr ActualityRefCounter; + + TEvReplicaLookup() + {} + + TEvReplicaLookup(ui64 tabletId, ui64 cookie) + { + Record.SetTabletID(tabletId); + Record.SetCookie(cookie); + } + + TEvReplicaLookup(ui64 tabletId, ui64 cookie, TActualityCounterPtr &actualityRefCounter) + : ActualityRefCounter(actualityRefCounter) + { + Record.SetTabletID(tabletId); + Record.SetCookie(cookie); + } + TString ToString() const { TStringStream str; str << "{EvReplicaLookup TabletID: " << Record.GetTabletID(); @@ -193,18 +193,18 @@ struct TEvStateStorage::TEvReplicaLookup : public TEventPB<TEvStateStorage::TEvR str << "}"; return str.Str(); } -}; - -struct TEvStateStorage::TEvReplicaUpdate : public TEventPB<TEvStateStorage::TEvReplicaUpdate, NKikimrStateStorage::TEvUpdate, TEvStateStorage::EvReplicaUpdate> { - TEvReplicaUpdate() - {} - - TEvReplicaUpdate(ui64 tabletId, ui32 proposedGeneration, ui32 proposedStep) - { - Record.SetTabletID(tabletId); - Record.SetProposedGeneration(proposedGeneration); - Record.SetProposedStep(proposedStep); - } +}; + +struct TEvStateStorage::TEvReplicaUpdate : public TEventPB<TEvStateStorage::TEvReplicaUpdate, NKikimrStateStorage::TEvUpdate, TEvStateStorage::EvReplicaUpdate> { + TEvReplicaUpdate() + {} + + TEvReplicaUpdate(ui64 tabletId, ui32 proposedGeneration, ui32 proposedStep) + { + Record.SetTabletID(tabletId); + Record.SetProposedGeneration(proposedGeneration); + Record.SetProposedStep(proposedStep); + } TString ToString() const { TStringStream str; @@ -214,8 +214,8 @@ struct TEvStateStorage::TEvReplicaUpdate : public TEventPB<TEvStateStorage::TEvR str << "}"; return str.Str(); } -}; - +}; + struct TEvStateStorage::TEvReplicaDelete : public TEventPB<TEvStateStorage::TEvReplicaDelete, NKikimrStateStorage::TEvDelete, TEvStateStorage::EvReplicaDelete> { TEvReplicaDelete() {} @@ -233,26 +233,26 @@ struct TEvStateStorage::TEvReplicaDelete : public TEventPB<TEvStateStorage::TEvR } }; -struct TEvStateStorage::TEvReplicaCleanup : public TEventPB<TEvStateStorage::TEvReplicaCleanup, NKikimrStateStorage::TEvCleanup, TEvStateStorage::EvReplicaCleanup> { - TEvReplicaCleanup() - {} - +struct TEvStateStorage::TEvReplicaCleanup : public TEventPB<TEvStateStorage::TEvReplicaCleanup, NKikimrStateStorage::TEvCleanup, TEvStateStorage::EvReplicaCleanup> { + TEvReplicaCleanup() + {} + TEvReplicaCleanup(ui64 tabletId, TActorId proposedLeader) - { - Record.SetTabletID(tabletId); + { + Record.SetTabletID(tabletId); ActorIdToProto(proposedLeader, Record.MutableProposedLeader()); - } -}; - -struct TEvStateStorage::TEvReplicaLock : public TEventPB<TEvStateStorage::TEvReplicaLock, NKikimrStateStorage::TEvLock, TEvStateStorage::EvReplicaLock> { - TEvReplicaLock() - {} - - TEvReplicaLock(ui64 tabletId, ui32 proposedGeneration) - { - Record.SetTabletID(tabletId); - Record.SetProposedGeneration(proposedGeneration); - } + } +}; + +struct TEvStateStorage::TEvReplicaLock : public TEventPB<TEvStateStorage::TEvReplicaLock, NKikimrStateStorage::TEvLock, TEvStateStorage::EvReplicaLock> { + TEvReplicaLock() + {} + + TEvReplicaLock(ui64 tabletId, ui32 proposedGeneration) + { + Record.SetTabletID(tabletId); + Record.SetProposedGeneration(proposedGeneration); + } TString ToString() const { TStringStream str; @@ -261,55 +261,55 @@ struct TEvStateStorage::TEvReplicaLock : public TEventPB<TEvStateStorage::TEvRep str << "}"; return str.Str(); } -}; - -struct TEvStateStorage::TEvReplicaBoardPublish : public TEventPB<TEvStateStorage::TEvReplicaBoardPublish, NKikimrStateStorage::TEvReplicaBoardPublish, TEvStateStorage::EvReplicaBoardPublish> { - TEvReplicaBoardPublish() - {} - +}; + +struct TEvStateStorage::TEvReplicaBoardPublish : public TEventPB<TEvStateStorage::TEvReplicaBoardPublish, NKikimrStateStorage::TEvReplicaBoardPublish, TEvStateStorage::EvReplicaBoardPublish> { + TEvReplicaBoardPublish() + {} + TEvReplicaBoardPublish(const TString &path, const TString &payload, ui64 ttlMs, bool reg, TActorId owner) - { - Record.SetPath(path); - Record.SetPayload(payload); - Record.SetTtlMs(ttlMs); - Record.SetRegister(reg); + { + Record.SetPath(path); + Record.SetPayload(payload); + Record.SetTtlMs(ttlMs); + Record.SetRegister(reg); ActorIdToProto(owner, Record.MutableOwner()); - } -}; - -struct TEvStateStorage::TEvReplicaBoardLookup : public TEventPB<TEvStateStorage::TEvReplicaBoardLookup, NKikimrStateStorage::TEvReplicaBoardLookup, TEvStateStorage::EvReplicaBoardLookup> { - TEvReplicaBoardLookup() - {} - + } +}; + +struct TEvStateStorage::TEvReplicaBoardLookup : public TEventPB<TEvStateStorage::TEvReplicaBoardLookup, NKikimrStateStorage::TEvReplicaBoardLookup, TEvStateStorage::EvReplicaBoardLookup> { + TEvReplicaBoardLookup() + {} + TEvReplicaBoardLookup(const TString &path, TActorId owner, bool sub) - { - Record.SetPath(path); + { + Record.SetPath(path); ActorIdToProto(owner, Record.MutableOwner()); - Record.SetSubscribe(sub); - } -}; - -struct TEvStateStorage::TEvReplicaBoardCleanup : public TEventPB<TEvStateStorage::TEvReplicaBoardCleanup, NKikimrStateStorage::TEvReplicaBoardCleanup, TEvStateStorage::EvReplicaBoardCleanup> { - TEvReplicaBoardCleanup() - {} -}; - -struct TEvStateStorage::TEvReplicaBoardPublishAck : public TEventPB<TEvStateStorage::TEvReplicaBoardPublishAck, NKikimrStateStorage::TEvReplicaBoardPublishAck, TEvStateStorage::EvReplicaBoardPublishAck> { - TEvReplicaBoardPublishAck() - {} -}; - -struct TEvStateStorage::TEvReplicaBoardInfo : public TEventPB<TEvStateStorage::TEvReplicaBoardInfo, NKikimrStateStorage::TEvReplicaBoardInfo, TEvStateStorage::EvReplicaBoardInfo> { - TEvReplicaBoardInfo() - {} - - TEvReplicaBoardInfo(const TString &path, bool dropped) - { - Record.SetPath(path); - Record.SetDropped(dropped); - } -}; - + Record.SetSubscribe(sub); + } +}; + +struct TEvStateStorage::TEvReplicaBoardCleanup : public TEventPB<TEvStateStorage::TEvReplicaBoardCleanup, NKikimrStateStorage::TEvReplicaBoardCleanup, TEvStateStorage::EvReplicaBoardCleanup> { + TEvReplicaBoardCleanup() + {} +}; + +struct TEvStateStorage::TEvReplicaBoardPublishAck : public TEventPB<TEvStateStorage::TEvReplicaBoardPublishAck, NKikimrStateStorage::TEvReplicaBoardPublishAck, TEvStateStorage::EvReplicaBoardPublishAck> { + TEvReplicaBoardPublishAck() + {} +}; + +struct TEvStateStorage::TEvReplicaBoardInfo : public TEventPB<TEvStateStorage::TEvReplicaBoardInfo, NKikimrStateStorage::TEvReplicaBoardInfo, TEvStateStorage::EvReplicaBoardInfo> { + TEvReplicaBoardInfo() + {} + + TEvReplicaBoardInfo(const TString &path, bool dropped) + { + Record.SetPath(path); + Record.SetDropped(dropped); + } +}; + IActor* CreateStateStorageReplicaProbe(TActorId replica); - -} + +} diff --git a/ydb/core/base/statestorage_monitoring.cpp b/ydb/core/base/statestorage_monitoring.cpp index 83122b6ad3..5bcc3ec67f 100644 --- a/ydb/core/base/statestorage_monitoring.cpp +++ b/ydb/core/base/statestorage_monitoring.cpp @@ -1,54 +1,54 @@ -#include "statestorage_impl.h" -#include "tabletid.h" +#include "statestorage_impl.h" +#include "tabletid.h" #include <ydb/core/protos/services.pb.h> #include <library/cpp/actors/core/interconnect.h> #include <library/cpp/monlib/service/pages/templates.h> #include <library/cpp/actors/core/mon.h> #include <library/cpp/actors/core/hfunc.h> #include <library/cpp/actors/core/actor_bootstrapped.h> - -namespace NKikimr { - -class TStateStorageMonitoringActor : public TActorBootstrapped<TStateStorageMonitoringActor> { - struct TReplicaInfo { + +namespace NKikimr { + +class TStateStorageMonitoringActor : public TActorBootstrapped<TStateStorageMonitoringActor> { + struct TReplicaInfo { TActorId ActorID; - TInstant ReplyTime; - + TInstant ReplyTime; + TActorId CurrentLeader; TActorId CurrentLeaderTablet; TVector<TActorId> Followers; - ui32 CurrentGeneration; - ui64 ConfigContentHash; - bool Locked; - ui64 LockedFor; - + ui32 CurrentGeneration; + ui64 ConfigContentHash; + bool Locked; + ui64 LockedFor; + TReplicaInfo(const TActorId &x) - : ActorID(x) + : ActorID(x) , ReplyTime(TInstant::MicroSeconds(Max<ui64>())) , CurrentLeader() , CurrentLeaderTablet() - , CurrentGeneration(Max<ui32>()) - , ConfigContentHash(0) - , Locked(false) - , LockedFor(0) - {} - }; - - const ui64 TabletID; + , CurrentGeneration(Max<ui32>()) + , ConfigContentHash(0) + , Locked(false) + , LockedFor(0) + {} + }; + + const ui64 TabletID; const TActorId Sender; const TString Query; - - TInstant BeginMoment; - TInstant ReplicasRequestMoment; - - TDuration ProxyReplyTime; + + TInstant BeginMoment; + TInstant ReplicasRequestMoment; + + TDuration ProxyReplyTime; TVector<TReplicaInfo> ReplicasInfo; - ui64 WaitingForReplicas; - ui64 SelfConfigContentHash; - + ui64 WaitingForReplicas; + ui64 SelfConfigContentHash; + void Reply(const TString &response, const TActorContext &ctx) { - TStringStream str; - + TStringStream str; + HTML(str) { H3() { str << "State Storage";} DIV_CLASS("container") { @@ -58,8 +58,8 @@ class TStateStorageMonitoringActor : public TActorBootstrapped<TStateStorageMoni if (ProxyReplyTime.GetValue() != Max<ui64>()) { DIV_CLASS("row") {str << "Proxy reply time: " << ProxyReplyTime.ToString(); } } - - DIV_CLASS("CfgHash") {str << "Config hash: " << SelfConfigContentHash; } + + DIV_CLASS("CfgHash") {str << "Config hash: " << SelfConfigContentHash; } DIV_CLASS("row") {str << " ";} } @@ -73,7 +73,7 @@ class TStateStorageMonitoringActor : public TActorBootstrapped<TStateStorageMoni TABLEH() { str << "Locked";} TABLEH() { str << "Generation";} TABLEH() { str << "Reply time";} - TABLEH() { str << "CfgHash";} + TABLEH() { str << "CfgHash";} } } TABLEBODY() { @@ -81,32 +81,32 @@ class TStateStorageMonitoringActor : public TActorBootstrapped<TStateStorageMoni TABLER() { TABLED() {str << replica.ActorID.NodeId();} if (replica.ReplyTime.GetValue() == Max<ui64>()) { // general timeout - TABLED() { str << "timeout";} - TABLED() { str << "-"; } - TABLED() { str << "-"; } - TABLED() { str << "-"; } - TABLED() { str << "-"; } - TABLED() { str << "-"; } + TABLED() { str << "timeout";} + TABLED() { str << "-"; } + TABLED() { str << "-"; } + TABLED() { str << "-"; } + TABLED() { str << "-"; } + TABLED() { str << "-"; } } else if (replica.CurrentGeneration == Max<ui32>()) { - TABLED() { str << "not available";} - TABLED() { str << "-"; } - TABLED() { str << "-"; } - TABLED() { str << "-"; } - TABLED() { str << "-"; } - TABLED() { str << replica.ConfigContentHash; } + TABLED() { str << "not available";} + TABLED() { str << "-"; } + TABLED() { str << "-"; } + TABLED() { str << "-"; } + TABLED() { str << "-"; } + TABLED() { str << replica.ConfigContentHash; } } else { TABLED() {str << replica.CurrentLeader;} - TABLED() { + TABLED() { if (replica.Followers) for (auto &s : replica.Followers) - str << s << "; "; - else - str << "-"; - } - TABLED() { str << replica.Locked; } - TABLED() { str << replica.CurrentGeneration; } - TABLED() { str << (replica.ReplyTime - ReplicasRequestMoment); } - TABLED() { str << replica.ConfigContentHash; } + str << s << "; "; + else + str << "-"; + } + TABLED() { str << replica.Locked; } + TABLED() { str << replica.CurrentGeneration; } + TABLED() { str << (replica.ReplyTime - ReplicasRequestMoment); } + TABLED() { str << replica.ConfigContentHash; } } } } @@ -114,133 +114,133 @@ class TStateStorageMonitoringActor : public TActorBootstrapped<TStateStorageMoni } } - ctx.Send(Sender, new NMon::TEvHttpInfoRes(str.Str())); - return Die(ctx); - } - - void CheckCompletion(const TActorContext &ctx) { - if (WaitingForReplicas > 0) - return; - - return Reply("complete", ctx); - } - - void Handle(TEvStateStorage::TEvResolveReplicasList::TPtr &ev, const TActorContext &ctx) { + ctx.Send(Sender, new NMon::TEvHttpInfoRes(str.Str())); + return Die(ctx); + } + + void CheckCompletion(const TActorContext &ctx) { + if (WaitingForReplicas > 0) + return; + + return Reply("complete", ctx); + } + + void Handle(TEvStateStorage::TEvResolveReplicasList::TPtr &ev, const TActorContext &ctx) { const TVector<TActorId> &replicasList = ev->Get()->Replicas; - - if (replicasList.empty()) - return Reply("empty replica list", ctx); - - SelfConfigContentHash = ev->Get()->ConfigContentHash; - - ReplicasRequestMoment = ctx.Now(); - ProxyReplyTime = ReplicasRequestMoment - BeginMoment; - - ReplicasInfo.reserve(replicasList.size()); - for (ui64 cookie = 0, e = replicasList.size(); cookie < e; ++cookie) { + + if (replicasList.empty()) + return Reply("empty replica list", ctx); + + SelfConfigContentHash = ev->Get()->ConfigContentHash; + + ReplicasRequestMoment = ctx.Now(); + ProxyReplyTime = ReplicasRequestMoment - BeginMoment; + + ReplicasInfo.reserve(replicasList.size()); + for (ui64 cookie = 0, e = replicasList.size(); cookie < e; ++cookie) { const TActorId &replica = replicasList[cookie]; - ReplicasInfo.push_back(replica); - ctx.Send(replica, new TEvStateStorage::TEvReplicaLookup(TabletID, cookie)); - } - WaitingForReplicas = ReplicasInfo.size(); - - Become(&TThis::StateCollect); - } - - void Handle(TEvStateStorage::TEvReplicaInfo::TPtr &ev, const TActorContext &ctx) { - const NKikimrStateStorage::TEvInfo &record = ev->Get()->Record; - const ui64 cookie = record.GetCookie(); + ReplicasInfo.push_back(replica); + ctx.Send(replica, new TEvStateStorage::TEvReplicaLookup(TabletID, cookie)); + } + WaitingForReplicas = ReplicasInfo.size(); + + Become(&TThis::StateCollect); + } + + void Handle(TEvStateStorage::TEvReplicaInfo::TPtr &ev, const TActorContext &ctx) { + const NKikimrStateStorage::TEvInfo &record = ev->Get()->Record; + const ui64 cookie = record.GetCookie(); Y_VERIFY(cookie < ReplicasInfo.size()); - - auto &xinfo = ReplicasInfo[cookie]; - - if (xinfo.ReplyTime.GetValue() != Max<ui64>()) - return; - - xinfo.ReplyTime = ctx.Now(); - --WaitingForReplicas; - - if (record.GetStatus() == NKikimrProto::OK) { + + auto &xinfo = ReplicasInfo[cookie]; + + if (xinfo.ReplyTime.GetValue() != Max<ui64>()) + return; + + xinfo.ReplyTime = ctx.Now(); + --WaitingForReplicas; + + if (record.GetStatus() == NKikimrProto::OK) { if (record.HasCurrentLeader()) xinfo.CurrentLeader = ActorIdFromProto(record.GetCurrentLeader()); if (record.HasCurrentLeaderTablet()) xinfo.CurrentLeaderTablet = ActorIdFromProto(record.GetCurrentLeaderTablet()); - xinfo.CurrentGeneration = record.HasCurrentGeneration() ? record.GetCurrentGeneration() : 0; - xinfo.Locked = record.HasLocked() ? record.GetLocked() : false; - xinfo.LockedFor = record.HasLockedFor() ? record.GetLockedFor() : 0; - } - - xinfo.ConfigContentHash = record.GetConfigContentHash(); - return CheckCompletion(ctx); - } - - void HandleInit(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) { + xinfo.CurrentGeneration = record.HasCurrentGeneration() ? record.GetCurrentGeneration() : 0; + xinfo.Locked = record.HasLocked() ? record.GetLocked() : false; + xinfo.LockedFor = record.HasLockedFor() ? record.GetLockedFor() : 0; + } + + xinfo.ConfigContentHash = record.GetConfigContentHash(); + return CheckCompletion(ctx); + } + + void HandleInit(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) { Y_UNUSED(ev); - return Reply("unknown state storage", ctx); - } - - void HandleCollect(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) { - for (auto &x : ReplicasInfo) { - if (x.ActorID == ev->Sender) { - if (x.ReplyTime.GetValue() == Max<ui64>()) { - x.ReplyTime = ctx.Now(); - --WaitingForReplicas; - } - break; - } - } - - return CheckCompletion(ctx); - } - - void Timeout(const TActorContext &ctx) { - return Reply("timeout", ctx); - } - -public: + return Reply("unknown state storage", ctx); + } + + void HandleCollect(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) { + for (auto &x : ReplicasInfo) { + if (x.ActorID == ev->Sender) { + if (x.ReplyTime.GetValue() == Max<ui64>()) { + x.ReplyTime = ctx.Now(); + --WaitingForReplicas; + } + break; + } + } + + return CheckCompletion(ctx); + } + + void Timeout(const TActorContext &ctx) { + return Reply("timeout", ctx); + } + +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::SS_MON; } TStateStorageMonitoringActor(ui64 tabletId, const TActorId &sender, const TString &query) - : TabletID(tabletId) - , Sender(sender) - , Query(query) + : TabletID(tabletId) + , Sender(sender) + , Query(query) , ProxyReplyTime(TDuration::MicroSeconds(Max<ui64>())) - , WaitingForReplicas(0) + , WaitingForReplicas(0) {} - - void Bootstrap(const TActorContext &ctx) { - // try to send monitoring request to proxy - const ui64 stateStorageGroup = StateStorageGroupFromTabletID(TabletID); + + void Bootstrap(const TActorContext &ctx) { + // try to send monitoring request to proxy + const ui64 stateStorageGroup = StateStorageGroupFromTabletID(TabletID); const TActorId proxyActorID = MakeStateStorageProxyID(stateStorageGroup); - - BeginMoment = ctx.Now(); - - ctx.Send(proxyActorID, new TEvStateStorage::TEvResolveReplicas(TabletID), IEventHandle::FlagTrackDelivery); - ctx.Schedule(TDuration::Seconds(10), new TEvents::TEvWakeup()); // global timeout - Become(&TThis::StateInit); - } - - STFUNC(StateInit) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvStateStorage::TEvResolveReplicasList, Handle); - HFunc(TEvents::TEvUndelivered, HandleInit); - CFunc(TEvents::TEvWakeup::EventType, Timeout); - } - } - - STFUNC(StateCollect) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvStateStorage::TEvReplicaInfo, Handle); - HFunc(TEvents::TEvUndelivered, HandleCollect); - CFunc(TEvents::TEvWakeup::EventType, Timeout); - } - } -}; - + + BeginMoment = ctx.Now(); + + ctx.Send(proxyActorID, new TEvStateStorage::TEvResolveReplicas(TabletID), IEventHandle::FlagTrackDelivery); + ctx.Schedule(TDuration::Seconds(10), new TEvents::TEvWakeup()); // global timeout + Become(&TThis::StateInit); + } + + STFUNC(StateInit) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvStateStorage::TEvResolveReplicasList, Handle); + HFunc(TEvents::TEvUndelivered, HandleInit); + CFunc(TEvents::TEvWakeup::EventType, Timeout); + } + } + + STFUNC(StateCollect) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvStateStorage::TEvReplicaInfo, Handle); + HFunc(TEvents::TEvUndelivered, HandleCollect); + CFunc(TEvents::TEvWakeup::EventType, Timeout); + } + } +}; + IActor* CreateStateStorageMonitoringActor(ui64 targetTablet, const TActorId &sender, const TString &query) { - return new TStateStorageMonitoringActor(targetTablet, sender, query); -} - -} + return new TStateStorageMonitoringActor(targetTablet, sender, query); +} + +} diff --git a/ydb/core/base/statestorage_proxy.cpp b/ydb/core/base/statestorage_proxy.cpp index 969e31bb31..13d396cb0f 100644 --- a/ydb/core/base/statestorage_proxy.cpp +++ b/ydb/core/base/statestorage_proxy.cpp @@ -1,5 +1,5 @@ -#include "statestorage_impl.h" -#include "tabletid.h" +#include "statestorage_impl.h" +#include "tabletid.h" #include <ydb/core/base/compile_time_flags.h> #include <ydb/core/protos/services.pb.h> @@ -10,594 +10,594 @@ #include <library/cpp/actors/core/log.h> #include <library/cpp/actors/helpers/flow_controlled_queue.h> -#include <util/digest/city.h> -#include <util/generic/xrange.h> - -#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR || defined BLOG_TRACE -#error log macro definition clash -#endif - -#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) -#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) -#define BLOG_W(stream) LOG_WARN_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) -#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) -#define BLOG_TRACE(stream) LOG_TRACE_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) - -namespace NKikimr { - -// make configurable, here is no sense in too low ttl -const static ui64 StateStorageRequestTimeout = 30 * 1000 * 1000; - -class TStateStorageProxyRequest : public TActor<TStateStorageProxyRequest> { - TIntrusivePtr<TStateStorageInfo> Info; - TIntrusivePtr<TStateStorageInfo> FlowControlledInfo; - - const bool UseInterconnectSubscribes; - ui64 TabletID; - ui64 Cookie; - TEvStateStorage::TProxyOptions ProxyOptions; - ui32 SuggestedGeneration; - ui32 SuggestedStep; +#include <util/digest/city.h> +#include <util/generic/xrange.h> + +#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR || defined BLOG_TRACE +#error log macro definition clash +#endif + +#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) +#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) +#define BLOG_W(stream) LOG_WARN_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) +#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) +#define BLOG_TRACE(stream) LOG_TRACE_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) + +namespace NKikimr { + +// make configurable, here is no sense in too low ttl +const static ui64 StateStorageRequestTimeout = 30 * 1000 * 1000; + +class TStateStorageProxyRequest : public TActor<TStateStorageProxyRequest> { + TIntrusivePtr<TStateStorageInfo> Info; + TIntrusivePtr<TStateStorageInfo> FlowControlledInfo; + + const bool UseInterconnectSubscribes; + ui64 TabletID; + ui64 Cookie; + TEvStateStorage::TProxyOptions ProxyOptions; + ui32 SuggestedGeneration; + ui32 SuggestedStep; TActorId SuggestedLeader; TActorId SuggestedLeaderTablet; TActorId Source; - - ui32 Replicas; - THolder<TStateStorageInfo::TSelection> ReplicaSelection; - TArrayHolder<ui64> Signature; - - TStateStorageInfo::TSelection::EStatus ReplyStatus; - ui32 RepliesMerged; - ui32 RepliesAfterReply; - ui32 SignaturesMerged; - + + ui32 Replicas; + THolder<TStateStorageInfo::TSelection> ReplicaSelection; + TArrayHolder<ui64> Signature; + + TStateStorageInfo::TSelection::EStatus ReplyStatus; + ui32 RepliesMerged; + ui32 RepliesAfterReply; + ui32 SignaturesMerged; + TActorId ReplyLeader; TActorId ReplyLeaderTablet; - ui32 ReplyGeneration; - ui32 ReplyStep; - bool ReplyLocked; - ui64 ReplyLockedFor; - + ui32 ReplyGeneration; + ui32 ReplyStep; + bool ReplyLocked; + ui64 ReplyLockedFor; + TMap<TActorId, TActorId> Followers; - - void SelectRequestReplicas(TStateStorageInfo *info) { - THolder<TStateStorageInfo::TSelection> selection(new TStateStorageInfo::TSelection()); - info->SelectReplicas(TabletID, selection.Get()); - Replicas = selection->Sz; - ReplicaSelection = std::move(selection); - Signature.Reset(new ui64[Replicas]); - Fill(Signature.Get(), Signature.Get() + Replicas, 0); - } - - template<typename T> - void SendRequest(const T &op) { - Y_VERIFY(ReplicaSelection && ReplicaSelection->SelectedReplicas && ReplicaSelection->Sz); - - ui64 cookie = 0; - const ui32 sendFlags = IEventHandle::FlagTrackDelivery | (UseInterconnectSubscribes ? IEventHandle::FlagSubscribeOnSession : 0); - for (ui32 i = 0; i < ReplicaSelection->Sz; ++i, ++cookie) - Send(ReplicaSelection->SelectedReplicas[i], op(cookie), sendFlags, cookie); - } - - void PassAway() override { - if (UseInterconnectSubscribes && ReplicaSelection) { + + void SelectRequestReplicas(TStateStorageInfo *info) { + THolder<TStateStorageInfo::TSelection> selection(new TStateStorageInfo::TSelection()); + info->SelectReplicas(TabletID, selection.Get()); + Replicas = selection->Sz; + ReplicaSelection = std::move(selection); + Signature.Reset(new ui64[Replicas]); + Fill(Signature.Get(), Signature.Get() + Replicas, 0); + } + + template<typename T> + void SendRequest(const T &op) { + Y_VERIFY(ReplicaSelection && ReplicaSelection->SelectedReplicas && ReplicaSelection->Sz); + + ui64 cookie = 0; + const ui32 sendFlags = IEventHandle::FlagTrackDelivery | (UseInterconnectSubscribes ? IEventHandle::FlagSubscribeOnSession : 0); + for (ui32 i = 0; i < ReplicaSelection->Sz; ++i, ++cookie) + Send(ReplicaSelection->SelectedReplicas[i], op(cookie), sendFlags, cookie); + } + + void PassAway() override { + if (UseInterconnectSubscribes && ReplicaSelection) { const ui32 selfNode = SelfId().NodeId(); - for (ui32 i = 0; i < ReplicaSelection->Sz; ++i) { - const ui32 node = ReplicaSelection->SelectedReplicas[i].NodeId(); + for (ui32 i = 0; i < ReplicaSelection->Sz; ++i) { + const ui32 node = ReplicaSelection->SelectedReplicas[i].NodeId(); if (node != selfNode) { Send(TActivationContext::InterconnectProxy(node), new TEvents::TEvUnsubscribe()); } - } - } - - TActor::PassAway(); - } - - void Reply(NKikimrProto::EReplyStatus status) { + } + } + + TActor::PassAway(); + } + + void Reply(NKikimrProto::EReplyStatus status) { Send(Source, new TEvStateStorage::TEvInfo(status, TabletID, Cookie, ReplyLeader, ReplyLeaderTablet, ReplyGeneration, ReplyStep, ReplyLocked, ReplyLockedFor, Signature.Get(), Replicas, Followers)); - } - - void ReplyAndDie(NKikimrProto::EReplyStatus status) { - Reply(status); - PassAway(); - } - - void ReplyAndSig(NKikimrProto::EReplyStatus status) { - Reply(status); - if (ProxyOptions.SigWaitMode == ProxyOptions.SigAsync && RepliesMerged != Replicas) - Become(&TThis::StateUpdateSig); - else - PassAway(); - } - - struct TCloneUpdateEventOp { - const TEvStateStorage::TEvUpdate * const Ev; + } + + void ReplyAndDie(NKikimrProto::EReplyStatus status) { + Reply(status); + PassAway(); + } + + void ReplyAndSig(NKikimrProto::EReplyStatus status) { + Reply(status); + if (ProxyOptions.SigWaitMode == ProxyOptions.SigAsync && RepliesMerged != Replicas) + Become(&TThis::StateUpdateSig); + else + PassAway(); + } + + struct TCloneUpdateEventOp { + const TEvStateStorage::TEvUpdate * const Ev; const bool UpdateLeaderTablet; - mutable ui32 Idx; - - TCloneUpdateEventOp(const TEvStateStorage::TEvUpdate *ev) - : Ev(ev) + mutable ui32 Idx; + + TCloneUpdateEventOp(const TEvStateStorage::TEvUpdate *ev) + : Ev(ev) , UpdateLeaderTablet(!!ev->ProposedLeaderTablet) - , Idx(0) - {} - - IEventBase* operator()(ui64 cookie) const { - THolder<TEvStateStorage::TEvReplicaUpdate> req(new TEvStateStorage::TEvReplicaUpdate()); - req->Record.SetTabletID(Ev->TabletID); + , Idx(0) + {} + + IEventBase* operator()(ui64 cookie) const { + THolder<TEvStateStorage::TEvReplicaUpdate> req(new TEvStateStorage::TEvReplicaUpdate()); + req->Record.SetTabletID(Ev->TabletID); ActorIdToProto(Ev->ProposedLeader, req->Record.MutableProposedLeader()); - + if (UpdateLeaderTablet) ActorIdToProto(Ev->ProposedLeaderTablet, req->Record.MutableProposedLeaderTablet()); - - req->Record.SetProposedGeneration(Ev->ProposedGeneration); - req->Record.SetProposedStep(Ev->ProposedStep); - req->Record.SetSignature(Ev->Signature[Idx]); - - ++Idx; - req->Record.SetCookie(cookie); - - return req.Release(); - } - }; - - struct TCloneLockEventOp { - const TEvStateStorage::TEvLock * const Ev; - mutable ui32 Idx; - - TCloneLockEventOp(const TEvStateStorage::TEvLock *ev) - : Ev(ev) - , Idx(0) - {} - - IEventBase* operator()(ui64 cookie) const { - THolder<TEvStateStorage::TEvReplicaLock> req(new TEvStateStorage::TEvReplicaLock()); - req->Record.SetTabletID(Ev->TabletID); + + req->Record.SetProposedGeneration(Ev->ProposedGeneration); + req->Record.SetProposedStep(Ev->ProposedStep); + req->Record.SetSignature(Ev->Signature[Idx]); + + ++Idx; + req->Record.SetCookie(cookie); + + return req.Release(); + } + }; + + struct TCloneLockEventOp { + const TEvStateStorage::TEvLock * const Ev; + mutable ui32 Idx; + + TCloneLockEventOp(const TEvStateStorage::TEvLock *ev) + : Ev(ev) + , Idx(0) + {} + + IEventBase* operator()(ui64 cookie) const { + THolder<TEvStateStorage::TEvReplicaLock> req(new TEvStateStorage::TEvReplicaLock()); + req->Record.SetTabletID(Ev->TabletID); ActorIdToProto(Ev->ProposedLeader, req->Record.MutableProposedLeader()); - req->Record.SetProposedGeneration(Ev->ProposedGeneration); - req->Record.SetSignature(Ev->Signature[Idx]); - - ++Idx; - req->Record.SetCookie(cookie); - - return req.Release(); - } - }; - - void MergeNodeError(ui32 node) { - ui64 cookie = 0; - for (ui32 i = 0; i < ReplicaSelection->Sz; ++i, ++cookie) { - const ui32 replicaNode = ReplicaSelection->SelectedReplicas[i].NodeId(); - if (replicaNode == node) - MergeConnectionError(cookie); - } - } - - void MergeConnectionError(ui64 cookie) { + req->Record.SetProposedGeneration(Ev->ProposedGeneration); + req->Record.SetSignature(Ev->Signature[Idx]); + + ++Idx; + req->Record.SetCookie(cookie); + + return req.Release(); + } + }; + + void MergeNodeError(ui32 node) { + ui64 cookie = 0; + for (ui32 i = 0; i < ReplicaSelection->Sz; ++i, ++cookie) { + const ui32 replicaNode = ReplicaSelection->SelectedReplicas[i].NodeId(); + if (replicaNode == node) + MergeConnectionError(cookie); + } + } + + void MergeConnectionError(ui64 cookie) { Y_VERIFY(cookie < Replicas); - - if (Signature[cookie] == 0) { - Signature[cookie] = Max<ui64>(); - ++RepliesMerged; - - ReplicaSelection->MergeReply(TStateStorageInfo::TSelection::StatusNoInfo, &ReplyStatus, cookie, false); - } - } - - void MergeReply(TEvStateStorage::TEvReplicaInfo *ev) { - const auto &record = ev->Record; - const NKikimrProto::EReplyStatus status = record.GetStatus(); - const ui64 cookie = record.GetCookie(); - - Y_VERIFY(cookie < Replicas); - Y_VERIFY(Signature[cookie] == 0 || Signature[cookie] == Max<ui64>()); - Signature[cookie] = ev->Record.GetSignature(); - ++RepliesMerged; - ++SignaturesMerged; - - if (status == NKikimrProto::OK) { - const ui32 gen = record.GetCurrentGeneration(); - const ui32 step = record.GetCurrentStep(); + + if (Signature[cookie] == 0) { + Signature[cookie] = Max<ui64>(); + ++RepliesMerged; + + ReplicaSelection->MergeReply(TStateStorageInfo::TSelection::StatusNoInfo, &ReplyStatus, cookie, false); + } + } + + void MergeReply(TEvStateStorage::TEvReplicaInfo *ev) { + const auto &record = ev->Record; + const NKikimrProto::EReplyStatus status = record.GetStatus(); + const ui64 cookie = record.GetCookie(); + + Y_VERIFY(cookie < Replicas); + Y_VERIFY(Signature[cookie] == 0 || Signature[cookie] == Max<ui64>()); + Signature[cookie] = ev->Record.GetSignature(); + ++RepliesMerged; + ++SignaturesMerged; + + if (status == NKikimrProto::OK) { + const ui32 gen = record.GetCurrentGeneration(); + const ui32 step = record.GetCurrentStep(); const TActorId leader = ActorIdFromProto(record.GetCurrentLeader()); - + if (gen < ReplyGeneration || (gen == ReplyGeneration && step < ReplyStep)) { - ReplicaSelection->MergeReply(TStateStorageInfo::TSelection::StatusOutdated, &ReplyStatus, cookie, false); - } else { + ReplicaSelection->MergeReply(TStateStorageInfo::TSelection::StatusOutdated, &ReplyStatus, cookie, false); + } else { const bool reset = gen > ReplyGeneration || step > ReplyStep || leader != ReplyLeader; const TActorId replyLeaderTablet = ActorIdFromProto(record.GetCurrentLeaderTablet()); - - ReplyGeneration = gen; - ReplyStep = step; - + + ReplyGeneration = gen; + ReplyStep = step; + if (ReplyLeader != leader) { ReplyLeader = leader; ReplyLeaderTablet = replyLeaderTablet; } else if (!ReplyLeaderTablet) { ReplyLeaderTablet = replyLeaderTablet; - } else { + } else { Y_VERIFY(ReplyLeaderTablet == replyLeaderTablet || !replyLeaderTablet); - } - - // todo: accurate handling of locked flag - ReplyLocked = (reset ? false : ReplyLocked) || record.GetLocked(); - ReplyLockedFor = reset ? record.GetLockedFor() : Max(ReplyLockedFor, record.GetLockedFor()); - - ReplicaSelection->MergeReply(TStateStorageInfo::TSelection::StatusOk, &ReplyStatus, cookie, reset); - } - } else if (status == NKikimrProto::ERROR) { - ReplicaSelection->MergeReply(TStateStorageInfo::TSelection::StatusNoInfo, &ReplyStatus, cookie, false); - } else { + } + + // todo: accurate handling of locked flag + ReplyLocked = (reset ? false : ReplyLocked) || record.GetLocked(); + ReplyLockedFor = reset ? record.GetLockedFor() : Max(ReplyLockedFor, record.GetLockedFor()); + + ReplicaSelection->MergeReply(TStateStorageInfo::TSelection::StatusOk, &ReplyStatus, cookie, reset); + } + } else if (status == NKikimrProto::ERROR) { + ReplicaSelection->MergeReply(TStateStorageInfo::TSelection::StatusNoInfo, &ReplyStatus, cookie, false); + } else { Y_FAIL(); - } - + } + for (ui32 i = 0, end = record.FollowerSize(); i < end; ++i) { Followers[ActorIdFromProto(record.GetFollower(i))] = ActorIdFromProto(record.GetFollowerTablet(i)); - } - } - - template<typename TEv> - void PrepareInit(TEv *ev, bool allowFlowControlled) { - TabletID = ev->TabletID; - Cookie = ev->Cookie; - ProxyOptions = ev->ProxyOptions; - - if (allowFlowControlled && FlowControlledInfo.Get() && KIKIMR_ALLOW_FLOWCONTROLLED_QUEUE_FOR_SSLOOKUP) - SelectRequestReplicas(FlowControlledInfo.Get()); - else - SelectRequestReplicas(Info.Get()); - } - - // request setup - - void HandleInit(TEvStateStorage::TEvLookup::TPtr &ev) { - TEvStateStorage::TEvLookup *msg = ev->Get(); - BLOG_D("ProxyRequest::HandleInit ev: " << msg->ToString()); - Source = ev->Sender; - - PrepareInit(msg, true); - SendRequest([this](ui64 cookie) { return new TEvStateStorage::TEvReplicaLookup(TabletID, cookie); }); - - Become(&TThis::StateLookup, TDuration::MicroSeconds(StateStorageRequestTimeout), new TEvents::TEvWakeup()); - } - - void HandleInit(TEvStateStorage::TEvUpdate::TPtr &ev) { - TEvStateStorage::TEvUpdate *msg = ev->Get(); - BLOG_D("ProxyRequest::HandleInit ev: %s" << msg->ToString()); - Source = ev->Sender; - - PrepareInit(msg, false); - + } + } + + template<typename TEv> + void PrepareInit(TEv *ev, bool allowFlowControlled) { + TabletID = ev->TabletID; + Cookie = ev->Cookie; + ProxyOptions = ev->ProxyOptions; + + if (allowFlowControlled && FlowControlledInfo.Get() && KIKIMR_ALLOW_FLOWCONTROLLED_QUEUE_FOR_SSLOOKUP) + SelectRequestReplicas(FlowControlledInfo.Get()); + else + SelectRequestReplicas(Info.Get()); + } + + // request setup + + void HandleInit(TEvStateStorage::TEvLookup::TPtr &ev) { + TEvStateStorage::TEvLookup *msg = ev->Get(); + BLOG_D("ProxyRequest::HandleInit ev: " << msg->ToString()); + Source = ev->Sender; + + PrepareInit(msg, true); + SendRequest([this](ui64 cookie) { return new TEvStateStorage::TEvReplicaLookup(TabletID, cookie); }); + + Become(&TThis::StateLookup, TDuration::MicroSeconds(StateStorageRequestTimeout), new TEvents::TEvWakeup()); + } + + void HandleInit(TEvStateStorage::TEvUpdate::TPtr &ev) { + TEvStateStorage::TEvUpdate *msg = ev->Get(); + BLOG_D("ProxyRequest::HandleInit ev: %s" << msg->ToString()); + Source = ev->Sender; + + PrepareInit(msg, false); + SuggestedLeader = msg->ProposedLeader; SuggestedLeaderTablet = msg->ProposedLeaderTablet; - SuggestedGeneration = msg->ProposedGeneration; - SuggestedStep = msg->ProposedStep; - - if (msg->SignatureSz == Replicas) { - TCloneUpdateEventOp op(msg); - SendRequest(op); - Become(&TThis::StateUpdate, TDuration::MicroSeconds(StateStorageRequestTimeout), new TEvents::TEvWakeup()); - } else { - // wrong signature, reply with no-info (but correct signature count) - ReplyAndDie(NKikimrProto::ERROR); - } - } - - void HandleInit(TEvStateStorage::TEvLock::TPtr &ev) { - TEvStateStorage::TEvLock *msg = ev->Get(); - BLOG_D("ProxyRequest::HandleInit ev: " << msg->ToString()); - Source = ev->Sender; - - PrepareInit(msg, false); - + SuggestedGeneration = msg->ProposedGeneration; + SuggestedStep = msg->ProposedStep; + + if (msg->SignatureSz == Replicas) { + TCloneUpdateEventOp op(msg); + SendRequest(op); + Become(&TThis::StateUpdate, TDuration::MicroSeconds(StateStorageRequestTimeout), new TEvents::TEvWakeup()); + } else { + // wrong signature, reply with no-info (but correct signature count) + ReplyAndDie(NKikimrProto::ERROR); + } + } + + void HandleInit(TEvStateStorage::TEvLock::TPtr &ev) { + TEvStateStorage::TEvLock *msg = ev->Get(); + BLOG_D("ProxyRequest::HandleInit ev: " << msg->ToString()); + Source = ev->Sender; + + PrepareInit(msg, false); + SuggestedLeader = msg->ProposedLeader; - SuggestedGeneration = msg->ProposedGeneration; - SuggestedStep = 0; - - if (msg->SignatureSz == Replicas) { - TCloneLockEventOp op(msg); - SendRequest(op); - Become(&TThis::StateUpdate, TDuration::MicroSeconds(StateStorageRequestTimeout), new TEvents::TEvWakeup()); - } else { // wrong signature, reply with no-info (but correct signature count) - ReplyAndDie(NKikimrProto::ERROR); - } - } - - // lookup handling - - void HandleLookupTimeout() { - BLOG_D("ProxyRequest::HandleLookupTimeout"); - switch (ReplyStatus) { - case TStateStorageInfo::TSelection::StatusUnknown: - ReplyAndDie(NKikimrProto::TIMEOUT); - return; - case TStateStorageInfo::TSelection::StatusOk: - ReplyAndDie(NKikimrProto::OK); - return; - case TStateStorageInfo::TSelection::StatusNoInfo: - ReplyAndDie(NKikimrProto::ERROR); - return; - case TStateStorageInfo::TSelection::StatusOutdated: - ReplyAndDie(NKikimrProto::RACE); - return; - } + SuggestedGeneration = msg->ProposedGeneration; + SuggestedStep = 0; + + if (msg->SignatureSz == Replicas) { + TCloneLockEventOp op(msg); + SendRequest(op); + Become(&TThis::StateUpdate, TDuration::MicroSeconds(StateStorageRequestTimeout), new TEvents::TEvWakeup()); + } else { // wrong signature, reply with no-info (but correct signature count) + ReplyAndDie(NKikimrProto::ERROR); + } + } + + // lookup handling + + void HandleLookupTimeout() { + BLOG_D("ProxyRequest::HandleLookupTimeout"); + switch (ReplyStatus) { + case TStateStorageInfo::TSelection::StatusUnknown: + ReplyAndDie(NKikimrProto::TIMEOUT); + return; + case TStateStorageInfo::TSelection::StatusOk: + ReplyAndDie(NKikimrProto::OK); + return; + case TStateStorageInfo::TSelection::StatusNoInfo: + ReplyAndDie(NKikimrProto::ERROR); + return; + case TStateStorageInfo::TSelection::StatusOutdated: + ReplyAndDie(NKikimrProto::RACE); + return; + } Y_VERIFY_DEBUG(false); - PassAway(); - } - - void CheckLookupReply() { - const ui32 majority = (Replicas / 2 + 1); - const bool allowReply = ProxyOptions.SigWaitMode == ProxyOptions.SigNone - || (ProxyOptions.SigWaitMode == ProxyOptions.SigAsync && SignaturesMerged >= majority) - || RepliesMerged == Replicas; - - if (allowReply) { - switch (ReplyStatus) { - case TStateStorageInfo::TSelection::StatusUnknown: - return; // not yet ready, do nothing - case TStateStorageInfo::TSelection::StatusOk: - ReplyAndSig(NKikimrProto::OK); - return; - case TStateStorageInfo::TSelection::StatusNoInfo: - if (RepliesMerged == Replicas) // for negative response always waits for full reply set to avoid herding of good replicas by fast retry cycle - ReplyAndSig(NKikimrProto::ERROR); - return; - case TStateStorageInfo::TSelection::StatusOutdated: - ReplyAndSig(NKikimrProto::RACE); - return; - } - } - } - - void HandleLookup(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) { - BLOG_D("ProxyRequest::HandleLookup ev: " << ev->Get()->ToString()); - const ui32 node = ev->Get()->NodeId; - MergeNodeError(node); - CheckLookupReply(); - } - - void HandleLookup(TEvents::TEvUndelivered::TPtr &ev) { - BLOG_D("ProxyRequest::HandleLookup ev: " << ev->Get()->ToString()); - const ui64 cookie = ev->Cookie; - MergeConnectionError(cookie); - CheckLookupReply(); - } - - void HandleLookup(TEvStateStorage::TEvReplicaInfo::TPtr &ev) { - BLOG_D("ProxyRequest::HandleLookup ev: " << ev->Get()->ToString()); - TEvStateStorage::TEvReplicaInfo *msg = ev->Get(); - MergeReply(msg); - CheckLookupReply(); - } - - // update handling - - void HandleUpdateTimeout() { - BLOG_D("ProxyRequest::HandleUpdateTimeout"); - switch (ReplyStatus) { - case TStateStorageInfo::TSelection::StatusUnknown: - ReplyAndDie(NKikimrProto::TIMEOUT); - return; - case TStateStorageInfo::TSelection::StatusOk: - { + PassAway(); + } + + void CheckLookupReply() { + const ui32 majority = (Replicas / 2 + 1); + const bool allowReply = ProxyOptions.SigWaitMode == ProxyOptions.SigNone + || (ProxyOptions.SigWaitMode == ProxyOptions.SigAsync && SignaturesMerged >= majority) + || RepliesMerged == Replicas; + + if (allowReply) { + switch (ReplyStatus) { + case TStateStorageInfo::TSelection::StatusUnknown: + return; // not yet ready, do nothing + case TStateStorageInfo::TSelection::StatusOk: + ReplyAndSig(NKikimrProto::OK); + return; + case TStateStorageInfo::TSelection::StatusNoInfo: + if (RepliesMerged == Replicas) // for negative response always waits for full reply set to avoid herding of good replicas by fast retry cycle + ReplyAndSig(NKikimrProto::ERROR); + return; + case TStateStorageInfo::TSelection::StatusOutdated: + ReplyAndSig(NKikimrProto::RACE); + return; + } + } + } + + void HandleLookup(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) { + BLOG_D("ProxyRequest::HandleLookup ev: " << ev->Get()->ToString()); + const ui32 node = ev->Get()->NodeId; + MergeNodeError(node); + CheckLookupReply(); + } + + void HandleLookup(TEvents::TEvUndelivered::TPtr &ev) { + BLOG_D("ProxyRequest::HandleLookup ev: " << ev->Get()->ToString()); + const ui64 cookie = ev->Cookie; + MergeConnectionError(cookie); + CheckLookupReply(); + } + + void HandleLookup(TEvStateStorage::TEvReplicaInfo::TPtr &ev) { + BLOG_D("ProxyRequest::HandleLookup ev: " << ev->Get()->ToString()); + TEvStateStorage::TEvReplicaInfo *msg = ev->Get(); + MergeReply(msg); + CheckLookupReply(); + } + + // update handling + + void HandleUpdateTimeout() { + BLOG_D("ProxyRequest::HandleUpdateTimeout"); + switch (ReplyStatus) { + case TStateStorageInfo::TSelection::StatusUnknown: + ReplyAndDie(NKikimrProto::TIMEOUT); + return; + case TStateStorageInfo::TSelection::StatusOk: + { const bool race = (ReplyLeader != SuggestedLeader || ReplyGeneration != SuggestedGeneration); - const NKikimrProto::EReplyStatus status = race ? NKikimrProto::RACE : NKikimrProto::OK; - ReplyAndDie(status); - } - return; - case TStateStorageInfo::TSelection::StatusNoInfo: - ReplyAndDie(NKikimrProto::ERROR); - return; - case TStateStorageInfo::TSelection::StatusOutdated: - ReplyAndDie(NKikimrProto::RACE); - return; - } + const NKikimrProto::EReplyStatus status = race ? NKikimrProto::RACE : NKikimrProto::OK; + ReplyAndDie(status); + } + return; + case TStateStorageInfo::TSelection::StatusNoInfo: + ReplyAndDie(NKikimrProto::ERROR); + return; + case TStateStorageInfo::TSelection::StatusOutdated: + ReplyAndDie(NKikimrProto::RACE); + return; + } Y_VERIFY_DEBUG(false); - PassAway(); - } - - void CheckUpdateReply() { - const bool allowReply = ProxyOptions.SigWaitMode != ProxyOptions.SigSync || RepliesMerged == Replicas; - - if (allowReply) { - switch (ReplyStatus) { - case TStateStorageInfo::TSelection::StatusUnknown: - return; - case TStateStorageInfo::TSelection::StatusOk: - { + PassAway(); + } + + void CheckUpdateReply() { + const bool allowReply = ProxyOptions.SigWaitMode != ProxyOptions.SigSync || RepliesMerged == Replicas; + + if (allowReply) { + switch (ReplyStatus) { + case TStateStorageInfo::TSelection::StatusUnknown: + return; + case TStateStorageInfo::TSelection::StatusOk: + { const bool race = (ReplyLeader != SuggestedLeader || ReplyGeneration != SuggestedGeneration); // step overrun is consumed - const NKikimrProto::EReplyStatus status = race ? NKikimrProto::RACE : NKikimrProto::OK; - ReplyAndSig(status); - } - return; - case TStateStorageInfo::TSelection::StatusNoInfo: - // should not happens for update queries - ReplyAndSig(NKikimrProto::ERROR); - return; - case TStateStorageInfo::TSelection::StatusOutdated: - ReplyAndSig(NKikimrProto::RACE); - return; - } - } - } - - void HandleUpdate(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) { - BLOG_D("ProxyRequest::HandleUpdate ev: " << ev->Get()->ToString()); - const ui32 node = ev->Get()->NodeId; - MergeNodeError(node); - CheckUpdateReply(); - } - - void HandleUpdate(TEvents::TEvUndelivered::TPtr &ev) { - BLOG_D("ProxyRequest::HandleUpdate ev: " << ev->Get()->ToString()); - const ui64 cookie = ev->Cookie; - MergeConnectionError(cookie); - CheckUpdateReply(); - } - - void HandleUpdate(TEvStateStorage::TEvReplicaInfo::TPtr &ev) { - BLOG_D("ProxyRequest::HandleUpdate ev: " << ev->Get()->ToString()); - TEvStateStorage::TEvReplicaInfo *msg = ev->Get(); - MergeReply(msg); - CheckUpdateReply(); - } - - // async wait for full signature - - void MergeSigNodeError(ui32 node) { - for (ui32 i = 0; i < ReplicaSelection->Sz; ++i) { - const ui32 replicaNode = ReplicaSelection->SelectedReplicas[i].NodeId(); - if (replicaNode == node) { - if (Signature[i] == 0) { - Signature[i] = Max<ui64>(); - ++RepliesAfterReply; - } - } - } - } - - void UpdateSigFor(ui64 cookie, ui64 sig) { + const NKikimrProto::EReplyStatus status = race ? NKikimrProto::RACE : NKikimrProto::OK; + ReplyAndSig(status); + } + return; + case TStateStorageInfo::TSelection::StatusNoInfo: + // should not happens for update queries + ReplyAndSig(NKikimrProto::ERROR); + return; + case TStateStorageInfo::TSelection::StatusOutdated: + ReplyAndSig(NKikimrProto::RACE); + return; + } + } + } + + void HandleUpdate(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) { + BLOG_D("ProxyRequest::HandleUpdate ev: " << ev->Get()->ToString()); + const ui32 node = ev->Get()->NodeId; + MergeNodeError(node); + CheckUpdateReply(); + } + + void HandleUpdate(TEvents::TEvUndelivered::TPtr &ev) { + BLOG_D("ProxyRequest::HandleUpdate ev: " << ev->Get()->ToString()); + const ui64 cookie = ev->Cookie; + MergeConnectionError(cookie); + CheckUpdateReply(); + } + + void HandleUpdate(TEvStateStorage::TEvReplicaInfo::TPtr &ev) { + BLOG_D("ProxyRequest::HandleUpdate ev: " << ev->Get()->ToString()); + TEvStateStorage::TEvReplicaInfo *msg = ev->Get(); + MergeReply(msg); + CheckUpdateReply(); + } + + // async wait for full signature + + void MergeSigNodeError(ui32 node) { + for (ui32 i = 0; i < ReplicaSelection->Sz; ++i) { + const ui32 replicaNode = ReplicaSelection->SelectedReplicas[i].NodeId(); + if (replicaNode == node) { + if (Signature[i] == 0) { + Signature[i] = Max<ui64>(); + ++RepliesAfterReply; + } + } + } + } + + void UpdateSigFor(ui64 cookie, ui64 sig) { + Y_VERIFY(cookie < Replicas); + + if (Signature[cookie] == 0) { + Signature[cookie] = sig; + ++RepliesAfterReply; + ++SignaturesMerged; + + if (RepliesMerged + RepliesAfterReply == Replicas) { + Send(Source, new TEvStateStorage::TEvUpdateSignature(TabletID, Signature.Get(), Replicas)); + return PassAway(); + } + } + } + + void HandleUpdateSig(TEvents::TEvUndelivered::TPtr &ev) { + const ui64 cookie = ev->Cookie; + BLOG_D("ProxyRequest::HandleUpdateSig undelivered for: " << cookie); + + return UpdateSigFor(cookie, Max<ui64>()); + } + + void HandleUpdateSig(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) { + const ui32 node = ev->Get()->NodeId; + BLOG_D("ProxyRequest::HandleUpdateSig node disconnected: " << node); + + MergeSigNodeError(node); + + if (RepliesMerged + RepliesAfterReply == Replicas) { + Send(Source, new TEvStateStorage::TEvUpdateSignature(TabletID, Signature.Get(), Replicas)); + return PassAway(); + } + } + + void HandleUpdateSig(TEvStateStorage::TEvReplicaInfo::TPtr &ev) { + BLOG_D("ProxyRequest::HandleUpdateSig ev: " << ev->Get()->ToString()); + + TEvStateStorage::TEvReplicaInfo *msg = ev->Get(); + const ui64 cookie = msg->Record.GetCookie(); Y_VERIFY(cookie < Replicas); - - if (Signature[cookie] == 0) { - Signature[cookie] = sig; - ++RepliesAfterReply; - ++SignaturesMerged; - - if (RepliesMerged + RepliesAfterReply == Replicas) { - Send(Source, new TEvStateStorage::TEvUpdateSignature(TabletID, Signature.Get(), Replicas)); - return PassAway(); - } - } - } - - void HandleUpdateSig(TEvents::TEvUndelivered::TPtr &ev) { - const ui64 cookie = ev->Cookie; - BLOG_D("ProxyRequest::HandleUpdateSig undelivered for: " << cookie); - - return UpdateSigFor(cookie, Max<ui64>()); - } - - void HandleUpdateSig(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) { - const ui32 node = ev->Get()->NodeId; - BLOG_D("ProxyRequest::HandleUpdateSig node disconnected: " << node); - - MergeSigNodeError(node); - - if (RepliesMerged + RepliesAfterReply == Replicas) { - Send(Source, new TEvStateStorage::TEvUpdateSignature(TabletID, Signature.Get(), Replicas)); - return PassAway(); - } - } - - void HandleUpdateSig(TEvStateStorage::TEvReplicaInfo::TPtr &ev) { - BLOG_D("ProxyRequest::HandleUpdateSig ev: " << ev->Get()->ToString()); - - TEvStateStorage::TEvReplicaInfo *msg = ev->Get(); - const ui64 cookie = msg->Record.GetCookie(); - Y_VERIFY(cookie < Replicas); - Y_VERIFY(Signature[cookie] == 0 || Signature[cookie] == Max<ui64>()); - - return UpdateSigFor(cookie, msg->Record.GetSignature()); - } - - void HandleUpdateSigTimeout() { - BLOG_D("ProxyRequest::HandleUpdateSigTimeout RepliesAfterReply# " << (ui32)RepliesAfterReply); - if (RepliesAfterReply > 0) - Send(Source, new TEvStateStorage::TEvUpdateSignature(TabletID, Signature.Get(), Replicas)); - PassAway(); - } - -public: + Y_VERIFY(Signature[cookie] == 0 || Signature[cookie] == Max<ui64>()); + + return UpdateSigFor(cookie, msg->Record.GetSignature()); + } + + void HandleUpdateSigTimeout() { + BLOG_D("ProxyRequest::HandleUpdateSigTimeout RepliesAfterReply# " << (ui32)RepliesAfterReply); + if (RepliesAfterReply > 0) + Send(Source, new TEvStateStorage::TEvUpdateSignature(TabletID, Signature.Get(), Replicas)); + PassAway(); + } + +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::SS_PROXY_REQUEST; } - TStateStorageProxyRequest(const TIntrusivePtr<TStateStorageInfo> &info, const TIntrusivePtr<TStateStorageInfo> &flowControlledInfo) - : TActor(&TThis::StateInit) - , Info(info) - , FlowControlledInfo(flowControlledInfo) + TStateStorageProxyRequest(const TIntrusivePtr<TStateStorageInfo> &info, const TIntrusivePtr<TStateStorageInfo> &flowControlledInfo) + : TActor(&TThis::StateInit) + , Info(info) + , FlowControlledInfo(flowControlledInfo) , UseInterconnectSubscribes(true) - , TabletID(0) - , Cookie(0) - , SuggestedGeneration(0) - , SuggestedStep(0) + , TabletID(0) + , Cookie(0) + , SuggestedGeneration(0) + , SuggestedStep(0) , Replicas(0) - , ReplyStatus(TStateStorageInfo::TSelection::StatusUnknown) - , RepliesMerged(0) - , RepliesAfterReply(0) - , SignaturesMerged(0) - , ReplyGeneration(0) - , ReplyStep(0) - , ReplyLocked(false) - , ReplyLockedFor(0) + , ReplyStatus(TStateStorageInfo::TSelection::StatusUnknown) + , RepliesMerged(0) + , RepliesAfterReply(0) + , SignaturesMerged(0) + , ReplyGeneration(0) + , ReplyStep(0) + , ReplyLocked(false) + , ReplyLockedFor(0) {} - - STATEFN(StateInit) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvLookup, HandleInit); - hFunc(TEvStateStorage::TEvUpdate, HandleInit); - hFunc(TEvStateStorage::TEvLock, HandleInit); + + STATEFN(StateInit) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvLookup, HandleInit); + hFunc(TEvStateStorage::TEvUpdate, HandleInit); + hFunc(TEvStateStorage::TEvLock, HandleInit); default: - BLOG_W("ProxyRequest::StateInit unexpected event type# " + BLOG_W("ProxyRequest::StateInit unexpected event type# " << ev->GetTypeRewrite() << " event: " << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?")); break; - } - } - - // main lookup - - STATEFN(StateLookup) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvReplicaInfo, HandleLookup); - hFunc(TEvents::TEvUndelivered, HandleLookup); + } + } + + // main lookup + + STATEFN(StateLookup) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvReplicaInfo, HandleLookup); + hFunc(TEvents::TEvUndelivered, HandleLookup); IgnoreFunc(TEvInterconnect::TEvNodeConnected); - hFunc(TEvInterconnect::TEvNodeDisconnected, HandleLookup); - cFunc(TEvents::TSystem::Wakeup, HandleLookupTimeout); + hFunc(TEvInterconnect::TEvNodeDisconnected, HandleLookup); + cFunc(TEvents::TSystem::Wakeup, HandleLookupTimeout); default: - BLOG_W("ProxyRequest::StateLookup unexpected event type# " + BLOG_W("ProxyRequest::StateLookup unexpected event type# " << ev->GetTypeRewrite() << " event: " << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?")); break; - } - } - - // both update and lock - STATEFN(StateUpdate) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvReplicaInfo, HandleUpdate); - hFunc(TEvents::TEvUndelivered, HandleUpdate); + } + } + + // both update and lock + STATEFN(StateUpdate) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvReplicaInfo, HandleUpdate); + hFunc(TEvents::TEvUndelivered, HandleUpdate); IgnoreFunc(TEvInterconnect::TEvNodeConnected); - hFunc(TEvInterconnect::TEvNodeDisconnected, HandleUpdate); - cFunc(TEvents::TSystem::Wakeup, HandleUpdateTimeout); + hFunc(TEvInterconnect::TEvNodeDisconnected, HandleUpdate); + cFunc(TEvents::TSystem::Wakeup, HandleUpdateTimeout); default: - BLOG_W("ProxyRequest::StateUpdate unexpected event type# " + BLOG_W("ProxyRequest::StateUpdate unexpected event type# " << ev->GetTypeRewrite() << " event: " << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?")); break; - } - } - - // already replied, async signature update - STATEFN(StateUpdateSig) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvReplicaInfo, HandleUpdateSig); - hFunc(TEvents::TEvUndelivered, HandleUpdateSig); + } + } + + // already replied, async signature update + STATEFN(StateUpdateSig) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvReplicaInfo, HandleUpdateSig); + hFunc(TEvents::TEvUndelivered, HandleUpdateSig); IgnoreFunc(TEvInterconnect::TEvNodeConnected); - hFunc(TEvInterconnect::TEvNodeDisconnected, HandleUpdateSig); - cFunc(TEvents::TSystem::Wakeup, HandleUpdateSigTimeout); + hFunc(TEvInterconnect::TEvNodeDisconnected, HandleUpdateSig); + cFunc(TEvents::TSystem::Wakeup, HandleUpdateSigTimeout); default: - BLOG_W("ProxyRequest::StateUpdateSig unexpected event type# " + BLOG_W("ProxyRequest::StateUpdateSig unexpected event type# " << ev->GetTypeRewrite() << " event: " << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?")); break; - } - } -}; - + } + } +}; + class TStateStorageDumpRequest : public TActorBootstrapped<TStateStorageDumpRequest> { protected: const TActorId Sender; @@ -617,51 +617,51 @@ public: , UndeliveredCount(0) {} - void SendResponse() { - Send(Sender, Response.Release()); - PassAway(); + void SendResponse() { + Send(Sender, Response.Release()); + PassAway(); } - void Bootstrap() { + void Bootstrap() { Response = new TEvStateStorage::TEvResponseReplicasDumps(); - AllReplicas = Info->SelectAllReplicas(); + AllReplicas = Info->SelectAllReplicas(); if (!AllReplicas.empty()) { Response->ReplicasDumps.reserve(AllReplicas.size()); for (const TActorId &replica : AllReplicas) { - Send(replica, new TEvStateStorage::TEvReplicaDumpRequest(), IEventHandle::FlagTrackDelivery); + Send(replica, new TEvStateStorage::TEvReplicaDumpRequest(), IEventHandle::FlagTrackDelivery); } - Schedule(TDuration::Seconds(60), new TEvents::TEvWakeup()); + Schedule(TDuration::Seconds(60), new TEvents::TEvWakeup()); Become(&TThis::StateRequestedDumps); } else { - SendResponse(); + SendResponse(); } } - STATEFN(StateRequestedDumps) { + STATEFN(StateRequestedDumps) { switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvReplicaDump, Handle); - hFunc(TEvents::TEvUndelivered, Undelivered); - cFunc(TEvents::TSystem::Wakeup, Timeout); + hFunc(TEvStateStorage::TEvReplicaDump, Handle); + hFunc(TEvents::TEvUndelivered, Undelivered); + cFunc(TEvents::TSystem::Wakeup, Timeout); } } - void OnResponseReceived() { + void OnResponseReceived() { if (Response->ReplicasDumps.size() + UndeliveredCount >= AllReplicas.size()) - SendResponse(); + SendResponse(); } - void Undelivered(TEvents::TEvUndelivered::TPtr &) { + void Undelivered(TEvents::TEvUndelivered::TPtr &) { ++UndeliveredCount; - OnResponseReceived(); + OnResponseReceived(); } - void Handle(TEvStateStorage::TEvReplicaDump::TPtr &ev) { + void Handle(TEvStateStorage::TEvReplicaDump::TPtr &ev) { Response->ReplicasDumps.emplace_back(std::make_pair(ev->Sender, ev->Release())); - OnResponseReceived(); + OnResponseReceived(); } - void Timeout() { - SendResponse(); + void Timeout() { + SendResponse(); } }; @@ -687,85 +687,85 @@ public: , TabletID(tabletId) {} - void SendResponse() { - Send(Sender, new TEvStateStorage::TEvDeleteResult(TabletID, Count > AllReplicas.size() / 2 ? NKikimrProto::OK : NKikimrProto::ERROR)); - PassAway(); + void SendResponse() { + Send(Sender, new TEvStateStorage::TEvDeleteResult(TabletID, Count > AllReplicas.size() / 2 ? NKikimrProto::OK : NKikimrProto::ERROR)); + PassAway(); } - void Bootstrap() { - AllReplicas = Info->SelectAllReplicas(); + void Bootstrap() { + AllReplicas = Info->SelectAllReplicas(); if (!AllReplicas.empty()) { for (const TActorId &replica : AllReplicas) { - Send(replica, new TEvStateStorage::TEvReplicaDelete(TabletID), IEventHandle::FlagTrackDelivery); + Send(replica, new TEvStateStorage::TEvReplicaDelete(TabletID), IEventHandle::FlagTrackDelivery); } - Schedule(TDuration::Seconds(60), new TEvents::TEvWakeup()); + Schedule(TDuration::Seconds(60), new TEvents::TEvWakeup()); Become(&TThis::StateRequestedDelete); } else { - SendResponse(); + SendResponse(); } } - STATEFN(StateRequestedDelete) { + STATEFN(StateRequestedDelete) { switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvReplicaInfo, Handle); - hFunc(TEvents::TEvUndelivered, Undelivered); - cFunc(TEvents::TSystem::Wakeup, Timeout); + hFunc(TEvStateStorage::TEvReplicaInfo, Handle); + hFunc(TEvents::TEvUndelivered, Undelivered); + cFunc(TEvents::TSystem::Wakeup, Timeout); } } - void OnResponseReceived() { + void OnResponseReceived() { if (Count + UndeliveredCount >= AllReplicas.size()) - SendResponse(); + SendResponse(); } - void Undelivered(TEvents::TEvUndelivered::TPtr &) { + void Undelivered(TEvents::TEvUndelivered::TPtr &) { ++UndeliveredCount; - OnResponseReceived(); + OnResponseReceived(); } - void Handle(TEvStateStorage::TEvReplicaInfo::TPtr &) { + void Handle(TEvStateStorage::TEvReplicaInfo::TPtr &) { ++Count; - OnResponseReceived(); + OnResponseReceived(); } - void Timeout() { - SendResponse(); + void Timeout() { + SendResponse(); } }; -class TStateStorageProxy : public TActor<TStateStorageProxy> { - TIntrusivePtr<TStateStorageInfo> Info; - TIntrusivePtr<TStateStorageInfo> BoardInfo; +class TStateStorageProxy : public TActor<TStateStorageProxy> { + TIntrusivePtr<TStateStorageInfo> Info; + TIntrusivePtr<TStateStorageInfo> BoardInfo; TIntrusivePtr<TStateStorageInfo> SchemeBoardInfo; - - TIntrusivePtr<TStateStorageInfo> FlowControlledInfo; - + + TIntrusivePtr<TStateStorageInfo> FlowControlledInfo; + TMap<TActorId, TActorId> ReplicaProbes; - - void Handle(TEvStateStorage::TEvRequestReplicasDumps::TPtr &ev) { - TActivationContext::Register(new TStateStorageDumpRequest(ev->Sender, Info)); - } - - void Handle(TEvStateStorage::TEvDelete::TPtr &ev) { - TActivationContext::Register(new TStateStorageDeleteRequest(ev->Sender, Info, ev->Get()->TabletID)); - } - + + void Handle(TEvStateStorage::TEvRequestReplicasDumps::TPtr &ev) { + TActivationContext::Register(new TStateStorageDumpRequest(ev->Sender, Info)); + } + + void Handle(TEvStateStorage::TEvDelete::TPtr &ev) { + TActivationContext::Register(new TStateStorageDeleteRequest(ev->Sender, Info, ev->Get()->TabletID)); + } + void SpreadCleanupRequest(const TStateStorageInfo::TSelection &selection, ui64 tabletId, TActorId proposedLeader) { - for (ui32 i = 0; i < selection.Sz; ++i) + for (ui32 i = 0; i < selection.Sz; ++i) Send(selection.SelectedReplicas[i], new TEvStateStorage::TEvReplicaCleanup(tabletId, proposedLeader)); - } - - void Handle(TEvStateStorage::TEvCleanup::TPtr &ev) { - const auto *msg = ev->Get(); - THolder<TStateStorageInfo::TSelection> selection(new TStateStorageInfo::TSelection()); - Info->SelectReplicas(msg->TabletID, selection.Get()); + } + + void Handle(TEvStateStorage::TEvCleanup::TPtr &ev) { + const auto *msg = ev->Get(); + THolder<TStateStorageInfo::TSelection> selection(new TStateStorageInfo::TSelection()); + Info->SelectReplicas(msg->TabletID, selection.Get()); SpreadCleanupRequest(*selection, msg->TabletID, msg->ProposedLeader); - } - - void Handle(TEvStateStorage::TEvResolveReplicas::TPtr &ev) { + } + + void Handle(TEvStateStorage::TEvResolveReplicas::TPtr &ev) { ResolveReplicas(ev, ev->Get()->TabletID, Info); } - + void Handle(TEvStateStorage::TEvResolveBoard::TPtr &ev) { if (!BoardInfo) { Send(ev->Sender, new TEvStateStorage::TEvResolveReplicasList(), 0, ev->Cookie); @@ -786,166 +786,166 @@ class TStateStorageProxy : public TActor<TStateStorageProxy> { const auto *msg = ev->Get(); - ui64 fakeTabletId; + ui64 fakeTabletId; switch (msg->KeyType) { case TEvStateStorage::TEvResolveSchemeBoard::KeyTypePath: - fakeTabletId = CityHash64(msg->Path); + fakeTabletId = CityHash64(msg->Path); break; case TEvStateStorage::TEvResolveSchemeBoard::KeyTypePathId: - fakeTabletId = msg->PathId.Hash(); + fakeTabletId = msg->PathId.Hash(); break; default: Y_FAIL("unreachable"); } - ResolveReplicas(ev, fakeTabletId, SchemeBoardInfo); + ResolveReplicas(ev, fakeTabletId, SchemeBoardInfo); } void Handle(TEvStateStorage::TEvListSchemeBoard::TPtr &ev) { if (!SchemeBoardInfo) { - Send(ev->Sender, new TEvStateStorage::TEvListSchemeBoardResult(nullptr), 0, ev->Cookie); + Send(ev->Sender, new TEvStateStorage::TEvListSchemeBoardResult(nullptr), 0, ev->Cookie); + return; + } + + Send(ev->Sender, new TEvStateStorage::TEvListSchemeBoardResult(SchemeBoardInfo), 0, ev->Cookie); + } + + void Handle(TEvStateStorage::TEvReplicaProbeSubscribe::TPtr &ev) { + const auto *msg = ev->Get(); + + if (!KIKIMR_ALLOW_SSREPLICA_PROBES) { + Send(ev->Sender, new TEvStateStorage::TEvReplicaProbeConnected(msg->ReplicaId)); return; } - Send(ev->Sender, new TEvStateStorage::TEvListSchemeBoardResult(SchemeBoardInfo), 0, ev->Cookie); - } - - void Handle(TEvStateStorage::TEvReplicaProbeSubscribe::TPtr &ev) { - const auto *msg = ev->Get(); - - if (!KIKIMR_ALLOW_SSREPLICA_PROBES) { - Send(ev->Sender, new TEvStateStorage::TEvReplicaProbeConnected(msg->ReplicaId)); - return; - } - - auto it = ReplicaProbes.find(msg->ReplicaId); - if (it == ReplicaProbes.end()) { - Send(ev->Sender, new TEvStateStorage::TEvReplicaProbeDisconnected(msg->ReplicaId)); - return; - } - - TActivationContext::Send(ev->Forward(it->second)); - } - - void Handle(TEvStateStorage::TEvReplicaProbeUnsubscribe::TPtr &ev) { - if (!KIKIMR_ALLOW_SSREPLICA_PROBES) - return; - - const auto *msg = ev->Get(); - - auto it = ReplicaProbes.find(msg->ReplicaId); - if (it != ReplicaProbes.end()) { - TActivationContext::Send(ev->Forward(it->second)); - } - } - - void Handle(TEvStateStorage::TEvUpdateGroupConfig::TPtr &ev) { - auto *msg = ev->Get(); - TIntrusivePtr<TStateStorageInfo> old = Info; - - Info = msg->GroupConfig; - BoardInfo = msg->BoardConfig; - SchemeBoardInfo = msg->SchemeBoardConfig; - - RegisterDerivedServices(TlsActivationContext->ExecutorThread.ActorSystem, old.Get()); - } - - void RegisterDerivedServices(TActorSystem *sys, const TStateStorageInfo *old) { - RegisterReplicaProbes(sys); - RegisterFlowContolled(sys, old); - } - - void RegisterReplicaProbes(TActorSystem *sys) { - if (!KIKIMR_ALLOW_SSREPLICA_PROBES) - return; - - for (auto &xpair : ReplicaProbes) - sys->Send(xpair.second, new TEvents::TEvPoisonPill()); - ReplicaProbes.clear(); - - for (auto &ring : Info->Rings) + auto it = ReplicaProbes.find(msg->ReplicaId); + if (it == ReplicaProbes.end()) { + Send(ev->Sender, new TEvStateStorage::TEvReplicaProbeDisconnected(msg->ReplicaId)); + return; + } + + TActivationContext::Send(ev->Forward(it->second)); + } + + void Handle(TEvStateStorage::TEvReplicaProbeUnsubscribe::TPtr &ev) { + if (!KIKIMR_ALLOW_SSREPLICA_PROBES) + return; + + const auto *msg = ev->Get(); + + auto it = ReplicaProbes.find(msg->ReplicaId); + if (it != ReplicaProbes.end()) { + TActivationContext::Send(ev->Forward(it->second)); + } + } + + void Handle(TEvStateStorage::TEvUpdateGroupConfig::TPtr &ev) { + auto *msg = ev->Get(); + TIntrusivePtr<TStateStorageInfo> old = Info; + + Info = msg->GroupConfig; + BoardInfo = msg->BoardConfig; + SchemeBoardInfo = msg->SchemeBoardConfig; + + RegisterDerivedServices(TlsActivationContext->ExecutorThread.ActorSystem, old.Get()); + } + + void RegisterDerivedServices(TActorSystem *sys, const TStateStorageInfo *old) { + RegisterReplicaProbes(sys); + RegisterFlowContolled(sys, old); + } + + void RegisterReplicaProbes(TActorSystem *sys) { + if (!KIKIMR_ALLOW_SSREPLICA_PROBES) + return; + + for (auto &xpair : ReplicaProbes) + sys->Send(xpair.second, new TEvents::TEvPoisonPill()); + ReplicaProbes.clear(); + + for (auto &ring : Info->Rings) for (const TActorId replicaId : ring.Replicas) { const TActorId probeId = sys->Register(CreateStateStorageReplicaProbe(replicaId)); - ReplicaProbes.emplace(replicaId, probeId); - } - } - + ReplicaProbes.emplace(replicaId, probeId); + } + } + template<typename TEventPtr> void ResolveReplicas(const TEventPtr &ev, ui64 tabletId, const TIntrusivePtr<TStateStorageInfo> &info) const { - THolder<TStateStorageInfo::TSelection> selection(new TStateStorageInfo::TSelection()); - info->SelectReplicas(tabletId, selection.Get()); - - TAutoPtr<TEvStateStorage::TEvResolveReplicasList> reply(new TEvStateStorage::TEvResolveReplicasList()); - reply->Replicas.insert(reply->Replicas.end(), selection->SelectedReplicas.Get(), selection->SelectedReplicas.Get() + selection->Sz); - reply->ConfigContentHash = info->ContentHash(); - Send(ev->Sender, reply.Release(), 0, ev->Cookie); - } - - void RegisterFlowContolled(TActorSystem *sys, const TStateStorageInfo *old) { - if (!KIKIMR_ALLOW_FLOWCONTROLLED_QUEUE_FOR_SSLOOKUP) - return; - - TIntrusivePtr<TStateStorageInfo> updated = new TStateStorageInfo(); - updated->StateStorageGroup = Info->StateStorageGroup; - updated->NToSelect = Info->NToSelect; - updated->Rings.resize(Info->Rings.size()); - - const bool checkOldInfo = FlowControlledInfo && old - && updated->StateStorageGroup == FlowControlledInfo->StateStorageGroup - && updated->NToSelect == FlowControlledInfo->NToSelect - && updated->Rings.size() == FlowControlledInfo->Rings.size(); - - ui32 ringIdx = 0; - for (const ui32 ringsSz = Info->Rings.size(); ringIdx < ringsSz; ++ringIdx) { - const bool checkRing = checkOldInfo && (FlowControlledInfo->Rings[ringIdx].Replicas.size() == Info->Rings[ringIdx].Replicas.size()); - - TStateStorageInfo::TRing &ctring = updated->Rings[ringIdx]; - TStateStorageInfo::TRing *fcring = checkRing ? &FlowControlledInfo->Rings[ringIdx] : nullptr; - const auto &srcring = Info->Rings[ringIdx]; - const auto *oldring = checkRing ? &old->Rings[ringIdx] : nullptr; - - ctring.Replicas.resize(srcring.Replicas.size()); - ui32 replicaIdx = 0; - for (const ui32 srcSize = srcring.Replicas.size(); replicaIdx < srcSize; ++replicaIdx) { - if (checkRing && srcring.Replicas[replicaIdx] == oldring->Replicas[replicaIdx]) { - ctring.Replicas[replicaIdx] = fcring->Replicas[replicaIdx]; + THolder<TStateStorageInfo::TSelection> selection(new TStateStorageInfo::TSelection()); + info->SelectReplicas(tabletId, selection.Get()); + + TAutoPtr<TEvStateStorage::TEvResolveReplicasList> reply(new TEvStateStorage::TEvResolveReplicasList()); + reply->Replicas.insert(reply->Replicas.end(), selection->SelectedReplicas.Get(), selection->SelectedReplicas.Get() + selection->Sz); + reply->ConfigContentHash = info->ContentHash(); + Send(ev->Sender, reply.Release(), 0, ev->Cookie); + } + + void RegisterFlowContolled(TActorSystem *sys, const TStateStorageInfo *old) { + if (!KIKIMR_ALLOW_FLOWCONTROLLED_QUEUE_FOR_SSLOOKUP) + return; + + TIntrusivePtr<TStateStorageInfo> updated = new TStateStorageInfo(); + updated->StateStorageGroup = Info->StateStorageGroup; + updated->NToSelect = Info->NToSelect; + updated->Rings.resize(Info->Rings.size()); + + const bool checkOldInfo = FlowControlledInfo && old + && updated->StateStorageGroup == FlowControlledInfo->StateStorageGroup + && updated->NToSelect == FlowControlledInfo->NToSelect + && updated->Rings.size() == FlowControlledInfo->Rings.size(); + + ui32 ringIdx = 0; + for (const ui32 ringsSz = Info->Rings.size(); ringIdx < ringsSz; ++ringIdx) { + const bool checkRing = checkOldInfo && (FlowControlledInfo->Rings[ringIdx].Replicas.size() == Info->Rings[ringIdx].Replicas.size()); + + TStateStorageInfo::TRing &ctring = updated->Rings[ringIdx]; + TStateStorageInfo::TRing *fcring = checkRing ? &FlowControlledInfo->Rings[ringIdx] : nullptr; + const auto &srcring = Info->Rings[ringIdx]; + const auto *oldring = checkRing ? &old->Rings[ringIdx] : nullptr; + + ctring.Replicas.resize(srcring.Replicas.size()); + ui32 replicaIdx = 0; + for (const ui32 srcSize = srcring.Replicas.size(); replicaIdx < srcSize; ++replicaIdx) { + if (checkRing && srcring.Replicas[replicaIdx] == oldring->Replicas[replicaIdx]) { + ctring.Replicas[replicaIdx] = fcring->Replicas[replicaIdx]; fcring->Replicas[replicaIdx] = TActorId(); - } else { - if (fcring && replicaIdx < fcring->Replicas.size()) - Send(fcring->Replicas[replicaIdx], new TEvents::TEvPoison()); - - TFlowControlledQueueConfig flowConfig; - flowConfig.MaxAllowedInFly = 10000; - flowConfig.TargetDynamicRate = 250000; - - ctring.Replicas[replicaIdx] = sys->Register( - CreateFlowControlledRequestQueue(srcring.Replicas[replicaIdx], NKikimrServices::TActivity::SS_PROXY_REQUEST, flowConfig), - TMailboxType::ReadAsFilled - ); - } - } - if (fcring) { - for (const ui32 fcSize = fcring->Replicas.size(); replicaIdx < fcSize; ++replicaIdx) { - Send(fcring->Replicas[replicaIdx], new TEvents::TEvPoison()); - } - } - } - if (FlowControlledInfo) { - for (const ui32 oldSize = FlowControlledInfo->Rings.size(); ringIdx < oldSize; ++ringIdx) { + } else { + if (fcring && replicaIdx < fcring->Replicas.size()) + Send(fcring->Replicas[replicaIdx], new TEvents::TEvPoison()); + + TFlowControlledQueueConfig flowConfig; + flowConfig.MaxAllowedInFly = 10000; + flowConfig.TargetDynamicRate = 250000; + + ctring.Replicas[replicaIdx] = sys->Register( + CreateFlowControlledRequestQueue(srcring.Replicas[replicaIdx], NKikimrServices::TActivity::SS_PROXY_REQUEST, flowConfig), + TMailboxType::ReadAsFilled + ); + } + } + if (fcring) { + for (const ui32 fcSize = fcring->Replicas.size(); replicaIdx < fcSize; ++replicaIdx) { + Send(fcring->Replicas[replicaIdx], new TEvents::TEvPoison()); + } + } + } + if (FlowControlledInfo) { + for (const ui32 oldSize = FlowControlledInfo->Rings.size(); ringIdx < oldSize; ++ringIdx) { for (TActorId outdated : FlowControlledInfo->Rings[oldSize].Replicas) - Send(outdated, new TEvents::TEvPoison()); - } - } - - FlowControlledInfo = std::move(updated); - } - + Send(outdated, new TEvents::TEvPoison()); + } + } + + FlowControlledInfo = std::move(updated); + } + void Registered(TActorSystem* sys, const TActorId&) { - RegisterDerivedServices(sys, nullptr); - } -public: + RegisterDerivedServices(sys, nullptr); + } +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::SS_PROXY; } @@ -954,79 +954,79 @@ public: const TIntrusivePtr<TStateStorageInfo> &info, const TIntrusivePtr<TStateStorageInfo> &boardInfo, const TIntrusivePtr<TStateStorageInfo> &schemeBoardInfo) - : TActor(&TThis::StateInit) - , Info(info) - , BoardInfo(boardInfo) + : TActor(&TThis::StateInit) + , Info(info) + , BoardInfo(boardInfo) , SchemeBoardInfo(schemeBoardInfo) {} - - STATEFN(StateInit) { - BLOG_TRACE("Proxy::StateInit ev type# " << ev->GetTypeRewrite() << " event: " + + STATEFN(StateInit) { + BLOG_TRACE("Proxy::StateInit ev type# " << ev->GetTypeRewrite() << " event: " << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?")); - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvRequestReplicasDumps, Handle); - hFunc(TEvStateStorage::TEvDelete, Handle); - hFunc(TEvStateStorage::TEvCleanup, Handle); - hFunc(TEvStateStorage::TEvResolveReplicas, Handle); - hFunc(TEvStateStorage::TEvResolveBoard, Handle); + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvRequestReplicasDumps, Handle); + hFunc(TEvStateStorage::TEvDelete, Handle); + hFunc(TEvStateStorage::TEvCleanup, Handle); + hFunc(TEvStateStorage::TEvResolveReplicas, Handle); + hFunc(TEvStateStorage::TEvResolveBoard, Handle); hFunc(TEvStateStorage::TEvResolveSchemeBoard, Handle); hFunc(TEvStateStorage::TEvListSchemeBoard, Handle); - hFunc(TEvStateStorage::TEvUpdateGroupConfig, Handle); - hFunc(TEvStateStorage::TEvReplicaProbeSubscribe, Handle); - hFunc(TEvStateStorage::TEvReplicaProbeUnsubscribe, Handle); - default: + hFunc(TEvStateStorage::TEvUpdateGroupConfig, Handle); + hFunc(TEvStateStorage::TEvReplicaProbeSubscribe, Handle); + hFunc(TEvStateStorage::TEvReplicaProbeUnsubscribe, Handle); + default: TActivationContext::Send(ev->Forward(RegisterWithSameMailbox(new TStateStorageProxyRequest(Info, FlowControlledInfo)))); - break; - } - } -}; - -class TStateStorageProxyStub : public TActor<TStateStorageProxyStub> { - - void Handle(TEvStateStorage::TEvLookup::TPtr &ev) { - BLOG_D("ProxyStub::Handle ev: " << ev->Get()->ToString()); - const TEvStateStorage::TEvLookup *msg = ev->Get(); - const ui64 tabletId = msg->TabletID; - const ui64 cookie = msg->Cookie; - - Send(ev->Sender, new TEvStateStorage::TEvInfo( - NKikimrProto::ERROR, + break; + } + } +}; + +class TStateStorageProxyStub : public TActor<TStateStorageProxyStub> { + + void Handle(TEvStateStorage::TEvLookup::TPtr &ev) { + BLOG_D("ProxyStub::Handle ev: " << ev->Get()->ToString()); + const TEvStateStorage::TEvLookup *msg = ev->Get(); + const ui64 tabletId = msg->TabletID; + const ui64 cookie = msg->Cookie; + + Send(ev->Sender, new TEvStateStorage::TEvInfo( + NKikimrProto::ERROR, tabletId, cookie, TActorId(), TActorId(), 0, 0, false, 0, nullptr, 0, TMap<TActorId, TActorId>())); - } -public: + } +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::SS_PROXY_STUB; } - TStateStorageProxyStub() - : TActor(&TThis::StateFunc) + TStateStorageProxyStub() + : TActor(&TThis::StateFunc) {} - - STATEFN(StateFunc) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvLookup, Handle); + + STATEFN(StateFunc) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvLookup, Handle); default: - BLOG_W("ProxyStub::StateFunc unexpected event type# " + BLOG_W("ProxyStub::StateFunc unexpected event type# " << ev->GetTypeRewrite() << " event: " << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?")); break; - } - } -}; - + } + } +}; + IActor* CreateStateStorageProxy( const TIntrusivePtr<TStateStorageInfo> &info, const TIntrusivePtr<TStateStorageInfo> &board, const TIntrusivePtr<TStateStorageInfo> &schemeBoard ) { return new TStateStorageProxy(info, board, schemeBoard); -} - -IActor* CreateStateStorageProxyStub() { - return new TStateStorageProxyStub(); -} - -} +} + +IActor* CreateStateStorageProxyStub() { + return new TStateStorageProxyStub(); +} + +} diff --git a/ydb/core/base/statestorage_replica.cpp b/ydb/core/base/statestorage_replica.cpp index a612baef41..aca41acb16 100644 --- a/ydb/core/base/statestorage_replica.cpp +++ b/ydb/core/base/statestorage_replica.cpp @@ -1,93 +1,93 @@ -#include "statestorage_impl.h" -#include "tabletid.h" +#include "statestorage_impl.h" +#include "tabletid.h" #include "appdata.h" -#include "tablet.h" +#include "tablet.h" #include <ydb/core/protos/services.pb.h> #include <library/cpp/actors/core/interconnect.h> #include <library/cpp/actors/core/hfunc.h> #include <library/cpp/actors/core/log.h> -#include <util/generic/map.h> -#include <util/generic/hash_set.h> - -#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR || defined BLOG_TRACE -#error log macro definition clash -#endif - -#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) -#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) -#define BLOG_W(stream) LOG_WARN_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) -#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) - -namespace NKikimr { - -class TStateStorageReplica : public TActor<TStateStorageReplica> { - TIntrusivePtr<TStateStorageInfo> Info; - const ui32 ReplicaIndex; - - struct TTabletState { - enum ETabletState { - Unknown, - Normal, - Locked, - }; - }; - +#include <util/generic/map.h> +#include <util/generic/hash_set.h> + +#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR || defined BLOG_TRACE +#error log macro definition clash +#endif + +#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) +#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) +#define BLOG_W(stream) LOG_WARN_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) +#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) + +namespace NKikimr { + +class TStateStorageReplica : public TActor<TStateStorageReplica> { + TIntrusivePtr<TStateStorageInfo> Info; + const ui32 ReplicaIndex; + + struct TTabletState { + enum ETabletState { + Unknown, + Normal, + Locked, + }; + }; + struct TFollowerEntryInfo { TActorId FollowerSys; TActorId FollowerTablet; - bool Candidate = false; - + bool Candidate = false; + TFollowerEntryInfo() = default; TFollowerEntryInfo(TActorId sys, TActorId tablet, bool candidate) : FollowerSys(sys) , FollowerTablet(tablet) - , Candidate(candidate) - {} - }; - - struct TEntry { - TTabletState::ETabletState TabletState; + , Candidate(candidate) + {} + }; + + struct TEntry { + TTabletState::ETabletState TabletState; TActorId CurrentLeader; TActorId CurrentLeaderTablet; TActorId CurrentGuardian; - ui32 CurrentGeneration; - ui32 CurrentStep; - ui64 LockedFrom; - + ui32 CurrentGeneration; + ui32 CurrentStep; + ui64 LockedFrom; + TMap<TActorId, TFollowerEntryInfo> Followers; // guardian -> follower actors - - TEntry() - : TabletState(TTabletState::Unknown) - , CurrentGeneration(0) - , CurrentStep(0) - , LockedFrom(0) - {} - }; - + + TEntry() + : TabletState(TTabletState::Unknown) + , CurrentGeneration(0) + , CurrentStep(0) + , LockedFrom(0) + {} + }; + typedef TMap<ui64, TEntry> TTablets; - TTablets Tablets; - + TTablets Tablets; + TMap<ui32, std::map<ui64, ui64>> FollowerIndex; // node, tablet, refcounter - - ui64 Signature() const { - return SelfId().LocalId(); - } - - template<typename TEv> - bool CheckSignature(const TEv *msg) const { - const bool ok = msg->Record.HasSignature() && msg->Record.GetSignature() == Signature(); - return ok; - } - + + ui64 Signature() const { + return SelfId().LocalId(); + } + + template<typename TEv> + bool CheckSignature(const TEv *msg) const { + const bool ok = msg->Record.HasSignature() && msg->Record.GetSignature() == Signature(); + return ok; + } + void NotifyWithTabletInfo(const TActorId &recp, ui64 tabletId, ui64 cookie, const TEntry *entry) { - THolder<TEvStateStorage::TEvReplicaInfo> msg; + THolder<TEvStateStorage::TEvReplicaInfo> msg; if (entry && entry->CurrentLeader) { - const bool locked = (entry->TabletState == TTabletState::Locked); - auto now = TActivationContext::Now(); - - const ui64 lockedFor = (locked && (now.MicroSeconds() > entry->LockedFrom)) ? (now.MicroSeconds() - entry->LockedFrom) : 0; + const bool locked = (entry->TabletState == TTabletState::Locked); + auto now = TActivationContext::Now(); + + const ui64 lockedFor = (locked && (now.MicroSeconds() > entry->LockedFrom)) ? (now.MicroSeconds() - entry->LockedFrom) : 0; msg.Reset(new TEvStateStorage::TEvReplicaInfo(tabletId, entry->CurrentLeader, entry->CurrentLeaderTablet, entry->CurrentGeneration, entry->CurrentStep, locked, lockedFor)); if (entry->Followers.size()) { msg->Record.MutableFollowerTablet()->Reserve(entry->Followers.size()); @@ -96,101 +96,101 @@ class TStateStorageReplica : public TActor<TStateStorageReplica> { const TFollowerEntryInfo &followerInfo = xpair.second; if (followerInfo.Candidate) { ActorIdToProto(followerInfo.FollowerSys, msg->Record.AddFollowerCandidates()); - } else { + } else { ActorIdToProto(followerInfo.FollowerSys, msg->Record.AddFollower()); ActorIdToProto(followerInfo.FollowerTablet, msg->Record.AddFollowerTablet()); - } - } - } - } else { - msg.Reset(new TEvStateStorage::TEvReplicaInfo(tabletId, NKikimrProto::ERROR)); - } - msg->Record.SetCookie(cookie); - msg->Record.SetSignature(Signature()); - msg->Record.SetConfigContentHash(Info->ContentHash()); - Send(recp, msg.Release()); - } - + } + } + } + } else { + msg.Reset(new TEvStateStorage::TEvReplicaInfo(tabletId, NKikimrProto::ERROR)); + } + msg->Record.SetCookie(cookie); + msg->Record.SetSignature(Signature()); + msg->Record.SetConfigContentHash(Info->ContentHash()); + Send(recp, msg.Release()); + } + void ReplyWithStatus(const TActorId &recp, ui64 tabletId, ui64 cookie, NKikimrProto::EReplyStatus status) { THolder<TEvStateStorage::TEvReplicaInfo> msg(new TEvStateStorage::TEvReplicaInfo(tabletId, status)); msg->Record.SetCookie(cookie); - msg->Record.SetSignature(Signature()); - msg->Record.SetConfigContentHash(Info->ContentHash()); - Send(recp, msg.Release()); + msg->Record.SetSignature(Signature()); + msg->Record.SetConfigContentHash(Info->ContentHash()); + Send(recp, msg.Release()); } bool EraseFollowerAndNotify(ui64 tabletId, TEntry &tabletEntry, TActorId followerGuardian) { if (!tabletEntry.Followers.erase(followerGuardian)) - return false; - - if (tabletEntry.CurrentGuardian) + return false; + + if (tabletEntry.CurrentGuardian) NotifyWithTabletInfo(followerGuardian, tabletId, 0, &tabletEntry); - - return true; - } - + + return true; + } + void ForgetFollower(ui64 tabletId, TActorId followerGuardian) { - auto tabletIt = Tablets.find(tabletId); - if (tabletIt == Tablets.end()) - return; - + auto tabletIt = Tablets.find(tabletId); + if (tabletIt == Tablets.end()) + return; + const bool erased = EraseFollowerAndNotify(tabletId, tabletIt->second, followerGuardian); - if (!erased) - return; - + if (!erased) + return; + const ui32 followerNodeId = followerGuardian.NodeId(); auto *followerIndex = FollowerIndex.FindPtr(followerNodeId); if (followerIndex == nullptr) - return; - + return; + auto it = followerIndex->find(tabletId); if (it == followerIndex->end()) - return; - - if (--it->second == 0) + return; + + if (--it->second == 0) followerIndex->erase(it); - } - - void PassAway() override { - const ui32 selfNode = SelfId().NodeId(); - THashSet<ui32> nodesToUnsubscribe; - - for (auto &xpair : Tablets) { - const auto &entry = xpair.second; - - if (entry.CurrentGuardian) - Send(entry.CurrentGuardian, new TEvStateStorage::TEvReplicaShutdown()); - + } + + void PassAway() override { + const ui32 selfNode = SelfId().NodeId(); + THashSet<ui32> nodesToUnsubscribe; + + for (auto &xpair : Tablets) { + const auto &entry = xpair.second; + + if (entry.CurrentGuardian) + Send(entry.CurrentGuardian, new TEvStateStorage::TEvReplicaShutdown()); + for (auto &spair : entry.Followers) { const TActorId followerGuardian = spair.first; if (followerGuardian.NodeId() != selfNode) nodesToUnsubscribe.insert(followerGuardian.NodeId()); Send(followerGuardian, new TEvStateStorage::TEvReplicaShutdown()); - } - } - - for (ui32 xnode : nodesToUnsubscribe) { - Send(TActivationContext::InterconnectProxy(xnode), new TEvents::TEvUnsubscribe()); - } - - TActor::PassAway(); - } - - void Handle(TEvStateStorage::TEvReplicaLookup::TPtr &ev) { - TEvStateStorage::TEvReplicaLookup *msg = ev->Get(); - BLOG_D("Replica::Handle ev: " << msg->ToString()); - const ui64 tabletId = msg->Record.GetTabletID(); + } + } + + for (ui32 xnode : nodesToUnsubscribe) { + Send(TActivationContext::InterconnectProxy(xnode), new TEvents::TEvUnsubscribe()); + } + + TActor::PassAway(); + } + + void Handle(TEvStateStorage::TEvReplicaLookup::TPtr &ev) { + TEvStateStorage::TEvReplicaLookup *msg = ev->Get(); + BLOG_D("Replica::Handle ev: " << msg->ToString()); + const ui64 tabletId = msg->Record.GetTabletID(); Y_VERIFY_DEBUG(StateStorageGroupFromTabletID(tabletId) == Info->StateStorageGroup, "tabletId# %" PRIu64 " SSGFTID# %" PRIu64 " SSG# %" PRIu64, (ui64)tabletId, (ui64)StateStorageGroupFromTabletID(tabletId), (ui64)Info->StateStorageGroup); - TTablets::const_iterator it = Tablets.find(msg->Record.GetTabletID()); - if (it != Tablets.end()) - NotifyWithTabletInfo(ev->Sender, it->first, msg->Record.GetCookie(), &it->second); - else - NotifyWithTabletInfo(ev->Sender, tabletId, msg->Record.GetCookie(), nullptr); - } - - void Handle(TEvStateStorage::TEvReplicaDumpRequest::TPtr &ev) { + TTablets::const_iterator it = Tablets.find(msg->Record.GetTabletID()); + if (it != Tablets.end()) + NotifyWithTabletInfo(ev->Sender, it->first, msg->Record.GetCookie(), &it->second); + else + NotifyWithTabletInfo(ev->Sender, tabletId, msg->Record.GetCookie(), nullptr); + } + + void Handle(TEvStateStorage::TEvReplicaDumpRequest::TPtr &ev) { TAutoPtr<TEvStateStorage::TEvReplicaDump> dump = new TEvStateStorage::TEvReplicaDump(); for (const auto &it : Tablets) { NKikimrStateStorage::TEvInfo& info = *dump->Record.AddInfo(); @@ -200,261 +200,261 @@ class TStateStorageReplica : public TActor<TStateStorageReplica> { ActorIdToProto(it.second.CurrentLeader, info.MutableCurrentLeader()); ActorIdToProto(it.second.CurrentLeaderTablet, info.MutableCurrentLeaderTablet()); if (it.second.TabletState == TTabletState::Locked) { - info.SetLockedFor(TActivationContext::Now().MicroSeconds() - it.second.LockedFrom); + info.SetLockedFor(TActivationContext::Now().MicroSeconds() - it.second.LockedFrom); } } - Send(ev->Sender, dump.Release(), 0, ev->Cookie); + Send(ev->Sender, dump.Release(), 0, ev->Cookie); } - void Handle(TEvStateStorage::TEvReplicaUpdate::TPtr &ev) { - TEvStateStorage::TEvReplicaUpdate *msg = ev->Get(); - BLOG_D("Replica::Handle ev: " << msg->ToString()); - const ui64 tabletId = msg->Record.GetTabletID(); + void Handle(TEvStateStorage::TEvReplicaUpdate::TPtr &ev) { + TEvStateStorage::TEvReplicaUpdate *msg = ev->Get(); + BLOG_D("Replica::Handle ev: " << msg->ToString()); + const ui64 tabletId = msg->Record.GetTabletID(); Y_VERIFY_DEBUG(StateStorageGroupFromTabletID(tabletId) == Info->StateStorageGroup); - - TEntry *x = nullptr; - auto tabletIt = Tablets.find(tabletId); - if (tabletIt != Tablets.end()) - x = &tabletIt->second; - + + TEntry *x = nullptr; + auto tabletIt = Tablets.find(tabletId); + if (tabletIt != Tablets.end()) + x = &tabletIt->second; + const TActorId proposedLeader = ActorIdFromProto(msg->Record.GetProposedLeader()); - const ui32 proposedGeneration = msg->Record.GetProposedGeneration(); - const ui32 proposedStep = msg->Record.GetProposedStep(); - - const bool allow = CheckSignature(msg) && - (!x - || (proposedGeneration > x->CurrentGeneration) + const ui32 proposedGeneration = msg->Record.GetProposedGeneration(); + const ui32 proposedStep = msg->Record.GetProposedStep(); + + const bool allow = CheckSignature(msg) && + (!x + || (proposedGeneration > x->CurrentGeneration) || (proposedGeneration == x->CurrentGeneration && proposedLeader == x->CurrentLeader && proposedStep >= x->CurrentStep) - ); - - if (allow) { - if (tabletIt == Tablets.end()) - tabletIt = Tablets.insert(std::make_pair(tabletId, TEntry())).first; - x = &tabletIt->second; - + ); + + if (allow) { + if (tabletIt == Tablets.end()) + tabletIt = Tablets.insert(std::make_pair(tabletId, TEntry())).first; + x = &tabletIt->second; + if (x->CurrentLeader && proposedLeader != x->CurrentLeader) Send(x->CurrentLeader, new TEvStateStorage::TEvReplicaLeaderDemoted(tabletId, Signature())); - - x->CurrentGeneration = proposedGeneration; - x->CurrentStep = proposedStep; + + x->CurrentGeneration = proposedGeneration; + x->CurrentStep = proposedStep; x->CurrentLeader = proposedLeader; - + if (msg->Record.HasProposedLeaderTablet()) x->CurrentLeaderTablet = ActorIdFromProto(msg->Record.GetProposedLeaderTablet()); - - if (msg->Record.GetIsGuardian()) - x->CurrentGuardian = ev->Sender; - - x->TabletState = TTabletState::Normal; - x->LockedFrom = 0; - } - - NotifyWithTabletInfo(ev->Sender, tabletId, msg->Record.GetCookie(), x); - } - - void Handle(TEvStateStorage::TEvReplicaCleanup::TPtr &ev) { - const auto &record = ev->Get()->Record; - BLOG_D("Replica::Handle ev: " << ev->Get()->ToString()); - const ui64 tabletId = record.GetTabletID(); - Y_VERIFY_DEBUG(StateStorageGroupFromTabletID(tabletId) == Info->StateStorageGroup); + + if (msg->Record.GetIsGuardian()) + x->CurrentGuardian = ev->Sender; + + x->TabletState = TTabletState::Normal; + x->LockedFrom = 0; + } + + NotifyWithTabletInfo(ev->Sender, tabletId, msg->Record.GetCookie(), x); + } + + void Handle(TEvStateStorage::TEvReplicaCleanup::TPtr &ev) { + const auto &record = ev->Get()->Record; + BLOG_D("Replica::Handle ev: " << ev->Get()->ToString()); + const ui64 tabletId = record.GetTabletID(); + Y_VERIFY_DEBUG(StateStorageGroupFromTabletID(tabletId) == Info->StateStorageGroup); const TActorId proposedLeader = ActorIdFromProto(record.GetProposedLeader()); - - auto tabletIt = Tablets.find(tabletId); + + auto tabletIt = Tablets.find(tabletId); if (tabletIt == Tablets.end() || tabletIt->second.CurrentLeader != proposedLeader) - return; - + return; + if (tabletIt->second.Followers) { BLOG_ERROR("trying to cleanup entry with attached followers. Suspicious! TabletId: " << tabletId); - return; - } - - Tablets.erase(tabletIt); - // do not reply anything - } - - void Handle(TEvStateStorage::TEvReplicaDelete::TPtr &ev) { + return; + } + + Tablets.erase(tabletIt); + // do not reply anything + } + + void Handle(TEvStateStorage::TEvReplicaDelete::TPtr &ev) { TEvStateStorage::TEvReplicaDelete *msg = ev->Get(); - BLOG_D("Replica::Handle ev: " << msg->ToString()); + BLOG_D("Replica::Handle ev: " << msg->ToString()); const ui64 tabletId = msg->Record.GetTabletID(); Y_VERIFY_DEBUG(StateStorageGroupFromTabletID(tabletId) == Info->StateStorageGroup); - - auto tabletIt = Tablets.find(tabletId); - if (tabletIt == Tablets.end()) { - ReplyWithStatus(ev->Sender, tabletId, 0/*msg->Record.GetCookie()*/, NKikimrProto::ALREADY); - return; - } - + + auto tabletIt = Tablets.find(tabletId); + if (tabletIt == Tablets.end()) { + ReplyWithStatus(ev->Sender, tabletId, 0/*msg->Record.GetCookie()*/, NKikimrProto::ALREADY); + return; + } + for (auto &sp : tabletIt->second.Followers) { const ui32 followerNodeId = sp.first.NodeId(); if (auto *x = FollowerIndex.FindPtr(followerNodeId)) - x->erase(tabletId); - } - - Tablets.erase(tabletIt); - ReplyWithStatus(ev->Sender, tabletId, 0/*msg->Record.GetCookie()*/, NKikimrProto::OK); + x->erase(tabletId); + } + + Tablets.erase(tabletIt); + ReplyWithStatus(ev->Sender, tabletId, 0/*msg->Record.GetCookie()*/, NKikimrProto::OK); } - void Handle(TEvStateStorage::TEvReplicaLock::TPtr &ev) { - TEvStateStorage::TEvReplicaLock *msg = ev->Get(); - BLOG_D("Replica::Handle ev: " << msg->ToString()); - const ui64 tabletId = msg->Record.GetTabletID(); + void Handle(TEvStateStorage::TEvReplicaLock::TPtr &ev) { + TEvStateStorage::TEvReplicaLock *msg = ev->Get(); + BLOG_D("Replica::Handle ev: " << msg->ToString()); + const ui64 tabletId = msg->Record.GetTabletID(); Y_VERIFY_DEBUG(StateStorageGroupFromTabletID(tabletId) == Info->StateStorageGroup); const TActorId &sender = ev->Sender; - - if (CheckSignature(msg)) { - TEntry &x = Tablets[tabletId]; - - const ui32 proposedGeneration = msg->Record.GetProposedGeneration(); + + if (CheckSignature(msg)) { + TEntry &x = Tablets[tabletId]; + + const ui32 proposedGeneration = msg->Record.GetProposedGeneration(); const TActorId proposedLeader = ActorIdFromProto(msg->Record.GetProposedLeader()); - - const bool allow = (proposedGeneration > x.CurrentGeneration + + const bool allow = (proposedGeneration > x.CurrentGeneration || (x.TabletState == TTabletState::Locked && proposedGeneration == x.CurrentGeneration && proposedLeader == x.CurrentLeader)); - - if (allow) { + + if (allow) { if (x.CurrentLeader && proposedLeader != x.CurrentLeader) Send(x.CurrentLeader, new TEvStateStorage::TEvReplicaLeaderDemoted(tabletId, Signature())); - - x.CurrentGeneration = proposedGeneration; - x.CurrentStep = 0; + + x.CurrentGeneration = proposedGeneration; + x.CurrentStep = 0; x.CurrentLeader = proposedLeader; x.CurrentLeaderTablet = TActorId(); x.CurrentGuardian = TActorId(); - x.TabletState = TTabletState::Locked; - x.LockedFrom = TActivationContext::Now().MicroSeconds(); - } - - NotifyWithTabletInfo(sender, tabletId, msg->Record.GetCookie(), &x); - } else { - NotifyWithTabletInfo(sender, tabletId, msg->Record.GetCookie(), nullptr); - } - } - + x.TabletState = TTabletState::Locked; + x.LockedFrom = TActivationContext::Now().MicroSeconds(); + } + + NotifyWithTabletInfo(sender, tabletId, msg->Record.GetCookie(), &x); + } else { + NotifyWithTabletInfo(sender, tabletId, msg->Record.GetCookie(), nullptr); + } + } + void Handle(TEvStateStorage::TEvReplicaRegFollower::TPtr &ev) { const NKikimrStateStorage::TEvRegisterFollower &record = ev->Get()->Record; - const ui64 tabletId = record.GetTabletID(); - Y_VERIFY_DEBUG(StateStorageGroupFromTabletID(tabletId) == Info->StateStorageGroup); + const ui64 tabletId = record.GetTabletID(); + Y_VERIFY_DEBUG(StateStorageGroupFromTabletID(tabletId) == Info->StateStorageGroup); TEntry &x = Tablets[tabletId]; // could lead to creation of zombie entries when follower exist w/o leader so we must filter on info - + const TActorId follower = ActorIdFromProto(record.GetFollower()); const TActorId tablet = ActorIdFromProto(record.GetFollowerTablet()); - const bool isCandidate = record.HasCandidate() && record.GetCandidate(); - + const bool isCandidate = record.HasCandidate() && record.GetCandidate(); + auto insIt = x.Followers.emplace(ev->Sender, TFollowerEntryInfo(follower, tablet, isCandidate)); TFollowerEntryInfo &followerInfo = insIt.first->second; - - if (insIt.second == false) { // already known + + if (insIt.second == false) { // already known Y_VERIFY(insIt.first->second.FollowerSys == follower); - + const bool hasChanges = (followerInfo.FollowerTablet != tablet) || (followerInfo.Candidate != isCandidate); - if (!hasChanges) - return; - + if (!hasChanges) + return; + followerInfo.Candidate = isCandidate; followerInfo.FollowerTablet = tablet; - } else { // new entry + } else { // new entry auto indIt = FollowerIndex[follower.NodeId()].insert(std::make_pair(tabletId, 1)); - if (indIt.second == false) - ++indIt.first->second; - - // and now send ping to detect lost unreg event and subscribe to session + if (indIt.second == false) + ++indIt.first->second; + + // and now send ping to detect lost unreg event and subscribe to session Send(ev->Sender, // ping replica guardian, not tablet as follower could be promoted to leader - new TEvTablet::TEvPing(tabletId, 0), - IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, - tabletId); - } - - if (x.CurrentGuardian) - NotifyWithTabletInfo(x.CurrentGuardian, tabletId, 0, &x); - } - + new TEvTablet::TEvPing(tabletId, 0), + IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, + tabletId); + } + + if (x.CurrentGuardian) + NotifyWithTabletInfo(x.CurrentGuardian, tabletId, 0, &x); + } + void Handle(TEvStateStorage::TEvReplicaUnregFollower::TPtr &ev) { const TEvStateStorage::TEvReplicaUnregFollower *msg = ev->Get(); - const ui64 tabletId = msg->Record.GetTabletID(); - Y_VERIFY_DEBUG(StateStorageGroupFromTabletID(tabletId) == Info->StateStorageGroup); - + const ui64 tabletId = msg->Record.GetTabletID(); + Y_VERIFY_DEBUG(StateStorageGroupFromTabletID(tabletId) == Info->StateStorageGroup); + ForgetFollower(tabletId, ev->Sender); - } - - void Handle(TEvents::TEvUndelivered::TPtr &ev) { - const ui64 tabletId = ev->Cookie; - Y_VERIFY_DEBUG(StateStorageGroupFromTabletID(tabletId) == Info->StateStorageGroup); - + } + + void Handle(TEvents::TEvUndelivered::TPtr &ev) { + const ui64 tabletId = ev->Cookie; + Y_VERIFY_DEBUG(StateStorageGroupFromTabletID(tabletId) == Info->StateStorageGroup); + ForgetFollower(tabletId, ev->Sender); - } - - void Handle(TEvents::TEvPing::TPtr &ev) { - Send(ev->Sender, new TEvents::TEvPong()); - } - - void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) { - const ui32 nodeId = ev->Get()->NodeId; - + } + + void Handle(TEvents::TEvPing::TPtr &ev) { + Send(ev->Sender, new TEvents::TEvPong()); + } + + void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) { + const ui32 nodeId = ev->Get()->NodeId; + auto *followerIndex = FollowerIndex.FindPtr(nodeId); if (followerIndex == nullptr) - return; - + return; + for (const auto &xpair : *followerIndex) { - const ui64 tabletId = xpair.first; - - if (auto *x = Tablets.FindPtr(tabletId)) { - bool changed = false; - + const ui64 tabletId = xpair.first; + + if (auto *x = Tablets.FindPtr(tabletId)) { + bool changed = false; + for (auto it = x->Followers.begin(); it != x->Followers.end();) { - if (it->first.NodeId() == nodeId) { - changed = true; + if (it->first.NodeId() == nodeId) { + changed = true; it = x->Followers.erase(it); - } - else - ++it; - } - - if (changed && x->CurrentGuardian) - NotifyWithTabletInfo(x->CurrentGuardian, tabletId, 0, x); - } - } - + } + else + ++it; + } + + if (changed && x->CurrentGuardian) + NotifyWithTabletInfo(x->CurrentGuardian, tabletId, 0, x); + } + } + followerIndex->clear(); - } - -public: + } + +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::SS_REPLICA; } TStateStorageReplica(const TIntrusivePtr<TStateStorageInfo> &info, ui32 replicaIndex) - : TActor(&TThis::StateInit) - , Info(info) - , ReplicaIndex(replicaIndex) - { + : TActor(&TThis::StateInit) + , Info(info) + , ReplicaIndex(replicaIndex) + { Y_UNUSED(ReplicaIndex); - } - - STATEFN(StateInit) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvReplicaLookup, Handle); - hFunc(TEvStateStorage::TEvReplicaDumpRequest, Handle); - hFunc(TEvStateStorage::TEvReplicaUpdate, Handle); - hFunc(TEvStateStorage::TEvReplicaLock, Handle); + } + + STATEFN(StateInit) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvReplicaLookup, Handle); + hFunc(TEvStateStorage::TEvReplicaDumpRequest, Handle); + hFunc(TEvStateStorage::TEvReplicaUpdate, Handle); + hFunc(TEvStateStorage::TEvReplicaLock, Handle); hFunc(TEvStateStorage::TEvReplicaRegFollower, Handle); hFunc(TEvStateStorage::TEvReplicaUnregFollower, Handle); - hFunc(TEvStateStorage::TEvReplicaDelete, Handle); - hFunc(TEvStateStorage::TEvReplicaCleanup, Handle); - hFunc(TEvents::TEvPing, Handle); - hFunc(TEvents::TEvUndelivered, Handle); - cFunc(TEvents::TEvPoison::EventType, PassAway); - hFunc(TEvInterconnect::TEvNodeDisconnected, Handle); - IgnoreFunc(TEvInterconnect::TEvNodeConnected); - + hFunc(TEvStateStorage::TEvReplicaDelete, Handle); + hFunc(TEvStateStorage::TEvReplicaCleanup, Handle); + hFunc(TEvents::TEvPing, Handle); + hFunc(TEvents::TEvUndelivered, Handle); + cFunc(TEvents::TEvPoison::EventType, PassAway); + hFunc(TEvInterconnect::TEvNodeDisconnected, Handle); + IgnoreFunc(TEvInterconnect::TEvNodeConnected); + default: - BLOG_W("Replica::StateInit unexpected event type# " << ev->GetTypeRewrite() + BLOG_W("Replica::StateInit unexpected event type# " << ev->GetTypeRewrite() << " event: " << ev->HasEvent() ? ev->GetBase()->ToString().data() : "serialized?"); break; - } - } -}; - + } + } +}; + IActor* CreateStateStorageReplica(const TIntrusivePtr<TStateStorageInfo> &info, ui32 replicaIndex) { - return new TStateStorageReplica(info, replicaIndex); -} - -} + return new TStateStorageReplica(info, replicaIndex); +} + +} diff --git a/ydb/core/base/statestorage_replica_probe.cpp b/ydb/core/base/statestorage_replica_probe.cpp index a2ce88517c..959c5a77ac 100644 --- a/ydb/core/base/statestorage_replica_probe.cpp +++ b/ydb/core/base/statestorage_replica_probe.cpp @@ -1,103 +1,103 @@ -#include "statestorage_impl.h" -#include "tabletid.h" -#include "appdata.h" - +#include "statestorage_impl.h" +#include "tabletid.h" +#include "appdata.h" + #include <ydb/core/protos/services.pb.h> #include <library/cpp/actors/core/interconnect.h> #include <library/cpp/actors/core/hfunc.h> #include <library/cpp/actors/core/log.h> #include <library/cpp/actors/core/actor_bootstrapped.h> - -#include <util/generic/set.h> - -#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR || defined BLOG_TRACE -#error log macro definition clash -#endif - -#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) -#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) -#define BLOG_W(stream) LOG_WARN_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) -#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) - -namespace NKikimr { - -class TStateStorageReplicaProbe : public TActorBootstrapped<TStateStorageReplicaProbe> { + +#include <util/generic/set.h> + +#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR || defined BLOG_TRACE +#error log macro definition clash +#endif + +#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) +#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) +#define BLOG_W(stream) LOG_WARN_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) +#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) + +namespace NKikimr { + +class TStateStorageReplicaProbe : public TActorBootstrapped<TStateStorageReplicaProbe> { const TActorId ReplicaId; - + TSet<TActorId> Subscribers; - - void PassAway() override { + + void PassAway() override { for (TActorId x : Subscribers) - Send(x, new TEvStateStorage::TEvReplicaProbeDisconnected(ReplicaId)); - Subscribers.clear(); - Send(TActivationContext::InterconnectProxy(ReplicaId.NodeId()), new TEvents::TEvUnsubscribe()); - - IActor::PassAway(); - } - - void HandleWait(TEvStateStorage::TEvReplicaProbeSubscribe::TPtr &ev) { - Subscribers.emplace(ev->Sender); - } - - void HandleConnected(TEvStateStorage::TEvReplicaProbeSubscribe::TPtr &ev) { - Send(ev->Sender, new TEvStateStorage::TEvReplicaProbeConnected(ReplicaId)); - } - - void Handle(TEvStateStorage::TEvReplicaProbeUnsubscribe::TPtr &ev) { - Subscribers.erase(ev->Sender); - } - - void HandlePong() { - // we can receive outdated pong, we don't care much, it's best effort + Send(x, new TEvStateStorage::TEvReplicaProbeDisconnected(ReplicaId)); + Subscribers.clear(); + Send(TActivationContext::InterconnectProxy(ReplicaId.NodeId()), new TEvents::TEvUnsubscribe()); + + IActor::PassAway(); + } + + void HandleWait(TEvStateStorage::TEvReplicaProbeSubscribe::TPtr &ev) { + Subscribers.emplace(ev->Sender); + } + + void HandleConnected(TEvStateStorage::TEvReplicaProbeSubscribe::TPtr &ev) { + Send(ev->Sender, new TEvStateStorage::TEvReplicaProbeConnected(ReplicaId)); + } + + void Handle(TEvStateStorage::TEvReplicaProbeUnsubscribe::TPtr &ev) { + Subscribers.erase(ev->Sender); + } + + void HandlePong() { + // we can receive outdated pong, we don't care much, it's best effort for (TActorId x : Subscribers) - Send(x, new TEvStateStorage::TEvReplicaProbeConnected(ReplicaId)); - Subscribers.clear(); - } - - void SomeSleep() { - Become(&TThis::StateWait, TDuration::MilliSeconds(75), new TEvents::TEvWakeup()); - } -public: - static constexpr NKikimrServices::TActivity::EType ActorActivityType() { - return NKikimrServices::TActivity::SS_PROXY; - } - - void Bootstrap() { - Send(ReplicaId, new TEvents::TEvPing(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession); - Become(&TThis::StateWait); - } - + Send(x, new TEvStateStorage::TEvReplicaProbeConnected(ReplicaId)); + Subscribers.clear(); + } + + void SomeSleep() { + Become(&TThis::StateWait, TDuration::MilliSeconds(75), new TEvents::TEvWakeup()); + } +public: + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { + return NKikimrServices::TActivity::SS_PROXY; + } + + void Bootstrap() { + Send(ReplicaId, new TEvents::TEvPing(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession); + Become(&TThis::StateWait); + } + TStateStorageReplicaProbe(TActorId replicaId) - : ReplicaId(replicaId) - {} - - STATEFN(StateWait) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvReplicaProbeSubscribe, HandleWait); - hFunc(TEvStateStorage::TEvReplicaProbeUnsubscribe, Handle); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); - cFunc(TEvents::TEvPong::EventType, HandlePong); - cFunc(TEvents::TEvWakeup::EventType, Bootstrap); - - cFunc(TEvents::TEvUndelivered::EventType, SomeSleep); - cFunc(TEvInterconnect::TEvNodeDisconnected::EventType, SomeSleep); - } - } - - STATEFN(StateConnected) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvReplicaProbeSubscribe, HandleConnected); - hFunc(TEvStateStorage::TEvReplicaProbeUnsubscribe, Handle); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); - - cFunc(TEvents::TEvUndelivered::EventType, SomeSleep); - cFunc(TEvInterconnect::TEvNodeDisconnected::EventType, SomeSleep); - } - } -}; - + : ReplicaId(replicaId) + {} + + STATEFN(StateWait) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvReplicaProbeSubscribe, HandleWait); + hFunc(TEvStateStorage::TEvReplicaProbeUnsubscribe, Handle); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + cFunc(TEvents::TEvPong::EventType, HandlePong); + cFunc(TEvents::TEvWakeup::EventType, Bootstrap); + + cFunc(TEvents::TEvUndelivered::EventType, SomeSleep); + cFunc(TEvInterconnect::TEvNodeDisconnected::EventType, SomeSleep); + } + } + + STATEFN(StateConnected) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvReplicaProbeSubscribe, HandleConnected); + hFunc(TEvStateStorage::TEvReplicaProbeUnsubscribe, Handle); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + + cFunc(TEvents::TEvUndelivered::EventType, SomeSleep); + cFunc(TEvInterconnect::TEvNodeDisconnected::EventType, SomeSleep); + } + } +}; + IActor* CreateStateStorageReplicaProbe(TActorId replica) { - return new TStateStorageReplicaProbe(replica); -} - -} + return new TStateStorageReplicaProbe(replica); +} + +} diff --git a/ydb/core/base/statestorage_ut.cpp b/ydb/core/base/statestorage_ut.cpp index 512ac834b9..94a49082db 100644 --- a/ydb/core/base/statestorage_ut.cpp +++ b/ydb/core/base/statestorage_ut.cpp @@ -1,41 +1,41 @@ -#include "statestorage.h" - -#include <util/generic/xrange.h> +#include "statestorage.h" + +#include <util/generic/xrange.h> #include <library/cpp/testing/unittest/registar.h> - -namespace NKikimr { - -Y_UNIT_TEST_SUITE(TStateStorageConfig) { - + +namespace NKikimr { + +Y_UNIT_TEST_SUITE(TStateStorageConfig) { + void FillStateStorageInfo(TStateStorageInfo *info, ui32 replicas, ui32 nToSelect, ui32 replicasInRing, bool useRingSpecificNodeSelection) { - info->StateStorageGroup = 1; - info->NToSelect = nToSelect; - - info->Rings.resize(replicas); - for (ui32 i : xrange(replicas)) { - for (ui32 j : xrange(replicasInRing)) { + info->StateStorageGroup = 1; + info->NToSelect = nToSelect; + + info->Rings.resize(replicas); + for (ui32 i : xrange(replicas)) { + for (ui32 j : xrange(replicasInRing)) { info->Rings[i].Replicas.push_back(TActorId(i, i, i + j, i)); info->Rings[i].UseRingSpecificNodeSelection = useRingSpecificNodeSelection; - } - } - } - + } + } + } + ui64 StabilityRun(ui32 replicas, ui32 nToSelect, ui32 replicasInRing, bool useRingSpecificNodeSelection) { - ui64 retHash = 0; - - TStateStorageInfo info; + ui64 retHash = 0; + + TStateStorageInfo info; FillStateStorageInfo(&info, replicas, nToSelect, replicasInRing, useRingSpecificNodeSelection); - - TStateStorageInfo::TSelection selection; - for (ui64 tabletId = 8000000; tabletId < 9000000; ++tabletId) { - info.SelectReplicas(tabletId, &selection); - Y_VERIFY(nToSelect == selection.Sz); - for (ui32 idx : xrange(nToSelect)) - retHash = CombineHashes<ui64>(retHash, selection.SelectedReplicas[idx].Hash()); - } - return retHash; - } - + + TStateStorageInfo::TSelection selection; + for (ui64 tabletId = 8000000; tabletId < 9000000; ++tabletId) { + info.SelectReplicas(tabletId, &selection); + Y_VERIFY(nToSelect == selection.Sz); + for (ui32 idx : xrange(nToSelect)) + retHash = CombineHashes<ui64>(retHash, selection.SelectedReplicas[idx].Hash()); + } + return retHash; + } + double UniqueCombinationsRun(ui32 replicas, ui32 nToSelect, ui32 replicasInRing, bool useRingSpecificNodeSelection) { const ui64 tabletStartId = 8000000; const ui64 tabletCount = 1000000; @@ -56,24 +56,24 @@ Y_UNIT_TEST_SUITE(TStateStorageConfig) { return static_cast<double>(hashes.size()) / static_cast<double>(tabletCount); } - Y_UNIT_TEST(TestReplicaSelection) { + Y_UNIT_TEST(TestReplicaSelection) { UNIT_ASSERT(StabilityRun(3, 3, 1, false) == 17606246762804570019ULL); UNIT_ASSERT(StabilityRun(13, 3, 1, false) == 421354124534079828ULL); UNIT_ASSERT(StabilityRun(13, 9, 1, false) == 10581416019959162949ULL); UNIT_ASSERT(StabilityRun(3, 3, 1, true) == 17606246762804570019ULL); UNIT_ASSERT(StabilityRun(13, 3, 1, true) == 421354124534079828ULL); UNIT_ASSERT(StabilityRun(13, 9, 1, true) == 10581416019959162949ULL); - } - - Y_UNIT_TEST(TestMultiReplicaFailDomains) { + } + + Y_UNIT_TEST(TestMultiReplicaFailDomains) { UNIT_ASSERT(StabilityRun(3, 3, 3, false) == 12043409773822600429ULL); UNIT_ASSERT(StabilityRun(13, 3, 5, false) == 3265154396592024904ULL); UNIT_ASSERT(StabilityRun(13, 9, 8, false) == 12079940289459527060ULL); UNIT_ASSERT(StabilityRun(3, 3, 3, true) == 7845257406715748850ULL); UNIT_ASSERT(StabilityRun(13, 3, 5, true) == 1986618578793030392ULL); UNIT_ASSERT(StabilityRun(13, 9, 8, true) == 6173011524598124144ULL); - } - + } + Y_UNIT_TEST(TestReplicaSelectionUniqueCombinations) { UNIT_ASSERT_DOUBLES_EQUAL(UniqueCombinationsRun(13, 3, 1, false), 0.000206, 1e-7); UNIT_ASSERT_DOUBLES_EQUAL(UniqueCombinationsRun(13, 3, 3, false), 0.000519, 1e-7); @@ -91,33 +91,33 @@ Y_UNIT_TEST_SUITE(TStateStorageConfig) { double UniformityRun(ui32 replicas, ui32 nToSelect, ui32 replicasInRing, bool useRingSpecificNodeSelection) { THashMap<TActorId, ui32> history; - - TStateStorageInfo info; + + TStateStorageInfo info; FillStateStorageInfo(&info, replicas, nToSelect, replicasInRing, useRingSpecificNodeSelection); - - TStateStorageInfo::TSelection selection; - for (ui64 tabletId = 8000000; tabletId < 9000000; ++tabletId) { - info.SelectReplicas(tabletId, &selection); - Y_VERIFY(nToSelect == selection.Sz); - for (ui32 idx : xrange(nToSelect)) - history[selection.SelectedReplicas[idx]] += 1; - } - - ui32 mn = history.begin()->second; - ui32 mx = history.begin()->second; - - for (auto &x : history) { - const ui32 cur = x.second; - if (cur < mn) - mn = cur; - if (cur > mx) - mx = cur; - } - - return static_cast<double>(mx - mn) / static_cast<double>(mx); - } - - Y_UNIT_TEST(UniformityTest) { + + TStateStorageInfo::TSelection selection; + for (ui64 tabletId = 8000000; tabletId < 9000000; ++tabletId) { + info.SelectReplicas(tabletId, &selection); + Y_VERIFY(nToSelect == selection.Sz); + for (ui32 idx : xrange(nToSelect)) + history[selection.SelectedReplicas[idx]] += 1; + } + + ui32 mn = history.begin()->second; + ui32 mx = history.begin()->second; + + for (auto &x : history) { + const ui32 cur = x.second; + if (cur < mn) + mn = cur; + if (cur > mx) + mx = cur; + } + + return static_cast<double>(mx - mn) / static_cast<double>(mx); + } + + Y_UNIT_TEST(UniformityTest) { UNIT_ASSERT(UniformityRun(13, 3, 1, false) < 0.10); UNIT_ASSERT(UniformityRun(13, 3, 3, false) < 0.10); UNIT_ASSERT(UniformityRun(113, 3, 1, false) < 0.10); @@ -130,7 +130,7 @@ Y_UNIT_TEST_SUITE(TStateStorageConfig) { UNIT_ASSERT(UniformityRun(113, 3, 5, true) < 0.10); UNIT_ASSERT(UniformityRun(113, 9, 1, true) < 0.10); UNIT_ASSERT(UniformityRun(113, 9, 8, true) < 0.10); - } -} - -} + } +} + +} diff --git a/ydb/core/base/statestorage_warden.cpp b/ydb/core/base/statestorage_warden.cpp index d383a2272b..972a74e1fb 100644 --- a/ydb/core/base/statestorage_warden.cpp +++ b/ydb/core/base/statestorage_warden.cpp @@ -1,8 +1,8 @@ -#include "statestorage_impl.h" -#include "tabletid.h" -#include "appdata.h" -#include "tablet.h" - +#include "statestorage_impl.h" +#include "tabletid.h" +#include "appdata.h" +#include "tablet.h" + #include <ydb/core/protos/services.pb.h> #include <ydb/core/cms/cms.h> #include <ydb/core/cms/console/console.h> @@ -11,141 +11,141 @@ #include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/actors/core/hfunc.h> #include <library/cpp/actors/core/log.h> - -#include <util/generic/map.h> -#include <util/generic/hash_set.h> - -#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR || defined BLOG_TRACE -#error log macro definition clash -#endif - -#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) -#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) -#define BLOG_W(stream) LOG_WARN_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) -#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) - -namespace NKikimr { - -class TStateStorageWarden : public TActorBootstrapped<TStateStorageWarden> { - const ui32 GroupId; // for convenience - - TIntrusivePtr<TStateStorageInfo> StateStorageInfo; - TIntrusivePtr<TStateStorageInfo> BoardInfo; - TIntrusivePtr<TStateStorageInfo> SchemeBoardInfo; - - template<typename TCreateFunc> - bool UpdateReplicaInfo(TIntrusivePtr<TStateStorageInfo> &updated, TIntrusivePtr<TStateStorageInfo> ¤t, TCreateFunc createFunc) { - // updates current to updated, kills unused replicas, starts new - // returns true is smth changed - const ui32 selfNode = SelfId().NodeId(); - TActorSystem *sys = TlsActivationContext->ExecutorThread.ActorSystem; - const ui32 sysPoolId = AppData()->SystemPoolId; - - bool hasChanges = false; - - const bool checkRings = (updated->Rings.size() == current->Rings.size()) && (updated->NToSelect == current->NToSelect); - ui32 ringIdx = 0; - ui32 index = 0; - for (const ui32 ringSz = updated->Rings.size(); ringIdx < ringSz; ++ringIdx) { - const auto &replicas = updated->Rings[ringIdx].Replicas; - const bool checkReplicas = checkRings && (replicas.size() == current->Rings[ringIdx].Replicas.size()); - - ui32 replicaIdx = 0; - for (const ui32 replicaSz = replicas.size(); replicaIdx < replicaSz; ++replicaIdx, ++index) { - // keep previous - if (checkReplicas && replicas[replicaIdx] == current->Rings[ringIdx].Replicas[replicaIdx]) - continue; - - hasChanges = true; - - // should kill? - if (ringIdx < current->Rings.size() && replicaIdx < current->Rings[ringIdx].Replicas.size()) { + +#include <util/generic/map.h> +#include <util/generic/hash_set.h> + +#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR || defined BLOG_TRACE +#error log macro definition clash +#endif + +#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) +#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) +#define BLOG_W(stream) LOG_WARN_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) +#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::STATESTORAGE, stream) + +namespace NKikimr { + +class TStateStorageWarden : public TActorBootstrapped<TStateStorageWarden> { + const ui32 GroupId; // for convenience + + TIntrusivePtr<TStateStorageInfo> StateStorageInfo; + TIntrusivePtr<TStateStorageInfo> BoardInfo; + TIntrusivePtr<TStateStorageInfo> SchemeBoardInfo; + + template<typename TCreateFunc> + bool UpdateReplicaInfo(TIntrusivePtr<TStateStorageInfo> &updated, TIntrusivePtr<TStateStorageInfo> ¤t, TCreateFunc createFunc) { + // updates current to updated, kills unused replicas, starts new + // returns true is smth changed + const ui32 selfNode = SelfId().NodeId(); + TActorSystem *sys = TlsActivationContext->ExecutorThread.ActorSystem; + const ui32 sysPoolId = AppData()->SystemPoolId; + + bool hasChanges = false; + + const bool checkRings = (updated->Rings.size() == current->Rings.size()) && (updated->NToSelect == current->NToSelect); + ui32 ringIdx = 0; + ui32 index = 0; + for (const ui32 ringSz = updated->Rings.size(); ringIdx < ringSz; ++ringIdx) { + const auto &replicas = updated->Rings[ringIdx].Replicas; + const bool checkReplicas = checkRings && (replicas.size() == current->Rings[ringIdx].Replicas.size()); + + ui32 replicaIdx = 0; + for (const ui32 replicaSz = replicas.size(); replicaIdx < replicaSz; ++replicaIdx, ++index) { + // keep previous + if (checkReplicas && replicas[replicaIdx] == current->Rings[ringIdx].Replicas[replicaIdx]) + continue; + + hasChanges = true; + + // should kill? + if (ringIdx < current->Rings.size() && replicaIdx < current->Rings[ringIdx].Replicas.size()) { const TActorId outdated = current->Rings[ringSz].Replicas[replicaIdx]; - if (outdated.NodeId() == selfNode) { + if (outdated.NodeId() == selfNode) { sys->RegisterLocalService(outdated, TActorId()); - Send(outdated, new TEvents::TEvPoison()); - } - } - - // must start? - if (replicas[replicaIdx].NodeId() == selfNode) { + Send(outdated, new TEvents::TEvPoison()); + } + } + + // must start? + if (replicas[replicaIdx].NodeId() == selfNode) { const TActorId replicaActorId = Register(createFunc(updated.Get(), index), TMailboxType::ReadAsFilled, sysPoolId); - sys->RegisterLocalService(replicas[replicaIdx], replicaActorId); - } - } - } - - if (hasChanges) - current = updated; - - return hasChanges; - } - - void UpdateConfig(const NKikimrConfig::TDomainsConfig::TStateStorage &config) { - TIntrusivePtr<TStateStorageInfo> stateStorageInfo; - TIntrusivePtr<TStateStorageInfo> boardInfo; - TIntrusivePtr<TStateStorageInfo> schemeBoardInfo; - - BuildStateStorageInfos(config, stateStorageInfo, boardInfo, schemeBoardInfo); - - bool hasChanges = false; - - hasChanges |= UpdateReplicaInfo(stateStorageInfo, StateStorageInfo, CreateStateStorageReplica); - hasChanges |= UpdateReplicaInfo(boardInfo, BoardInfo, CreateStateStorageBoardReplica); - hasChanges |= UpdateReplicaInfo(schemeBoardInfo, SchemeBoardInfo, CreateSchemeBoardReplica); - - // Update proxy config - if (hasChanges) { - Send(MakeStateStorageProxyID(GroupId), new TEvStateStorage::TEvUpdateGroupConfig(stateStorageInfo, boardInfo, schemeBoardInfo)); - } - } - - void Handle(NConsole::TEvConsole::TEvConfigNotificationRequest::TPtr &ev) { - const auto &record = ev->Get()->Record; - - if (!record.GetConfig().HasDomainsConfig()) - return; - - for (const NKikimrConfig::TDomainsConfig::TStateStorage &config : record.GetConfig().GetDomainsConfig().GetStateStorage()) { - if (config.GetSSId() == GroupId) { - UpdateConfig(config); - break; - } - } - } - -public: - static constexpr NKikimrServices::TActivity::EType ActorActivityType() { - return NKikimrServices::TActivity::SS_PROXY; - } - - TStateStorageWarden(const TIntrusivePtr<TStateStorageInfo> &info, const TIntrusivePtr<TStateStorageInfo> &board, const TIntrusivePtr<TStateStorageInfo> &schemeBoard) - : GroupId(info->StateStorageGroup) - , StateStorageInfo(info) - , BoardInfo(board) - , SchemeBoardInfo(schemeBoard) - { - Y_VERIFY(GroupId == board->StateStorageGroup); - Y_VERIFY(GroupId == schemeBoard->StateStorageGroup); - } - - void Bootstrap() - { - Send(NConsole::MakeConfigsDispatcherID(SelfId().NodeId()), - new NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionRequest(NKikimrConsole::TConfigItem::DomainsConfigItem)); - Become(&TThis::StateWork); - } - - STATEFN(StateWork) { - switch (ev->GetTypeRewrite()) { - cFunc(TEvents::TEvPoison::EventType, PassAway); - hFunc(NConsole::TEvConsole::TEvConfigNotificationRequest, Handle); - } - } -}; - -IActor* CreateStateStorageWarden(const TIntrusivePtr<TStateStorageInfo> &info, const TIntrusivePtr<TStateStorageInfo> &board, const TIntrusivePtr<TStateStorageInfo> &schemeBoard) { - return new TStateStorageWarden(info, board, schemeBoard); -} - -} + sys->RegisterLocalService(replicas[replicaIdx], replicaActorId); + } + } + } + + if (hasChanges) + current = updated; + + return hasChanges; + } + + void UpdateConfig(const NKikimrConfig::TDomainsConfig::TStateStorage &config) { + TIntrusivePtr<TStateStorageInfo> stateStorageInfo; + TIntrusivePtr<TStateStorageInfo> boardInfo; + TIntrusivePtr<TStateStorageInfo> schemeBoardInfo; + + BuildStateStorageInfos(config, stateStorageInfo, boardInfo, schemeBoardInfo); + + bool hasChanges = false; + + hasChanges |= UpdateReplicaInfo(stateStorageInfo, StateStorageInfo, CreateStateStorageReplica); + hasChanges |= UpdateReplicaInfo(boardInfo, BoardInfo, CreateStateStorageBoardReplica); + hasChanges |= UpdateReplicaInfo(schemeBoardInfo, SchemeBoardInfo, CreateSchemeBoardReplica); + + // Update proxy config + if (hasChanges) { + Send(MakeStateStorageProxyID(GroupId), new TEvStateStorage::TEvUpdateGroupConfig(stateStorageInfo, boardInfo, schemeBoardInfo)); + } + } + + void Handle(NConsole::TEvConsole::TEvConfigNotificationRequest::TPtr &ev) { + const auto &record = ev->Get()->Record; + + if (!record.GetConfig().HasDomainsConfig()) + return; + + for (const NKikimrConfig::TDomainsConfig::TStateStorage &config : record.GetConfig().GetDomainsConfig().GetStateStorage()) { + if (config.GetSSId() == GroupId) { + UpdateConfig(config); + break; + } + } + } + +public: + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { + return NKikimrServices::TActivity::SS_PROXY; + } + + TStateStorageWarden(const TIntrusivePtr<TStateStorageInfo> &info, const TIntrusivePtr<TStateStorageInfo> &board, const TIntrusivePtr<TStateStorageInfo> &schemeBoard) + : GroupId(info->StateStorageGroup) + , StateStorageInfo(info) + , BoardInfo(board) + , SchemeBoardInfo(schemeBoard) + { + Y_VERIFY(GroupId == board->StateStorageGroup); + Y_VERIFY(GroupId == schemeBoard->StateStorageGroup); + } + + void Bootstrap() + { + Send(NConsole::MakeConfigsDispatcherID(SelfId().NodeId()), + new NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionRequest(NKikimrConsole::TConfigItem::DomainsConfigItem)); + Become(&TThis::StateWork); + } + + STATEFN(StateWork) { + switch (ev->GetTypeRewrite()) { + cFunc(TEvents::TEvPoison::EventType, PassAway); + hFunc(NConsole::TEvConsole::TEvConfigNotificationRequest, Handle); + } + } +}; + +IActor* CreateStateStorageWarden(const TIntrusivePtr<TStateStorageInfo> &info, const TIntrusivePtr<TStateStorageInfo> &board, const TIntrusivePtr<TStateStorageInfo> &schemeBoard) { + return new TStateStorageWarden(info, board, schemeBoard); +} + +} diff --git a/ydb/core/base/tablet.cpp b/ydb/core/base/tablet.cpp index 9267c0f972..db3a3deb80 100644 --- a/ydb/core/base/tablet.cpp +++ b/ydb/core/base/tablet.cpp @@ -1,102 +1,102 @@ -#include "tablet.h" - -namespace NKikimr { - +#include "tablet.h" + +namespace NKikimr { + TIntrusivePtr<TTabletStorageInfo> TabletStorageInfoFromProto(const NKikimrTabletBase::TTabletStorageInfo &proto) { auto info = MakeIntrusive<TTabletStorageInfo>(); - - info->TabletID = proto.GetTabletID(); - - if (proto.HasTabletType()) - info->TabletType = proto.GetTabletType(); - - if (proto.HasVersion()) - info->Version = proto.GetVersion(); - - info->Channels.resize((ui32)proto.ChannelsSize()); - for (ui32 i = 0, e = info->Channels.size(); i != e; ++i) { - const NKikimrTabletBase::TTabletChannelInfo &channelInfo = proto.GetChannels(i); - TTabletChannelInfo &x = info->Channels[i]; - x.Channel = channelInfo.GetChannel(); - - if (channelInfo.HasChannelType()) { - auto erasure = (TBlobStorageGroupType::EErasureSpecies)channelInfo.GetChannelType(); - x.Type = TBlobStorageGroupType(erasure); - Y_VERIFY(!channelInfo.HasChannelErasureName()); - } else { - auto erasure = TBlobStorageGroupType::ErasureSpeciesByName(channelInfo.GetChannelErasureName()); - x.Type = TBlobStorageGroupType(erasure); - } - Y_VERIFY((ui32)x.Type.GetErasure() < x.Type.ErasureSpeciesCount); - - x.StoragePool = channelInfo.GetStoragePool(); - - x.History.resize((ui32)channelInfo.HistorySize()); - for (ui32 j = 0, je = x.History.size(); j != je; ++j) { - const NKikimrTabletBase::TTabletChannelInfo::THistoryEntry &entry = channelInfo.GetHistory(j); - TTabletChannelInfo::THistoryEntry &m = x.History[j]; - - m.FromGeneration = entry.GetFromGeneration(); - m.GroupID = entry.GetGroupID(); - } - } - - if ((proto.HasTenantIdOwner() && proto.GetTenantIdOwner() && proto.GetTenantIdOwner() != InvalidOwnerId) - || (proto.HasTenantIdLocalId() && proto.GetTenantIdLocalId() && proto.GetTenantIdLocalId() != InvalidLocalPathId)) - { - info->TenantPathId = TPathId(proto.GetTenantIdOwner(), proto.GetTenantIdLocalId()); - } - - return info; -} - -void TabletStorageInfoToProto(const TTabletStorageInfo &info, NKikimrTabletBase::TTabletStorageInfo *proto) { - proto->SetTabletID(info.TabletID); - proto->SetTabletType(info.TabletType); - proto->SetVersion(info.Version); - proto->MutableChannels()->Clear(); - proto->MutableChannels()->Reserve(info.Channels.size()); - - for (ui32 i = 0, e = info.Channels.size(); i != e; ++i) { - NKikimrTabletBase::TTabletChannelInfo *x = proto->MutableChannels()->Add(); - const TTabletChannelInfo &channelInfo = info.Channels[i]; - x->SetChannel(channelInfo.Channel); - x->SetChannelType(channelInfo.Type.GetErasure()); - x->SetStoragePool(channelInfo.StoragePool); - - x->MutableHistory()->Reserve(channelInfo.History.size()); - for (ui32 j = 0, je = channelInfo.History.size(); j != je; ++j) { - NKikimrTabletBase::TTabletChannelInfo::THistoryEntry *m = x->MutableHistory()->Add(); - const TTabletChannelInfo::THistoryEntry &entry = channelInfo.History[j]; - m->SetFromGeneration(entry.FromGeneration); - m->SetGroupID(entry.GroupID); - } - } - - if (info.TenantPathId) { - proto->SetTenantIdOwner(info.TenantPathId.OwnerId); - proto->SetTenantIdLocalId(info.TenantPathId.LocalPathId); - } -} - -const char* TEvTablet::TEvTabletDead::Str(EReason status) { - switch (status) { - TABLET_DEAD_REASON_MAP(ENUM_TO_STRING_IMPL_ITEM) - default: - return "TabletReadReasonNotDefined"; - } -} - -void TEvTablet::TEvTabletDead::Out(IOutputStream& os, EReason x) { - switch (x) { - TABLET_DEAD_REASON_MAP(ENUM_LTLT_IMPL_ITEM); - default: - os << static_cast<int>(x); - return; - } -} - -} + + info->TabletID = proto.GetTabletID(); + + if (proto.HasTabletType()) + info->TabletType = proto.GetTabletType(); + + if (proto.HasVersion()) + info->Version = proto.GetVersion(); + + info->Channels.resize((ui32)proto.ChannelsSize()); + for (ui32 i = 0, e = info->Channels.size(); i != e; ++i) { + const NKikimrTabletBase::TTabletChannelInfo &channelInfo = proto.GetChannels(i); + TTabletChannelInfo &x = info->Channels[i]; + x.Channel = channelInfo.GetChannel(); + + if (channelInfo.HasChannelType()) { + auto erasure = (TBlobStorageGroupType::EErasureSpecies)channelInfo.GetChannelType(); + x.Type = TBlobStorageGroupType(erasure); + Y_VERIFY(!channelInfo.HasChannelErasureName()); + } else { + auto erasure = TBlobStorageGroupType::ErasureSpeciesByName(channelInfo.GetChannelErasureName()); + x.Type = TBlobStorageGroupType(erasure); + } + Y_VERIFY((ui32)x.Type.GetErasure() < x.Type.ErasureSpeciesCount); + + x.StoragePool = channelInfo.GetStoragePool(); + + x.History.resize((ui32)channelInfo.HistorySize()); + for (ui32 j = 0, je = x.History.size(); j != je; ++j) { + const NKikimrTabletBase::TTabletChannelInfo::THistoryEntry &entry = channelInfo.GetHistory(j); + TTabletChannelInfo::THistoryEntry &m = x.History[j]; + + m.FromGeneration = entry.GetFromGeneration(); + m.GroupID = entry.GetGroupID(); + } + } + + if ((proto.HasTenantIdOwner() && proto.GetTenantIdOwner() && proto.GetTenantIdOwner() != InvalidOwnerId) + || (proto.HasTenantIdLocalId() && proto.GetTenantIdLocalId() && proto.GetTenantIdLocalId() != InvalidLocalPathId)) + { + info->TenantPathId = TPathId(proto.GetTenantIdOwner(), proto.GetTenantIdLocalId()); + } + + return info; +} + +void TabletStorageInfoToProto(const TTabletStorageInfo &info, NKikimrTabletBase::TTabletStorageInfo *proto) { + proto->SetTabletID(info.TabletID); + proto->SetTabletType(info.TabletType); + proto->SetVersion(info.Version); + proto->MutableChannels()->Clear(); + proto->MutableChannels()->Reserve(info.Channels.size()); + + for (ui32 i = 0, e = info.Channels.size(); i != e; ++i) { + NKikimrTabletBase::TTabletChannelInfo *x = proto->MutableChannels()->Add(); + const TTabletChannelInfo &channelInfo = info.Channels[i]; + x->SetChannel(channelInfo.Channel); + x->SetChannelType(channelInfo.Type.GetErasure()); + x->SetStoragePool(channelInfo.StoragePool); + + x->MutableHistory()->Reserve(channelInfo.History.size()); + for (ui32 j = 0, je = channelInfo.History.size(); j != je; ++j) { + NKikimrTabletBase::TTabletChannelInfo::THistoryEntry *m = x->MutableHistory()->Add(); + const TTabletChannelInfo::THistoryEntry &entry = channelInfo.History[j]; + m->SetFromGeneration(entry.FromGeneration); + m->SetGroupID(entry.GroupID); + } + } + + if (info.TenantPathId) { + proto->SetTenantIdOwner(info.TenantPathId.OwnerId); + proto->SetTenantIdLocalId(info.TenantPathId.LocalPathId); + } +} + +const char* TEvTablet::TEvTabletDead::Str(EReason status) { + switch (status) { + TABLET_DEAD_REASON_MAP(ENUM_TO_STRING_IMPL_ITEM) + default: + return "TabletReadReasonNotDefined"; + } +} + +void TEvTablet::TEvTabletDead::Out(IOutputStream& os, EReason x) { + switch (x) { + TABLET_DEAD_REASON_MAP(ENUM_LTLT_IMPL_ITEM); + default: + os << static_cast<int>(x); + return; + } +} + +} Y_DECLARE_OUT_SPEC(, NKikimr::TEvTablet::TEvTabletStop::EReason, o, x) { o << NKikimrTabletBase::TEvTabletStop::EReason_Name(x); diff --git a/ydb/core/base/tablet.h b/ydb/core/base/tablet.h index ac25709d73..602e39c600 100644 --- a/ydb/core/base/tablet.h +++ b/ydb/core/base/tablet.h @@ -1,8 +1,8 @@ -#pragma once +#pragma once #include "blobstorage.h" -#include "defs.h" -#include "events.h" -#include "logoblob.h" +#include "defs.h" +#include "events.h" +#include "logoblob.h" #include "shared_quota.h" #include <ydb/core/base/resource_profile.h> @@ -12,37 +12,37 @@ #include <ydb/core/tablet/tablet_metrics.h> #include <library/cpp/deprecated/enum_codegen/enum_codegen.h> -#include <util/generic/deque.h> -#include <util/generic/vector.h> -#include <util/datetime/base.h> +#include <util/generic/deque.h> +#include <util/generic/vector.h> +#include <util/datetime/base.h> #include <functional> - -namespace NKikimr { - + +namespace NKikimr { + TIntrusivePtr<TTabletStorageInfo> TabletStorageInfoFromProto(const NKikimrTabletBase::TTabletStorageInfo &proto); -void TabletStorageInfoToProto(const TTabletStorageInfo &info, NKikimrTabletBase::TTabletStorageInfo *proto); - -inline ui64 MakeGenStepPair(ui32 gen, ui32 step) { - ui64 g = gen; - ui64 s = step; - return (g << 32ull) | s; -} - +void TabletStorageInfoToProto(const TTabletStorageInfo &info, NKikimrTabletBase::TTabletStorageInfo *proto); + +inline ui64 MakeGenStepPair(ui32 gen, ui32 step) { + ui64 g = gen; + ui64 s = step; + return (g << 32ull) | s; +} + inline std::pair<ui32, ui32> ExpandGenStepPair(ui64 x) { - ui32 g = (ui32)(x >> 32ull); - ui32 s = (ui32)(x); + ui32 g = (ui32)(x >> 32ull); + ui32 s = (ui32)(x); return std::pair<ui32, ui32>(g, s); -} - -struct TEvTablet { - enum EEv { - EvBoot = EventSpaceBegin(TKikimrEvents::ES_TABLET), - EvRestored, - EvCommitStatus, - EvCommitResult, - EvPing, - EvDemoted, +} + +struct TEvTablet { + enum EEv { + EvBoot = EventSpaceBegin(TKikimrEvents::ES_TABLET), + EvRestored, + EvCommitStatus, + EvCommitResult, + EvPing, + EvDemoted, EvNewFollowerAttached, EvFBoot, EvFUpdate, @@ -52,25 +52,25 @@ struct TEvTablet { EvFollowerSyncComplete, // from leader to user tablet when all old followers are touched and synced EvCutTabletHistory, EvUpdateConfig, - - EvCommit = EvBoot + 512, - EvAux, - EvPong, - EvPreCommit, - EvTabletActive, + + EvCommit = EvBoot + 512, + EvAux, + EvPong, + EvPreCommit, + EvTabletActive, EvPromoteToLeader, EvFGcAck, // from user tablet to follower - - EvTabletDead = EvBoot + 1024, + + EvTabletDead = EvBoot + 1024, EvFollowerUpdateState, // notifications to guardian EvFeatures, // from user tablet to sys tablet, notify on supported features EvTabletStop, // from local to sys tablet, from sys tablet to user tablet EvTabletStopped, // from user tablet to sys tablet, ready to die now - + EvReadLocalBase = EvBoot + 1536, EvReadLocalBaseResult, - EvLocalMKQL, - EvLocalMKQLResponse, + EvLocalMKQL, + EvLocalMKQLResponse, EvLocalSchemeTx, EvLocalSchemeTxResponse, EvGetCounters, @@ -82,66 +82,66 @@ struct TEvTablet { EvFollowerAttach = EvBoot + 2048, EvFollowerDetach, EvFollowerListRefresh, // from guardian to leader - EvReserved_00, + EvReserved_00, EvFollowerGcAck, // from follower to leader - + // from leader to follower EvFollowerUpdate = EvBoot + 2560, EvFollowerAuxUpdate, - EvReserved_01, + EvReserved_01, EvFollowerDisconnect, EvFollowerRefresh, // from leader to follower - - // utilitary - EvCheckBlobstorageStatusResult = EvBoot + 3072, + + // utilitary + EvCheckBlobstorageStatusResult = EvBoot + 3072, EvResetTabletResult, - - EvEnd - }; - + + EvEnd + }; + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_TABLET), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_TABLET)"); - - struct TDependencyGraph : public TThrRefBase { - struct TEntry { + + struct TDependencyGraph : public TThrRefBase { + struct TEntry { std::pair<ui32, ui32> Id; - bool IsSnapshot; + bool IsSnapshot; TVector<TLogoBlobID> References; - + TVector<TLogoBlobID> GcDiscovered; TVector<TLogoBlobID> GcLeft; - + TString EmbeddedLogBody; - - TEntry() - : IsSnapshot(false) - {} - + + TEntry() + : IsSnapshot(false) + {} + void Set(const std::pair<ui32, ui32> &id, TVector<TLogoBlobID> &refs, bool isSnapshot, TVector<TLogoBlobID> &gcDiscovered, TVector<TLogoBlobID> &gcLeft) { - Id = id; - References.swap(refs); - IsSnapshot = isSnapshot; - GcDiscovered.swap(gcDiscovered); - GcLeft.swap(gcLeft); - EmbeddedLogBody.clear(); - } - + Id = id; + References.swap(refs); + IsSnapshot = isSnapshot; + GcDiscovered.swap(gcDiscovered); + GcLeft.swap(gcLeft); + EmbeddedLogBody.clear(); + } + void Set(const std::pair<ui32, ui32> &id, const TString &embeddedLogBody, TVector<TLogoBlobID> &gcDiscovered, TVector<TLogoBlobID> &gcLeft) { - Id = id; - References.clear(); - IsSnapshot = false; - GcDiscovered.swap(gcDiscovered); - GcLeft.swap(gcLeft); - EmbeddedLogBody = embeddedLogBody; - } - }; - + Id = id; + References.clear(); + IsSnapshot = false; + GcDiscovered.swap(gcDiscovered); + GcLeft.swap(gcLeft); + EmbeddedLogBody = embeddedLogBody; + } + }; + std::pair<ui32, ui32> Snapshot; TDeque<TEntry> Entries; - + TDependencyGraph(const std::pair<ui32, ui32> &snap) - : Snapshot(snap) - {} - + : Snapshot(snap) + {} + void Describe(IOutputStream &out) const noexcept { out << "Deps{" << Snapshot.first << ":" << Snapshot.second @@ -149,41 +149,41 @@ struct TEvTablet { } void AddEntry(const std::pair<ui32, ui32> &id, TVector<TLogoBlobID> &references, bool isSnapshot, TVector<TLogoBlobID> &gcDiscovered, TVector<TLogoBlobID> &gcLeft) { - if (isSnapshot) { - Snapshot = id; - Entries.clear(); - } - - Entries.push_back(TEntry()); - Entries.back().Set(id, references, isSnapshot, gcDiscovered, gcLeft); - } - + if (isSnapshot) { + Snapshot = id; + Entries.clear(); + } + + Entries.push_back(TEntry()); + Entries.back().Set(id, references, isSnapshot, gcDiscovered, gcLeft); + } + void AddEntry(const std::pair<ui32, ui32> &id, const TString &embeddedLogBody, TVector<TLogoBlobID> &gcDiscovered, TVector<TLogoBlobID> &gcLeft) { - Entries.push_back(TEntry()); - Entries.back().Set(id, embeddedLogBody, gcDiscovered, gcLeft); - } - - void Invalidate() { + Entries.push_back(TEntry()); + Entries.back().Set(id, embeddedLogBody, gcDiscovered, gcLeft); + } + + void Invalidate() { Snapshot = std::make_pair(Max<ui32>(), Max<ui32>()); - Entries.clear(); - } - - bool IsValid() const { + Entries.clear(); + } + + bool IsValid() const { return (Snapshot.first != Max<ui32>()); - } - }; - - using TLogEntryReference = TLogoBlob; - - // dependency graph to boot tablet, not yet ready - struct TEvBoot : public TEventLocal<TEvBoot, EvBoot> { - const ui64 TabletID; - const ui32 Generation; - - TIntrusivePtr<TDependencyGraph> DependencyGraph; - + } + }; + + using TLogEntryReference = TLogoBlob; + + // dependency graph to boot tablet, not yet ready + struct TEvBoot : public TEventLocal<TEvBoot, EvBoot> { + const ui64 TabletID; + const ui32 Generation; + + TIntrusivePtr<TDependencyGraph> DependencyGraph; + const TActorId Launcher; - TIntrusivePtr<TTabletStorageInfo> TabletStorageInfo; + TIntrusivePtr<TTabletStorageInfo> TabletStorageInfo; TResourceProfilesPtr ResourceProfiles; TSharedQuotaPtr TxCacheQuota; @@ -200,129 +200,129 @@ struct TEvTablet { TSharedQuotaPtr txCacheQuota = nullptr, NMetrics::TTabletThroughputRawValue&& read = NMetrics::TTabletThroughputRawValue(), NMetrics::TTabletIopsRawValue&& readOps = NMetrics::TTabletIopsRawValue()) - : TabletID(tabletId) - , Generation(generation) - , DependencyGraph(dependencyGraph) + : TabletID(tabletId) + , Generation(generation) + , DependencyGraph(dependencyGraph) , Launcher(launcher) - , TabletStorageInfo(info) + , TabletStorageInfo(info) , ResourceProfiles(profiles) , TxCacheQuota(txCacheQuota) , GroupReadBytes(std::move(read)) , GroupReadOps(std::move(readOps)) - {} - }; - - // tablet is ready for operation - struct TEvRestored : public TEventLocal<TEvRestored, EvRestored> { - const ui64 TabletID; - const ui32 Generation; + {} + }; + + // tablet is ready for operation + struct TEvRestored : public TEventLocal<TEvRestored, EvRestored> { + const ui64 TabletID; + const ui32 Generation; const TActorId UserTabletActor; const bool Follower; - + TEvRestored(ui64 tabletId, ui32 generation, const TActorId &userTabletActor, bool follower) - : TabletID(tabletId) - , Generation(generation) - , UserTabletActor(userTabletActor) + : TabletID(tabletId) + , Generation(generation) + , UserTabletActor(userTabletActor) , Follower(follower) - {} - }; - + {} + }; + struct TEvNewFollowerAttached : public TEventLocal<TEvNewFollowerAttached, EvNewFollowerAttached> { const ui32 TotalFollowers; - + TEvNewFollowerAttached(ui32 totalFollowers) : TotalFollowers(totalFollowers) - {} - }; - - // tablet - struct TCommitInfo { - const ui64 TabletID; - const ui32 Generation; - const ui32 Step; + {} + }; + + // tablet + struct TCommitInfo { + const ui64 TabletID; + const ui32 Generation; + const ui32 Step; const TVector<ui32> DependsOn; - const bool IsSnapshot; - bool IsTotalSnapshot; + const bool IsSnapshot; + bool IsTotalSnapshot; bool WaitFollowerGcAck; - + TCommitInfo(ui64 tabletId, ui32 gen, ui32 step, const TVector<ui32> &dependsOn, bool isSnapshot) - : TabletID(tabletId) - , Generation(gen) - , Step(step) - , DependsOn(dependsOn) - , IsSnapshot(isSnapshot) - , IsTotalSnapshot(false) + : TabletID(tabletId) + , Generation(gen) + , Step(step) + , DependsOn(dependsOn) + , IsSnapshot(isSnapshot) + , IsTotalSnapshot(false) , WaitFollowerGcAck(false) - {} - }; - - struct TEvCommit : public TEventLocal<TEvCommit, EvCommit>, public TCommitInfo { - const bool PreCommited; - TEvBlobStorage::TEvPut::ETactic CommitTactic; - + {} + }; + + struct TEvCommit : public TEventLocal<TEvCommit, EvCommit>, public TCommitInfo { + const bool PreCommited; + TEvBlobStorage::TEvPut::ETactic CommitTactic; + TVector<TLogoBlobID> ExternalReferences; TVector<TLogEntryReference> References; - + TVector<TLogoBlobID> GcDiscovered; TVector<TLogoBlobID> GcLeft; TString EmbeddedLogBody; TString FollowerAux; - - TEvCommit(ui64 tabletId, ui32 gen, ui32 step, const TVector<ui32> &dependsOn, bool isSnapshot - , bool preCommited = false - , TEvBlobStorage::TEvPut::ETactic tactic = TEvBlobStorage::TEvPut::TacticMinLatency) - : TCommitInfo(tabletId, gen, step, dependsOn, isSnapshot) - , PreCommited(preCommited) - , CommitTactic(tactic) - {} - }; - - struct TEvAux : public TEventLocal<TEvAux, EvAux> { + + TEvCommit(ui64 tabletId, ui32 gen, ui32 step, const TVector<ui32> &dependsOn, bool isSnapshot + , bool preCommited = false + , TEvBlobStorage::TEvPut::ETactic tactic = TEvBlobStorage::TEvPut::TacticMinLatency) + : TCommitInfo(tabletId, gen, step, dependsOn, isSnapshot) + , PreCommited(preCommited) + , CommitTactic(tactic) + {} + }; + + struct TEvAux : public TEventLocal<TEvAux, EvAux> { TString FollowerAux; - + TEvAux(TString followerAux) : FollowerAux(std::move(followerAux)) - {} - }; - - struct TEvPreCommit : public TEventLocal<TEvPreCommit, EvPreCommit>, public TCommitInfo { + {} + }; + + struct TEvPreCommit : public TEventLocal<TEvPreCommit, EvPreCommit>, public TCommitInfo { TEvPreCommit(ui64 tabletId, ui32 gen, ui32 step, const TVector<ui32> &dependsOn, bool isSnapshot) - : TCommitInfo(tabletId, gen, step, dependsOn, isSnapshot) - {} - }; - - struct TEvTabletActive : public TEventLocal<TEvTabletActive, EvTabletActive> {}; - - struct TEvDemoted : public TEventLocal<TEvDemoted, EvDemoted> { - const bool ByIsolation; - - TEvDemoted(bool byIsolation) - : ByIsolation(byIsolation) - {} - }; - + : TCommitInfo(tabletId, gen, step, dependsOn, isSnapshot) + {} + }; + + struct TEvTabletActive : public TEventLocal<TEvTabletActive, EvTabletActive> {}; + + struct TEvDemoted : public TEventLocal<TEvDemoted, EvDemoted> { + const bool ByIsolation; + + TEvDemoted(bool byIsolation) + : ByIsolation(byIsolation) + {} + }; + struct TEvPromoteToLeader : public TEventLocal<TEvPromoteToLeader, EvPromoteToLeader> { - const ui32 SuggestedGeneration; + const ui32 SuggestedGeneration; TIntrusivePtr<TTabletStorageInfo> TabletStorageInfo; - + TEvPromoteToLeader(ui32 suggestedGeneration, TIntrusivePtr<TTabletStorageInfo> info) - : SuggestedGeneration(suggestedGeneration) - , TabletStorageInfo(info) - {} - }; - - struct TEvCommitResult : public TEventLocal<TEvCommitResult, EvCommitResult> { - const NKikimrProto::EReplyStatus Status; - const ui64 TabletID; - const ui32 Generation; - const ui32 Step; + : SuggestedGeneration(suggestedGeneration) + , TabletStorageInfo(info) + {} + }; + + struct TEvCommitResult : public TEventLocal<TEvCommitResult, EvCommitResult> { + const NKikimrProto::EReplyStatus Status; + const ui64 TabletID; + const ui32 Generation; + const ui32 Step; const ui32 ConfirmedOnSend; TVector<ui32> YellowMoveChannels; TVector<ui32> YellowStopChannels; NMetrics::TTabletThroughputRawValue GroupWrittenBytes; NMetrics::TTabletIopsRawValue GroupWrittenOps; - + TEvCommitResult( NKikimrProto::EReplyStatus status, ui64 tabletId, @@ -333,146 +333,146 @@ struct TEvTablet { TVector<ui32>&& yellowStopChannels, NMetrics::TTabletThroughputRawValue&& written, NMetrics::TTabletIopsRawValue&& writtenOps) - : Status(status) - , TabletID(tabletId) - , Generation(gen) - , Step(step) + : Status(status) + , TabletID(tabletId) + , Generation(gen) + , Step(step) , ConfirmedOnSend(confirmedOnSend) , YellowMoveChannels(std::move(yellowMoveChannels)) , YellowStopChannels(std::move(yellowStopChannels)) , GroupWrittenBytes(std::move(written)) , GroupWrittenOps(std::move(writtenOps)) - {} - }; - - struct TEvTabletDead : public TEventLocal<TEvTabletDead, EvTabletDead> { -#define TABLET_DEAD_REASON_MAP(XX) \ - XX(ReasonBootLocked, 0) \ - XX(ReasonBootSSTimeout, 1) \ - XX(ReasonBootRace, 2) \ - XX(ReasonReserved01, 3) \ - XX(ReasonBootBSError, 4) \ - XX(ReasonBootSuggestOutdated, 5) \ + {} + }; + + struct TEvTabletDead : public TEventLocal<TEvTabletDead, EvTabletDead> { +#define TABLET_DEAD_REASON_MAP(XX) \ + XX(ReasonBootLocked, 0) \ + XX(ReasonBootSSTimeout, 1) \ + XX(ReasonBootRace, 2) \ + XX(ReasonReserved01, 3) \ + XX(ReasonBootBSError, 4) \ + XX(ReasonBootSuggestOutdated, 5) \ XX(ReasonBootSSError, 6) \ - XX(ReasonBootReservedValue, 32) \ - XX(ReasonPill, 33) \ - XX(ReasonError, 34) \ - XX(ReasonDemotedByStateStorage, 35) \ - XX(ReasonReserved03, 36) \ - XX(ReasonBSError, 37) \ - XX(ReasonInconsistentCommit, 38) \ - XX(ReasonIsolated, 39) \ - XX(ReasonDemotedByBlobStorage, 40) - - enum EReason { - TABLET_DEAD_REASON_MAP(ENUM_VALUE_GEN) - }; - + XX(ReasonBootReservedValue, 32) \ + XX(ReasonPill, 33) \ + XX(ReasonError, 34) \ + XX(ReasonDemotedByStateStorage, 35) \ + XX(ReasonReserved03, 36) \ + XX(ReasonBSError, 37) \ + XX(ReasonInconsistentCommit, 38) \ + XX(ReasonIsolated, 39) \ + XX(ReasonDemotedByBlobStorage, 40) + + enum EReason { + TABLET_DEAD_REASON_MAP(ENUM_VALUE_GEN) + }; + static void Out(IOutputStream& o, EReason x); - static const char* Str(EReason status); - - const ui64 TabletID; - const EReason Reason; - const ui32 Generation; - - bool IsBootReason() const { - return (Reason <= ReasonBootReservedValue); - } - - TEvTabletDead(ui64 tabletId, EReason reason, ui32 generation) - : TabletID(tabletId) - , Reason(reason) - , Generation(generation) - {} - }; - + static const char* Str(EReason status); + + const ui64 TabletID; + const EReason Reason; + const ui32 Generation; + + bool IsBootReason() const { + return (Reason <= ReasonBootReservedValue); + } + + TEvTabletDead(ui64 tabletId, EReason reason, ui32 generation) + : TabletID(tabletId) + , Reason(reason) + , Generation(generation) + {} + }; + struct TEvFollowerUpdateState : public TEventLocal<TEvFollowerUpdateState, EvFollowerUpdateState> { - const bool IsCandidate; + const bool IsCandidate; const TActorId FollowerActor; const TActorId TabletActor; - + TEvFollowerUpdateState(bool isCandidate, TActorId followerActor, TActorId tabletActor) - : IsCandidate(isCandidate) + : IsCandidate(isCandidate) , FollowerActor(followerActor) - , TabletActor(tabletActor) - {} - }; - - struct TEvPing : public TEventPB<TEvPing, NKikimrTabletBase::TEvPing, EvPing> { - enum EFlags { - FlagWaitBoot = 1, - }; - - TEvPing() - {} - - TEvPing(ui64 tabletId, ui64 flags) - { - Record.SetTabletID(tabletId); - Record.SetFlags(flags); - } - }; - - struct TEvPong : public TEventPB<TEvPong, NKikimrTabletBase::TEvPong, EvPong> { - enum EFlags { - FlagBoot = 1, + , TabletActor(tabletActor) + {} + }; + + struct TEvPing : public TEventPB<TEvPing, NKikimrTabletBase::TEvPing, EvPing> { + enum EFlags { + FlagWaitBoot = 1, + }; + + TEvPing() + {} + + TEvPing(ui64 tabletId, ui64 flags) + { + Record.SetTabletID(tabletId); + Record.SetFlags(flags); + } + }; + + struct TEvPong : public TEventPB<TEvPong, NKikimrTabletBase::TEvPong, EvPong> { + enum EFlags { + FlagBoot = 1, FlagLeader = 2, FlagFollower = 4, - }; - - TEvPong() - {} - - TEvPong(ui64 tabletId, ui64 flags) - { - Record.SetTabletID(tabletId); - Record.SetFlags(flags); - } - }; - - struct TEvReadLocalBase : public TEventPB<TEvReadLocalBase, NKikimrTabletBase::TEvReadLocalBase, EvReadLocalBase> { - TEvReadLocalBase() - {} + }; + + TEvPong() + {} + + TEvPong(ui64 tabletId, ui64 flags) + { + Record.SetTabletID(tabletId); + Record.SetFlags(flags); + } + }; + + struct TEvReadLocalBase : public TEventPB<TEvReadLocalBase, NKikimrTabletBase::TEvReadLocalBase, EvReadLocalBase> { + TEvReadLocalBase() + {} TEvReadLocalBase(const TString& rootKey, bool saveScheme) { - if (!rootKey.empty()) - Record.SetRootKey(rootKey); - if (saveScheme) - Record.SetSaveScheme(true); + if (!rootKey.empty()) + Record.SetRootKey(rootKey); + if (saveScheme) + Record.SetSaveScheme(true); } }; - struct TEvReadLocalBaseResult : public TEventPB<TEvReadLocalBaseResult, NKikimrTabletBase::TEvReadLocalBaseResult, TEvTablet::EvReadLocalBaseResult> { + struct TEvReadLocalBaseResult : public TEventPB<TEvReadLocalBaseResult, NKikimrTabletBase::TEvReadLocalBaseResult, TEvTablet::EvReadLocalBaseResult> { + + ui64 Origin() const { return Record.GetOrigin(); } + bool IsError() const { return Record.HasIsError() && Record.GetIsError(); } + TStringBuf DocBuffer() const { return Record.HasDocBuffer() ? Record.GetDocBuffer() : TStringBuf(); } + + TEvReadLocalBaseResult() + {} - ui64 Origin() const { return Record.GetOrigin(); } - bool IsError() const { return Record.HasIsError() && Record.GetIsError(); } - TStringBuf DocBuffer() const { return Record.HasDocBuffer() ? Record.GetDocBuffer() : TStringBuf(); } - - TEvReadLocalBaseResult() - {} - TEvReadLocalBaseResult(ui64 origin, const TString& rootKey, bool isError, const TString& docBuffer, const TString* schemeBuffer) { - Record.SetOrigin(origin); - Record.SetRootKey(rootKey); - Record.SetIsError(isError); - Record.SetDocBuffer(docBuffer); - if (schemeBuffer) - Record.SetScheme(*schemeBuffer); + Record.SetOrigin(origin); + Record.SetRootKey(rootKey); + Record.SetIsError(isError); + Record.SetDocBuffer(docBuffer); + if (schemeBuffer) + Record.SetScheme(*schemeBuffer); } }; - + struct TEvLocalMKQL : public TEventPB<TEvLocalMKQL, NKikimrTabletTxBase::TEvLocalMKQL, TEvTablet::EvLocalMKQL> { - TEvLocalMKQL() - {} - }; - + TEvLocalMKQL() + {} + }; + struct TEvLocalMKQLResponse : public TEventPB<TEvLocalMKQLResponse, NKikimrTabletTxBase::TEvLocalMKQLResponse, TEvTablet::EvLocalMKQLResponse> { - TEvLocalMKQLResponse() - {} - }; - + TEvLocalMKQLResponse() + {} + }; + struct TEvLocalSchemeTx : public TEventPB<TEvLocalSchemeTx, NKikimrTabletTxBase::TEvLocalSchemeTx, TEvTablet::EvLocalSchemeTx> { TEvLocalSchemeTx() {} @@ -495,225 +495,225 @@ struct TEvTablet { struct TEvFollowerAttach : public TEventPB<TEvFollowerAttach, NKikimrTabletBase::TEvFollowerAttach, EvFollowerAttach> { TEvFollowerAttach() - {} - + {} + TEvFollowerAttach(ui64 tabletId, ui32 followerAttempt) - { - Record.SetTabletId(tabletId); + { + Record.SetTabletId(tabletId); Record.SetFollowerAttempt(followerAttempt); - } - }; - + } + }; + struct TEvFollowerUpdate : public TEventPB<TEvFollowerUpdate, NKikimrTabletBase::TEvFollowerUpdate, EvFollowerUpdate> { TEvFollowerUpdate() - {} - + {} + TEvFollowerUpdate(ui64 tabletId, ui32 followerAttempt, ui64 streamCounter) - { - Record.SetTabletId(tabletId); + { + Record.SetTabletId(tabletId); Record.SetFollowerAttempt(followerAttempt); - Record.SetStreamCounter(streamCounter); - } - }; - + Record.SetStreamCounter(streamCounter); + } + }; + struct TEvFollowerAuxUpdate : public TEventPB<TEvFollowerAuxUpdate, NKikimrTabletBase::TEvFollowerAuxUpdate, EvFollowerAuxUpdate> { TEvFollowerAuxUpdate() = default; - + TEvFollowerAuxUpdate(ui64 tabletId, ui32 followerAttempt, ui64 streamCounter) - { - Record.SetTabletId(tabletId); + { + Record.SetTabletId(tabletId); Record.SetFollowerAttempt(followerAttempt); - Record.SetStreamCounter(streamCounter); - } - }; - + Record.SetStreamCounter(streamCounter); + } + }; + struct TEvFollowerDetach : public TEventPB<TEvFollowerDetach, NKikimrTabletBase::TEvFollowerDetach, EvFollowerDetach> { TEvFollowerDetach() - {} - + {} + TEvFollowerDetach(ui64 tabletId, ui32 followerAttempt) - { - Record.SetTabletId(tabletId); + { + Record.SetTabletId(tabletId); Record.SetFollowerAttempt(followerAttempt); - } - }; - + } + }; + struct TEvFollowerListRefresh : public TEventLocal<TEvFollowerListRefresh, EvFollowerListRefresh> { TVector<TActorId> FollowerList; - + TEvFollowerListRefresh(TVector<TActorId> &&followers) : FollowerList(std::move(followers)) - {} - }; - + {} + }; + struct TEvFollowerDisconnect : public TEventPB<TEvFollowerDisconnect, NKikimrTabletBase::TEvFollowerDisconnect, EvFollowerDisconnect> { TEvFollowerDisconnect() - {} - + {} + TEvFollowerDisconnect(ui64 tabletId, ui32 followerAttempt) - { - Record.SetTabletId(tabletId); + { + Record.SetTabletId(tabletId); Record.SetFollowerAttempt(followerAttempt); - } - }; - + } + }; + struct TEvFollowerRefresh : public TEventPB<TEvFollowerRefresh, NKikimrTabletBase::TEvFollowerRefresh, EvFollowerRefresh> { TEvFollowerRefresh() - {} - + {} + TEvFollowerRefresh(ui64 tabletId, ui32 generation) - { - Record.SetTabletId(tabletId); - Record.SetGeneration(generation); - } - }; - + { + Record.SetTabletId(tabletId); + Record.SetGeneration(generation); + } + }; + struct TEvFollowerGcAck : public TEventPB<TEvFollowerGcAck, NKikimrTabletBase::TEvFollowerGcAck, EvFollowerGcAck> { TEvFollowerGcAck() - {} - + {} + TEvFollowerGcAck(ui64 tabletId, ui32 followerAttempt, ui32 generation, ui32 step) - { - Record.SetTabletId(tabletId); + { + Record.SetTabletId(tabletId); Record.SetFollowerAttempt(followerAttempt); - Record.SetGeneration(generation); - Record.SetStep(step); - } - }; - + Record.SetGeneration(generation); + Record.SetStep(step); + } + }; + struct TFUpdateBody { - const bool IsSnapshot; - const ui32 Step; + const bool IsSnapshot; + const ui32 Step; TString EmbeddedBody; TVector<std::pair<TLogoBlobID, TString>> References; TString AuxPayload; - + bool NeedFollowerGcAck; - + TFUpdateBody(const TEvFollowerUpdate &upd) - : IsSnapshot(upd.Record.GetIsSnapshot()) - , Step(upd.Record.GetStep()) + : IsSnapshot(upd.Record.GetIsSnapshot()) + , Step(upd.Record.GetStep()) , NeedFollowerGcAck(upd.Record.HasNeedGCApplyAck() ? upd.Record.GetNeedGCApplyAck() : false) - { - const auto &r = upd.Record; - if (r.HasBody()) - EmbeddedBody = r.GetBody(); - if (r.HasAuxPayload()) - AuxPayload = r.GetAuxPayload(); - - References.reserve(r.ReferencesIdsSize()); - for (ui32 i = 0, end = r.ReferencesIdsSize(); i != end; ++i) { - const TLogoBlobID &id = LogoBlobIDFromLogoBlobID(r.GetReferencesIds(i)); - References.emplace_back(std::make_pair(id, r.GetReferences(i))); - } - } - + { + const auto &r = upd.Record; + if (r.HasBody()) + EmbeddedBody = r.GetBody(); + if (r.HasAuxPayload()) + AuxPayload = r.GetAuxPayload(); + + References.reserve(r.ReferencesIdsSize()); + for (ui32 i = 0, end = r.ReferencesIdsSize(); i != end; ++i) { + const TLogoBlobID &id = LogoBlobIDFromLogoBlobID(r.GetReferencesIds(i)); + References.emplace_back(std::make_pair(id, r.GetReferences(i))); + } + } + TFUpdateBody(TString auxUpdate) - : IsSnapshot(false) - , Step(0) + : IsSnapshot(false) + , Step(0) , AuxPayload(std::move(auxUpdate)) , NeedFollowerGcAck(false) - {} - }; - + {} + }; + struct TEvFBoot : public TEventLocal<TEvFBoot, EvFBoot> { // boot new round of follower - const ui64 TabletID; + const ui64 TabletID; const ui32 FollowerID; - const ui32 Generation; - + const ui32 Generation; + const TActorId Launcher; - + // must be present one of: or loaded graph or snapshot follower update - TIntrusivePtr<TDependencyGraph> DependencyGraph; + TIntrusivePtr<TDependencyGraph> DependencyGraph; THolder<TFUpdateBody> Update; - - TIntrusivePtr<TTabletStorageInfo> TabletStorageInfo; - + + TIntrusivePtr<TTabletStorageInfo> TabletStorageInfo; + TResourceProfilesPtr ResourceProfiles; TSharedQuotaPtr TxCacheQuota; TEvFBoot(ui64 tabletID, ui32 followerID, ui32 generation, TActorId launcher, const TEvFollowerUpdate &upd, TIntrusivePtr<TTabletStorageInfo> info, TResourceProfilesPtr profiles = nullptr, TSharedQuotaPtr txCacheQuota = nullptr) - : TabletID(tabletID) + : TabletID(tabletID) , FollowerID(followerID) - , Generation(generation) - , Launcher(launcher) + , Generation(generation) + , Launcher(launcher) , Update(new TFUpdateBody(upd)) - , TabletStorageInfo(info) + , TabletStorageInfo(info) , ResourceProfiles(profiles) , TxCacheQuota(txCacheQuota) - {} - + {} + TEvFBoot(ui64 tabletID, ui32 followerID, ui32 generation, TActorId launcher, TDependencyGraph *dependencyGraph, TIntrusivePtr<TTabletStorageInfo> info, TResourceProfilesPtr profiles = nullptr, TSharedQuotaPtr txCacheQuota = nullptr) - : TabletID(tabletID) + : TabletID(tabletID) , FollowerID(followerID) - , Generation(generation) - , Launcher(launcher) - , DependencyGraph(dependencyGraph) - , TabletStorageInfo(info) - , ResourceProfiles(profiles) - , TxCacheQuota(txCacheQuota) - {} - }; - + , Generation(generation) + , Launcher(launcher) + , DependencyGraph(dependencyGraph) + , TabletStorageInfo(info) + , ResourceProfiles(profiles) + , TxCacheQuota(txCacheQuota) + {} + }; + struct TEvFUpdate : public TEventLocal<TEvFUpdate, EvFUpdate> { THolder<TFUpdateBody> Update; - + TEvFUpdate(const TEvFollowerUpdate &upd) : Update(new TFUpdateBody(upd)) - {} - }; - + {} + }; + struct TEvFAuxUpdate : public TEventLocal<TEvFAuxUpdate, EvFAuxUpdate> { const TString AuxUpdate; - + TEvFAuxUpdate(const TString &auxUpdate) - : AuxUpdate(auxUpdate) - {} - }; - + : AuxUpdate(auxUpdate) + {} + }; + struct TEvFollowerGcApplied : public TEventLocal<TEvFollowerGcApplied, EvFollowerGcApplied> { - const ui64 TabletID; - const ui32 Generation; - const ui32 Step; + const ui64 TabletID; + const ui32 Generation; + const ui32 Step; const TDuration FollowerSyncDelay; - + TEvFollowerGcApplied(ui64 tabletId, ui32 gen, ui32 step, TDuration followerSyncDelay) - : TabletID(tabletId) - , Generation(gen) - , Step(step) + : TabletID(tabletId) + , Generation(gen) + , Step(step) , FollowerSyncDelay(followerSyncDelay) - {} - }; - + {} + }; + struct TEvFollowerSyncComplete : public TEventLocal<TEvFollowerSyncComplete, EvFollowerSyncComplete> {}; - + struct TEvFGcAck : public TEventLocal<TEvFGcAck, EvFGcAck> { - const ui64 TabletID; - const ui32 Generation; - const ui32 Step; - + const ui64 TabletID; + const ui32 Generation; + const ui32 Step; + TEvFGcAck(ui64 tabletId, ui32 gen, ui32 step) - : TabletID(tabletId) - , Generation(gen) - , Step(step) - {} - }; - - struct TEvCheckBlobstorageStatusResult : public TEventLocal<TEvCheckBlobstorageStatusResult, EvCheckBlobstorageStatusResult> { + : TabletID(tabletId) + , Generation(gen) + , Step(step) + {} + }; + + struct TEvCheckBlobstorageStatusResult : public TEventLocal<TEvCheckBlobstorageStatusResult, EvCheckBlobstorageStatusResult> { TVector<ui32> LightYellowMoveGroups; TVector<ui32> YellowStopGroups; - + TEvCheckBlobstorageStatusResult(TVector<ui32> &&lightYellowMoveGroups, TVector<ui32> &&yellowStopGroups) : LightYellowMoveGroups(std::move(lightYellowMoveGroups)) , YellowStopGroups(std::move(yellowStopGroups)) - {} - }; + {} + }; struct TEvResetTabletResult : public TEventLocal<TEvResetTabletResult, EvResetTabletResult> { const NKikimrProto::EReplyStatus Status; @@ -777,19 +777,19 @@ struct TEvTablet { }; struct TEvTabletStopped : TEventLocal<TEvTabletStopped, EvTabletStopped> {}; -}; - +}; + IActor* CreateTabletKiller(ui64 tabletId, ui32 nodeId = 0, ui32 maxGeneration = Max<ui32>()); IActor* CreateTabletDSChecker(const TActorId &replyTo, TTabletStorageInfo *info); IActor* CreateTabletReqReset(const TActorId &replyTo, const TIntrusivePtr<TTabletStorageInfo> &tabletStorageInfo, ui32 knownGeneration = 0); - -} - -template<> + +} + +template<> inline void Out<NKikimr::TEvTablet::TEvTabletDead::EReason>(IOutputStream& o, NKikimr::TEvTablet::TEvTabletDead::EReason x) { - return NKikimr::TEvTablet::TEvTabletDead::Out(o, x); -} - + return NKikimr::TEvTablet::TEvTabletDead::Out(o, x); +} + inline TString ToString(NKikimr::TEvTablet::TEvTabletDead::EReason x) { - return NKikimr::TEvTablet::TEvTabletDead::Str(x); -} + return NKikimr::TEvTablet::TEvTabletDead::Str(x); +} diff --git a/ydb/core/base/tablet_killer.cpp b/ydb/core/base/tablet_killer.cpp index 907fca83d3..d46e2c5c89 100644 --- a/ydb/core/base/tablet_killer.cpp +++ b/ydb/core/base/tablet_killer.cpp @@ -1,20 +1,20 @@ -#include "statestorage.h" -#include "tablet.h" -#include "tabletid.h" - +#include "statestorage.h" +#include "tablet.h" +#include "tabletid.h" + #include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/actors/core/hfunc.h> namespace NKikimr { class TTabletKillRequest : public TActorBootstrapped<TTabletKillRequest> { -private: - const ui64 TabletId; +private: + const ui64 TabletId; const ui32 NodeId; const ui32 MaxGeneration; - void Handle(TEvStateStorage::TEvInfo::TPtr &ev, const TActorContext &ctx) { - TEvStateStorage::TEvInfo *msg = ev->Get(); + void Handle(TEvStateStorage::TEvInfo::TPtr &ev, const TActorContext &ctx) { + TEvStateStorage::TEvInfo *msg = ev->Get(); TActorId LeaderActor; if (NodeId == 0) { LeaderActor = msg->CurrentLeader; @@ -47,13 +47,13 @@ public: void Bootstrap(const TActorContext &ctx) { const TActorId stateStorageProxyId = MakeStateStorageProxyID(StateStorageGroupFromTabletID(TabletId)); - ctx.Send(stateStorageProxyId, new TEvStateStorage::TEvLookup(TabletId, 0)); + ctx.Send(stateStorageProxyId, new TEvStateStorage::TEvLookup(TabletId, 0)); Become(&TTabletKillRequest::StateFunc); } STFUNC(StateFunc) { switch (ev->GetTypeRewrite()) { - HFunc(TEvStateStorage::TEvInfo, Handle); + HFunc(TEvStateStorage::TEvInfo, Handle); } } }; @@ -62,5 +62,5 @@ IActor* CreateTabletKiller(ui64 tabletId, ui32 nodeId, ui32 maxGeneration) { return new TTabletKillRequest(tabletId, nodeId, maxGeneration); } -} - +} + diff --git a/ydb/core/base/tablet_pipe.h b/ydb/core/base/tablet_pipe.h index 54cfed771f..a0420b8672 100644 --- a/ydb/core/base/tablet_pipe.h +++ b/ydb/core/base/tablet_pipe.h @@ -29,7 +29,7 @@ namespace NKikimr { EvActivate, EvShutdown, EvClientRetry, - EvClientCheckDelay, + EvClientCheckDelay, EvClientShuttingDown, EvMessage, // replacement for EvSend @@ -120,7 +120,7 @@ namespace NKikimr { , ClientId(clientId) , ServerId(serverId) , Leader(leader) - , Dead(dead) + , Dead(dead) {} const ui64 TabletId; @@ -128,7 +128,7 @@ namespace NKikimr { const TActorId ClientId; const TActorId ServerId; const bool Leader; - const bool Dead; + const bool Dead; }; struct TEvServerConnected : public TEventLocal<TEvServerConnected, EvServerConnected> { @@ -214,10 +214,10 @@ namespace NKikimr { struct TEvClientRetry : public TEventLocal<TEvClientRetry, EvClientRetry> { TEvClientRetry() {} }; - - struct TEvClientCheckDelay : public TEventLocal<TEvClientCheckDelay, EvClientCheckDelay> { - TEvClientCheckDelay() {} - }; + + struct TEvClientCheckDelay : public TEventLocal<TEvClientCheckDelay, EvClientCheckDelay> { + TEvClientCheckDelay() {} + }; class TEvMessage : public TEventLocal<TEvMessage, EvMessage> { public: @@ -291,7 +291,7 @@ namespace NKikimr { virtual void Stop(TActorIdentity owner) = 0; // Destroys all servers, created by Accept or Enqueue. - virtual void Detach(TActorIdentity owner) = 0; + virtual void Detach(TActorIdentity owner) = 0; // Creates an inactive server, returns server Id. // Owner of context is not captured at this time. @@ -336,19 +336,19 @@ namespace NKikimr { struct TClientRetryState { bool IsAllowedToRetry(TDuration& wait, const TClientRetryPolicy& policy); - TDuration MakeCheckDelay(); + TDuration MakeCheckDelay(); protected: ui64 RetryNumber = 0; TDuration RetryDuration; }; struct TClientConfig { - bool ConnectToUserTablet = false; + bool ConnectToUserTablet = false; bool AllowFollower = false; bool ForceFollower = false; - bool ForceLocal = false; - bool PreferLocal = false; - bool CheckAliveness = false; + bool ForceLocal = false; + bool PreferLocal = false; + bool CheckAliveness = false; bool ExpectShutdown = false; TClientRetryPolicy RetryPolicy; diff --git a/ydb/core/base/tablet_pipecache.h b/ydb/core/base/tablet_pipecache.h index 7023f6b7eb..d3a519c9bd 100644 --- a/ydb/core/base/tablet_pipecache.h +++ b/ydb/core/base/tablet_pipecache.h @@ -1,58 +1,58 @@ -#pragma once -#include "defs.h" -#include "events.h" +#pragma once +#include "defs.h" +#include "events.h" #include "counters.h" - + #include <ydb/core/base/tablet_pipe.h> #include <library/cpp/actors/core/event_local.h> -#include <util/stream/str.h> - -namespace NKikimr { - -struct TEvPipeCache { - enum EEv { - EvForward = EventSpaceBegin(TKikimrEvents::ES_PIPECACHE), - EvUnlink, +#include <util/stream/str.h> + +namespace NKikimr { + +struct TEvPipeCache { + enum EEv { + EvForward = EventSpaceBegin(TKikimrEvents::ES_PIPECACHE), + EvUnlink, EvGetTabletNode, - - EvDeliveryProblem = EvForward + 1 * 512, + + EvDeliveryProblem = EvForward + 1 * 512, EvGetTabletNodeResult, - - EvEnd - }; - - static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_PIPECACHE), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_PIPECACHE)"); - - struct TEvForward : public TEventLocal<TEvForward, EvForward> { - public: - THolder<IEventBase> Ev; - const ui64 TabletId; - const bool Subscribe; - - TEvForward(IEventBase *ev, ui64 tabletId, bool subscribe = true) - : Ev(ev) - , TabletId(tabletId) - , Subscribe(subscribe) - {} - }; - - struct TEvUnlink : public TEventLocal<TEvUnlink, EvUnlink> { - const ui64 TabletId; - - TEvUnlink(ui64 tabletId) - : TabletId(tabletId) - {} - }; - - struct TEvDeliveryProblem : public TEventLocal<TEvDeliveryProblem, EvDeliveryProblem> { - const ui64 TabletId; - const bool NotDelivered; - - TEvDeliveryProblem(ui64 tabletId, bool notDelivered) - : TabletId(tabletId) - , NotDelivered(notDelivered) - {} - }; + + EvEnd + }; + + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_PIPECACHE), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_PIPECACHE)"); + + struct TEvForward : public TEventLocal<TEvForward, EvForward> { + public: + THolder<IEventBase> Ev; + const ui64 TabletId; + const bool Subscribe; + + TEvForward(IEventBase *ev, ui64 tabletId, bool subscribe = true) + : Ev(ev) + , TabletId(tabletId) + , Subscribe(subscribe) + {} + }; + + struct TEvUnlink : public TEventLocal<TEvUnlink, EvUnlink> { + const ui64 TabletId; + + TEvUnlink(ui64 tabletId) + : TabletId(tabletId) + {} + }; + + struct TEvDeliveryProblem : public TEventLocal<TEvDeliveryProblem, EvDeliveryProblem> { + const ui64 TabletId; + const bool NotDelivered; + + TEvDeliveryProblem(ui64 tabletId, bool notDelivered) + : TabletId(tabletId) + , NotDelivered(notDelivered) + {} + }; /** * Requests node id of the given tablet id, where pipe cache is connected @@ -77,21 +77,21 @@ struct TEvPipeCache { , NodeId(nodeId) {} }; -}; - -struct TPipePeNodeCacheConfig : public TAtomicRefCount<TPipePeNodeCacheConfig>{ - ui64 TabletCacheLimit; - TDuration PipeRefreshTime; - NTabletPipe::TClientConfig PipeConfig; +}; + +struct TPipePeNodeCacheConfig : public TAtomicRefCount<TPipePeNodeCacheConfig>{ + ui64 TabletCacheLimit; + TDuration PipeRefreshTime; + NTabletPipe::TClientConfig PipeConfig; NMonitoring::TDynamicCounterPtr Counters; - - TPipePeNodeCacheConfig() - : TabletCacheLimit(500000) - , PipeRefreshTime(TDuration::Seconds(30)) - {} -}; - -IActor* CreatePipePeNodeCache(const TIntrusivePtr<TPipePeNodeCacheConfig> &config); + + TPipePeNodeCacheConfig() + : TabletCacheLimit(500000) + , PipeRefreshTime(TDuration::Seconds(30)) + {} +}; + +IActor* CreatePipePeNodeCache(const TIntrusivePtr<TPipePeNodeCacheConfig> &config); TActorId MakePipePeNodeCacheID(bool allowFollower); - -} + +} diff --git a/ydb/core/base/tablet_resolver.h b/ydb/core/base/tablet_resolver.h index a2c446cec2..24744cef47 100644 --- a/ydb/core/base/tablet_resolver.h +++ b/ydb/core/base/tablet_resolver.h @@ -1,36 +1,36 @@ -#pragma once -#include "defs.h" -#include "events.h" - +#pragma once +#include "defs.h" +#include "events.h" + #include <ydb/core/protos/base.pb.h> #include <library/cpp/actors/core/event_local.h> #include <util/stream/str.h> #include <util/string/builder.h> - -namespace NKikimr { - -struct TEvTabletResolver { - enum EEv { - EvForward = EventSpaceBegin(TKikimrEvents::ES_TABLETRESOLVER), - EvTabletProblem, + +namespace NKikimr { + +struct TEvTabletResolver { + enum EEv { + EvForward = EventSpaceBegin(TKikimrEvents::ES_TABLETRESOLVER), + EvTabletProblem, EvNodeProblem, - - EvForwardResult = EvForward + 1 * 512, - - EvEnd - }; - + + EvForwardResult = EvForward + 1 * 512, + + EvEnd + }; + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_TABLETRESOLVER), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_TABLETRESOLVER)"); - - struct TEvForward : public TEventLocal<TEvForward, EvForward> { + + struct TEvForward : public TEventLocal<TEvForward, EvForward> { /// enum class EResolvePrio : ui8 { ResPrioDisallow, ResPrioAllow, ResPrioPrefer, ResPrioForce, - }; - + }; + /// struct TResolveFlags { EResolvePrio LocalNodePrio; @@ -104,17 +104,17 @@ struct TEvTabletResolver { SysTablet, }; - const ui64 TabletID; - THolder<IEventHandle> Ev; + const ui64 TabletID; + THolder<IEventHandle> Ev; TResolveFlags ResolveFlags; EActor Actor; - + TEvForward(ui64 tabletId, IEventHandle *ev, TResolveFlags flags = TResolveFlags(), EActor actor = EActor::Tablet) - : TabletID(tabletId) - , Ev(ev) + : TabletID(tabletId) + , Ev(ev) , ResolveFlags(flags) , Actor(actor) - {} + {} TString ToString() const { TStringStream str; @@ -133,16 +133,16 @@ struct TEvTabletResolver { return sysTablet; } } - }; - - struct TEvTabletProblem : public TEventLocal<TEvTabletProblem, EvTabletProblem> { - const ui64 TabletID; + }; + + struct TEvTabletProblem : public TEventLocal<TEvTabletProblem, EvTabletProblem> { + const ui64 TabletID; const TActorId TabletActor; - + TEvTabletProblem(ui64 tabletId, const TActorId &tabletActor) - : TabletID(tabletId) - , TabletActor(tabletActor) - {} + : TabletID(tabletId) + , TabletActor(tabletActor) + {} TString ToString() const { TStringStream str; @@ -151,8 +151,8 @@ struct TEvTabletResolver { str << "}"; return str.Str(); } - }; - + }; + struct TEvNodeProblem : public TEventLocal<TEvNodeProblem, EvNodeProblem> { const ui32 NodeId; const ui64 CacheEpoch; @@ -170,27 +170,27 @@ struct TEvTabletResolver { } }; - struct TEvForwardResult : public TEventLocal<TEvForwardResult, EvForwardResult> { - const NKikimrProto::EReplyStatus Status; - - ui64 TabletID; + struct TEvForwardResult : public TEventLocal<TEvForwardResult, EvForwardResult> { + const NKikimrProto::EReplyStatus Status; + + ui64 TabletID; TActorId TabletActor; TActorId Tablet; ui64 CacheEpoch; - - TEvForwardResult(NKikimrProto::EReplyStatus status, ui64 tabletId) - : Status(status) - , TabletID(tabletId) + + TEvForwardResult(NKikimrProto::EReplyStatus status, ui64 tabletId) + : Status(status) + , TabletID(tabletId) , CacheEpoch(0) - {} - + {} + TEvForwardResult(ui64 tabletId, const TActorId &tabletActor, const TActorId &tablet, ui64 cacheEpoch) - : Status(NKikimrProto::OK) - , TabletID(tabletId) - , TabletActor(tabletActor) + : Status(NKikimrProto::OK) + , TabletID(tabletId) + , TabletActor(tabletActor) , Tablet(tablet) , CacheEpoch(cacheEpoch) - {} + {} TString ToString() const { TStringStream str; @@ -202,18 +202,18 @@ struct TEvTabletResolver { str << "}"; return str.Str(); } - }; -}; - + }; +}; + struct TTabletResolverConfig : public TThrRefBase { ui64 TabletCacheLimit; TTabletResolverConfig() - : TabletCacheLimit(500000) + : TabletCacheLimit(500000) {} }; IActor* CreateTabletResolver(const TIntrusivePtr<TTabletResolverConfig> &config); TActorId MakeTabletResolverID(); - -} + +} diff --git a/ydb/core/base/tablet_status_checker.cpp b/ydb/core/base/tablet_status_checker.cpp index d5ebfe87fe..bfb51b8e85 100644 --- a/ydb/core/base/tablet_status_checker.cpp +++ b/ydb/core/base/tablet_status_checker.cpp @@ -1,71 +1,71 @@ -#include "tablet.h" +#include "tablet.h" #include <ydb/core/base/blobstorage.h> #include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/actors/core/hfunc.h> - + #include <util/generic/hash_set.h> -namespace NKikimr { - -class TTabletStatusCheckRequest : public TActorBootstrapped<TTabletStatusCheckRequest> { -private: +namespace NKikimr { + +class TTabletStatusCheckRequest : public TActorBootstrapped<TTabletStatusCheckRequest> { +private: const TActorId ReplyTo; - TIntrusiveConstPtr<TTabletStorageInfo> Info; - ui32 RequestsLeft; + TIntrusiveConstPtr<TTabletStorageInfo> Info; + ui32 RequestsLeft; TVector<ui32> LightYellowMoveGroups; TVector<ui32> YellowStopGroups; - - void Handle(TEvBlobStorage::TEvStatusResult::TPtr &ev, const TActorContext &ctx) { - const TEvBlobStorage::TEvStatusResult *msg = ev->Get(); - --RequestsLeft; - + + void Handle(TEvBlobStorage::TEvStatusResult::TPtr &ev, const TActorContext &ctx) { + const TEvBlobStorage::TEvStatusResult *msg = ev->Get(); + --RequestsLeft; + if (msg->StatusFlags.Check(NKikimrBlobStorage::StatusDiskSpaceLightYellowMove)) { LightYellowMoveGroups.push_back(ev->Cookie); } if (msg->StatusFlags.Check(NKikimrBlobStorage::StatusDiskSpaceYellowStop)) { YellowStopGroups.push_back(ev->Cookie); } - - if (RequestsLeft == 0) { + + if (RequestsLeft == 0) { ctx.Send(ReplyTo, new TEvTablet::TEvCheckBlobstorageStatusResult(std::move(LightYellowMoveGroups), std::move(YellowStopGroups))); - return Die(ctx); - } - } - -public: + return Die(ctx); + } + } + +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TABLET_ACTOR; - } - + } + TTabletStatusCheckRequest(const TActorId &replyTo, TTabletStorageInfo *info) - : ReplyTo(replyTo) - , Info(info) - , RequestsLeft(0) - {} - - void Bootstrap(const TActorContext &ctx) { + : ReplyTo(replyTo) + , Info(info) + , RequestsLeft(0) + {} + + void Bootstrap(const TActorContext &ctx) { THashSet<ui32> seen; - for (const auto &channel : Info->Channels) { - const ui32 groupToCheck = channel.History.back().GroupID; + for (const auto &channel : Info->Channels) { + const ui32 groupToCheck = channel.History.back().GroupID; if (seen.insert(groupToCheck).second) { SendToBSProxy(ctx, groupToCheck, new TEvBlobStorage::TEvStatus(TInstant::Max()), groupToCheck); ++RequestsLeft; } - } + } Become(&TTabletStatusCheckRequest::StateFunc); - } - - STFUNC(StateFunc) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvBlobStorage::TEvStatusResult, Handle); - CFunc(TEvents::TSystem::PoisonPill, Die); - } - } -}; - + } + + STFUNC(StateFunc) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvBlobStorage::TEvStatusResult, Handle); + CFunc(TEvents::TSystem::PoisonPill, Die); + } + } +}; + IActor* CreateTabletDSChecker(const TActorId &replyTo, TTabletStorageInfo *info) { - return new TTabletStatusCheckRequest(replyTo, info); -} - -} + return new TTabletStatusCheckRequest(replyTo, info); +} + +} diff --git a/ydb/core/base/tabletid.h b/ydb/core/base/tabletid.h index 67a575473b..cd0a7cb58f 100644 --- a/ydb/core/base/tabletid.h +++ b/ydb/core/base/tabletid.h @@ -1,25 +1,25 @@ -#pragma once -#include "defs.h" - -namespace NKikimr { - // extract 8 bits of state-storage group - inline ui64 StateStorageGroupFromTabletID(ui64 tabletId) { - return (tabletId >> 56) & 0xFFull; - } - - inline ui32 StateStorageHashFromTabletID(ui64 tabletId) { +#pragma once +#include "defs.h" + +namespace NKikimr { + // extract 8 bits of state-storage group + inline ui64 StateStorageGroupFromTabletID(ui64 tabletId) { + return (tabletId >> 56) & 0xFFull; + } + + inline ui32 StateStorageHashFromTabletID(ui64 tabletId) { return (ui32)Hash64to32(tabletId); - } - + } + // extract 12 bits of hive group id (zero is 'human assigned') inline ui64 HiveUidFromTabletID(ui64 tabletId) { - return (tabletId >> 44) & 0xFFFull; - } - - inline ui64 UniqPartFromTabletID(ui64 tabletId) { - return (tabletId & 0x00000FFFFFFFFFFFull); - } - + return (tabletId >> 44) & 0xFFFull; + } + + inline ui64 UniqPartFromTabletID(ui64 tabletId) { + return (tabletId & 0x00000FFFFFFFFFFFull); + } + inline ui64 AvoidReservedUniqPart(ui64 candidate, ui64 brokenBegin, ui64 brokenEnd) { if (candidate >= brokenBegin && candidate < brokenEnd) { return brokenEnd; @@ -43,24 +43,24 @@ namespace NKikimr { return uniqPart != AvoidReservedUniqPartsBySystemTablets(uniqPart); } - // 8 + 12 + 44 + // 8 + 12 + 44 inline ui64 MakeTabletID(ui64 stateStorageGroup, ui64 hiveUid, ui64 uniqPart) { Y_VERIFY(stateStorageGroup < (1ull << 8ull) && hiveUid < (1ull << 12ull) && uniqPart < (1ull << 44ull)); return (stateStorageGroup << 56ull) | (hiveUid << 44ull) | uniqPart; - } - + } + // blob storage controller (exactly one per domain in default state storage group) inline ui64 MakeBSControllerID(ui64 stateStorageGroup) { Y_VERIFY_DEBUG(stateStorageGroup < (1ull << 8ull)); return MakeTabletID(stateStorageGroup, 0, 0x1001); - } - + } + // one default hive per domain (in default state storage group!) inline ui64 MakeDefaultHiveID(ui64 stateStorageGroup) { Y_VERIFY_DEBUG(stateStorageGroup < (1ull << 8ull)); return MakeTabletID(stateStorageGroup, 0, 1); - } - + } + // cluster management system tablet (exactly one per domain in default state storage group) inline ui64 MakeCmsID(ui64 stateStorageGroup) { Y_VERIFY_DEBUG(stateStorageGroup < (1ull << 8ull)); @@ -86,12 +86,12 @@ namespace NKikimr { } // TODO: think about encoding scheme for sibling group hive - + inline TActorId MakeStateStorageProxyID(ui64 stateStorageGroup) { Y_VERIFY_DEBUG(stateStorageGroup < (1ull << 8ull)); - char x[12] = { 's', 't', 's', 'p', 'r', 'o', 'x', 'y' }; - x[8] = (char)stateStorageGroup; + char x[12] = { 's', 't', 's', 'p', 'r', 'o', 'x', 'y' }; + x[8] = (char)stateStorageGroup; return TActorId(0, TStringBuf(x, 12)); - } + } -} +} diff --git a/ydb/core/base/tracing.h b/ydb/core/base/tracing.h index 8f8b5b728d..40420e4541 100644 --- a/ydb/core/base/tracing.h +++ b/ydb/core/base/tracing.h @@ -111,7 +111,7 @@ public: class ITrace { public: enum EType { - TypeSysTabletBootstrap, + TypeSysTabletBootstrap, TypeReqRebuildHistoryGraph }; diff --git a/ydb/core/base/ut/ya.make b/ydb/core/base/ut/ya.make index d999eb8780..7d6b2f3546 100644 --- a/ydb/core/base/ut/ya.make +++ b/ydb/core/base/ut/ya.make @@ -16,8 +16,8 @@ SRCS( localdb_ut.cpp logoblob_ut.cpp shared_data_ut.cpp - statestorage_ut.cpp - statestorage_guardian_impl_ut.cpp + statestorage_ut.cpp + statestorage_guardian_impl_ut.cpp ) END() diff --git a/ydb/core/base/ya.make b/ydb/core/base/ya.make index a98739b702..83db5825c3 100644 --- a/ydb/core/base/ya.make +++ b/ydb/core/base/ya.make @@ -1,5 +1,5 @@ -LIBRARY() - +LIBRARY() + OWNER( ddoarn vvvv @@ -13,71 +13,71 @@ IF (KIKIMR_DEFAULT_SHARDED_COMPACTION) ) ENDIF() -SRCS( +SRCS( actor_activity_names.cpp - appdata.h + appdata.h appdata.cpp - board_lookup.cpp - board_publish.cpp - board_replica.cpp + board_lookup.cpp + board_publish.cpp + board_replica.cpp blobstorage.h blobstorage.cpp channel_profiles.h counters.cpp counters.h - defs.h - domain.h + defs.h + domain.h event_filter.cpp event_filter.h - events.h + events.h group_stat.cpp group_stat.h hive.h interconnect_channels.h - kikimr_issue.cpp - kikimr_issue.h + kikimr_issue.cpp + kikimr_issue.h localdb.cpp localdb.h location.h - logoblob.cpp - logoblob.h + logoblob.cpp + logoblob.h nameservice.h path.cpp pathid.cpp - pool_stats_collector.cpp - pool_stats_collector.h - quoter.cpp - quoter.h + pool_stats_collector.cpp + pool_stats_collector.h + quoter.cpp + quoter.h resource_profile.h row_version.cpp row_version.h services_assert.cpp shared_data.cpp shared_quota.h - statestorage.cpp - statestorage.h - statestorage_event_filter.cpp - statestorage_guardian.cpp - statestorage_guardian_impl.h - statestorage_impl.h - statestorage_monitoring.cpp - statestorage_proxy.cpp - statestorage_replica.cpp - statestorage_replica_probe.cpp - statestorage_warden.cpp + statestorage.cpp + statestorage.h + statestorage_event_filter.cpp + statestorage_guardian.cpp + statestorage_guardian_impl.h + statestorage_impl.h + statestorage_monitoring.cpp + statestorage_proxy.cpp + statestorage_replica.cpp + statestorage_replica_probe.cpp + statestorage_warden.cpp storage_pools.cpp storage_pools.h subdomain.h subdomain.cpp table_index.cpp - tablet.cpp - tablet.h - tablet_killer.cpp + tablet.cpp + tablet.h + tablet_killer.cpp tablet_pipe.h - tablet_pipecache.h - tablet_resolver.h - tablet_status_checker.cpp - tabletid.h + tablet_pipecache.h + tablet_resolver.h + tablet_status_checker.cpp + tabletid.h tablet_types.h traceid.cpp traceid.h @@ -86,9 +86,9 @@ SRCS( tx_processing.cpp user_registry.h blobstorage_grouptype.cpp -) - -PEERDIR( +) + +PEERDIR( library/cpp/actors/core library/cpp/actors/helpers library/cpp/actors/interconnect @@ -112,15 +112,15 @@ PEERDIR( ydb/library/wilson ydb/public/api/protos/out ydb/library/yql/minikql -) - -RESOURCE( +) + +RESOURCE( ydb/core/base/kikimr_issue.txt kikimr_issue.txt -) - +) + GENERATE_ENUM_SERIALIZATION(quoter.h) -END() +END() RECURSE_FOR_TESTS( ut diff --git a/ydb/core/blobstorage/backpressure/queue_backpressure_client.cpp b/ydb/core/blobstorage/backpressure/queue_backpressure_client.cpp index b90fd1a57a..200b85f616 100644 --- a/ydb/core/blobstorage/backpressure/queue_backpressure_client.cpp +++ b/ydb/core/blobstorage/backpressure/queue_backpressure_client.cpp @@ -498,7 +498,7 @@ private: if (ev && ev->Get()->Cookie != CheckReadinessCookie) { return; // obsolete scheduled event } - + QLOG_INFO_S("BSQ16", "called" << " CheckReadinessCookie# " << CheckReadinessCookie << " State# " << GetStateName()); diff --git a/ydb/core/blobstorage/base/blobstorage_vdiskid.h b/ydb/core/blobstorage/base/blobstorage_vdiskid.h index f2f397c0e4..c8d5a818b1 100644 --- a/ydb/core/blobstorage/base/blobstorage_vdiskid.h +++ b/ydb/core/blobstorage/base/blobstorage_vdiskid.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "defs.h" @@ -7,8 +7,8 @@ #include <util/str_stl.h> #include <util/digest/numeric.h> -namespace NKikimr { - +namespace NKikimr { + class TBlobStorageGroupInfo; struct TVDiskIdShort; @@ -16,37 +16,37 @@ struct TVDiskIdShort; // TVDiskID -- global vdisk identifier //////////////////////////////////////////////////////////////////////////// #pragma pack(push, 4) -struct TVDiskID { +struct TVDiskID { ui32 GroupID = 0; ui32 GroupGeneration = 0; ui8 FailRealm = 0; ui8 FailDomain = 0; ui8 VDisk = 0; ui8 Padding = 0; - + TVDiskID() = default; TVDiskID(ui32 groupId, ui32 groupGen, TVDiskIdShort vdiskIdShort); TVDiskID(IInputStream &str); - + TVDiskID(ui32 groupId, ui32 groupGen, ui8 failRealm, ui8 failDomain, ui8 vdisk) - : GroupID(groupId) - , GroupGeneration(groupGen) + : GroupID(groupId) + , GroupGeneration(groupGen) , FailRealm(failRealm) , FailDomain(failDomain) - , VDisk(vdisk) + , VDisk(vdisk) {} - + bool SameGroupAndGeneration(const TVDiskID &x) const { - return x.GroupID == GroupID && x.GroupGeneration == GroupGeneration; - } + return x.GroupID == GroupID && x.GroupGeneration == GroupGeneration; + } bool SameGroupAndGeneration(const NKikimrBlobStorage::TVDiskID &x) const { - return x.GetGroupID() == GroupID && x.GetGroupGeneration() == GroupGeneration; - } - + return x.GetGroupID() == GroupID && x.GetGroupGeneration() == GroupGeneration; + } + bool SameExceptGeneration(const TVDiskID &x) const { return x.GroupID == GroupID && x.FailRealm == FailRealm && x.FailDomain == FailDomain && x.VDisk == VDisk; - } + } bool SameDisk(const TVDiskID &x) const { return *this == x; @@ -76,12 +76,12 @@ struct TVDiskID { } static const TVDiskID InvalidId; -}; +}; #pragma pack(pop) - -TVDiskID VDiskIDFromVDiskID(const NKikimrBlobStorage::TVDiskID &x); -void VDiskIDFromVDiskID(const TVDiskID &id, NKikimrBlobStorage::TVDiskID *proto); - + +TVDiskID VDiskIDFromVDiskID(const NKikimrBlobStorage::TVDiskID &x); +void VDiskIDFromVDiskID(const TVDiskID &id, NKikimrBlobStorage::TVDiskID *proto); + //////////////////////////////////////////////////////////////////////////// // TVDiskIdShort -- topology info about VDisk, it avoids runtime info like // group generation @@ -112,7 +112,7 @@ struct TVDiskIdShort { , FailDomain(id.FailDomain) , VDisk(id.VDisk) {} - + ui64 GetRaw() const { return (ui64(FailRealm) << 16) | (ui64(FailDomain) << 8) | ui64(VDisk); } @@ -146,9 +146,9 @@ struct TVDiskIdShort { ui32 x = (((ui32(FailRealm) << 8) | ui32(FailDomain)) << 8) | ui32(VDisk); return IntHash<ui64>(x); } -}; +}; #pragma pack(pop) - + } // NKikimr diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_discover.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_discover.cpp index 12bf08fe0e..2605a19a2e 100644 --- a/ydb/core/blobstorage/dsproxy/dsproxy_discover.cpp +++ b/ydb/core/blobstorage/dsproxy/dsproxy_discover.cpp @@ -448,20 +448,20 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB vDiskData.IsMoreRequested = false; if (vDiskData.Blobs.size() > 0) { TLogoBlobID &lastBlobId = vDiskData.Blobs.back().Id; - + ui64 tablet = lastBlobId.TabletID(); - ui32 channel = lastBlobId.Channel(); - ui32 gen = lastBlobId.Generation(); - ui32 step = lastBlobId.Step(); - ui32 cookie = lastBlobId.Cookie(); - - if (cookie > 0) - vDiskData.nextLogoBlobId = TLogoBlobID(tablet, gen, step, channel, TLogoBlobID::MaxBlobSize, cookie - 1); - else if (step > 0) - vDiskData.nextLogoBlobId = TLogoBlobID(tablet, gen, step - 1, channel, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie); - else if (gen > 0) - vDiskData.nextLogoBlobId = TLogoBlobID(tablet, gen - 1, Max<ui32>(), channel, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie); - else + ui32 channel = lastBlobId.Channel(); + ui32 gen = lastBlobId.Generation(); + ui32 step = lastBlobId.Step(); + ui32 cookie = lastBlobId.Cookie(); + + if (cookie > 0) + vDiskData.nextLogoBlobId = TLogoBlobID(tablet, gen, step, channel, TLogoBlobID::MaxBlobSize, cookie - 1); + else if (step > 0) + vDiskData.nextLogoBlobId = TLogoBlobID(tablet, gen, step - 1, channel, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie); + else if (gen > 0) + vDiskData.nextLogoBlobId = TLogoBlobID(tablet, gen - 1, Max<ui32>(), channel, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie); + else vDiskData.IsAllRead = true; } diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_base.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_base.cpp index 8c9b9f3edb..c73c20712e 100644 --- a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_base.cpp +++ b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_base.cpp @@ -59,7 +59,7 @@ void TStrategyBase::EvaluateCurrentLayout(TLogContext &logCtx, TBlobState &state for (ui32 partIdx = beginPartIdx; partIdx < endPartIdx; ++partIdx) { TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation; if (partSituation == TBlobState::ESituation::Present) { - R_LOG_DEBUG_SX(logCtx, "BPG42", "Request# " + R_LOG_DEBUG_SX(logCtx, "BPG42", "Request# " << " Id# " << state.Id.ToString() << " Disk# " << diskIdx << " Part# " << partIdx << " Present"); presentLayout.AddItem(diskIdx, partIdx, info.Type); diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_discover.h b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_discover.h index c14df21045..2e8df42324 100644 --- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_discover.h +++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_discover.h @@ -69,7 +69,7 @@ public: SetFailedDisks(failedDisks); SendToBSProxy(GetActorContext(), Info->GroupID, new TEvBlobStorage::TEvDiscover(tabletId, 0, false, false, - TInstant::Max(), 0)); + TInstant::Max(), 0)); auto resp = WaitForSpecificEvent<TEvBlobStorage::TEvDiscoverResult>(); const NKikimrProto::EReplyStatus status = resp->Get()->Status; @@ -109,7 +109,7 @@ public: TLogoBlobID::MaxChannel, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie), disks, false); - SendToBSProxy(GetActorContext(), Info->GroupID, new TEvBlobStorage::TEvDiscover(tabletId, 0, true, true, TInstant::Max(), 0)); + SendToBSProxy(GetActorContext(), Info->GroupID, new TEvBlobStorage::TEvDiscover(tabletId, 0, true, true, TInstant::Max(), 0)); auto response = WaitForSpecificEvent<TEvBlobStorage::TEvDiscoverResult>(); UNIT_ASSERT_VALUES_EQUAL(response->Get()->Status, NKikimrProto::OK); diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_runtime.h b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_runtime.h index d483efadbf..bc33af4b86 100644 --- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_runtime.h +++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_runtime.h @@ -27,7 +27,7 @@ public: TVector<std::pair<TVDiskID, TActorId>> VDisks; std::unique_ptr<TAppData> AppData; std::unique_ptr<TActorSystem> ActorSystem; - TProgramShouldContinue KikimrShouldContinue; + TProgramShouldContinue KikimrShouldContinue; void Setup(TBlobStorageGroupType groupType, ui32 numFailDomains, ui32 numVDisksPerFailDomain, ui32 numRealms) { Counters = new NMonitoring::TDynamicCounters; diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_sequence_ut.cpp b/ydb/core/blobstorage/dsproxy/ut/dsproxy_sequence_ut.cpp index d4da4506d4..fdd7a92ea3 100644 --- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_sequence_ut.cpp +++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_sequence_ut.cpp @@ -1277,7 +1277,7 @@ Y_UNIT_TEST(TestGivenBlock42Put6PartsOnOneVDiskWhenDiscoverThenRecoverFirst) { const ui32 minGeneration = 0; // Send Discover runtime.Send(new IEventHandle( - proxy, sender, new TEvBlobStorage::TEvDiscover(tabletId, minGeneration, true, false, TInstant::Max(), 0))); + proxy, sender, new TEvBlobStorage::TEvDiscover(tabletId, minGeneration, true, false, TInstant::Max(), 0))); // Receive VGet TMap<TActorId, TGetRequest> lastRequest; diff --git a/ydb/core/blobstorage/dsproxy/ut_fat/dsproxy_ut.cpp b/ydb/core/blobstorage/dsproxy/ut_fat/dsproxy_ut.cpp index 16aa7af975..13b1bec356 100644 --- a/ydb/core/blobstorage/dsproxy/ut_fat/dsproxy_ut.cpp +++ b/ydb/core/blobstorage/dsproxy/ut_fat/dsproxy_ut.cpp @@ -967,7 +967,7 @@ class TTestBlobStorageProxyBlock : public TTestBlobStorageProxy { TEST_RESPONSE(MessagePutResult, BLOCKED, 0, ""); VERBOSE_COUT("Sending TEvDiscover, read body = true, expecting OK + data"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, true, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, true, TInstant::Max(), 0)); break; case 80: { @@ -2337,13 +2337,13 @@ class TTestBlobStorageProxySimpleDiscover : public TTestBlobStorageProxy { TEST_RESPONSE(MessagePutResult, OK, 0, ""); VERBOSE_COUT("Sending TEvDiscover, read body = true, expecting OK + data"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, false, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, false, TInstant::Max(), 0)); break; case 30: TEST_RESPONSE(MessageDiscoverResult, OK, 1, testData2); VERBOSE_COUT("Sending TEvDiscover, read body = true, expecting OK + data"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, true, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, true, TInstant::Max(), 0)); break; case 40: TEST_RESPONSE(MessageDiscoverResult, OK, 1, testData2); @@ -2375,7 +2375,7 @@ class TTestBlobStorageProxyDiscover : public TTestBlobStorageProxy { "Unexpected " << (int)LastResponse.Message); VERBOSE_COUT("Sending TEvDiscover, read body = true, expecting OK + data"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, false, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, false, TInstant::Max(), 0)); break; case 10: UNIT_ASSERT_EQUAL_C(LastResponse.Message, TResponseData::MessageDiscoverResult, @@ -2383,7 +2383,7 @@ class TTestBlobStorageProxyDiscover : public TTestBlobStorageProxy { if (LastResponse.Status != NKikimrProto::OK) { VERBOSE_COUT("ReSending TEvDiscover (due to " << (int)LastResponse.Status << ")"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, false, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, false, TInstant::Max(), 0)); TestStep -= 10; break; } @@ -2391,14 +2391,14 @@ class TTestBlobStorageProxyDiscover : public TTestBlobStorageProxy { TEST_RESPONSE(MessageDiscoverResult, OK, 1, testData2); VERBOSE_COUT("Sending TEvDiscover, read body = true, expecting OK + data"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, true, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, true, TInstant::Max(), 0)); break; case 20: UNIT_ASSERT_EQUAL_C(LastResponse.Message, TResponseData::MessageDiscoverResult, "Unexpected message type# " << (int)LastResponse.Message); if (LastResponse.Status != NKikimrProto::OK) { VERBOSE_COUT("ReSending TEvDiscover (due to " << (int)LastResponse.Status << ")"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, true, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, true, TInstant::Max(), 0)); TestStep -= 10; break; } @@ -2429,13 +2429,13 @@ class TTestBlobStorageProxyDiscoverFail : public TTestBlobStorageProxy { "Unexpected " << (int)LastResponse.Message); VERBOSE_COUT("Sending TEvDiscover, read body = true, expecting OK + data"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, false, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, false, TInstant::Max(), 0)); break; case 10: TEST_RESPONSE(MessageDiscoverResult, ERROR, 0, ""); VERBOSE_COUT("Sending TEvDiscover, read body = true, expecting OK + data"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, true, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, true, TInstant::Max(), 0)); break; case 20: TEST_RESPONSE(MessageDiscoverResult, ERROR, 0, ""); @@ -2465,13 +2465,13 @@ class TTestBlobStorageProxyDiscoverEmpty : public TTestBlobStorageProxy { "Unexpected " << (int)LastResponse.Message); VERBOSE_COUT("Sending TEvDiscover, read body = true, expecting OK + data"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, false, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, false, TInstant::Max(), 0)); break; case 10: TEST_RESPONSE(MessageDiscoverResult, NODATA, 0, ""); VERBOSE_COUT("Sending TEvDiscover, read body = true, expecting OK + data"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, true, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, true, TInstant::Max(), 0)); break; case 20: TEST_RESPONSE(MessageDiscoverResult, NODATA, 0, ""); @@ -2501,13 +2501,13 @@ class TTestBlobStorageProxyDiscoverTimeout : public TTestBlobStorageProxy { "Unexpected " << (int)LastResponse.Message); VERBOSE_COUT("Sending TEvDiscover, read body = true, expecting OK + data"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, false, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, false, TInstant::Max(), 0)); break; case 10: TEST_RESPONSE(MessageDiscoverResult, TIMEOUT, 0, ""); VERBOSE_COUT("Sending TEvDiscover, read body = true, expecting OK + data"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, true, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, true, TInstant::Max(), 0)); break; case 20: TEST_RESPONSE(MessageDiscoverResult, TIMEOUT, 0, ""); @@ -2698,14 +2698,14 @@ class TTestBlobStorageProxyLongTailDiscover : public TTestBlobStorageProxy { "Unexpected " << (int)LastResponse.Message); VERBOSE_COUT("Sending TEvDiscover, read body = true, expecting OK + data"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, false, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, false, TInstant::Max(), 0)); break; case 10: TEST_RESPONSE(MessageDiscoverResult, OK, 1, testData2); VERBOSE_COUT("Sending TEvDiscover, read body = true, expecting OK + data"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, true, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, true, TInstant::Max(), 0)); break; case 20: TEST_RESPONSE(MessageDiscoverResult, OK, 1, testData2); @@ -3065,7 +3065,7 @@ class TTestBlobStorageProxyBasic1 : public TTestBlobStorageProxy { TEST_RESPONSE(MessagePutResult, OK, 0, ""); } VERBOSE_COUT("Sending TEvDiscover, read body = true, expecting OK + data"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, false, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, false, TInstant::Max(), 0)); break; case 230: if (Env->ShouldBeUndiscoverable) { @@ -3074,7 +3074,7 @@ class TTestBlobStorageProxyBasic1 : public TTestBlobStorageProxy { TEST_RESPONSE(MessageDiscoverResult, OK, 1, testData2); } VERBOSE_COUT("Sending TEvDiscover, read body = false, expecting OK"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, false, false, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, false, false, TInstant::Max(), 0)); break; case 240: if (Env->ShouldBeUndiscoverable) { @@ -3083,7 +3083,7 @@ class TTestBlobStorageProxyBasic1 : public TTestBlobStorageProxy { TEST_RESPONSE(MessageDiscoverResult, OK, 1, ""); } VERBOSE_COUT("Sending TEvDiscover, read body = true, expecting NODATA"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(2/*tabletId*/, 0, true, false, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(2/*tabletId*/, 0, true, false, TInstant::Max(), 0)); break; case 250: if (Env->ShouldBeUndiscoverable) { @@ -3092,7 +3092,7 @@ class TTestBlobStorageProxyBasic1 : public TTestBlobStorageProxy { TEST_RESPONSE(MessageDiscoverResult, NODATA, 0, ""); } VERBOSE_COUT("Sending TEvDiscover, read body = true, expecting OK + data"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, true, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, true, true, TInstant::Max(), 0)); break; case 260: if (Env->ShouldBeUndiscoverable) { @@ -3101,7 +3101,7 @@ class TTestBlobStorageProxyBasic1 : public TTestBlobStorageProxy { TEST_RESPONSE(MessageDiscoverResult, OK, 1, testData2); } VERBOSE_COUT("Sending TEvDiscover, read body = false, expecting OK"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, false, true, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(1, 0, false, true, TInstant::Max(), 0)); break; case 270: if (Env->ShouldBeUndiscoverable) { @@ -3110,7 +3110,7 @@ class TTestBlobStorageProxyBasic1 : public TTestBlobStorageProxy { TEST_RESPONSE(MessageDiscoverResult, OK, 1, ""); } VERBOSE_COUT("Sending TEvDiscover, read body = true, expecting NODATA"); - ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(2/*tabletId*/, 0, true, true, TInstant::Max(), 0)); + ctx.Send(Proxy, new TEvBlobStorage::TEvDiscover(2/*tabletId*/, 0, true, true, TInstant::Max(), 0)); break; case 280: { diff --git a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.cpp b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.cpp index 221c55ce00..054d5be665 100644 --- a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.cpp +++ b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.cpp @@ -5,7 +5,7 @@ #include "blobstorage_groupinfo_partlayout.h" #include <ydb/core/base/services/blobstorage_service_id.h> #include <ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.h> - + #include <library/cpp/actors/core/interconnect.h> #include <library/cpp/pop_count/popcount.h> @@ -18,8 +18,8 @@ #include <util/random/fast.h> #include <util/system/unaligned_mem.h> -namespace NKikimr { - +namespace NKikimr { + class TQuorumCheckerBase : public TBlobStorageGroupInfo::IQuorumChecker { protected: const TBlobStorageGroupInfo::TTopology *Top; @@ -784,8 +784,8 @@ void TBlobStorageGroupInfo::PickSubgroup(ui32 hash, TVDiskIds *outVDisk, TServic outServiceIds->push_back(GetActorId(x)); } } -} - +} + bool TBlobStorageGroupInfo::BelongsToSubgroup(const TVDiskID &vdisk, ui32 hash) const { Y_VERIFY_DEBUG_S(vdisk.GroupID == GroupID, "Expected GroupID# " << GroupID << ", given GroupID# " << vdisk.GroupID); Y_VERIFY_DEBUG_S(vdisk.GroupGeneration == GroupGeneration, "Expected GroupGeeration# " << GroupGeneration @@ -902,21 +902,21 @@ TString TBlobStorageGroupInfo::ToString() const { -TVDiskID VDiskIDFromVDiskID(const NKikimrBlobStorage::TVDiskID &x) { - return TVDiskID(x.GetGroupID(), x.GetGroupGeneration(), x.GetRing(), x.GetDomain(), x.GetVDisk()); -} - -void VDiskIDFromVDiskID(const TVDiskID &id, NKikimrBlobStorage::TVDiskID *proto) { - proto->SetGroupID(id.GroupID); - proto->SetGroupGeneration(id.GroupGeneration); +TVDiskID VDiskIDFromVDiskID(const NKikimrBlobStorage::TVDiskID &x) { + return TVDiskID(x.GetGroupID(), x.GetGroupGeneration(), x.GetRing(), x.GetDomain(), x.GetVDisk()); +} + +void VDiskIDFromVDiskID(const TVDiskID &id, NKikimrBlobStorage::TVDiskID *proto) { + proto->SetGroupID(id.GroupID); + proto->SetGroupGeneration(id.GroupGeneration); proto->SetRing(id.FailRealm); proto->SetDomain(id.FailDomain); - proto->SetVDisk(id.VDisk); -} - - + proto->SetVDisk(id.VDisk); +} + + TFailDomain::TLevelIds::TLevelIds() { -} +} bool TFailDomain::TLevelIds::IsEmpty() const { return Ids.empty(); diff --git a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h index 918283ffad..e2d1445be4 100644 --- a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h +++ b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "defs.h" #include <ydb/core/blobstorage/base/blobstorage_vdiskid.h> @@ -18,8 +18,8 @@ namespace NActors { class TNodeLocation; } // NActors -namespace NKikimr { - +namespace NKikimr { + struct TDsProxyNodeMon; class TSubgroupPartLayout; @@ -55,7 +55,7 @@ struct TEncryptionKey { } }; -// current state of storage group +// current state of storage group class TBlobStorageGroupInfo : public TThrRefBase { public: //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -161,19 +161,19 @@ public: ui32 FailDomainOrderNumber = 0; }; - struct TFailDomain { + struct TFailDomain { // VDisks composing this fail domain TVector<TVDiskInfo> VDisks; // fail domain order number; domains are numbered continuously through all fail realms ui32 FailDomainOrderNumber = 0; - }; - + }; + struct TFailRealm { // fail domains contained in this fail realm TVector<TFailDomain> FailDomains; - }; - + }; + struct TTopology { // group type (i.e. erasure) const TBlobStorageGroupType GType; @@ -315,7 +315,7 @@ public: static TIntrusivePtr<TBlobStorageGroupInfo> Parse(const NKikimrBlobStorage::TGroupInfo& group, const TEncryptionKey *key, IOutputStream *err); - + static bool DecryptGroupKey(TBlobStorageGroupInfo::EEncryptionMode encryptionMode, const TString& mainKeyId, const TString& encryptedGroupKey, ui64 groupKeyNonce, const TCypherKey& tenantKey, TCypherKey *outGroupKey, ui32 groupId); @@ -429,8 +429,8 @@ private: TMaybe<TKikimrScopeId> AcceptedScope; TString StoragePoolName; TPDiskCategory::EDeviceType DeviceType = TPDiskCategory::DEVICE_TYPE_UNKNOWN; -}; - +}; + // physical fail domain description struct TFailDomain { struct TLevelIds { diff --git a/ydb/core/blobstorage/nodewarden/blobstorage_node_warden_ut.cpp b/ydb/core/blobstorage/nodewarden/blobstorage_node_warden_ut.cpp index 4ecd790f01..e3c74cce7b 100644 --- a/ydb/core/blobstorage/nodewarden/blobstorage_node_warden_ut.cpp +++ b/ydb/core/blobstorage/nodewarden/blobstorage_node_warden_ut.cpp @@ -125,7 +125,7 @@ void SetupServices(TTestActorRuntime &runtime, TString extraPath, TIntrusivePtr< { // setup domain info app.ClearDomainsAndHive(); auto domain = TDomainsInfo::TDomain::ConstructDomainWithExplicitTabletIds("dc-1", domainId, 0, - domainId, domainId, TVector<ui32>{domainId}, + domainId, domainId, TVector<ui32>{domainId}, domainId, TVector<ui32>{domainId}, 100500, TVector<ui64>{}, diff --git a/ydb/core/blobstorage/nodewarden/group_stat_aggregator.cpp b/ydb/core/blobstorage/nodewarden/group_stat_aggregator.cpp index 41fd81aa0d..9f63143b32 100644 --- a/ydb/core/blobstorage/nodewarden/group_stat_aggregator.cpp +++ b/ydb/core/blobstorage/nodewarden/group_stat_aggregator.cpp @@ -21,10 +21,10 @@ namespace { THashMap<ui32, TNodeStat> PerNodeStat; public: - static constexpr NKikimrServices::TActivity::EType ActorActivityType() { - return NKikimrServices::TActivity::NODE_WARDEN_STATAGGR_ACTOR; - } - + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { + return NKikimrServices::TActivity::NODE_WARDEN_STATAGGR_ACTOR; + } + TGroupStatAggregatorActor(ui32 groupId, const TActorId& vdiskServiceId, TDuration reportPeriod = TDuration::Seconds(10)) : GroupId(groupId) , VDiskServiceId(vdiskServiceId) diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_actor.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_actor.cpp index 131298cd4e..d92b19c6cc 100644 --- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_actor.cpp +++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_actor.cpp @@ -807,7 +807,7 @@ public: ui64 whiteboardReportCycles = 0; ui64 updateSchedulerCycles = 0; if (!IsFormattingNow && AtomicGet(PDisk->IsStarted)) { - PDisk->InputRequest(request.Release()); + PDisk->InputRequest(request.Release()); // Update the current scheduler whiteboardReportCycles = timer.Elapsed(); diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_restore_ut.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_restore_ut.cpp index 520387dca0..2e0cc9c9a7 100644 --- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_restore_ut.cpp +++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_restore_ut.cpp @@ -1,35 +1,35 @@ -#include "defs.h" +#include "defs.h" -#include "blobstorage_pdisk_ut.h" +#include "blobstorage_pdisk_ut.h" #include "blobstorage_pdisk_ut_actions.h" #include "blobstorage_pdisk_ut_config.h" #include "blobstorage_pdisk_ut_run.h" - + #include <util/folder/tempdir.h> -namespace NKikimr { - +namespace NKikimr { + Y_UNIT_TEST_SUITE(TYardTestRestore) { - - YARD_UNIT_TEST(TestRestore15) { + + YARD_UNIT_TEST(TestRestore15) { TTestContext tc(false, true); - ui32 chunkSize = MIN_CHUNK_SIZE; + ui32 chunkSize = MIN_CHUNK_SIZE; Run<TTestWriteChunksAndLog>(&tc, 1, chunkSize, false, true); - - ui32 dataSize = 8 * chunkSize; - NPDisk::TAlignedData dataAfter(dataSize); + + ui32 dataSize = 8 * chunkSize; + NPDisk::TAlignedData dataAfter(dataSize); ReadPdiskFile(&tc, dataSize, dataAfter); - - for (ui32 i = 0; i < 15; ++i) { - VERBOSE_COUT("TestRestore15 i=" << i); + + for (ui32 i = 0; i < 15; ++i) { + VERBOSE_COUT("TestRestore15 i=" << i); DestroySectors(&tc, dataAfter, dataSize, i, 15); - + Run<TTestCheckLog>(&tc, 1, chunkSize, false, true); - //Can't use resutlts for the next test because we don't wait for the restoration before shutting down. - } - } - -} - -} // namespace NKikimr + //Can't use resutlts for the next test because we don't wait for the restoration before shutting down. + } + } + +} + +} // namespace NKikimr diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut.h index 3da1bddc17..6bf5c0695d 100644 --- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut.h +++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut.h @@ -1,6 +1,6 @@ -#pragma once -#include "defs.h" - +#pragma once +#include "defs.h" + #include "blobstorage_pdisk_ut_defs.h" #include "blobstorage_pdisk_blockdevice.h" #include <ydb/library/pdisk_io/buffers.h> @@ -20,7 +20,7 @@ #include <ydb/core/node_whiteboard/node_whiteboard.h> #include <ydb/core/protos/blobstorage_vdisk_config.pb.h> #include <ydb/core/protos/services.pb.h> - + #include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/actors/core/event_local.h> #include <library/cpp/actors/core/events.h> @@ -36,18 +36,18 @@ #include <library/cpp/svnversion/svnversion.h> #include <library/cpp/testing/unittest/registar.h> #include <library/cpp/testing/unittest/tests_data.h> - -#include <util/folder/dirut.h> -#include <util/generic/hash.h> + +#include <util/folder/dirut.h> +#include <util/generic/hash.h> #include <util/generic/queue.h> -#include <util/generic/string.h> -#include <util/generic/yexception.h> -#include <util/generic/ymath.h> -#include <util/random/entropy.h> -#include <util/stream/input.h> -#include <util/string/printf.h> +#include <util/generic/string.h> +#include <util/generic/yexception.h> +#include <util/generic/ymath.h> +#include <util/random/entropy.h> +#include <util/stream/input.h> +#include <util/string/printf.h> #include <util/system/backtrace.h> -#include <util/system/defaults.h> -#include <util/system/event.h> -#include <util/system/sanitizers.h> -#include <util/system/valgrind.h> +#include <util/system/defaults.h> +#include <util/system/event.h> +#include <util/system/sanitizers.h> +#include <util/system/valgrind.h> diff --git a/ydb/core/blobstorage/testload/test_load_actor.cpp b/ydb/core/blobstorage/testload/test_load_actor.cpp index c482893ebf..c8788b1310 100644 --- a/ydb/core/blobstorage/testload/test_load_actor.cpp +++ b/ydb/core/blobstorage/testload/test_load_actor.cpp @@ -330,12 +330,12 @@ public: Y_VERIFY(it != InfoRequests.end()); THttpInfoRequest& info = it->second; -#define PROFILE(NAME) \ - str << "<option value=\"" << ui32(NKikimrBlobStorage::TEvTestLoadRequest::NAME) << "\">" << #NAME << "</option>"; - -#define PUT_HANDLE_CLASS(NAME) \ - str << "<option value=\"" << ui32(NKikimrBlobStorage::NAME) << "\">" << #NAME << "</option>"; - +#define PROFILE(NAME) \ + str << "<option value=\"" << ui32(NKikimrBlobStorage::TEvTestLoadRequest::NAME) << "\">" << #NAME << "</option>"; + +#define PUT_HANDLE_CLASS(NAME) \ + str << "<option value=\"" << ui32(NKikimrBlobStorage::NAME) << "\">" << #NAME << "</option>"; + TStringStream str; HTML(str) { if (info.ErrorMessage) { diff --git a/ydb/core/blobstorage/ut_pdiskfit/lib/fail_injection_test.h b/ydb/core/blobstorage/ut_pdiskfit/lib/fail_injection_test.h index 7455fbc55c..7e0bfa05e0 100644 --- a/ydb/core/blobstorage/ut_pdiskfit/lib/fail_injection_test.h +++ b/ydb/core/blobstorage/ut_pdiskfit/lib/fail_injection_test.h @@ -111,7 +111,7 @@ struct TPDiskFailureInjectionTest { TIntrusivePtr<NMonitoring::TDynamicCounters> Counters; - TProgramShouldContinue KikimrShouldContinue; + TProgramShouldContinue KikimrShouldContinue; std::unique_ptr<NKikimr::TAppData> AppData; std::shared_ptr<NKikimr::NPDisk::IIoContextFactory> IoContext; std::unique_ptr<NActors::TActorSystem> ActorSystem; diff --git a/ydb/core/blobstorage/ut_vdisk/lib/astest.h b/ydb/core/blobstorage/ut_vdisk/lib/astest.h index 2bbb6b7095..2cf254eff2 100644 --- a/ydb/core/blobstorage/ut_vdisk/lib/astest.h +++ b/ydb/core/blobstorage/ut_vdisk/lib/astest.h @@ -31,7 +31,7 @@ public: } private: - TProgramShouldContinue KikimrShouldContinue; + TProgramShouldContinue KikimrShouldContinue; TIntrusivePtr<NMonitoring::TDynamicCounters> Counters; std::unique_ptr<NActors::TMon> Monitoring; std::unique_ptr<NKikimr::TAppData> AppData; diff --git a/ydb/core/blobstorage/ut_vdisk/lib/prepare.cpp b/ydb/core/blobstorage/ut_vdisk/lib/prepare.cpp index 501ef3a384..b2c020c3d2 100644 --- a/ydb/core/blobstorage/ut_vdisk/lib/prepare.cpp +++ b/ydb/core/blobstorage/ut_vdisk/lib/prepare.cpp @@ -274,7 +274,7 @@ TConfiguration::~TConfiguration() { } } -static TProgramShouldContinue KikimrShouldContinue; +static TProgramShouldContinue KikimrShouldContinue; void TConfiguration::Prepare(IVDiskSetup *vdiskSetup, bool newPDisks, bool runRepl) { // FIXME: put newPDisks into configuration (see up) Counters = TIntrusivePtr<NMonitoring::TDynamicCounters>(new NMonitoring::TDynamicCounters()); diff --git a/ydb/core/blobstorage/ut_vdisk/vdisk_test.cpp b/ydb/core/blobstorage/ut_vdisk/vdisk_test.cpp index 58384e8668..694828c9f8 100644 --- a/ydb/core/blobstorage/ut_vdisk/vdisk_test.cpp +++ b/ydb/core/blobstorage/ut_vdisk/vdisk_test.cpp @@ -379,7 +379,7 @@ Y_UNIT_TEST_SUITE(TBsVDiskOutOfSpace) { Y_UNIT_TEST(WriteUntilYellowZone) { TWriteUntilYellowZone test; const ui32 chunkSize = 512u << 10u; - const ui64 diskSize = 700ull << 20ull; + const ui64 diskSize = 700ull << 20ull; TestRun<TWriteUntilYellowZone, TFastVDiskSetupCompacted>(&test, TIMEOUT, chunkSize, diskSize); } } diff --git a/ydb/core/blobstorage/vdisk/handoff/handoff_proxy.cpp b/ydb/core/blobstorage/vdisk/handoff/handoff_proxy.cpp index ecbcf16288..9a2d1676e0 100644 --- a/ydb/core/blobstorage/vdisk/handoff/handoff_proxy.cpp +++ b/ydb/core/blobstorage/vdisk/handoff/handoff_proxy.cpp @@ -322,12 +322,12 @@ namespace NKikimr { , WaitQueue() , InFlightQueue() , State() - { - BadStateTimeouts[0] = TDuration::Seconds(0); - BadStateTimeouts[1] = TDuration::MilliSeconds(500); - BadStateTimeouts[2] = TDuration::Seconds(3); - BadStateTimeouts[3] = TDuration::Seconds(10); - } + { + BadStateTimeouts[0] = TDuration::Seconds(0); + BadStateTimeouts[1] = TDuration::MilliSeconds(500); + BadStateTimeouts[2] = TDuration::Seconds(3); + BadStateTimeouts[3] = TDuration::Seconds(10); + } }; IActor *CreateHandoffProxyActor(TIntrusivePtr<TBlobStorageGroupInfo> info, diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullwritesst_ut.cpp b/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullwritesst_ut.cpp index b6c6ea31eb..2bd6de3d43 100644 --- a/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullwritesst_ut.cpp +++ b/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullwritesst_ut.cpp @@ -156,7 +156,7 @@ namespace NKikimr { TTLogoBlobCompactRecordMerger merger(TBlobStorageGroupType::ErasureMirror3); for (ui32 step = 0; step < maxStep; step++) { - TLogoBlobID id(1, 1, step, 0, 0, 0); + TLogoBlobID id(1, 1, step, 0, 0, 0); TKeyLogoBlob key(id); ui64 ingressMagic = ui64(1) << ui64(2); // magic @@ -193,7 +193,7 @@ namespace NKikimr { TTLogoBlobCompactRecordMerger merger(TBlobStorageGroupType::ErasureMirror3); for (ui32 step = 0; step < maxStep; step++) { - TLogoBlobID id(1, 1, step, 0, 0, 0); + TLogoBlobID id(1, 1, step, 0, 0, 0); TKeyLogoBlob key(id); ui64 ingressMagic1 = ui64(1) << ui64(2); // magic diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst_it_all_ut.cpp b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst_it_all_ut.cpp index 748bb79054..f965e75f61 100644 --- a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst_it_all_ut.cpp +++ b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst_it_all_ut.cpp @@ -17,12 +17,12 @@ namespace NKikimr { static const ui32 CompWorthReadSize = 2u << 20u; TLogoBlobSstPtr GenerateSst(ui32 step, ui32 recs, ui32 plus, ui64 tabletId = 0, ui32 generation = 0, - ui32 channel = 0, ui32 cookie = 0) { - using TRec = TLogoBlobSst::TRec; + ui32 channel = 0, ui32 cookie = 0) { + using TRec = TLogoBlobSst::TRec; Y_UNUSED(step); TLogoBlobSstPtr ptr(new TLogoBlobSst(TTestContexts().GetVCtx())); for (ui32 i = 0; i < recs; i++) { - TLogoBlobID id(tabletId, generation, step + i * plus, channel, 0, cookie); + TLogoBlobID id(tabletId, generation, step + i * plus, channel, 0, cookie); TRec rec {TKeyLogoBlob(id), TMemRecLogoBlob()}; ptr->LoadedIndex.push_back(rec); } @@ -30,10 +30,10 @@ namespace NKikimr { } TLogoBlobOrderedSstsPtr GenerateOrderedSsts(ui32 step, ui32 recs, ui32 plus, ui32 ssts, ui64 tabletId = 0, - ui32 generation = 0, ui32 channel = 0, ui32 cookie = 0) { + ui32 generation = 0, ui32 channel = 0, ui32 cookie = 0) { TSegments vec; for (ui32 i = 0; i < ssts; i++) { - vec.push_back(GenerateSst(step, recs, plus, tabletId, generation, channel, cookie)); + vec.push_back(GenerateSst(step, recs, plus, tabletId, generation, channel, cookie)); step += recs * plus; } @@ -46,7 +46,7 @@ namespace NKikimr { Y_UNIT_TEST_SUITE(TBlobStorageHullSstIt) { using namespace NBlobStorageHullSstItHelpers; - using TMemIterator = TLogoBlobSst::TMemIterator; + using TMemIterator = TLogoBlobSst::TMemIterator; Y_UNIT_TEST(TestSeekToFirst) { TLogoBlobSstPtr ptr(GenerateSst(10, 10, 1)); @@ -89,7 +89,7 @@ namespace NKikimr { TMemIterator it(ptr.Get()); TLogoBlobID id; - id = TLogoBlobID(0, 0, 15, 0, 0, 0); + id = TLogoBlobID(0, 0, 15, 0, 0, 0); it.Seek(id); UNIT_ASSERT(it.GetCurKey().ToString() == TString("[0:0:15:0:0:0:0]")); @@ -109,7 +109,7 @@ namespace NKikimr { TMemIterator it(ptr.Get()); TLogoBlobID id; - id = TLogoBlobID(0, 0, 15, 0, 0, 0); + id = TLogoBlobID(0, 0, 15, 0, 0, 0); it.Seek(id); UNIT_ASSERT(it.GetCurKey().ToString() == TString("[0:0:15:0:0:0:0]")); @@ -129,7 +129,7 @@ namespace NKikimr { TMemIterator it(ptr.Get()); TLogoBlobID id; - id = TLogoBlobID(0, 0, 5, 0, 0, 0); + id = TLogoBlobID(0, 0, 5, 0, 0, 0); it.Seek(id); UNIT_ASSERT(it.GetCurKey().ToString() == "[0:0:10:0:0:0:0]"); } @@ -139,7 +139,7 @@ namespace NKikimr { TMemIterator it(ptr.Get()); TLogoBlobID id; - id = TLogoBlobID(0, 0, 25, 0, 0, 0); + id = TLogoBlobID(0, 0, 25, 0, 0, 0); it.Seek(id); UNIT_ASSERT(!it.Valid()); it.Prev(); @@ -152,7 +152,7 @@ namespace NKikimr { TMemIterator it(ptr.Get()); TLogoBlobID id; - id = TLogoBlobID(0, 0, 15, 0, 0, 0); + id = TLogoBlobID(0, 0, 15, 0, 0, 0); it.Seek(id); UNIT_ASSERT(it.GetCurKey().ToString() == "[0:0:16:0:0:0:0]"); } @@ -161,7 +161,7 @@ namespace NKikimr { Y_UNIT_TEST_SUITE(TBlobStorageHullOrderedSstsIt) { using namespace NBlobStorageHullSstItHelpers; - using TIterator = TLogoBlobOrderedSsts::TReadIterator; + using TIterator = TLogoBlobOrderedSsts::TReadIterator; TTestContexts TestCtx(ChunkSize, CompWorthReadSize); Y_UNIT_TEST(TestSeekToFirst) { @@ -214,7 +214,7 @@ namespace NKikimr { TIterator it(hullCtx, ptr.Get()); TLogoBlobID id; - id = TLogoBlobID(0, 0, 30, 0, 0, 0); + id = TLogoBlobID(0, 0, 30, 0, 0, 0); it.Seek(id); UNIT_ASSERT(!it.Valid()); it.Prev(); diff --git a/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress_ut.cpp b/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress_ut.cpp index 19651da55c..82cf659f5a 100644 --- a/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress_ut.cpp +++ b/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress_ut.cpp @@ -20,7 +20,7 @@ namespace NKikimr { TVDiskID vdisk21 = TVDiskID(0, 1, 0, 2, 1); TVDiskID vdisk30 = TVDiskID(0, 1, 0, 3, 0); - TLogoBlobID lb1(0, 0, 0, 0, 0, 0); + TLogoBlobID lb1(0, 0, 0, 0, 0, 0); // correspondings parts TIngress i1 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdisk10, TLogoBlobID(lb1, 1)); @@ -101,7 +101,7 @@ namespace NKikimr { Y_UNIT_TEST(IngressLocalParts) { TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4); - TLogoBlobID lb1(0, 1, 0, 0, 0, 0); + TLogoBlobID lb1(0, 1, 0, 0, 0, 0); TBlobStorageGroupInfo::TVDiskIds vDisks; TBlobStorageGroupInfo::TServiceIds serviceIds; groupInfo.PickSubgroup(lb1.Hash(), &vDisks, &serviceIds); @@ -195,7 +195,7 @@ namespace NKikimr { Y_UNIT_TEST(IngressGetMainReplica) { TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4); - TLogoBlobID lb1(0, 1, 0, 0, 0, 0); + TLogoBlobID lb1(0, 1, 0, 0, 0, 0); TBlobStorageGroupInfo::TVDiskIds vDisks; TBlobStorageGroupInfo::TServiceIds serviceIds; groupInfo.PickSubgroup(lb1.Hash(), &vDisks, &serviceIds); @@ -216,7 +216,7 @@ namespace NKikimr { Y_UNIT_TEST(IngressHandoffPartsDelete) { TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4); - TLogoBlobID lb1(0, 1, 0, 0, 0, 0); + TLogoBlobID lb1(0, 1, 0, 0, 0, 0); TBlobStorageGroupInfo::TVDiskIds vDisks; TBlobStorageGroupInfo::TServiceIds serviceIds; groupInfo.PickSubgroup(lb1.Hash(), &vDisks, &serviceIds); diff --git a/ydb/core/blobstorage/vdisk/query/query_stream.h b/ydb/core/blobstorage/vdisk/query/query_stream.h index ff7cadb334..1f5236284d 100644 --- a/ydb/core/blobstorage/vdisk/query/query_stream.h +++ b/ydb/core/blobstorage/vdisk/query/query_stream.h @@ -260,10 +260,10 @@ namespace NKikimr { TDumpProcessor Processor; public: - static constexpr NKikimrServices::TActivity::EType ActorActivityType() { - return NKikimrServices::TActivity::BS_MONSTREAM_ACTOR; - } - + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { + return NKikimrServices::TActivity::BS_MONSTREAM_ACTOR; + } + TLevelIndexStreamActor(THullDsSnap&& fullSnap, TEvBlobStorage::TEvMonStreamQuery::TPtr& ev) : FullSnap(std::move(fullSnap)) , StreamId(std::move(ev->Get()->StreamId)) diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.cpp b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.cpp index 4f741e4524..44b3c58c9c 100644 --- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.cpp +++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.cpp @@ -382,8 +382,8 @@ namespace NKikimr { } else if (allButton) { // browse database IsRangeQuery = true; - From = TLogoBlobID(0, 4294967295, 4294967295, 0, 0, 0, TLogoBlobID::MaxPartId); - To = TLogoBlobID(0, 0, 0, 0, 0, 0, 1); + From = TLogoBlobID(0, 4294967295, 4294967295, 0, 0, 0, TLogoBlobID::MaxPartId); + To = TLogoBlobID(0, 0, 0, 0, 0, 0, 1); req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(SelfVDiskId, TInstant::Max(), NKikimrBlobStorage::EGetHandleClass::AsyncRead, flags, {}, From, To, 15); } else diff --git a/ydb/core/blobstorage/vdisk/syncer/guid_proxybase.h b/ydb/core/blobstorage/vdisk/syncer/guid_proxybase.h index 2db69beb32..ffdd4b26c7 100644 --- a/ydb/core/blobstorage/vdisk/syncer/guid_proxybase.h +++ b/ydb/core/blobstorage/vdisk/syncer/guid_proxybase.h @@ -33,7 +33,7 @@ namespace NKikimr { void Die(const TActorContext &ctx) override { // unsubscribe on session when die auto nodeId = TargetServiceId.NodeId(); - ctx.Send(TActivationContext::InterconnectProxy(nodeId), + ctx.Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe); TActor::Die(ctx); } diff --git a/ydb/core/blobstorage/vdisk/syncer/syncer_job_actor.cpp b/ydb/core/blobstorage/vdisk/syncer/syncer_job_actor.cpp index 69dc453f43..c1a1629bf1 100644 --- a/ydb/core/blobstorage/vdisk/syncer/syncer_job_actor.cpp +++ b/ydb/core/blobstorage/vdisk/syncer/syncer_job_actor.cpp @@ -70,7 +70,7 @@ namespace NKikimr { // overridden Die (unsubsribe from Message/Session tracking) void Die(const TActorContext &ctx) override { // unsubscribe on session when die - ctx.Send(TActivationContext::InterconnectProxy(NodeId), + ctx.Send(TActivationContext::InterconnectProxy(NodeId), new TEvents::TEvUnsubscribe); TBase::Die(ctx); } diff --git a/ydb/core/client/client_ut.cpp b/ydb/core/client/client_ut.cpp index a4a95c54fa..b94c722588 100644 --- a/ydb/core/client/client_ut.cpp +++ b/ydb/core/client/client_ut.cpp @@ -27,7 +27,7 @@ using NClient::TValue; namespace Tests { using namespace NMiniKQL; -// const ui32 TestDomain = 1; +// const ui32 TestDomain = 1; static const TString TablePlacement = "/dc-1/Berkanavt/tables"; @@ -101,7 +101,7 @@ struct TTestTables { TTestTables(TClient& client, EVariant var, ui32 numFollowers = 0) : Client(client) - { + { TOpts opts(var, numFollowers); NKikimrSchemeOp::TTableDescription tableSimple; { @@ -115,24 +115,24 @@ struct TTestTables { auto *c3 = tableSimple.AddColumns(); c3->SetName("bytes"); c3->SetType("String"); - + if (opts.Sharded) tableSimple.SetUniformPartitionsCount(10); - + if (opts.FollowerCount) tableSimple.MutablePartitionConfig()->SetFollowerCount(opts.FollowerCount); - + if (opts.OutOfOrder) { tableSimple.MutablePartitionConfig()->MutablePipelineConfig()->SetNumActiveTx(8); tableSimple.MutablePartitionConfig()->MutablePipelineConfig()->SetEnableOutOfOrder(true); } - + if (opts.SoftUpdates) tableSimple.MutablePartitionConfig()->MutablePipelineConfig()->SetEnableSoftUpdates(true); - + *tableSimple.AddKeyColumnNames() = "key"; } - + NKikimrSchemeOp::TTableDescription tableByBytes; { tableByBytes.SetName("ByBytes"); @@ -179,14 +179,14 @@ struct TTestTables { UNIT_ASSERT_EQUAL(client.CreateTable(TablePlacement, tableSimple), NMsgBusProxy::MSTATUS_OK); UNIT_ASSERT_EQUAL(client.CreateTable(TablePlacement, tableByBytes), NMsgBusProxy::MSTATUS_OK); UNIT_ASSERT_EQUAL(client.CreateTable(TablePlacement, tableComp), NMsgBusProxy::MSTATUS_OK); - } - + } + ~TTestTables() { UNIT_ASSERT_EQUAL(Client.DeleteTable(TablePlacement, "Simple"), NMsgBusProxy::MSTATUS_OK); UNIT_ASSERT_EQUAL(Client.DeleteTable(TablePlacement, "ByBytes"), NMsgBusProxy::MSTATUS_OK); UNIT_ASSERT_EQUAL(Client.DeleteTable(TablePlacement, "Comp"), NMsgBusProxy::MSTATUS_OK); } - + private: TClient& Client; }; @@ -337,21 +337,21 @@ Y_UNIT_TEST_SUITE(TClientTest) { TServer server(settings); TClient client(settings); - NKikimrMiniKQL::TResult res; + NKikimrMiniKQL::TResult res; UNIT_ASSERT(client.LocalQuery(TxAllocator, "(" - "(let row '('('dummyKey (Bool 'true))))" - "(let select '('reservedIds))" + "(let row '('('dummyKey (Bool 'true))))" + "(let select '('reservedIds))" "(return (AsList (SetResult 'reservedIds (SelectRow 'config row select))))" - ")", res)); + ")", res)); { TValue value = TValue::Create(res.GetValue(), res.GetType()); UNIT_ASSERT(value["reservedIds"].Size() <= 1); } - } + } Y_UNIT_TEST(NoAffectedProgram) { - using namespace NScheme; + using namespace NScheme; TPortManager tp; ui16 port = tp.GetPort(2134); @@ -359,10 +359,10 @@ Y_UNIT_TEST_SUITE(TClientTest) { TServer server(settings); TClient client(settings); - NKikimrMiniKQL::TResult res; - UNIT_ASSERT(client.FlatQuery("(" - "(return (AsList (SetResult 'res1 (Int32 '42))))" - ")", res)); + NKikimrMiniKQL::TResult res; + UNIT_ASSERT(client.FlatQuery("(" + "(return (AsList (SetResult 'res1 (Int32 '42))))" + ")", res)); { TValue value = TValue::Create(res.GetValue(), res.GetType()); @@ -370,7 +370,7 @@ Y_UNIT_TEST_SUITE(TClientTest) { UNIT_ASSERT(resOpt.HaveValue()); UNIT_ASSERT_EQUAL(i32(resOpt), 42); } - } + } Y_UNIT_TEST(ReadWriteMiniKQL) { TPortManager tp; @@ -412,42 +412,42 @@ Y_UNIT_TEST_SUITE(TClientTest) { } void ReadWriteViaMiniKQLBody(TClient &client, bool useHead, bool useFollower) { - NKikimrMiniKQL::TResult writeRes; + NKikimrMiniKQL::TResult writeRes; const TString writeQuery = R"___( - ( - (let row1 '('('key (Uint64 '2)))) - (let row2 '('('key (Uint64 '2305843009213693951)))) - (let update '( '('uint (Uint64 '10)))) - (let result1 (UpdateRow '/dc-1/Berkanavt/tables/Simple row1 update)) - (let result2 (UpdateRow '/dc-1/Berkanavt/tables/Simple row2 update)) - - (return (AsList result1 result2)) - ) - )___"; - - UNIT_ASSERT(client.FlatQuery(writeQuery, writeRes)); - - NKikimrMiniKQL::TResult readRes; + ( + (let row1 '('('key (Uint64 '2)))) + (let row2 '('('key (Uint64 '2305843009213693951)))) + (let update '( '('uint (Uint64 '10)))) + (let result1 (UpdateRow '/dc-1/Berkanavt/tables/Simple row1 update)) + (let result2 (UpdateRow '/dc-1/Berkanavt/tables/Simple row2 update)) + + (return (AsList result1 result2)) + ) + )___"; + + UNIT_ASSERT(client.FlatQuery(writeQuery, writeRes)); + + NKikimrMiniKQL::TResult readRes; const TString readQueryTemplate = R"___( - ( - (let row1 '('('key (Uint64 '2)))) - (let nonExistRow1 '('('key (Uint64 '3)))) - (let row2 '('('key (Uint64 '2305843009213693951)))) - (let nonExistRow2 '('('key (Uint64 '2305843009213693952)))) - (let select '('uint)) + ( + (let row1 '('('key (Uint64 '2)))) + (let nonExistRow1 '('('key (Uint64 '3)))) + (let row2 '('('key (Uint64 '2305843009213693951)))) + (let nonExistRow2 '('('key (Uint64 '2305843009213693952)))) + (let select '('uint)) (let result1 (SelectRow '/dc-1/Berkanavt/tables/Simple row1 select __HEAD__)) (let result2 (SelectRow '/dc-1/Berkanavt/tables/Simple row2 select __HEAD__)) - (let entry1 (Coalesce (FlatMap result1 (lambda '(x) (Member x 'uint))) (Uint64 '0))) - (let entry2 (Coalesce (FlatMap result2 (lambda '(x) (Member x 'uint))) (Uint64 '0))) + (let entry1 (Coalesce (FlatMap result1 (lambda '(x) (Member x 'uint))) (Uint64 '0))) + (let entry2 (Coalesce (FlatMap result2 (lambda '(x) (Member x 'uint))) (Uint64 '0))) (let non1 (SelectRow '/dc-1/Berkanavt/tables/Simple nonExistRow1 select __HEAD__)) (let non2 (SelectRow '/dc-1/Berkanavt/tables/Simple nonExistRow2 select __HEAD__)) - (return (AsList (SetResult 'uint1 entry1) (SetResult 'uint2 entry2) (SetResult 'empty1 (Exists non1)) (SetResult 'empty2 (Exists non2)) )) - ) - )___"; + (return (AsList (SetResult 'uint1 entry1) (SetResult 'uint2 entry2) (SetResult 'empty1 (Exists non1)) (SetResult 'empty2 (Exists non2)) )) + ) + )___"; TString readQuery = readQueryTemplate; SubstGlobal(readQuery, "__HEAD__", !useHead ? (useFollower ? "'follower" : "'online") : "'head"); - UNIT_ASSERT(client.FlatQuery(readQuery, readRes)); + UNIT_ASSERT(client.FlatQuery(readQuery, readRes)); { TValue value = TValue::Create(readRes.GetValue(), readRes.GetType()); @@ -520,7 +520,7 @@ Y_UNIT_TEST_SUITE(TClientTest) { TTestTables tables(client, TTestTables::Sharded_NoOpts); ReadWriteViaMiniKQLBody(client, false, false); } - } + } Y_UNIT_TEST(ReadWrite_MiniKQL_AfterAlter) { TPortManager tp; @@ -607,74 +607,74 @@ Y_UNIT_TEST_SUITE(TClientTest) { } Y_UNIT_TEST(ReadWriteViaMiniKQLRecreateDifferentTable) { - TPortManager tp; - ui16 port = tp.GetPort(2134); - + TPortManager tp; + ui16 port = tp.GetPort(2134); + const auto settings = TServerSettings(port); TServer server(settings); TClient client(settings); client.InitRootScheme(); - + { TTestTables tables(client, TTestTables::OneShard_NoOpts); ReadWriteViaMiniKQLBody(client, false, false); } - - { + + { NKikimrSchemeOp::TTableDescription tableSimple; - tableSimple.SetName("Simple"); - auto *c1 = tableSimple.AddColumns(); - c1->SetName("key"); - c1->SetType("Uint32"); - auto *c2 = tableSimple.AddColumns(); - c2->SetName("uint"); - c2->SetType("Uint64"); - auto *c3 = tableSimple.AddColumns(); - c3->SetName("bytes"); + tableSimple.SetName("Simple"); + auto *c1 = tableSimple.AddColumns(); + c1->SetName("key"); + c1->SetType("Uint32"); + auto *c2 = tableSimple.AddColumns(); + c2->SetName("uint"); + c2->SetType("Uint64"); + auto *c3 = tableSimple.AddColumns(); + c3->SetName("bytes"); c3->SetType("String"); - - *tableSimple.AddKeyColumnNames() = "key"; - client.CreateTable(TablePlacement, tableSimple); - } - + + *tableSimple.AddKeyColumnNames() = "key"; + client.CreateTable(TablePlacement, tableSimple); + } + const TString writeQuery = R"___( - ( - (let row1 '('('key (Uint32 '2)))) - (let row2 '('('key (Uint32 '3)))) - (let update '( '('uint (Uint64 '10)))) - (let result1 (UpdateRow '/dc-1/Berkanavt/tables/Simple row1 update)) - (let result2 (UpdateRow '/dc-1/Berkanavt/tables/Simple row2 update)) - - (return (AsList result1 result2)) - ) - )___"; - - NKikimrMiniKQL::TResult writeRes; - UNIT_ASSERT(client.FlatQuery(writeQuery, writeRes)); - } - + ( + (let row1 '('('key (Uint32 '2)))) + (let row2 '('('key (Uint32 '3)))) + (let update '( '('uint (Uint64 '10)))) + (let result1 (UpdateRow '/dc-1/Berkanavt/tables/Simple row1 update)) + (let result2 (UpdateRow '/dc-1/Berkanavt/tables/Simple row2 update)) + + (return (AsList result1 result2)) + ) + )___"; + + NKikimrMiniKQL::TResult writeRes; + UNIT_ASSERT(client.FlatQuery(writeQuery, writeRes)); + } + Y_UNIT_TEST(ReadWriteViaMiniKQLRecreateSameTable) { - TPortManager tp; - ui16 port = tp.GetPort(2134); - + TPortManager tp; + ui16 port = tp.GetPort(2134); + const auto settings = TServerSettings(port); TServer server(settings); TClient client(settings); client.InitRootScheme(); - + { TTestTables tables(client, TTestTables::OneShard_NoOpts); ReadWriteViaMiniKQLBody(client, false, false); } - + { TTestTables tables(client, TTestTables::Sharded_NoOpts); ReadWriteViaMiniKQLBody(client, false, false); } - } - + } + Y_UNIT_TEST(ReadWriteViaMiniKQLShardedHead) { TPortManager tp; ui16 port = tp.GetPort(2134); @@ -802,42 +802,42 @@ Y_UNIT_TEST_SUITE(TClientTest) { GetStepTxIdBody(client, true); } - void CASViaMiniKQLBody(TClient &client) { - NKikimrMiniKQL::TResult writeRes; + void CASViaMiniKQLBody(TClient &client) { + NKikimrMiniKQL::TResult writeRes; const TString writeQuery = R"___( - ( - (let table '/dc-1/Berkanavt/tables/Simple) - (let row1 '('('key (Uint64 '2)))) - (let row2 '('('key (Uint64 '2305843009213693951)))) - (return (AsList - (UpdateRow table row1 '( '('uint (Uint64 '10)))) - (UpdateRow table row2 '( '('uint (Uint64 '20))))) - ) - ) - )___"; - - UNIT_ASSERT(client.FlatQuery(writeQuery, writeRes)); - - NKikimrMiniKQL::TResult updateRes; + ( + (let table '/dc-1/Berkanavt/tables/Simple) + (let row1 '('('key (Uint64 '2)))) + (let row2 '('('key (Uint64 '2305843009213693951)))) + (return (AsList + (UpdateRow table row1 '( '('uint (Uint64 '10)))) + (UpdateRow table row2 '( '('uint (Uint64 '20))))) + ) + ) + )___"; + + UNIT_ASSERT(client.FlatQuery(writeQuery, writeRes)); + + NKikimrMiniKQL::TResult updateRes; const TString updateQuery = R"___( - ( - (let table '/dc-1/Berkanavt/tables/Simple) - (let row1 '('('key (Uint64 '2)))) - (let row2 '('('key (Uint64 '2305843009213693951)))) - (let select '('uint)) - (let read1 (SelectRow table row1 select)) - (let read2 (SelectRow table row2 select)) + ( + (let table '/dc-1/Berkanavt/tables/Simple) + (let row1 '('('key (Uint64 '2)))) + (let row2 '('('key (Uint64 '2305843009213693951)))) + (let select '('uint)) + (let read1 (SelectRow table row1 select)) + (let read2 (SelectRow table row2 select)) (let cmp1 (IfPresent read1 (lambda '(x) (Coalesce (Equal (Member x 'uint) (Uint64 '10)) (Bool 'false))) (Bool 'false))) (let cmp2 (IfPresent read2 (lambda '(x) (Coalesce (Equal (Member x 'uint) (Uint64 '10)) (Bool 'false))) (Bool 'false))) - (return (Extend (Extend - (AsList (SetResult 'cmp1 cmp1) (SetResult 'cmp2 cmp2)) - (ListIf cmp2 (UpdateRow table row1 '('('uint (Uint64 '50)))))) - (ListIf cmp1 (UpdateRow table row2 '('('uint (Uint64 '50))))) - )) - ) - )___"; + (return (Extend (Extend + (AsList (SetResult 'cmp1 cmp1) (SetResult 'cmp2 cmp2)) + (ListIf cmp2 (UpdateRow table row1 '('('uint (Uint64 '50)))))) + (ListIf cmp1 (UpdateRow table row2 '('('uint (Uint64 '50))))) + )) + ) + )___"; - UNIT_ASSERT(client.FlatQuery(updateQuery, updateRes)); + UNIT_ASSERT(client.FlatQuery(updateQuery, updateRes)); { TValue value = TValue::Create(updateRes.GetValue(), updateRes.GetType()); @@ -848,24 +848,24 @@ Y_UNIT_TEST_SUITE(TClientTest) { UNIT_ASSERT(cmp2Opt.HaveValue() && bool(cmp2Opt) == false); } - NKikimrMiniKQL::TResult readRes; + NKikimrMiniKQL::TResult readRes; const TString readQuery = R"___( - ( - (let table '/dc-1/Berkanavt/tables/Simple) - (let row1 '('('key (Uint64 '2)))) - (let row2 '('('key (Uint64 '2305843009213693951)))) - (let select '('uint)) - (let read1 (SelectRow table row1 select)) - (let read2 (SelectRow table row2 select)) - (let emptyList (List (ListType(VoidType)))) - (return (Extend - (IfPresent read1 (lambda '(x) (IfPresent (Member x 'uint) (lambda '(z) (AsList (SetResult 'row1 z))) emptyList )) emptyList) - (IfPresent read2 (lambda '(x) (IfPresent (Member x 'uint) (lambda '(z) (AsList (SetResult 'row2 z))) emptyList )) emptyList) - )) - ) - )___"; - - UNIT_ASSERT(client.FlatQuery(readQuery, readRes)); + ( + (let table '/dc-1/Berkanavt/tables/Simple) + (let row1 '('('key (Uint64 '2)))) + (let row2 '('('key (Uint64 '2305843009213693951)))) + (let select '('uint)) + (let read1 (SelectRow table row1 select)) + (let read2 (SelectRow table row2 select)) + (let emptyList (List (ListType(VoidType)))) + (return (Extend + (IfPresent read1 (lambda '(x) (IfPresent (Member x 'uint) (lambda '(z) (AsList (SetResult 'row1 z))) emptyList )) emptyList) + (IfPresent read2 (lambda '(x) (IfPresent (Member x 'uint) (lambda '(z) (AsList (SetResult 'row2 z))) emptyList )) emptyList) + )) + ) + )___"; + + UNIT_ASSERT(client.FlatQuery(readQuery, readRes)); { TValue value = TValue::Create(readRes.GetValue(), readRes.GetType()); @@ -926,60 +926,60 @@ Y_UNIT_TEST_SUITE(TClientTest) { TTestTables tables(client, TTestTables::Sharded_OutOfOrder_SoftUpdates); CASViaMiniKQLBody(client); } - } - - void RowEraseViaMiniKQLBody(TClient &client) { - NKikimrMiniKQL::TResult writeRes; + } + + void RowEraseViaMiniKQLBody(TClient &client) { + NKikimrMiniKQL::TResult writeRes; const TString writeQuery = R"___( - ( - (let table '/dc-1/Berkanavt/tables/Simple) - (let row1 '('('key (Uint64 '2)))) - (let row2 '('('key (Uint64 '2305843009213693951)))) - (return (AsList - (UpdateRow table row1 '( '('uint (Uint64 '10)))) - (UpdateRow table row2 '( '('uint (Uint64 '20))))) - ) - ) - )___"; - - UNIT_ASSERT(client.FlatQuery(writeQuery, writeRes)); - - NKikimrMiniKQL::TResult updateRes; + ( + (let table '/dc-1/Berkanavt/tables/Simple) + (let row1 '('('key (Uint64 '2)))) + (let row2 '('('key (Uint64 '2305843009213693951)))) + (return (AsList + (UpdateRow table row1 '( '('uint (Uint64 '10)))) + (UpdateRow table row2 '( '('uint (Uint64 '20))))) + ) + ) + )___"; + + UNIT_ASSERT(client.FlatQuery(writeQuery, writeRes)); + + NKikimrMiniKQL::TResult updateRes; const TString updateQuery = R"___( - ( - (let table '/dc-1/Berkanavt/tables/Simple) - (let row1 '('('key (Uint64 '2)))) - (let row2 '('('key (Uint64 '2305843009213693951)))) - (return (AsList (EraseRow table row2))) - ) - )___"; - - UNIT_ASSERT(client.FlatQuery(updateQuery, updateRes)); - - NKikimrMiniKQL::TResult readRes; + ( + (let table '/dc-1/Berkanavt/tables/Simple) + (let row1 '('('key (Uint64 '2)))) + (let row2 '('('key (Uint64 '2305843009213693951)))) + (return (AsList (EraseRow table row2))) + ) + )___"; + + UNIT_ASSERT(client.FlatQuery(updateQuery, updateRes)); + + NKikimrMiniKQL::TResult readRes; const TString readQuery = R"___( - ( - (let table '/dc-1/Berkanavt/tables/Simple) - (let row1 '('('key (Uint64 '2)))) - (let row2 '('('key (Uint64 '2305843009213693951)))) - (let select '('uint)) - (let read1 (SelectRow table row1 select)) - (let read2 (SelectRow table row2 select)) - (let emptyList (List (ListType(VoidType)))) - (return (Extend - (IfPresent read1 (lambda '(x) (IfPresent (Member x 'uint) (lambda '(z) (AsList (SetResult 'row1 z))) emptyList )) emptyList) - (IfPresent read2 (lambda '(x) (IfPresent (Member x 'uint) (lambda '(z) (AsList (SetResult 'row2 z))) emptyList )) emptyList) - )) - ) - )___"; - - UNIT_ASSERT(client.FlatQuery(readQuery, readRes)); - + ( + (let table '/dc-1/Berkanavt/tables/Simple) + (let row1 '('('key (Uint64 '2)))) + (let row2 '('('key (Uint64 '2305843009213693951)))) + (let select '('uint)) + (let read1 (SelectRow table row1 select)) + (let read2 (SelectRow table row2 select)) + (let emptyList (List (ListType(VoidType)))) + (return (Extend + (IfPresent read1 (lambda '(x) (IfPresent (Member x 'uint) (lambda '(z) (AsList (SetResult 'row1 z))) emptyList )) emptyList) + (IfPresent read2 (lambda '(x) (IfPresent (Member x 'uint) (lambda '(z) (AsList (SetResult 'row2 z))) emptyList )) emptyList) + )) + ) + )___"; + + UNIT_ASSERT(client.FlatQuery(readQuery, readRes)); + { TValue value = TValue::Create(readRes.GetValue(), readRes.GetType()); TValue row1Opt = value["row1"]; TValue row2Opt = value["row2"]; - + UNIT_ASSERT(row1Opt.HaveValue() && ui64(row1Opt) == 10); UNIT_ASSERT(!row2Opt.HaveValue()); } @@ -988,23 +988,23 @@ Y_UNIT_TEST_SUITE(TClientTest) { Y_UNIT_TEST(RowEraseViaMiniKQL) { TPortManager tp; ui16 port = tp.GetPort(2134); - + const auto settings = TServerSettings(port); TServer server(settings); TClient client(settings); client.InitRootScheme(); - + { TTestTables tables(client, TTestTables::OneShard_NoOpts); RowEraseViaMiniKQLBody(client); } - + { TTestTables tables(client, TTestTables::OneShard_OutOfOrder); RowEraseViaMiniKQLBody(client); } - + { TTestTables tables(client, TTestTables::OneShard_SoftUpdates); RowEraseViaMiniKQLBody(client); @@ -1014,7 +1014,7 @@ Y_UNIT_TEST_SUITE(TClientTest) { TTestTables tables(client, TTestTables::OneShard_OutOfOrder_SoftUpdates); RowEraseViaMiniKQLBody(client); } - + { TTestTables tables(client, TTestTables::Sharded_NoOpts); RowEraseViaMiniKQLBody(client); @@ -1034,73 +1034,73 @@ Y_UNIT_TEST_SUITE(TClientTest) { TTestTables tables(client, TTestTables::Sharded_OutOfOrder_SoftUpdates); RowEraseViaMiniKQLBody(client); } - } - - void ReadRangeViaMiniKQLBody(TClient &client) { - NKikimrMiniKQL::TResult writeRes; + } + + void ReadRangeViaMiniKQLBody(TClient &client) { + NKikimrMiniKQL::TResult writeRes; const TString writeQuery = R"___( - ( - (let table '/dc-1/Berkanavt/tables/Simple) - (let row1 '('('key (Uint64 '2)))) - (let row2 '('('key (Uint64 '2305843009213693951)))) - (return (AsList - (UpdateRow table row1 '( '('uint (Uint64 '10)))) - (UpdateRow table row2 '( '('uint (Uint64 '20))))) - ) - ) - )___"; - - UNIT_ASSERT(client.FlatQuery(writeQuery, writeRes)); - - NKikimrMiniKQL::TResult readRes; + ( + (let table '/dc-1/Berkanavt/tables/Simple) + (let row1 '('('key (Uint64 '2)))) + (let row2 '('('key (Uint64 '2305843009213693951)))) + (return (AsList + (UpdateRow table row1 '( '('uint (Uint64 '10)))) + (UpdateRow table row2 '( '('uint (Uint64 '20))))) + ) + ) + )___"; + + UNIT_ASSERT(client.FlatQuery(writeQuery, writeRes)); + + NKikimrMiniKQL::TResult readRes; const TString readQuery = R"___( - ( - (let table '/dc-1/Berkanavt/tables/Simple) - (let range '('IncFrom '('key (Uint64 '0) (Void)))) - (let select '('uint 'key)) - (let options '()) - (let res (SelectRange table range select options)) - (let reslist (Member res 'List)) - (return (AsList - (SetResult 'list reslist) - )) - ) - )___"; - + ( + (let table '/dc-1/Berkanavt/tables/Simple) + (let range '('IncFrom '('key (Uint64 '0) (Void)))) + (let select '('uint 'key)) + (let options '()) + (let res (SelectRange table range select options)) + (let reslist (Member res 'List)) + (return (AsList + (SetResult 'list reslist) + )) + ) + )___"; + UNIT_ASSERT(client.FlatQuery(readQuery, readRes)); - + { TValue value = TValue::Create(readRes.GetValue(), readRes.GetType()); TValue list = value["list"]; - + UNIT_ASSERT_VALUES_EQUAL(list.Size(), 2); UNIT_ASSERT_VALUES_EQUAL(ui64(list[0]["uint"]), 10); UNIT_ASSERT_VALUES_EQUAL(ui64(list[0]["key"]), 2); UNIT_ASSERT_VALUES_EQUAL(ui64(list[1]["uint"]), 20); UNIT_ASSERT_VALUES_EQUAL(ui64(list[1]["key"]), 2305843009213693951); } - } - + } + Y_UNIT_TEST(ReadRangeViaMiniKQL) { TPortManager tp; ui16 port = tp.GetPort(2134); - + const auto settings = TServerSettings(port); TServer server(settings); TClient client(settings); client.InitRootScheme(); - + { TTestTables tables(client, TTestTables::OneShard_NoOpts); ReadRangeViaMiniKQLBody(client); } - + { TTestTables tables(client, TTestTables::OneShard_OutOfOrder); ReadRangeViaMiniKQLBody(client); } - + { TTestTables tables(client, TTestTables::OneShard_SoftUpdates); ReadRangeViaMiniKQLBody(client); @@ -1110,7 +1110,7 @@ Y_UNIT_TEST_SUITE(TClientTest) { TTestTables tables(client, TTestTables::OneShard_OutOfOrder_SoftUpdates); ReadRangeViaMiniKQLBody(client); } - + { TTestTables tables(client, TTestTables::Sharded_NoOpts); ReadRangeViaMiniKQLBody(client); @@ -1130,56 +1130,56 @@ Y_UNIT_TEST_SUITE(TClientTest) { TTestTables tables(client, TTestTables::Sharded_OutOfOrder_SoftUpdates); ReadRangeViaMiniKQLBody(client); } - } - - void SelectRangeOptionsBody(TClient &client) { - NKikimrMiniKQL::TResult writeRes; + } + + void SelectRangeOptionsBody(TClient &client) { + NKikimrMiniKQL::TResult writeRes; const TString writeQuery = R"___( - ( - (let table '/dc-1/Berkanavt/tables/Simple) - (let row1 '('('key (Uint64 '2)))) - (let row2 '('('key (Uint64 '3)))) - (let row3 '('('key (Uint64 '2305843009213693951)))) - (let row4 '('('key (Uint64 '2305843009213693952)))) - (return (AsList - (UpdateRow table row1 '( '('uint (Uint64 '10)))) - (UpdateRow table row2 '( '('uint (Uint64 '20)))) - (UpdateRow table row3 '( '('uint (Uint64 '30)))) - (UpdateRow table row4 '( '('uint (Uint64 '40)))) - )) - ) - )___"; - - UNIT_ASSERT(client.FlatQuery(writeQuery, writeRes)); - - { - NKikimrMiniKQL::TResult readRes; + ( + (let table '/dc-1/Berkanavt/tables/Simple) + (let row1 '('('key (Uint64 '2)))) + (let row2 '('('key (Uint64 '3)))) + (let row3 '('('key (Uint64 '2305843009213693951)))) + (let row4 '('('key (Uint64 '2305843009213693952)))) + (return (AsList + (UpdateRow table row1 '( '('uint (Uint64 '10)))) + (UpdateRow table row2 '( '('uint (Uint64 '20)))) + (UpdateRow table row3 '( '('uint (Uint64 '30)))) + (UpdateRow table row4 '( '('uint (Uint64 '40)))) + )) + ) + )___"; + + UNIT_ASSERT(client.FlatQuery(writeQuery, writeRes)); + + { + NKikimrMiniKQL::TResult readRes; const TString readQuery = R"___( - ( + ( (let from (Parameter 'FROM (DataType 'Uint64))) (let to (Parameter 'TO (DataType 'Uint64))) - (let table '/dc-1/Berkanavt/tables/Simple) - (let range '('IncFrom 'IncTo '('key from to))) - (let select '('uint 'key)) - (let options '()) - (let res (SelectRange table range select options)) - (let reslist (Member res 'List)) - (return (AsList - (SetResult 'list reslist) - )) - ) - )___"; + (let table '/dc-1/Berkanavt/tables/Simple) + (let range '('IncFrom 'IncTo '('key from to))) + (let select '('uint 'key)) + (let options '()) + (let res (SelectRange table range select options)) + (let reslist (Member res 'List)) + (return (AsList + (SetResult 'list reslist) + )) + ) + )___"; const TString readParams = R"___( - ( - (let params (Parameters)) - (let params (AddParameter params 'FROM (Uint64 '2))) - (let params (AddParameter params 'TO (Uint64 '2305843009213693952))) - (return params) - ) - )___"; + ( + (let params (Parameters)) + (let params (AddParameter params 'FROM (Uint64 '2))) + (let params (AddParameter params 'TO (Uint64 '2305843009213693952))) + (return params) + ) + )___"; - UNIT_ASSERT(client.FlatQueryParams(readQuery, readParams, false, readRes)); + UNIT_ASSERT(client.FlatQueryParams(readQuery, readParams, false, readRes)); { TValue value = TValue::Create(readRes.GetValue(), readRes.GetType()); @@ -1195,40 +1195,40 @@ Y_UNIT_TEST_SUITE(TClientTest) { UNIT_ASSERT_VALUES_EQUAL(ui64(list[3]["uint"]), 40); UNIT_ASSERT_VALUES_EQUAL(ui64(list[3]["key"]), 2305843009213693952); } - } + } - { + { TString binQuery; - NKikimrMiniKQL::TResult readRes; + NKikimrMiniKQL::TResult readRes; const TString readQuery = R"___( - ( + ( (let from (Parameter 'FROM (DataType 'Uint64))) (let to (Parameter 'TO (DataType 'Uint64))) - (let table '/dc-1/Berkanavt/tables/Simple) - (let range '('ExcFrom 'IncTo '('key from to))) - (let select '('uint 'key)) - (let options '()) - (let res (SelectRange table range select options)) - (let reslist (Member res 'List)) - (return (AsList - (SetResult 'list reslist) - )) - ) - )___"; - - UNIT_ASSERT(client.Compile(readQuery, binQuery)); + (let table '/dc-1/Berkanavt/tables/Simple) + (let range '('ExcFrom 'IncTo '('key from to))) + (let select '('uint 'key)) + (let options '()) + (let res (SelectRange table range select options)) + (let reslist (Member res 'List)) + (return (AsList + (SetResult 'list reslist) + )) + ) + )___"; + + UNIT_ASSERT(client.Compile(readQuery, binQuery)); const TString readParams = R"___( - ( - (let params (Parameters)) - (let params (AddParameter params 'FROM (Uint64 '2))) - (let params (AddParameter params 'TO (Uint64 '2305843009213693952))) - (return params) - ) - )___"; + ( + (let params (Parameters)) + (let params (AddParameter params 'FROM (Uint64 '2))) + (let params (AddParameter params 'TO (Uint64 '2305843009213693952))) + (return params) + ) + )___"; - UNIT_ASSERT(client.FlatQueryParams(binQuery, readParams, true, readRes)); + UNIT_ASSERT(client.FlatQueryParams(binQuery, readParams, true, readRes)); { TValue value = TValue::Create(readRes.GetValue(), readRes.GetType()); @@ -1242,23 +1242,23 @@ Y_UNIT_TEST_SUITE(TClientTest) { UNIT_ASSERT_VALUES_EQUAL(ui64(list[2]["uint"]), 40); UNIT_ASSERT_VALUES_EQUAL(ui64(list[2]["key"]), 2305843009213693952); } - } + } - { - NKikimrMiniKQL::TResult readRes; + { + NKikimrMiniKQL::TResult readRes; const TString readQuery = R"___( - ( - (let table '/dc-1/Berkanavt/tables/Simple) - (let range '('IncFrom 'ExcTo '('key (Uint64 '4) (Uint64 '2305843009213693952)))) - (let select '('uint 'key)) - (let options '()) - (let res (SelectRange table range select options)) - (let reslist (Member res 'List)) - (return (AsList - (SetResult 'list reslist) - )) - ) - )___"; + ( + (let table '/dc-1/Berkanavt/tables/Simple) + (let range '('IncFrom 'ExcTo '('key (Uint64 '4) (Uint64 '2305843009213693952)))) + (let select '('uint 'key)) + (let options '()) + (let res (SelectRange table range select options)) + (let reslist (Member res 'List)) + (return (AsList + (SetResult 'list reslist) + )) + ) + )___"; UNIT_ASSERT(client.FlatQuery(readQuery, readRes)); @@ -1270,23 +1270,23 @@ Y_UNIT_TEST_SUITE(TClientTest) { UNIT_ASSERT_VALUES_EQUAL(ui64(list[0]["uint"]), 30); UNIT_ASSERT_VALUES_EQUAL(ui64(list[0]["key"]), 2305843009213693951); } - } + } - { - NKikimrMiniKQL::TResult readRes; + { + NKikimrMiniKQL::TResult readRes; const TString readQuery = R"___( - ( - (let table '/dc-1/Berkanavt/tables/Simple) - (let range '('ExcFrom 'IncTo '('key (Uint64 '3) (Uint64 '2305843009213693950)))) - (let select '('uint 'key)) - (let options '()) - (let res (SelectRange table range select options)) - (let reslist (Member res 'List)) - (return (AsList - (SetResult 'list reslist) - )) - ) - )___"; + ( + (let table '/dc-1/Berkanavt/tables/Simple) + (let range '('ExcFrom 'IncTo '('key (Uint64 '3) (Uint64 '2305843009213693950)))) + (let select '('uint 'key)) + (let options '()) + (let res (SelectRange table range select options)) + (let reslist (Member res 'List)) + (return (AsList + (SetResult 'list reslist) + )) + ) + )___"; UNIT_ASSERT(client.FlatQuery(readQuery, readRes)); @@ -1295,7 +1295,7 @@ Y_UNIT_TEST_SUITE(TClientTest) { TValue list = value["list"]; UNIT_ASSERT_VALUES_EQUAL(list.Size(), 0); } - } + } } Y_UNIT_TEST(SelectRangeOptions) { @@ -1542,89 +1542,89 @@ Y_UNIT_TEST_SUITE(TClientTest) { } Y_UNIT_TEST(FollowerCacheRefresh) { - TPortManager tp; - ui16 port = tp.GetPort(2134); + TPortManager tp; + ui16 port = tp.GetPort(2134); auto settings = TServerSettings(port); settings.SetNodeCount(2); TServer server(settings); TClient client(settings); - server.GetRuntime()->SetLogPriority(NKikimrServices::TABLET_EXECUTOR, NActors::NLog::PRI_DEBUG); - - client.MarkNodeInHive(server.GetRuntime(), 1, false); - - PrepareTestData(client, true); - - client.MarkNodeInHive(server.GetRuntime(), 1, true); - - const ui64 tabletId = 72075186224037888ull; + server.GetRuntime()->SetLogPriority(NKikimrServices::TABLET_EXECUTOR, NActors::NLog::PRI_DEBUG); + + client.MarkNodeInHive(server.GetRuntime(), 1, false); + + PrepareTestData(client, true); + + client.MarkNodeInHive(server.GetRuntime(), 1, true); + + const ui64 tabletId = 72075186224037888ull; WaitForLeaderStart(client, server.GetRuntime(), tabletId, TDuration::Seconds(5)); WaitForFollowerStart(client, server.GetRuntime(), tabletId, TDuration::Seconds(5)); - - // force some rounds of compaction - for (ui32 i : xrange(50, 3000)) { - NKikimrMiniKQL::TResult writeRes; + + // force some rounds of compaction + for (ui32 i : xrange(50, 3000)) { + NKikimrMiniKQL::TResult writeRes; const TString writeQuery = "((let table '/dc-1/Berkanavt/tables/Simple)" - "(let row1 '('('key (Uint64 '" + ToString(i) + "))))" - "(return (AsList" - "(UpdateRow table row1 '( '('uint (Uint64 '" + ToString(i) + "))))" - ")))"; - - UNIT_ASSERT(client.FlatQuery(writeQuery, writeRes)); - } - + "(let row1 '('('key (Uint64 '" + ToString(i) + "))))" + "(return (AsList" + "(UpdateRow table row1 '( '('uint (Uint64 '" + ToString(i) + "))))" + ")))"; + + UNIT_ASSERT(client.FlatQuery(writeQuery, writeRes)); + } + Cout << "Read from leader" << Endl; - CheckRead(client, false); + CheckRead(client, false); Cout << "Read from leader again" << Endl; - CheckRead(client, false); + CheckRead(client, false); Cout << "Read from follower" << Endl; - CheckRead(client, true); - } - + CheckRead(client, true); + } + Y_UNIT_TEST(FollowerDrop) { - TPortManager tp; - ui16 port = tp.GetPort(2134); - - auto settings = TServerSettings(port); - settings.SetNodeCount(1); - TServer server(settings); - TClient client(settings); - - server.GetRuntime()->SetLogPriority(NKikimrServices::TABLET_EXECUTOR, NActors::NLog::PRI_DEBUG); - - PrepareTestData(client, false); - - const ui64 tabletId = 72075186224037888ull; + TPortManager tp; + ui16 port = tp.GetPort(2134); + + auto settings = TServerSettings(port); + settings.SetNodeCount(1); + TServer server(settings); + TClient client(settings); + + server.GetRuntime()->SetLogPriority(NKikimrServices::TABLET_EXECUTOR, NActors::NLog::PRI_DEBUG); + + PrepareTestData(client, false); + + const ui64 tabletId = 72075186224037888ull; WaitForLeaderStart(client, server.GetRuntime(), tabletId, TDuration::Seconds(5)); WaitForFollowerStart(client, server.GetRuntime(), tabletId, TDuration::Seconds(5)); - - NTabletPipe::TClientConfig pipeClientConfig; + + NTabletPipe::TClientConfig pipeClientConfig; pipeClientConfig.ForceFollower = true; server.GetRuntime()->SendToPipe(tabletId, TActorId(), new TEvents::TEvPoisonPill(), 0, pipeClientConfig); - - client.AlterTable(TablePlacement, Sprintf( - R"___( - Name: "Simple" - Columns { Name: "key" Type: "Uint64"} - Columns { Name: "uint" Type: "Uint64"} - KeyColumnNames: ["key"] + + client.AlterTable(TablePlacement, Sprintf( + R"___( + Name: "Simple" + Columns { Name: "key" Type: "Uint64"} + Columns { Name: "uint" Type: "Uint64"} + KeyColumnNames: ["key"] PartitionConfig { FollowerCount: 0 } - )___")); - - // force some rounds of compaction - for (ui32 i : xrange(50, 3000)) { - NKikimrMiniKQL::TResult writeRes; - const TString writeQuery = "((let table '/dc-1/Berkanavt/tables/Simple)" - "(let row1 '('('key (Uint64 '" + ToString(i) + "))))" - "(return (AsList" - "(UpdateRow table row1 '( '('uint (Uint64 '" + ToString(i) + "))))" - ")))"; - - UNIT_ASSERT(client.FlatQuery(writeQuery, writeRes)); - } - } - + )___")); + + // force some rounds of compaction + for (ui32 i : xrange(50, 3000)) { + NKikimrMiniKQL::TResult writeRes; + const TString writeQuery = "((let table '/dc-1/Berkanavt/tables/Simple)" + "(let row1 '('('key (Uint64 '" + ToString(i) + "))))" + "(return (AsList" + "(UpdateRow table row1 '( '('uint (Uint64 '" + ToString(i) + "))))" + ")))"; + + UNIT_ASSERT(client.FlatQuery(writeQuery, writeRes)); + } + } + Y_UNIT_TEST(PromoteFollower) { TPortManager tp; ui16 port = tp.GetPort(2134); @@ -1852,42 +1852,42 @@ Y_UNIT_TEST_SUITE(TClientTest) { Cout << schemaDiff << Endl; UNIT_ASSERT_C(!schemaDiff.empty(), "Schema not changed after update"); } - + Y_UNIT_TEST(LocalSchemeDropTable) { - TPortManager tp; - ui16 port = tp.GetPort(2134); - + TPortManager tp; + ui16 port = tp.GetPort(2134); + const auto settings = TServerSettings(port); TServer server(settings); TClient client(settings); - server.StartDummyTablets(); + server.StartDummyTablets(); WaitForLeaderStart(client, server.GetRuntime(), ChangeStateStorage(Tests::DummyTablet1, TestDomain), TDuration::Seconds(1)); - - NTabletFlatScheme::TSchemeChanges schemeInitial; + + NTabletFlatScheme::TSchemeChanges schemeInitial; TString err; - bool success = false; - - success = client.LocalSchemeTx(Tests::DummyTablet1, "", true, schemeInitial, err); - UNIT_ASSERT(success); + bool success = false; + + success = client.LocalSchemeTx(Tests::DummyTablet1, "", true, schemeInitial, err); + UNIT_ASSERT(success); const TString oldScheme = ToString(schemeInitial); - + TString change = R"___( - Delta { - DeltaType: DropTable - TableId: 32 - } - )___"; - - // Update - NTabletFlatScheme::TSchemeChanges schemeChanged; - success = client.LocalSchemeTx(Tests::DummyTablet1, change, false, schemeChanged, err); - UNIT_ASSERT(success); + Delta { + DeltaType: DropTable + TableId: 32 + } + )___"; + + // Update + NTabletFlatScheme::TSchemeChanges schemeChanged; + success = client.LocalSchemeTx(Tests::DummyTablet1, change, false, schemeChanged, err); + UNIT_ASSERT(success); const TString newScheme = ToString(schemeChanged); - + TString schemaDiff = DiffStrings(oldScheme, newScheme); - UNIT_ASSERT_C(!schemaDiff.empty(), "Schema not changed after update"); - } + UNIT_ASSERT_C(!schemaDiff.empty(), "Schema not changed after update"); + } Y_UNIT_TEST(TestOldTypes) { TPortManager tp; @@ -2051,104 +2051,104 @@ Y_UNIT_TEST_SUITE(TClientTest) { // TODO: check resluts } - + void OfflineFollowerContinueWork() { - TPortManager tp; - ui16 port = tp.GetPort(2134); - - const auto settings = TServerSettings(port); - TServer server(settings); - TClient client(settings); + TPortManager tp; + ui16 port = tp.GetPort(2134); + + const auto settings = TServerSettings(port); + TServer server(settings); + TClient client(settings); SetupLogging(server); - + TTestActorRuntime &runtime = *server.GetRuntime(); - const ui64 tabletId = ChangeStateStorage(DummyTablet1, settings.Domain); + const ui64 tabletId = ChangeStateStorage(DummyTablet1, settings.Domain); TIntrusivePtr<TTabletStorageInfo> tabletInfo = CreateTestTabletInfo(tabletId, TTabletTypes::TX_DUMMY); TIntrusivePtr<TTabletSetupInfo> setupInfo = new TTabletSetupInfo(&CreateFlatDummyTablet, TMailboxType::Simple, 0, TMailboxType::Simple, 0); - + const TActorId edge = runtime.AllocateEdgeActor(); - + const TActorId leaderTablet = runtime.Register(CreateTablet(edge, tabletInfo.Get(), setupInfo.Get(), 0, nullptr, nullptr)); const TActorId leaderId = runtime.GrabEdgeEvent<TEvTablet::TEvRestored>(edge)->Get()->UserTabletActor; - + const TActorId followerTablet = runtime.Register(CreateTabletFollower(edge, tabletInfo.Get(), setupInfo.Get(), 1, nullptr, nullptr)); const TActorId followerId = runtime.GrabEdgeEvent<TEvTablet::TEvRestored>(edge)->Get()->UserTabletActor; Y_UNUSED(followerTablet); - - const char *writeQuery = R"__(( - (let row_ '('('key (Uint64 '42)))) - (let update_ '('('v_ui64 (Uint64 '%lu)))) - (let result_ (UpdateRow 't_by_ui64 row_ update_)) - (return (AsList result_)) - ))__"; - - const char *readQuery = R"__(( - (let row_ '('('key (Uint64 '42)))) - (let select_ '('v_ui64)) - (let pgmReturn (AsList - (SetResult 'res (SelectRow 't_by_ui64 row_ select_)) - )) - (return pgmReturn) - ))__"; - - { + + const char *writeQuery = R"__(( + (let row_ '('('key (Uint64 '42)))) + (let update_ '('('v_ui64 (Uint64 '%lu)))) + (let result_ (UpdateRow 't_by_ui64 row_ update_)) + (return (AsList result_)) + ))__"; + + const char *readQuery = R"__(( + (let row_ '('('key (Uint64 '42)))) + (let select_ '('v_ui64)) + (let pgmReturn (AsList + (SetResult 'res (SelectRow 't_by_ui64 row_ select_)) + )) + (return pgmReturn) + ))__"; + + { THolder<TEvTablet::TEvLocalMKQL> reqWrite = MakeHolder<TEvTablet::TEvLocalMKQL>(); - reqWrite->Record.MutableProgram()->MutableProgram()->SetText(Sprintf(writeQuery, ui64(10))); + reqWrite->Record.MutableProgram()->MutableProgram()->SetText(Sprintf(writeQuery, ui64(10))); runtime.Send(new IEventHandle(leaderId, edge, reqWrite.Release())); - - auto reply = runtime.GrabEdgeEvent<TEvTablet::TEvLocalMKQLResponse>(edge); - UNIT_ASSERT_VALUES_EQUAL(reply->Get()->Record.GetStatus(), 0); - } - - { + + auto reply = runtime.GrabEdgeEvent<TEvTablet::TEvLocalMKQLResponse>(edge); + UNIT_ASSERT_VALUES_EQUAL(reply->Get()->Record.GetStatus(), 0); + } + + { runtime.Send(new IEventHandle(leaderTablet, edge, new TEvents::TEvPoisonPill())); - auto reply = runtime.GrabEdgeEvent<TEvTablet::TEvTabletDead>(edge); - UNIT_ASSERT_VALUES_EQUAL(reply->Get()->TabletID, tabletId); - } - - { + auto reply = runtime.GrabEdgeEvent<TEvTablet::TEvTabletDead>(edge); + UNIT_ASSERT_VALUES_EQUAL(reply->Get()->TabletID, tabletId); + } + + { THolder<TEvTablet::TEvLocalMKQL> reqRead = MakeHolder<TEvTablet::TEvLocalMKQL>(); - reqRead->Record.MutableProgram()->MutableProgram()->SetText(readQuery); + reqRead->Record.MutableProgram()->MutableProgram()->SetText(readQuery); runtime.Send(new IEventHandle(followerId, edge, reqRead.Release())); - - auto reply = runtime.GrabEdgeEvent<TEvTablet::TEvLocalMKQLResponse>(edge); - UNIT_ASSERT_VALUES_EQUAL(reply->Get()->Record.GetStatus(), 0); - } - - { - NTabletPipe::TClientConfig pipeClientConfig; + + auto reply = runtime.GrabEdgeEvent<TEvTablet::TEvLocalMKQLResponse>(edge); + UNIT_ASSERT_VALUES_EQUAL(reply->Get()->Record.GetStatus(), 0); + } + + { + NTabletPipe::TClientConfig pipeClientConfig; pipeClientConfig.AllowFollower = true; pipeClientConfig.ForceFollower = true; - runtime.Register(NTabletPipe::CreateClient(edge, tabletId, pipeClientConfig)); - - auto reply = runtime.GrabEdgeEvent<TEvTabletPipe::TEvClientConnected>(edge); - + runtime.Register(NTabletPipe::CreateClient(edge, tabletId, pipeClientConfig)); + + auto reply = runtime.GrabEdgeEvent<TEvTabletPipe::TEvClientConnected>(edge); + UNIT_ASSERT_VALUES_EQUAL(reply->Get()->Status, NKikimrProto::OK); - } - } - + } + } + Y_UNIT_TEST(OfflineFollowerContinueWork) { OfflineFollowerContinueWork(); } void FollowerOfflineBoot() { - TPortManager tp; - ui16 port = tp.GetPort(2134); - - const auto settings = TServerSettings(port); - TServer server(settings); - TClient client(settings); + TPortManager tp; + ui16 port = tp.GetPort(2134); + + const auto settings = TServerSettings(port); + TServer server(settings); + TClient client(settings); SetupLogging(server); - + TTestActorRuntime &runtime = *server.GetRuntime(); - const ui64 tabletId = ChangeStateStorage(DummyTablet1, settings.Domain); + const ui64 tabletId = ChangeStateStorage(DummyTablet1, settings.Domain); TIntrusivePtr<TTabletStorageInfo> tabletInfo = CreateTestTabletInfo(tabletId, TTabletTypes::TX_DUMMY); TIntrusivePtr<TTabletSetupInfo> setupInfo = new TTabletSetupInfo(&CreateFlatDummyTablet, TMailboxType::Simple, 0, TMailboxType::Simple, 0); - + const TActorId edge = runtime.AllocateEdgeActor(); - + { const TActorId leaderTablet = runtime.Register(CreateTablet(edge, tabletInfo.Get(), setupInfo.Get(), 0, nullptr, nullptr)); const TActorId leaderId = runtime.GrabEdgeEvent<TEvTablet::TEvRestored>(edge)->Get()->UserTabletActor; @@ -2161,23 +2161,23 @@ Y_UNIT_TEST_SUITE(TClientTest) { const TActorId followerTablet = runtime.Register(CreateTabletFollower(edge, tabletInfo.Get(), setupInfo.Get(), 1, nullptr, nullptr)); Y_UNUSED(followerTablet); - + const TActorId followerId = runtime.GrabEdgeEvent<TEvTablet::TEvRestored>(edge)->Get()->UserTabletActor; Y_UNUSED(followerId); - { - NTabletPipe::TClientConfig pipeClientConfig; + { + NTabletPipe::TClientConfig pipeClientConfig; pipeClientConfig.AllowFollower = true; pipeClientConfig.ForceFollower = true; pipeClientConfig.RetryPolicy = {.RetryLimitCount = 2}; - runtime.Register(NTabletPipe::CreateClient(edge, tabletId, pipeClientConfig)); - - auto reply = runtime.GrabEdgeEvent<TEvTabletPipe::TEvClientConnected>(edge); - + runtime.Register(NTabletPipe::CreateClient(edge, tabletId, pipeClientConfig)); + + auto reply = runtime.GrabEdgeEvent<TEvTabletPipe::TEvClientConnected>(edge); + UNIT_ASSERT_VALUES_EQUAL(reply->Get()->Status, NKikimrProto::OK); - } - } - + } + } + Y_UNIT_TEST(FollowerOfflineBoot) { FollowerOfflineBoot(); } diff --git a/ydb/core/client/flat_ut.cpp b/ydb/core/client/flat_ut.cpp index ddd5d8e5a0..362c052aa1 100644 --- a/ydb/core/client/flat_ut.cpp +++ b/ydb/core/client/flat_ut.cpp @@ -14,7 +14,7 @@ #include <library/cpp/testing/unittest/tests_data.h> #include <library/cpp/testing/unittest/registar.h> #include <google/protobuf/text_format.h> -#include <util/generic/xrange.h> +#include <util/generic/xrange.h> #include <util/random/mersenne.h> #include <util/system/sanitizers.h> @@ -1800,7 +1800,7 @@ Y_UNIT_TEST_SUITE(TFlatTest) { Columns { Name: "unused004" Type: "Float"} KeyColumnNames: ["Key"] UniformPartitionsCount: 2 - + PartitionConfig { FollowerCount: %d CompactionPolicy { @@ -1916,7 +1916,7 @@ Y_UNIT_TEST_SUITE(TFlatTest) { annoyingClient.CreateTable("/dc-1/Dir", " Name: \"Table2\" CopyFromTable: \"/dc-1/Dir/TableOld\""); strResult = ReadFromTable(annoyingClient, "/dc-1/Dir/Table2"); UNIT_ASSERT_NO_DIFF(strResult, strResultOld); - } + } Y_UNIT_TEST(CopyTableAndCompareColumnsSchema) { TPortManager pm; @@ -1974,34 +1974,34 @@ Y_UNIT_TEST_SUITE(TFlatTest) { Y_UNIT_TEST(CopyCopiedTableAndRead) { - TPortManager pm; - ui16 port = pm.GetPort(2134); + TPortManager pm; + ui16 port = pm.GetPort(2134); TServer cleverServer = TServer(TServerSettings(port)); - + cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::OPS_COMPACT, NActors::NLog::PRI_INFO); - TFlatMsgBusClient annoyingClient(port); - + TFlatMsgBusClient annoyingClient(port); + PrepareSourceTable(annoyingClient); - - // Copy the table - cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::FLAT_TX_SCHEMESHARD, NActors::NLog::PRI_DEBUG); - cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::TX_DATASHARD, NActors::NLog::PRI_DEBUG); + + // Copy the table + cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::FLAT_TX_SCHEMESHARD, NActors::NLog::PRI_DEBUG); + cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::TX_DATASHARD, NActors::NLog::PRI_DEBUG); Cerr << "Copy TableOld to Table" << Endl; - annoyingClient.CreateTable("/dc-1/Dir", " Name: \"Table\" CopyFromTable: \"/dc-1/Dir/TableOld\""); + annoyingClient.CreateTable("/dc-1/Dir", " Name: \"Table\" CopyFromTable: \"/dc-1/Dir/TableOld\""); TString strResultOld = ReadFromTable(annoyingClient, "/dc-1/Dir/TableOld"); TString strResult = ReadFromTable(annoyingClient, "/dc-1/Dir/Table"); - - Cout << strResult << Endl; - UNIT_ASSERT_NO_DIFF(strResult, strResultOld); - + + Cout << strResult << Endl; + UNIT_ASSERT_NO_DIFF(strResult, strResultOld); + // Make second copy of the old table Cerr << "Copy Table to Table2" << Endl; annoyingClient.CreateTable("/dc-1/Dir", " Name: \"Table3\" CopyFromTable: \"/dc-1/Dir/Table\""); strResult = ReadFromTable(annoyingClient, "/dc-1/Dir/Table3"); UNIT_ASSERT_NO_DIFF(strResult, strResultOld); } - + Y_UNIT_TEST(CopyTableAndAddFollowers) { TPortManager pm; ui16 port = pm.GetPort(2134); @@ -2052,11 +2052,11 @@ Y_UNIT_TEST_SUITE(TFlatTest) { TPortManager pm; ui16 port = pm.GetPort(2134); TServer cleverServer = TServer(TServerSettings(port)); - + cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::OPS_COMPACT, NActors::NLog::PRI_INFO); TFlatMsgBusClient annoyingClient(port); - + PrepareSourceTable(annoyingClient); TString strResultOld = ReadFromTable(annoyingClient, "/dc-1/Dir/TableOld"); Cerr << strResultOld << Endl; @@ -2713,61 +2713,61 @@ Y_UNIT_TEST_SUITE(TFlatTest) { } Y_UNIT_TEST(WriteSplitAndReadFromFollower) { - TPortManager pm; - ui16 port = pm.GetPort(2134); + TPortManager pm; + ui16 port = pm.GetPort(2134); TServer cleverServer = TServer(TServerSettings(port).SetNodeCount(2)); DisableSplitMergePartCountLimit(cleverServer); cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::OPS_COMPACT, NActors::NLog::PRI_INFO); - TFlatMsgBusClient annoyingClient(port); - PrepareSourceTable(annoyingClient, true); - - cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::FLAT_TX_SCHEMESHARD, NActors::NLog::PRI_DEBUG); - cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::TX_DATASHARD, NActors::NLog::PRI_DEBUG); - - // Write new rows to the copy in order to trigger compaction + TFlatMsgBusClient annoyingClient(port); + PrepareSourceTable(annoyingClient, true); + + cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::FLAT_TX_SCHEMESHARD, NActors::NLog::PRI_DEBUG); + cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::TX_DATASHARD, NActors::NLog::PRI_DEBUG); + + // Write new rows to the copy in order to trigger compaction TMap<ui32, TString> rows ={ - {1, "AAA"}, - {201, "BBB"}, - {301, "CCC"} - }; - - UNIT_ASSERT(annoyingClient.WaitForTabletAlive(cleverServer.GetRuntime(), 72075186224037888, false, TDuration::Minutes(1))); - - for (const auto& r : rows) { - WriteRow(annoyingClient, "TableOld", r.first, r.second); - } - + {1, "AAA"}, + {201, "BBB"}, + {301, "CCC"} + }; + + UNIT_ASSERT(annoyingClient.WaitForTabletAlive(cleverServer.GetRuntime(), 72075186224037888, false, TDuration::Minutes(1))); + + for (const auto& r : rows) { + WriteRow(annoyingClient, "TableOld", r.first, r.second); + } + TString strResult = ReadFromTable(annoyingClient, "/dc-1/Dir/TableOld", 201, false); - - SplitTable(annoyingClient, "/dc-1/Dir/TableOld", 0, {100, 200}); - - for (const auto& r : rows) { + + SplitTable(annoyingClient, "/dc-1/Dir/TableOld", 0, {100, 200}); + + for (const auto& r : rows) { TString val = ReadRow(annoyingClient, "TableOld", r.first); - UNIT_ASSERT_VALUES_EQUAL(val, r.second); - } - - for (auto tabletId : xrange(72075186224037888, 72075186224037893)) { - cleverServer.GetRuntime()->Send( + UNIT_ASSERT_VALUES_EQUAL(val, r.second); + } + + for (auto tabletId : xrange(72075186224037888, 72075186224037893)) { + cleverServer.GetRuntime()->Send( new IEventHandle(MakeTabletResolverID(), TActorId(), new TEvTabletResolver::TEvTabletProblem(tabletId, TActorId()) - )); - } - - for (auto tabletId : xrange(72075186224037890, 72075186224037893)) { - UNIT_ASSERT(annoyingClient.WaitForTabletAlive(cleverServer.GetRuntime(), tabletId, false, TDuration::Minutes(1))); - } - + )); + } + + for (auto tabletId : xrange(72075186224037890, 72075186224037893)) { + UNIT_ASSERT(annoyingClient.WaitForTabletAlive(cleverServer.GetRuntime(), tabletId, false, TDuration::Minutes(1))); + } + for (ui32 i = 0; i < 20; ++i) { // multiple rounds to move some reads to followers TString strResultAfter = ReadFromTable(annoyingClient, "/dc-1/Dir/TableOld", 201, true); - UNIT_ASSERT_NO_DIFF(strResultAfter, strResult); - } - - annoyingClient.DeleteTable("/dc-1/Dir", "TableOld"); - annoyingClient.Ls("/dc-1/Dir/TableOld"); - } - + UNIT_ASSERT_NO_DIFF(strResultAfter, strResult); + } + + annoyingClient.DeleteTable("/dc-1/Dir", "TableOld"); + annoyingClient.Ls("/dc-1/Dir/TableOld"); + } + Y_UNIT_TEST(WriteSplitKillRead) { TPortManager pm; ui16 port = pm.GetPort(2134); @@ -2778,7 +2778,7 @@ Y_UNIT_TEST_SUITE(TFlatTest) { TFlatMsgBusClient annoyingClient(port); PrepareSourceTable(annoyingClient); - + cleverServer.GetRuntime()->SetLogPriority(NKikimrServices::FLAT_TX_SCHEMESHARD, NActors::NLog::PRI_DEBUG); // Write new rows to the copy in order to trigger compaction diff --git a/ydb/core/client/flat_ut_client.h b/ydb/core/client/flat_ut_client.h index f9fb19897d..07f5b30cc6 100644 --- a/ydb/core/client/flat_ut_client.h +++ b/ydb/core/client/flat_ut_client.h @@ -73,14 +73,14 @@ public: void KillTablet(Tests::TServer &server, ui64 tabletId) { TTestActorRuntime* runtime = server.GetRuntime(); TActorId sender = runtime->AllocateEdgeActor(); - + runtime->Send(new IEventHandle(MakeTabletResolverID(), sender, new TEvTabletResolver::TEvTabletProblem(tabletId, TActorId()))); - runtime->Send(new IEventHandle(MakeTabletResolverID(), sender, new TEvTabletResolver::TEvForward(tabletId, nullptr))); - - TAutoPtr<IEventHandle> handle; - auto forwardResult = runtime->GrabEdgeEventRethrow<TEvTabletResolver::TEvForwardResult>(handle); - UNIT_ASSERT(forwardResult && forwardResult->Tablet); - runtime->Send(new IEventHandle(forwardResult->Tablet, sender, new TEvents::TEvPoisonPill())); + runtime->Send(new IEventHandle(MakeTabletResolverID(), sender, new TEvTabletResolver::TEvForward(tabletId, nullptr))); + + TAutoPtr<IEventHandle> handle; + auto forwardResult = runtime->GrabEdgeEventRethrow<TEvTabletResolver::TEvForwardResult>(handle); + UNIT_ASSERT(forwardResult && forwardResult->Tablet); + runtime->Send(new IEventHandle(forwardResult->Tablet, sender, new TEvents::TEvPoisonPill())); runtime->Send(new IEventHandle(MakeTabletResolverID(), sender, new TEvTabletResolver::TEvTabletProblem(tabletId, TActorId()))); } diff --git a/ydb/core/client/minikql_compile/db_key_resolver.h b/ydb/core/client/minikql_compile/db_key_resolver.h index 2ad0943978..e748525fa8 100644 --- a/ydb/core/client/minikql_compile/db_key_resolver.h +++ b/ydb/core/client/minikql_compile/db_key_resolver.h @@ -24,14 +24,14 @@ public: struct TTable { TString TableName; TSet<TString> ColumnNames; - ui64 RefreshAgainst = 0; + ui64 RefreshAgainst = 0; }; struct TTableResult { enum EStatus { Ok = 0, - Error = 1, - LookupError = 2 + Error = 1, + LookupError = 2 }; TTableResult(EStatus status, const TString& reason = TString()) @@ -52,7 +52,7 @@ public: TAutoPtr<NKikimr::TTableId> TableId; ui32 KeyColumnCount = 0; TMap<TString, TColumn> Columns; - ui64 CacheGeneration = 0; + ui64 CacheGeneration = 0; }; using TTableResults = TVector<TTableResult>; @@ -70,9 +70,9 @@ public: }; static_assert(End < EventSpaceEnd(NActors::TEvents::ES_PRIVATE), "expect End < EventSpaceEnd(TEvents::ES_PRIVATE)"); - struct TEvResolveTablesResult : public NActors::TEventLocal<TEvResolveTablesResult, EvResolveTablesResult> { + struct TEvResolveTablesResult : public NActors::TEventLocal<TEvResolveTablesResult, EvResolveTablesResult> { TEvResolveTablesResult(TTableResults&& result); - + TTableResults Result; }; }; diff --git a/ydb/core/client/minikql_compile/mkql_compile_service.cpp b/ydb/core/client/minikql_compile/mkql_compile_service.cpp index 88ba107928..e01d61a22c 100644 --- a/ydb/core/client/minikql_compile/mkql_compile_service.cpp +++ b/ydb/core/client/minikql_compile/mkql_compile_service.cpp @@ -17,12 +17,12 @@ namespace NKikimr { TMiniKQLCompileServiceEvents::TEvCompile::TEvCompile(const TString& program) : Program(program) -{} +{} TMiniKQLCompileServiceEvents::TEvCompileStatus::TEvCompileStatus(const TString& pgm, const NYql::TMiniKQLCompileResult& result) : Program(pgm) , Result(result) -{} +{} // Actor with queue of programs to compile. Creates TMiniKQLCompileActor for each program. class TMiniKQLCompileService : public NActors::TActorBootstrapped<TMiniKQLCompileService> { @@ -39,7 +39,7 @@ public: , Alloc(allocPoolCounters, functionRegistry->SupportsSizedAllocators()) , TypeEnv(Alloc) , Cookie(0) - , Retried(false) + , Retried(false) { Alloc.Release(); } @@ -54,9 +54,9 @@ public: NMiniKQL::TScopedAlloc Alloc; NMiniKQL::TTypeEnvironment TypeEnv; ui64 Cookie; - bool Retried; + bool Retried; THashMap<TString, ui64> CompileResolveCookies; - bool ForceRefresh; + bool ForceRefresh; }; static constexpr NKikimrServices::TActivity::EType ActorActivityType() { @@ -70,10 +70,10 @@ public: } void Bootstrap(const TActorContext& ctx) { - + Counters = GetServiceCounters(AppData(ctx)->Counters, "compile")->GetSubgroup("subsystem", "cache"); AllocPoolCounters = TAlignedPagePoolCounters(AppData(ctx)->Counters, "compile"); - + if (!DbSchemeResolver) { DbSchemeResolver.Reset(MakeDbSchemeResolver(ctx)); } @@ -99,41 +99,41 @@ public: private: void Handle(TMiniKQLCompileServiceEvents::TEvCompile::TPtr& ev, const TActorContext& ctx) { - TMiniKQLCompileServiceEvents::TEvCompile *msg = ev->Get(); + TMiniKQLCompileServiceEvents::TEvCompile *msg = ev->Get(); TCompileContext::TPtr c(new TCompileContext(msg->Program, ev->Sender, AllocPoolCounters, AppData(ctx)->FunctionRegistry)); c->Cookie = ev->Cookie; - c->CompileResolveCookies = std::move(msg->CompileResolveCookies); - c->ForceRefresh = msg->ForceRefresh; + c->CompileResolveCookies = std::move(msg->CompileResolveCookies); + c->ForceRefresh = msg->ForceRefresh; CompileQueue.push(c); Compile(ctx); } void Handle(NYql::TMiniKQLCompileActorEvents::TEvCompileResult::TPtr& ev, const TActorContext& ctx) { - auto *msg = ev->Get(); + auto *msg = ev->Get(); auto it = Compiling.find(ev->Sender); Y_VERIFY(it != Compiling.end()); - - TCompileContext::TPtr cptr = it->second; + + TCompileContext::TPtr cptr = it->second; Compiling.erase(it); - - const bool hasErrors = !msg->Result.Errors.Empty(); - if (!hasErrors || cptr->Retried || cptr->ForceRefresh) { - auto* compileStatusEv = new TMiniKQLCompileServiceEvents::TEvCompileStatus(cptr->Program, msg->Result); - compileStatusEv->CompileResolveCookies = std::move(msg->CompileResolveCookies); - ctx.ExecutorThread.Send(new IEventHandle(cptr->ResponseTo, ctx.SelfID, compileStatusEv, - 0, cptr->Cookie)); - Compile(ctx); - } else { - // recreate compile context - const TAppData *appData = AppData(ctx); + + const bool hasErrors = !msg->Result.Errors.Empty(); + if (!hasErrors || cptr->Retried || cptr->ForceRefresh) { + auto* compileStatusEv = new TMiniKQLCompileServiceEvents::TEvCompileStatus(cptr->Program, msg->Result); + compileStatusEv->CompileResolveCookies = std::move(msg->CompileResolveCookies); + ctx.ExecutorThread.Send(new IEventHandle(cptr->ResponseTo, ctx.SelfID, compileStatusEv, + 0, cptr->Cookie)); + Compile(ctx); + } else { + // recreate compile context + const TAppData *appData = AppData(ctx); TCompileContext::TPtr c = new TCompileContext(cptr->Program, cptr->ResponseTo, AllocPoolCounters, appData->FunctionRegistry); - c->Cookie = cptr->Cookie; - c->Retried = true; - - auto *compileActor = NYql::CreateCompileActor(c->Program, &c->TypeEnv, DbSchemeResolver.Get(), ctx.SelfID, std::move(msg->CompileResolveCookies), false); + c->Cookie = cptr->Cookie; + c->Retried = true; + + auto *compileActor = NYql::CreateCompileActor(c->Program, &c->TypeEnv, DbSchemeResolver.Get(), ctx.SelfID, std::move(msg->CompileResolveCookies), false); const TActorId actId = ctx.ExecutorThread.RegisterActor(compileActor, TMailboxType::HTSwap, appData->UserPoolId); - Compiling.insert(TCompilingMap::value_type(actId, c)); - } + Compiling.insert(TCompilingMap::value_type(actId, c)); + } } void Compile(const TActorContext& ctx) { @@ -141,14 +141,14 @@ private: return; } auto next = CompileQueue.front(); - auto* act = NYql::CreateCompileActor( - next->Program, - &next->TypeEnv, - DbSchemeResolver.Get(), - ctx.SelfID, - std::move(next->CompileResolveCookies), - next->ForceRefresh); - auto *appData = AppData(ctx); + auto* act = NYql::CreateCompileActor( + next->Program, + &next->TypeEnv, + DbSchemeResolver.Get(), + ctx.SelfID, + std::move(next->CompileResolveCookies), + next->ForceRefresh); + auto *appData = AppData(ctx); auto actId = ctx.ExecutorThread.RegisterActor(act, TMailboxType::HTSwap, appData->UserPoolId); Compiling.insert(TCompilingMap::value_type(actId, next)); CompileQueue.pop(); @@ -164,7 +164,7 @@ private: using TCompilingMap = THashMap<TActorId, TCompileContext::TPtr>; TCompilingMap Compiling; - TIntrusivePtr<NMonitoring::TDynamicCounters> Counters; + TIntrusivePtr<NMonitoring::TDynamicCounters> Counters; TAlignedPagePoolCounters AllocPoolCounters; TActorId SchemeCache; THolder<NYql::IDbSchemeResolver> DbSchemeResolver; diff --git a/ydb/core/client/minikql_compile/mkql_compile_service.h b/ydb/core/client/minikql_compile/mkql_compile_service.h index ddb832b5ad..4b0aca1491 100644 --- a/ydb/core/client/minikql_compile/mkql_compile_service.h +++ b/ydb/core/client/minikql_compile/mkql_compile_service.h @@ -22,18 +22,18 @@ struct TMiniKQLCompileServiceEvents { static_assert(End < EventSpaceEnd(NActors::TEvents::ES_USERSPACE), "expect End < EventSpaceEnd(TEvents::ES_USERSPACE)"); - struct TEvCompile : public NActors::TEventLocal<TEvCompile, Compile> { + struct TEvCompile : public NActors::TEventLocal<TEvCompile, Compile> { explicit TEvCompile(const TString& program); - + TString Program; - bool ForceRefresh = false; + bool ForceRefresh = false; THashMap<TString, ui64> CompileResolveCookies; }; - struct TEvCompileStatus : public NActors::TEventLocal<TEvCompileStatus, CompileStatus> { - + struct TEvCompileStatus : public NActors::TEventLocal<TEvCompileStatus, CompileStatus> { + TEvCompileStatus(const TString& program, const NYql::TMiniKQLCompileResult& result); - + TString Program; NYql::TMiniKQLCompileResult Result; THashMap<TString, ui64> CompileResolveCookies; diff --git a/ydb/core/client/minikql_compile/yql_expr_minikql.cpp b/ydb/core/client/minikql_compile/yql_expr_minikql.cpp index 44cde3a555..76f38bf35c 100644 --- a/ydb/core/client/minikql_compile/yql_expr_minikql.cpp +++ b/ydb/core/client/minikql_compile/yql_expr_minikql.cpp @@ -42,7 +42,7 @@ #include <util/generic/vector.h> #include <util/string/cast.h> #include <util/string/hex.h> -#include <util/string/builder.h> +#include <util/string/builder.h> #include <utility> namespace NYql { @@ -1417,8 +1417,8 @@ ConvertToMiniKQL(TExprContainer::TPtr expr, TMiniKQLCompileActorEvents::TEvCompileResult::TEvCompileResult(const TMiniKQLCompileResult& result, THashMap<TString, ui64> &&resolveCookies) : Result(result) - , CompileResolveCookies(std::move(resolveCookies)) -{} + , CompileResolveCookies(std::move(resolveCookies)) +{} class TMiniKQLCompileActor : public TActorBootstrapped<TMiniKQLCompileActor> { public: @@ -1431,12 +1431,12 @@ public: IDbSchemeResolver* dbSchemeResolver, TActorId responseTo, THashMap<TString, ui64> &&resolveRefreshCookies, - bool forceCacheRefresh) + bool forceCacheRefresh) : TypeEnv(typeEnv) , Program(program) , DbSchemeResolver(dbSchemeResolver) , ResponseTo(responseTo) - , ResolveRefreshCookies(std::move(resolveRefreshCookies)) + , ResolveRefreshCookies(std::move(resolveRefreshCookies)) { Y_UNUSED(forceCacheRefresh); } @@ -1447,7 +1447,7 @@ public: try { TMiniKQLCompileResult result; if (!ParseProgram(result.Errors)) { - return SendResponseAndDie(result, {}, ctx); + return SendResponseAndDie(result, {}, ctx); } CollectKeys(Expr->Root.Get(), CompileCtx); @@ -1466,20 +1466,20 @@ public: } else { if (!PerformTypeAnnotation(Expr->Root, Expr->Context, CompileCtx)) { result.Errors.AddIssues(Expr->Context.IssueManager.GetIssues()); - return SendResponseAndDie(result, {}, ctx); + return SendResponseAndDie(result, {}, ctx); } result.CompiledProgram = CompileProgram(); - return SendResponseAndDie(result, {}, ctx); + return SendResponseAndDie(result, {}, ctx); } } catch (const TNodeException& ex) { // TODO: pass backtrace TMiniKQLCompileResult res(NYql::TIssue(Expr->Context.GetPosition(ex.Pos()), ex.what())); - return SendResponseAndDie(res, {}, ctx); + return SendResponseAndDie(res, {}, ctx); } catch (const yexception& ex) { // Catch TProgramBuilder exceptions. // TODO: pass backtrace TMiniKQLCompileResult res(NYql::ExceptionToIssue(ex)); - return SendResponseAndDie(res, {}, ctx); + return SendResponseAndDie(res, {}, ctx); } } @@ -1494,22 +1494,22 @@ public: private: void Handle(IDbSchemeResolver::TEvents::TEvResolveTablesResult::TPtr& ev, const TActorContext& ctx) { THashMap<TString, ui64> compileResolveCookies; - + try { const auto& results = ev->Get()->Result; auto& tablesToResolve = CompileCtx->GetTablesToResolve(); Y_VERIFY_DEBUG(tablesToResolve.size() == results.size(), "tablesToResolve.size() != results.size()"); - + TVector<NYql::TIssue> resolveErrors; ui32 i = 0; - for (auto &xpair : tablesToResolve) { - auto &x = xpair.second; - auto &response = results[i]; - + for (auto &xpair : tablesToResolve) { + auto &x = xpair.second; + auto &response = results[i]; + switch (response.Status) { case IDbSchemeResolver::TTableResult::Ok: break; - + case IDbSchemeResolver::TTableResult::LookupError: resolveErrors.push_back( NYql::TIssue(TPosition(), TStringBuilder() @@ -1527,35 +1527,35 @@ private: break; } - compileResolveCookies[x.Request.TableName] = response.CacheGeneration; - x.Response = response; - ++i; + compileResolveCookies[x.Request.TableName] = response.CacheGeneration; + x.Response = response; + ++i; } if (!resolveErrors.empty()) { TMiniKQLCompileResult result(resolveErrors); return SendResponseAndDie(result, std::move(compileResolveCookies), ctx); } - + TMiniKQLCompileResult result; if (!PerformTypeAnnotation(Expr->Root, Expr->Context, CompileCtx)) { result.Errors.AddIssues(Expr->Context.IssueManager.GetIssues()); - return SendResponseAndDie(result, std::move(compileResolveCookies), ctx); + return SendResponseAndDie(result, std::move(compileResolveCookies), ctx); } result.CompiledProgram = CompileProgram(); - return SendResponseAndDie(result, std::move(compileResolveCookies), ctx); + return SendResponseAndDie(result, std::move(compileResolveCookies), ctx); } catch (const TNodeException& ex) { // TODO: pass backtrace TMiniKQLCompileResult result(NYql::TIssue(Expr->Context.GetPosition(ex.Pos()), ex.what())); - return SendResponseAndDie(result, std::move(compileResolveCookies), ctx); + return SendResponseAndDie(result, std::move(compileResolveCookies), ctx); } catch (const yexception& ex) { // Catch TProgramBuilder exceptions. // TODO: pass backtrace TMiniKQLCompileResult result(NYql::ExceptionToIssue(ex)); - return SendResponseAndDie(result, std::move(compileResolveCookies), ctx); + return SendResponseAndDie(result, std::move(compileResolveCookies), ctx); } } @@ -1593,22 +1593,22 @@ private: } void SendResponseAndDie(const TMiniKQLCompileResult& result, THashMap<TString, ui64> &&resolveCookies, const TActorContext& ctx) { - ctx.ExecutorThread.Send( - new IEventHandle( - ResponseTo, - ctx.SelfID, - new TMiniKQLCompileActorEvents::TEvCompileResult(result, std::move(resolveCookies)) - )); + ctx.ExecutorThread.Send( + new IEventHandle( + ResponseTo, + ctx.SelfID, + new TMiniKQLCompileActorEvents::TEvCompileResult(result, std::move(resolveCookies)) + )); Die(ctx); } private: - void Cleanup() { - CompileCtx.Drop(); - Expr.Drop(); - Compiler.Drop(); - } - + void Cleanup() { + CompileCtx.Drop(); + Expr.Drop(); + Compiler.Drop(); + } + const NKikimr::NMiniKQL::TTypeEnvironment* TypeEnv; TString Program; TContext::TPtr CompileCtx; @@ -1625,9 +1625,9 @@ CreateCompileActor(const TString& program, IDbSchemeResolver* dbSchemeResolver, TActorId responseTo, THashMap<TString, ui64> &&resolveRefreshCookies, - bool forceCacheRefresh) + bool forceCacheRefresh) { - return new TMiniKQLCompileActor(program, typeEnv, dbSchemeResolver, responseTo, std::move(resolveRefreshCookies), forceCacheRefresh); + return new TMiniKQLCompileActor(program, typeEnv, dbSchemeResolver, responseTo, std::move(resolveRefreshCookies), forceCacheRefresh); } } // namespace NYql diff --git a/ydb/core/client/minikql_compile/yql_expr_minikql.h b/ydb/core/client/minikql_compile/yql_expr_minikql.h index 265991094b..ab6011c105 100644 --- a/ydb/core/client/minikql_compile/yql_expr_minikql.h +++ b/ydb/core/client/minikql_compile/yql_expr_minikql.h @@ -1,7 +1,7 @@ #pragma once #include "compile_result.h" -#include "compile_context.h" +#include "compile_context.h" #include "db_key_resolver.h" #include <library/cpp/actors/core/actor.h> @@ -46,7 +46,7 @@ struct TMiniKQLCompileActorEvents { struct TEvCompileResult : public NActors::TEventBase<TEvCompileResult, CompileResult> { explicit TEvCompileResult(const TMiniKQLCompileResult& result, THashMap<TString, ui64> &&resolveCookies); DEFINE_SIMPLE_LOCAL_EVENT(TEvCompileResult, "EvCompileResult"); - + TMiniKQLCompileResult Result; THashMap<TString, ui64> CompileResolveCookies; }; @@ -58,6 +58,6 @@ CreateCompileActor(const TString& program, IDbSchemeResolver* dbSchemeResolver, NActors::TActorId responseTo, THashMap<TString, ui64> &&resolveRefreshCookies, - bool forceCacheRefresh); // TEvCompileResult. + bool forceCacheRefresh); // TEvCompileResult. } // namespace NYql diff --git a/ydb/core/client/scheme_cache_lib/yql_db_scheme_resolver.cpp b/ydb/core/client/scheme_cache_lib/yql_db_scheme_resolver.cpp index 63a1c2ea67..eb74fa36e9 100644 --- a/ydb/core/client/scheme_cache_lib/yql_db_scheme_resolver.cpp +++ b/ydb/core/client/scheme_cache_lib/yql_db_scheme_resolver.cpp @@ -14,52 +14,52 @@ using namespace NThreading; namespace { -class TTableProxyActor : public TActorBootstrapped<TTableProxyActor> { - using TTable = NYql::IDbSchemeResolver::TTable; - using TTableResult = NYql::IDbSchemeResolver::TTableResult; - using TTableResults = NYql::IDbSchemeResolver::TTableResults; - +class TTableProxyActor : public TActorBootstrapped<TTableProxyActor> { + using TTable = NYql::IDbSchemeResolver::TTable; + using TTableResult = NYql::IDbSchemeResolver::TTableResult; + using TTableResults = NYql::IDbSchemeResolver::TTableResults; + const TActorId SchemeCache; const TActorId ResponseTo; TVector<TTable> Tables; - - void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev, const TActorContext &ctx) { + + void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev, const TActorContext &ctx) { const NSchemeCache::TSchemeCacheNavigate &request = *ev->Get()->Request; Y_VERIFY(request.ResultSet.size() == Tables.size()); - + TVector<TTableResult> results; - results.reserve(Tables.size()); - - for (ui32 idx = 0, end = Tables.size(); idx != end; ++idx) { - auto &src = Tables[idx]; - const NSchemeCache::TSchemeCacheNavigate::TEntry &res = request.ResultSet[idx]; - - switch (res.Status) { - case NSchemeCache::TSchemeCacheNavigate::EStatus::Ok: - { - results.push_back({TTableResult::Ok}); - auto &reply = results.back(); - - reply.Status = TTableResult::Ok; - reply.Table.TableName = src.TableName; - reply.Table.ColumnNames = std::move(src.ColumnNames); - reply.TableId = new TTableId(res.TableId); + results.reserve(Tables.size()); + + for (ui32 idx = 0, end = Tables.size(); idx != end; ++idx) { + auto &src = Tables[idx]; + const NSchemeCache::TSchemeCacheNavigate::TEntry &res = request.ResultSet[idx]; + + switch (res.Status) { + case NSchemeCache::TSchemeCacheNavigate::EStatus::Ok: + { + results.push_back({TTableResult::Ok}); + auto &reply = results.back(); + + reply.Status = TTableResult::Ok; + reply.Table.TableName = src.TableName; + reply.Table.ColumnNames = std::move(src.ColumnNames); + reply.TableId = new TTableId(res.TableId); reply.CacheGeneration = 0; - + TSet<TString> replyColumns; - TMap<TString, THashMap<ui32, TSysTables::TTableColumnInfo>::const_iterator> backindex; - for (auto it = res.Columns.begin(), eit = res.Columns.end(); it != eit; ++it) { + TMap<TString, THashMap<ui32, TSysTables::TTableColumnInfo>::const_iterator> backindex; + for (auto it = res.Columns.begin(), eit = res.Columns.end(); it != eit; ++it) { auto& name = it->second.Name; backindex.insert({name, it}); if (it->second.KeyOrder >= 0) { replyColumns.insert(name); - ++reply.KeyColumnCount; + ++reply.KeyColumnCount; } - } - + } + replyColumns.insert(reply.Table.ColumnNames.begin(), reply.Table.ColumnNames.end()); for (const auto &column : replyColumns) { @@ -71,80 +71,80 @@ class TTableProxyActor : public TActorBootstrapped<TTableProxyActor> { }); continue; } - const auto *x = backindex.FindPtr(column); - if (x == nullptr) { - reply.Status = TTableResult::Error; - reply.Reason = "column '" + column + "' not exist"; - } else { - const auto &col = (*x)->second; - reply.Columns.insert(std::make_pair(column, - IDbSchemeResolver::TTableResult::TColumn{col.Id, col.KeyOrder, col.PType, 0})); - } - } - } - break; - case NSchemeCache::TSchemeCacheNavigate::EStatus::RootUnknown: - case NSchemeCache::TSchemeCacheNavigate::EStatus::PathErrorUnknown: - results.push_back({TTableResult::Error, ToString(res.Status)}); - break; - default: - results.push_back({TTableResult::LookupError, ToString(res.Status)}); - break; - } - } - - ctx.Send(ResponseTo, new NYql::IDbSchemeResolver::TEvents::TEvResolveTablesResult(std::move(results))); - return Die(ctx); - } -public: + const auto *x = backindex.FindPtr(column); + if (x == nullptr) { + reply.Status = TTableResult::Error; + reply.Reason = "column '" + column + "' not exist"; + } else { + const auto &col = (*x)->second; + reply.Columns.insert(std::make_pair(column, + IDbSchemeResolver::TTableResult::TColumn{col.Id, col.KeyOrder, col.PType, 0})); + } + } + } + break; + case NSchemeCache::TSchemeCacheNavigate::EStatus::RootUnknown: + case NSchemeCache::TSchemeCacheNavigate::EStatus::PathErrorUnknown: + results.push_back({TTableResult::Error, ToString(res.Status)}); + break; + default: + results.push_back({TTableResult::LookupError, ToString(res.Status)}); + break; + } + } + + ctx.Send(ResponseTo, new NYql::IDbSchemeResolver::TEvents::TEvResolveTablesResult(std::move(results))); + return Die(ctx); + } +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TABLE_SCHEME_RESOLVER; } TTableProxyActor(TActorId schemeCache, TActorId responseTo, const TVector<TTable> &tables) - : SchemeCache(schemeCache) - , ResponseTo(responseTo) - , Tables(tables) - {} - - void Bootstrap(const TActorContext &ctx) { + : SchemeCache(schemeCache) + , ResponseTo(responseTo) + , Tables(tables) + {} + + void Bootstrap(const TActorContext &ctx) { TAutoPtr<NSchemeCache::TSchemeCacheNavigate> request(new NSchemeCache::TSchemeCacheNavigate()); - - request->ResultSet.reserve(Tables.size()); - for (auto &table : Tables) { - request->ResultSet.push_back({}); - auto &x = request->ResultSet.back(); + + request->ResultSet.reserve(Tables.size()); + for (auto &table : Tables) { + request->ResultSet.push_back({}); + auto &x = request->ResultSet.back(); x.Path = SplitPath(table.TableName); x.Operation = NSchemeCache::TSchemeCacheNavigate::OpTable; x.ShowPrivatePath = true; - } - - ctx.Send(SchemeCache, new TEvTxProxySchemeCache::TEvNavigateKeySet(request)); - Become(&TThis::StateWait); - } - - STFUNC(StateWait) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle); - } - } -}; - + } + + ctx.Send(SchemeCache, new TEvTxProxySchemeCache::TEvNavigateKeySet(request)); + Become(&TThis::StateWait); + } + + STFUNC(StateWait) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle); + } + } +}; + } // anonymous namespace class TDbSchemeResolver : public IDbSchemeResolver { public: - TDbSchemeResolver(TActorSystem *actorSystem) - : HostActorSystem(actorSystem) + TDbSchemeResolver(TActorSystem *actorSystem) + : HostActorSystem(actorSystem) { } TDbSchemeResolver(TActorSystem *actorSystem, const TActorId &schemeCacheActor) - : HostActorSystem(actorSystem) - , SchemeCacheActor(schemeCacheActor) - {} + : HostActorSystem(actorSystem) + , SchemeCacheActor(schemeCacheActor) + {} - virtual ~TDbSchemeResolver() {} + virtual ~TDbSchemeResolver() {} virtual NThreading::TFuture<TTableResults> ResolveTables(const TVector<TTable>& tables) override { TTableResults results; @@ -158,17 +158,17 @@ public: } virtual void ResolveTables(const TVector<TTable>& tables, NActors::TActorId responseTo) override { - TAutoPtr<NActors::IActor> proxyActor(new TTableProxyActor(SchemeCacheActor, responseTo, tables)); + TAutoPtr<NActors::IActor> proxyActor(new TTableProxyActor(SchemeCacheActor, responseTo, tables)); HostActorSystem->Register(proxyActor.Release(), TMailboxType::HTSwap, HostActorSystem->AppData<TAppData>()->UserPoolId); } private: - TActorSystem *HostActorSystem; + TActorSystem *HostActorSystem; TActorId SchemeCacheActor; }; NYql::IDbSchemeResolver* CreateDbSchemeResolver(TActorSystem *actorSystem, const TActorId &schemeCacheActor) { - TAutoPtr<NYql::IDbSchemeResolver> resolver(new TDbSchemeResolver(actorSystem, schemeCacheActor)); + TAutoPtr<NYql::IDbSchemeResolver> resolver(new TDbSchemeResolver(actorSystem, schemeCacheActor)); return resolver.Release(); } diff --git a/ydb/core/client/scheme_cache_lib/yql_db_scheme_resolver.h b/ydb/core/client/scheme_cache_lib/yql_db_scheme_resolver.h index 2bd037e50e..b1d2eaae8e 100644 --- a/ydb/core/client/scheme_cache_lib/yql_db_scheme_resolver.h +++ b/ydb/core/client/scheme_cache_lib/yql_db_scheme_resolver.h @@ -5,11 +5,11 @@ namespace NYql { class IDbSchemeResolver; } // namespace NYql -namespace NActors { - class TActorSystem; +namespace NActors { + class TActorSystem; struct TActorId; -} - +} + namespace NKikimr { namespace NSchCache { diff --git a/ydb/core/client/server/grpc_proxy_status.cpp b/ydb/core/client/server/grpc_proxy_status.cpp index d30c697b0e..827335ad40 100644 --- a/ydb/core/client/server/grpc_proxy_status.cpp +++ b/ydb/core/client/server/grpc_proxy_status.cpp @@ -67,7 +67,7 @@ public: void Die(const TActorContext& ctx) override { for (const ui32 node : Nodes) { - ctx.Send(TActivationContext::InterconnectProxy(node), new TEvents::TEvUnsubscribe()); + ctx.Send(TActivationContext::InterconnectProxy(node), new TEvents::TEvUnsubscribe()); } TBase::Die(ctx); } diff --git a/ydb/core/client/server/msgbus_blobstorage_config.cpp b/ydb/core/client/server/msgbus_blobstorage_config.cpp index 1949c542b4..a0af40eac9 100644 --- a/ydb/core/client/server/msgbus_blobstorage_config.cpp +++ b/ydb/core/client/server/msgbus_blobstorage_config.cpp @@ -12,7 +12,7 @@ namespace { class TMessageBusBlobStorageConfig : public TMessageBusSecureRequest<TMessageBusSimpleTabletRequest< TMessageBusBlobStorageConfig, - TEvBlobStorage::TEvControllerConfigResponse, + TEvBlobStorage::TEvControllerConfigResponse, NKikimrServices::TActivity::FRONT_BSADM_CONFIG >> { diff --git a/ydb/core/client/server/msgbus_bsadm.cpp b/ydb/core/client/server/msgbus_bsadm.cpp index deae48ded7..a3bed376f4 100644 --- a/ydb/core/client/server/msgbus_bsadm.cpp +++ b/ydb/core/client/server/msgbus_bsadm.cpp @@ -1,14 +1,14 @@ -#include "msgbus_tabletreq.h" +#include "msgbus_tabletreq.h" #include "msgbus_securereq.h" #include <ydb/core/blobstorage/base/blobstorage_events.h> - -namespace NKikimr { -namespace NMsgBusProxy { - -namespace { + +namespace NKikimr { +namespace NMsgBusProxy { + +namespace { const ui64 DefaultTimeout = 90000; -} - +} + class TMessageBusBSAdmGroupReconfigureWipe : public TMessageBusSecureRequest< TMessageBusSimpleTabletRequest< TMessageBusBSAdmGroupReconfigureWipe, @@ -53,10 +53,10 @@ public: IActor* CreateMessageBusBSAdm(TBusMessageContext &msg) { const NKikimrClient::TBSAdm &record = static_cast<TBusBSAdm *>(msg.GetMessage())->Record; - - const ui32 targetDomain = record.GetDomain(); - const ui64 tabletId = MakeBSControllerID(targetDomain); - + + const ui32 targetDomain = record.GetDomain(); + const ui64 tabletId = MakeBSControllerID(targetDomain); + if (record.HasGroupReconfigureWipe()) { const auto &x = record.GetGroupReconfigureWipe(); if (!x.HasLocation()) { @@ -73,10 +73,10 @@ IActor* CreateMessageBusBSAdm(TBusMessageContext &msg) { return new TMessageBusBSAdmGroupReconfigureWipe(msg, tabletId, req, true, TDuration::MilliSeconds(DefaultTimeout)); - } - - return nullptr; -} - -} -} + } + + return nullptr; +} + +} +} diff --git a/ydb/core/client/server/msgbus_server.cpp b/ydb/core/client/server/msgbus_server.cpp index 8276af570d..8a4d8a3bbd 100644 --- a/ydb/core/client/server/msgbus_server.cpp +++ b/ydb/core/client/server/msgbus_server.cpp @@ -1,14 +1,14 @@ #include <library/cpp/monlib/messagebus/mon_messagebus.h> #include <ydb/core/base/appdata.h> #include <ydb/core/node_whiteboard/node_whiteboard.h> -#include "msgbus_server.h" +#include "msgbus_server.h" #include "msgbus_server_tracer.h" #include "msgbus_http_server.h" #include "grpc_server.h" - -namespace NKikimr { -namespace NMsgBusProxy { - + +namespace NKikimr { +namespace NMsgBusProxy { + class TBusMessageContext::TImpl : public TThrRefBase { public: virtual ~TImpl() = default; @@ -441,95 +441,95 @@ TMessageBusServer::TMessageBusServer( ui32 bindPort, std::shared_ptr<IPersQueueGetReadSessionsInfoWorkerFactory> pqReadSessionsInfoWorkerFactory ) - : SessionConfig(sessionConfig) - , BusQueue(busQueue) + : SessionConfig(sessionConfig) + , BusQueue(busQueue) , PQReadSessionsInfoWorkerFactory(pqReadSessionsInfoWorkerFactory) - , Protocol(bindPort) -{} - -TMessageBusServer::~TMessageBusServer() { - -} - + , Protocol(bindPort) +{} + +TMessageBusServer::~TMessageBusServer() { + +} + void TMessageBusServer::InitSession(TActorSystem *actorSystem, const TActorId &proxy) { - ActorSystem = actorSystem; - Proxy = proxy; - Session = NBus::TBusServerSession::Create(&Protocol, this, SessionConfig, BusQueue); + ActorSystem = actorSystem; + Proxy = proxy; + Session = NBus::TBusServerSession::Create(&Protocol, this, SessionConfig, BusQueue); HttpServer.Reset(CreateMessageBusHttpServer(actorSystem, this, Protocol, SessionConfig)); Monitor = ActorSystem->Register(new TMessageBusMonitorActor(Session, SessionConfig), TMailboxType::HTSwap, actorSystem->AppData<TAppData>()->UserPoolId); -} - -void TMessageBusServer::ShutdownSession() { +} + +void TMessageBusServer::ShutdownSession() { HttpServer.Reset(); - if (Session) { - Session->Shutdown(); - } -} - -void TMessageBusServer::RegisterMonPage(NMonitoring::TBusNgMonPage *busMonPage) { - busMonPage->BusWww->RegisterServerSession(Session); -} - -void TMessageBusServer::OnMessage(NBus::TOnMessageContext &msg) { + if (Session) { + Session->Shutdown(); + } +} + +void TMessageBusServer::RegisterMonPage(NMonitoring::TBusNgMonPage *busMonPage) { + busMonPage->BusWww->RegisterServerSession(Session); +} + +void TMessageBusServer::OnMessage(NBus::TOnMessageContext &msg) { TBusMessageContext messageContext(msg); OnMessage(messageContext); } void TMessageBusServer::OnMessage(TBusMessageContext &msg) { - const ui32 msgType = msg.GetMessage()->GetHeader()->Type; + const ui32 msgType = msg.GetMessage()->GetHeader()->Type; - switch (msgType) { - case MTYPE_CLIENT_REQUEST: - return ClientProxyRequest<TEvBusProxy::TEvRequest>(msg); - case MTYPE_CLIENT_SCHEME_INITROOT: + switch (msgType) { + case MTYPE_CLIENT_REQUEST: + return ClientProxyRequest<TEvBusProxy::TEvRequest>(msg); + case MTYPE_CLIENT_SCHEME_INITROOT: return ClientProxyRequest<TEvBusProxy::TEvInitRoot>(msg); - case MTYPE_CLIENT_BSADM: - return ClientActorRequest(CreateMessageBusBSAdm, msg); - case MTYPE_CLIENT_SCHEME_NAVIGATE: - return ClientProxyRequest<TEvBusProxy::TEvNavigate>(msg); + case MTYPE_CLIENT_BSADM: + return ClientActorRequest(CreateMessageBusBSAdm, msg); + case MTYPE_CLIENT_SCHEME_NAVIGATE: + return ClientProxyRequest<TEvBusProxy::TEvNavigate>(msg); case MTYPE_CLIENT_TYPES_REQUEST: return GetTypes(msg); case MTYPE_CLIENT_HIVE_CREATE_TABLET: case MTYPE_CLIENT_OLD_HIVE_CREATE_TABLET: - return ClientActorRequest(CreateMessageBusHiveCreateTablet, msg); + return ClientActorRequest(CreateMessageBusHiveCreateTablet, msg); case MTYPE_CLIENT_LOCAL_ENUMERATE_TABLETS: case MTYPE_CLIENT_OLD_LOCAL_ENUMERATE_TABLETS: - return ClientActorRequest(CreateMessageBusLocalEnumerateTablets, msg); + return ClientActorRequest(CreateMessageBusLocalEnumerateTablets, msg); case MTYPE_CLIENT_KEYVALUE: case MTYPE_CLIENT_OLD_KEYVALUE: - return ClientActorRequest(CreateMessageBusKeyValue, msg); + return ClientActorRequest(CreateMessageBusKeyValue, msg); case MTYPE_CLIENT_PERSQUEUE: - return ClientProxyRequest<TEvBusProxy::TEvPersQueue>(msg); + return ClientProxyRequest<TEvBusProxy::TEvPersQueue>(msg); case MTYPE_CLIENT_CHOOSE_PROXY: return ClientActorRequest(CreateMessageBusChooseProxy, msg); case MTYPE_CLIENT_TABLET_STATE_REQUEST: - return ClientActorRequest(CreateMessageBusTabletStateRequest, msg); + return ClientActorRequest(CreateMessageBusTabletStateRequest, msg); case MTYPE_CLIENT_TABLET_COUNTERS_REQUEST: return ClientActorRequest(CreateMessageBusTabletCountersRequest, msg); - case MTYPE_CLIENT_LOCAL_MINIKQL: - return ClientActorRequest(CreateMessageBusLocalMKQL, msg); + case MTYPE_CLIENT_LOCAL_MINIKQL: + return ClientActorRequest(CreateMessageBusLocalMKQL, msg); case MTYPE_CLIENT_LOCAL_SCHEME_TX: - return ClientActorRequest(CreateMessageBusLocalSchemeTx, msg); + return ClientActorRequest(CreateMessageBusLocalSchemeTx, msg); case MTYPE_CLIENT_TABLET_KILL_REQUEST: - return ClientActorRequest(CreateMessageBusTabletKillRequest, msg); + return ClientActorRequest(CreateMessageBusTabletKillRequest, msg); case MTYPE_CLIENT_FLAT_TX_REQUEST: - return ClientProxyRequest<TEvBusProxy::TEvFlatTxRequest>(msg); + return ClientProxyRequest<TEvBusProxy::TEvFlatTxRequest>(msg); case MTYPE_CLIENT_FLAT_TX_STATUS_REQUEST: return ClientActorRequest(CreateMessageBusSchemeOperationStatus, msg); case MTYPE_CLIENT_FLAT_DESCRIBE_REQUEST: case MTYPE_CLIENT_OLD_FLAT_DESCRIBE_REQUEST: - return ClientProxyRequest<TEvBusProxy::TEvFlatDescribeRequest>(msg); + return ClientProxyRequest<TEvBusProxy::TEvFlatDescribeRequest>(msg); case MTYPE_CLIENT_LOAD_REQUEST: return ClientActorRequest(CreateMessageBusBlobStorageLoadRequest, msg); case MTYPE_CLIENT_GET_REQUEST: return ClientActorRequest(CreateMessageBusBlobStorageGetRequest, msg); case MTYPE_CLIENT_DB_SCHEMA: - return ClientProxyRequest<TEvBusProxy::TEvDbSchema>(msg); + return ClientProxyRequest<TEvBusProxy::TEvDbSchema>(msg); case MTYPE_CLIENT_DB_OPERATION: - return ClientProxyRequest<TEvBusProxy::TEvDbOperation>(msg); + return ClientProxyRequest<TEvBusProxy::TEvDbOperation>(msg); case MTYPE_CLIENT_DB_BATCH: - return ClientProxyRequest<TEvBusProxy::TEvDbBatch>(msg); + return ClientProxyRequest<TEvBusProxy::TEvDbBatch>(msg); case MTYPE_CLIENT_BLOB_STORAGE_CONFIG_REQUEST: return ClientActorRequest(CreateMessageBusBlobStorageConfig, msg); case MTYPE_CLIENT_DRAIN_NODE: @@ -552,12 +552,12 @@ void TMessageBusServer::OnMessage(TBusMessageContext &msg) { return ClientActorRequest(CreateMessageBusConsoleRequest, msg); case MTYPE_CLIENT_TEST_SHARD_CONTROL: return ClientActorRequest(CreateMessageBusTestShardControl, msg); - default: - return UnknownMessage(msg); - } -} - -void TMessageBusServer::OnError(TAutoPtr<NBus::TBusMessage> msg, NBus::EMessageStatus status) { + default: + return UnknownMessage(msg); + } +} + +void TMessageBusServer::OnError(TAutoPtr<NBus::TBusMessage> msg, NBus::EMessageStatus status) { if (ActorSystem) { if (status == NBus::MESSAGE_SHUTDOWN) { LOG_DEBUG_S(*ActorSystem, NKikimrServices::MSGBUS_REQUEST, "Msgbus client disconnected before reply was sent" @@ -567,18 +567,18 @@ void TMessageBusServer::OnError(TAutoPtr<NBus::TBusMessage> msg, NBus::EMessageS << " msg# " << msg->Describe()); } } -} - -template<typename TEv> -void TMessageBusServer::ClientProxyRequest(TBusMessageContext &msg) { - if (Proxy) - ActorSystem->Send(Proxy, new TEv(msg)); - else +} + +template<typename TEv> +void TMessageBusServer::ClientProxyRequest(TBusMessageContext &msg) { + if (Proxy) + ActorSystem->Send(Proxy, new TEv(msg)); + else msg.SendReplyMove(new TBusResponseStatus(MSTATUS_ERROR, "MessageBus proxy is not available")); } -void TMessageBusServer::ClientActorRequest(ActorCreationFunc func, TBusMessageContext &msg) { - if (IActor *x = func(msg)) +void TMessageBusServer::ClientActorRequest(ActorCreationFunc func, TBusMessageContext &msg) { + if (IActor *x = func(msg)) ActorSystem->Register(x, TMailboxType::HTSwap, ActorSystem->AppData<TAppData>()->UserPoolId); else msg.SendReplyMove(new TBusResponseStatus(MSTATUS_ERROR)); @@ -596,12 +596,12 @@ void TMessageBusServer::GetTypes(TBusMessageContext &msg) { void TMessageBusServer::UnknownMessage(TBusMessageContext &msg) { msg.SendReplyMove(new TBusResponseStatus(MSTATUS_UNKNOWN, "undocumented error 9")); -} - +} + IActor* TMessageBusServer::CreateProxy() { return CreateMessageBusServerProxy(this, PQReadSessionsInfoWorkerFactory); -} - +} + IActor* TMessageBusServer::CreateMessageBusTraceService() { return nullptr; } @@ -613,7 +613,7 @@ IMessageBusServer* CreateMsgBusServer( ui32 bindPort ) { return new TMessageBusServer(config, queue, bindPort, pqReadSessionsInfoWorkerFactory); -} - -} -} +} + +} +} diff --git a/ydb/core/client/server/msgbus_server.h b/ydb/core/client/server/msgbus_server.h index 24e2544771..3d40fc9001 100644 --- a/ydb/core/client/server/msgbus_server.h +++ b/ydb/core/client/server/msgbus_server.h @@ -1,23 +1,23 @@ -#pragma once +#pragma once #include <library/cpp/actors/core/actorsystem.h> #include <library/cpp/actors/core/actor_bootstrapped.h> #include <ydb/public/lib/base/defs.h> #include <ydb/public/lib/base/msgbus.h> #include "msgbus_http_server.h" #include "msgbus_server_pq_metacache.h" - -namespace NMonitoring { - class TBusNgMonPage; -} - -namespace NKikimr { + +namespace NMonitoring { + class TBusNgMonPage; +} + +namespace NKikimr { namespace NGRpcProxy { class IRequestContext; } // NGRpcProxy -namespace NMsgBusProxy { - +namespace NMsgBusProxy { + class IMessageWatcher { public: virtual ~IMessageWatcher() {} @@ -90,10 +90,10 @@ private: THolder<TMessageBusSessionIdentHolder::TImpl> CreateSessionIdentHolder(); }; -struct TEvBusProxy { - enum EEv { - EvRequest = EventSpaceBegin(TKikimrEvents::ES_PROXY_BUS), - EvNavigate, +struct TEvBusProxy { + enum EEv { + EvRequest = EventSpaceBegin(TKikimrEvents::ES_PROXY_BUS), + EvNavigate, EvFlatTxRequest, EvFlatDescribeRequest, EvPersQueue, @@ -106,18 +106,18 @@ struct TEvBusProxy { EvStreamIsReadyNotUsed = EvRequest + 512, EvStreamIsDeadNotUsed, - EvEnd - }; - - template<EEv EvId> - struct TEvMsgBusRequest : public TEventLocal<TEvMsgBusRequest<EvId>, EvId> { + EvEnd + }; + + template<EEv EvId> + struct TEvMsgBusRequest : public TEventLocal<TEvMsgBusRequest<EvId>, EvId> { TBusMessageContext MsgContext; - + TEvMsgBusRequest(TBusMessageContext &msg) { - MsgContext.Swap(msg); - } - }; - + MsgContext.Swap(msg); + } + }; + typedef TEvMsgBusRequest<EvRequest> TEvRequest; typedef TEvMsgBusRequest<EvNavigate> TEvNavigate; typedef TEvMsgBusRequest<EvFlatTxRequest> TEvFlatTxRequest; @@ -128,51 +128,51 @@ struct TEvBusProxy { typedef TEvMsgBusRequest<EvDbOperation> TEvDbOperation; typedef TEvMsgBusRequest<EvDbBatch> TEvDbBatch; typedef TEvMsgBusRequest<EvInitRoot> TEvInitRoot; -}; - -class TMessageBusServer : public IMessageBusServer, public NBus::IBusServerHandler { - const NBus::TBusServerSessionConfig &SessionConfig; - NBus::TBusMessageQueuePtr BusQueue; +}; + +class TMessageBusServer : public IMessageBusServer, public NBus::IBusServerHandler { + const NBus::TBusServerSessionConfig &SessionConfig; + NBus::TBusMessageQueuePtr BusQueue; NBus::TBusServerSessionPtr Session; TActorId Proxy; TActorId Monitor; std::shared_ptr<IPersQueueGetReadSessionsInfoWorkerFactory> PQReadSessionsInfoWorkerFactory; protected: - TProtocol Protocol; + TProtocol Protocol; TActorSystem *ActorSystem = nullptr; TIntrusivePtr<IMessageBusHttpServer> HttpServer; -public: +public: TMessageBusServer( const NBus::TBusServerSessionConfig &sessionConfig, NBus::TBusMessageQueue *busQueue, ui32 bindPort, std::shared_ptr<IPersQueueGetReadSessionsInfoWorkerFactory> pqReadSessionsInfoWorkerFactory ); - ~TMessageBusServer(); - + ~TMessageBusServer(); + void InitSession(TActorSystem *actorSystem, const TActorId &proxy); - void ShutdownSession(); - - void RegisterMonPage(NMonitoring::TBusNgMonPage *busMonPage); + void ShutdownSession(); + + void RegisterMonPage(NMonitoring::TBusNgMonPage *busMonPage); protected: void OnMessage(NBus::TOnMessageContext &msg) override; void OnMessage(TBusMessageContext &msg); IActor* CreateMessageBusTraceService() override; -private: +private: IActor* CreateProxy() override; - void OnError(TAutoPtr<NBus::TBusMessage> message, NBus::EMessageStatus status) override; - + void OnError(TAutoPtr<NBus::TBusMessage> message, NBus::EMessageStatus status) override; + void GetTypes(TBusMessageContext &msg); void UnknownMessage(TBusMessageContext &msg); - - template<typename TEv> - void ClientProxyRequest(TBusMessageContext &msg); - - typedef std::function<IActor* (TBusMessageContext &msg)> ActorCreationFunc; - void ClientActorRequest(ActorCreationFunc func, TBusMessageContext &msg); -}; - + + template<typename TEv> + void ClientProxyRequest(TBusMessageContext &msg); + + typedef std::function<IActor* (TBusMessageContext &msg)> ActorCreationFunc; + void ClientActorRequest(ActorCreationFunc func, TBusMessageContext &msg); +}; + template <typename TProto> void CopyProtobufsByFieldName(TProto& protoTo, const TProto& protoFrom) { using namespace ::google::protobuf; @@ -273,7 +273,7 @@ void CopyProtobufsByFieldName(TProtoTo& protoTo, const TProtoFrom& protoFrom) { } class IPersQueueGetReadSessionsInfoWorkerFactory; - + IActor* CreateMessageBusServerProxy( TMessageBusServer *server, std::shared_ptr<IPersQueueGetReadSessionsInfoWorkerFactory> pqReadSessionsInfoWorkerFactory @@ -281,7 +281,7 @@ IActor* CreateMessageBusServerProxy( //IActor* CreateMessageBusDatashardSetConfig(TBusMessageContext &msg); IActor* CreateMessageBusTabletCountersRequest(TBusMessageContext &msg); -IActor* CreateMessageBusLocalMKQL(TBusMessageContext &msg); +IActor* CreateMessageBusLocalMKQL(TBusMessageContext &msg); IActor* CreateMessageBusLocalSchemeTx(TBusMessageContext &msg); IActor* CreateMessageBusSchemeInitRoot(TBusMessageContext &msg); IActor* CreateMessageBusBSAdm(TBusMessageContext &msg); @@ -309,8 +309,8 @@ IActor* CreateMessageBusS3ListingRequest(TBusMessageContext& msg); IActor* CreateMessageBusInterconnectDebug(TBusMessageContext& msg); IActor* CreateMessageBusConsoleRequest(TBusMessageContext &msg); IActor* CreateMessageBusTestShardControl(TBusMessageContext &msg); - -TBusResponse* ProposeTransactionStatusToResponse(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus &result); -} -} +TBusResponse* ProposeTransactionStatusToResponse(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus &result); + +} +} diff --git a/ydb/core/client/server/msgbus_server_db.cpp b/ydb/core/client/server/msgbus_server_db.cpp index 7ba54a6ed8..08f3d71786 100644 --- a/ydb/core/client/server/msgbus_server_db.cpp +++ b/ydb/core/client/server/msgbus_server_db.cpp @@ -92,7 +92,7 @@ public: } } } else { - TAutoPtr<TBusResponse> response(ProposeTransactionStatusToResponse(status, result)); + TAutoPtr<TBusResponse> response(ProposeTransactionStatusToResponse(status, result)); if (result.HasExecutionEngineEvaluatedResponse()) { response->Record.MutableExecutionEngineEvaluatedResponse()->CopyFrom(result.GetExecutionEngineEvaluatedResponse()); } @@ -286,8 +286,8 @@ protected: case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardTryLater: case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardOverloaded: return ReplyWithResult(MSTATUS_REJECTED, msg->Record, ctx); - case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardUnknown: - return ReplyWithResult(MSTATUS_TIMEOUT, msg->Record, ctx); + case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardUnknown: + return ReplyWithResult(MSTATUS_TIMEOUT, msg->Record, ctx); default: return ReplyWithResult(MSTATUS_INTERNALERROR, msg->Record, ctx); } @@ -709,8 +709,8 @@ protected: case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardTryLater: case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardOverloaded: return ReplyWithResult(MSTATUS_REJECTED, msg->Record, ctx); - case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardUnknown: - return ReplyWithResult(MSTATUS_TIMEOUT, msg->Record, ctx); + case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardUnknown: + return ReplyWithResult(MSTATUS_TIMEOUT, msg->Record, ctx); default: return ReplyWithResult(MSTATUS_INTERNALERROR, msg->Record, ctx); } diff --git a/ydb/core/client/server/msgbus_server_hive_create_tablet.cpp b/ydb/core/client/server/msgbus_server_hive_create_tablet.cpp index 0d7ad8b14e..0c41e53f09 100644 --- a/ydb/core/client/server/msgbus_server_hive_create_tablet.cpp +++ b/ydb/core/client/server/msgbus_server_hive_create_tablet.cpp @@ -1,23 +1,23 @@ -#include "msgbus_tabletreq.h" +#include "msgbus_tabletreq.h" #include <ydb/core/base/appdata.h> #include <ydb/core/base/storage_pools.h> #include <ydb/core/protos/hive.pb.h> #include <ydb/core/base/hive.h> #include <ydb/core/base/subdomain.h> - -namespace NKikimr { -namespace NMsgBusProxy { - -namespace { + +namespace NKikimr { +namespace NMsgBusProxy { + +namespace { const ui32 DefaultTimeout = 90000; -} - +} + template <typename ResponseType> class TMessageBusHiveCreateTablet : public TActorBootstrapped<TMessageBusHiveCreateTablet<ResponseType>> , public TMessageBusSessionIdentHolder { using TBase = TActorBootstrapped<TMessageBusHiveCreateTablet<ResponseType>>; - + struct TRequest { TEvHive::EEv Event; ui64 OwnerId; @@ -64,11 +64,11 @@ using TBase = TActorBootstrapped<TMessageBusHiveCreateTablet<ResponseType>>; ui32 ResponsesReceived; ui32 DomainUid; TString ErrorReason; -public: +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::MSGBUS_COMMON; } - + TMessageBusHiveCreateTablet(TBusMessageContext &msg) : TMessageBusSessionIdentHolder(msg) , Status(NKikimrProto::UNKNOWN) @@ -126,7 +126,7 @@ public: ErrorReason = Sprintf("Unexpected reply from Hive with Cookie# %" PRIu64 ", Marker# HC2", (ui64)ev->Cookie); return SendReplyAndDie(CreateErrorReply(MSTATUS_ERROR, ctx), ctx); - } + } TRequest &cmd = Requests[ev->Cookie]; if (cmd.Status != NKikimrProto::UNKNOWN) { @@ -199,8 +199,8 @@ public: } } } - } - + } + void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx) { TEvTabletPipe::TEvClientConnected *msg = ev->Get(); if (msg->Status != NKikimrProto::OK) { @@ -304,13 +304,13 @@ public: } TBase::Become(&TMessageBusHiveCreateTablet<ResponseType>::StateWaiting, ctx, Timeout, new TEvents::TEvWakeup()); - } else { + } else { if (ErrorReason.size() == 0) { ErrorReason = Sprintf("Unexpected Status, Marker# HC8"); } return SendReplyAndDie(CreateErrorReply(MSTATUS_ERROR, ctx), ctx); - } - } + } + } STFUNC(StateWaiting) { switch (ev->GetTypeRewrite()) { @@ -320,15 +320,15 @@ public: CFunc(TEvents::TSystem::Wakeup, HandleTimeout); } } -}; - +}; + IActor* CreateMessageBusHiveCreateTablet(TBusMessageContext &msg) { if (msg.GetMessage()->GetHeader()->Type == MTYPE_CLIENT_OLD_HIVE_CREATE_TABLET) { return new TMessageBusHiveCreateTablet<TBusHiveCreateTabletResult>(msg); } else { return new TMessageBusHiveCreateTablet<TBusResponse>(msg); } -} - -} -} +} + +} +} diff --git a/ydb/core/client/server/msgbus_server_ic_debug.cpp b/ydb/core/client/server/msgbus_server_ic_debug.cpp index 69759324f9..7757757fee 100644 --- a/ydb/core/client/server/msgbus_server_ic_debug.cpp +++ b/ydb/core/client/server/msgbus_server_ic_debug.cpp @@ -34,17 +34,17 @@ public: } else if (record.HasPoisonSessionNodeId()) { const ui32 nodeId = record.GetPoisonSessionNodeId(); Callback = [=](const TActorContext& ctx) { - ctx.Send(TActivationContext::InterconnectProxy(nodeId), new NActors::TEvInterconnect::TEvPoisonSession); + ctx.Send(TActivationContext::InterconnectProxy(nodeId), new NActors::TEvInterconnect::TEvPoisonSession); }; } else if (record.HasCloseInputSessionNodeId()) { const ui32 nodeId = record.GetCloseInputSessionNodeId(); Callback = [=](const TActorContext& ctx) { - ctx.Send(TActivationContext::InterconnectProxy(nodeId), new NActors::TEvInterconnect::TEvCloseInputSession); + ctx.Send(TActivationContext::InterconnectProxy(nodeId), new NActors::TEvInterconnect::TEvCloseInputSession); }; } else if (record.HasClosePeerSocketNodeId()) { const ui32 nodeId = record.GetClosePeerSocketNodeId(); Callback = [=](const TActorContext& ctx) { - ctx.Send(TActivationContext::InterconnectProxy(nodeId), new NActors::TEvInterconnect::TEvClosePeerSocket); + ctx.Send(TActivationContext::InterconnectProxy(nodeId), new NActors::TEvInterconnect::TEvClosePeerSocket); }; } else { NInterconnect::TLoadParams params; diff --git a/ydb/core/client/server/msgbus_server_keyvalue.cpp b/ydb/core/client/server/msgbus_server_keyvalue.cpp index 925ce5c0ea..ad644f4c26 100644 --- a/ydb/core/client/server/msgbus_server_keyvalue.cpp +++ b/ydb/core/client/server/msgbus_server_keyvalue.cpp @@ -1,9 +1,9 @@ -#include "msgbus_tabletreq.h" +#include "msgbus_tabletreq.h" #include <ydb/core/keyvalue/keyvalue_events.h> - -namespace NKikimr { -namespace NMsgBusProxy { - + +namespace NKikimr { +namespace NMsgBusProxy { + namespace { const ui32 DefaultTimeoutMs = 1000 * 90; // 90 seconds is a good default const ui64 MaxAllowedTimeoutMs = 1000 * 60 * 30; // 30 minutes is an instanely long request @@ -13,29 +13,29 @@ template <typename ResponseType> class TMessageBusKeyValue : public TMessageBusSimpleTabletRequest<TMessageBusKeyValue<ResponseType>, TEvKeyValue::TEvResponse, NKikimrServices::TActivity::FRONT_KV_REQUEST> { using TBase = TMessageBusSimpleTabletRequest<TMessageBusKeyValue<ResponseType>, TEvKeyValue::TEvResponse, NKikimrServices::TActivity::FRONT_KV_REQUEST>; -public: +public: NKikimrClient::TKeyValueRequest RequestProto; ui64 TabletId; TMessageBusKeyValue(TBusMessageContext &msg, ui64 tabletId, bool withRetry, TDuration timeout) - : TBase(msg, tabletId, withRetry, timeout, false) + : TBase(msg, tabletId, withRetry, timeout, false) , RequestProto(static_cast<TBusKeyValue *>(msg.GetMessage())->Record) , TabletId(tabletId) - {} - + {} + void Handle(TEvKeyValue::TEvResponse::TPtr &ev, const TActorContext &ctx) { TEvKeyValue::TEvResponse *msg = ev->Get(); TAutoPtr<ResponseType> response(new ResponseType()); CopyProtobufsByFieldName(response->Record, msg->Record); TBase::SendReplyAndDie(response.Release(), ctx); - } - + } + TEvKeyValue::TEvRequest* MakeReq(const TActorContext &ctx) { Y_UNUSED(ctx); THolder<TEvKeyValue::TEvRequest> request(new TEvKeyValue::TEvRequest()); request->Record = RequestProto; return request.Release(); - } + } NBus::TBusMessage* CreateErrorReply(EResponseStatus status, const TActorContext &ctx, const TString& text = TString()) override { @@ -55,11 +55,11 @@ public: } return response.Release(); } -}; - +}; + IActor* CreateMessageBusKeyValue(NKikimr::NMsgBusProxy::TBusMessageContext &msg) { auto &record = static_cast<TBusKeyValue *>(msg.GetMessage())->Record; - + const ui64 tabletId = record.GetTabletId(); const bool withRetry = true; TDuration timeout = TDuration::MilliSeconds(DefaultTimeoutMs); @@ -92,7 +92,7 @@ IActor* CreateMessageBusKeyValue(NKikimr::NMsgBusProxy::TBusMessageContext &msg) } else { return new TMessageBusKeyValue<TBusResponse>(msg, tabletId, withRetry, timeout); } -} - -} -} +} + +} +} diff --git a/ydb/core/client/server/msgbus_server_local_minikql.cpp b/ydb/core/client/server/msgbus_server_local_minikql.cpp index 198b76a61b..42fa4ed9a8 100644 --- a/ydb/core/client/server/msgbus_server_local_minikql.cpp +++ b/ydb/core/client/server/msgbus_server_local_minikql.cpp @@ -1,70 +1,70 @@ -#include "msgbus_tabletreq.h" +#include "msgbus_tabletreq.h" #include "msgbus_securereq.h" - -namespace NKikimr { -namespace NMsgBusProxy { - -namespace { - const ui64 DefaultTimeout = 90000; -} - + +namespace NKikimr { +namespace NMsgBusProxy { + +namespace { + const ui64 DefaultTimeout = 90000; +} + class TMessageBusLocalMKQL : public TMessageBusSecureRequest<TMessageBusSimpleTabletRequest<TMessageBusLocalMKQL, TEvTablet::TEvLocalMKQLResponse, NKikimrServices::TActivity::FRONT_LOCAL_MQKL>> { const NKikimrClient::TLocalMKQL Request; -public: +public: TMessageBusLocalMKQL(TBusMessageContext &msg, const NKikimrClient::TLocalMKQL &request, ui64 tabletId, bool withRetry, TDuration timeout, bool connectToFollower) : TMessageBusSecureRequest(msg, tabletId, withRetry, timeout, connectToFollower) - , Request(request) + , Request(request) { SetSecurityToken(static_cast<TBusTabletLocalMKQL*>(msg.GetMessage())->Record.GetSecurityToken()); SetRequireAdminAccess(true); } - - void Handle(TEvTablet::TEvLocalMKQLResponse::TPtr &ev, const TActorContext &ctx) { - const auto &record = ev->Get()->Record; - - const auto replyStatus = (record.GetStatus() == NKikimrProto::OK) ? MSTATUS_OK : MSTATUS_ERROR; - TAutoPtr<TBusResponse> response(new TBusResponseStatus(replyStatus)); - - response->Record.SetTabletId(TabletID); - if (record.HasExecutionEngineEvaluatedResponse()) - *response->Record.MutableExecutionEngineEvaluatedResponse() = record.GetExecutionEngineEvaluatedResponse(); - if (record.HasEngineStatus()) - response->Record.SetExecutionEngineStatus(record.GetEngineStatus()); - if (record.HasEngineResponseStatus()) - response->Record.SetExecutionEngineResponseStatus(record.GetEngineResponseStatus()); - - if (record.HasMiniKQLErrors()) - response->Record.SetMiniKQLErrors(record.GetMiniKQLErrors()); - - if (record.HasCompileResults()) - *response->Record.MutableMiniKQLCompileResults() = record.GetCompileResults(); - - return SendReplyAndDie(response.Release(), ctx); - } - - TEvTablet::TEvLocalMKQL* MakeReq(const TActorContext &ctx) { + + void Handle(TEvTablet::TEvLocalMKQLResponse::TPtr &ev, const TActorContext &ctx) { + const auto &record = ev->Get()->Record; + + const auto replyStatus = (record.GetStatus() == NKikimrProto::OK) ? MSTATUS_OK : MSTATUS_ERROR; + TAutoPtr<TBusResponse> response(new TBusResponseStatus(replyStatus)); + + response->Record.SetTabletId(TabletID); + if (record.HasExecutionEngineEvaluatedResponse()) + *response->Record.MutableExecutionEngineEvaluatedResponse() = record.GetExecutionEngineEvaluatedResponse(); + if (record.HasEngineStatus()) + response->Record.SetExecutionEngineStatus(record.GetEngineStatus()); + if (record.HasEngineResponseStatus()) + response->Record.SetExecutionEngineResponseStatus(record.GetEngineResponseStatus()); + + if (record.HasMiniKQLErrors()) + response->Record.SetMiniKQLErrors(record.GetMiniKQLErrors()); + + if (record.HasCompileResults()) + *response->Record.MutableMiniKQLCompileResults() = record.GetCompileResults(); + + return SendReplyAndDie(response.Release(), ctx); + } + + TEvTablet::TEvLocalMKQL* MakeReq(const TActorContext &ctx) { Y_UNUSED(ctx); - - TAutoPtr<TEvTablet::TEvLocalMKQL> req = new TEvTablet::TEvLocalMKQL(); - auto *pgm = req->Record.MutableProgram(); - *pgm = Request.GetProgram(); - - return req.Release(); - } -}; - -IActor* CreateMessageBusLocalMKQL(TBusMessageContext &msg) { - const auto &record = static_cast<TBusTabletLocalMKQL *>(msg.GetMessage())->Record; - - if (!record.HasProgram()) - return nullptr; - + + TAutoPtr<TEvTablet::TEvLocalMKQL> req = new TEvTablet::TEvLocalMKQL(); + auto *pgm = req->Record.MutableProgram(); + *pgm = Request.GetProgram(); + + return req.Release(); + } +}; + +IActor* CreateMessageBusLocalMKQL(TBusMessageContext &msg) { + const auto &record = static_cast<TBusTabletLocalMKQL *>(msg.GetMessage())->Record; + + if (!record.HasProgram()) + return nullptr; + const bool connectToFollower = record.HasConnectToFollower() ? record.GetConnectToFollower() : false; - const ui64 tabletId = record.GetTabletID(); - const bool withRetry = record.HasWithRetry() ? record.GetWithRetry() : false; - const TDuration timeout = TDuration::MilliSeconds(record.HasTimeout() ? record.GetTimeout() : DefaultTimeout); - + const ui64 tabletId = record.GetTabletID(); + const bool withRetry = record.HasWithRetry() ? record.GetWithRetry() : false; + const TDuration timeout = TDuration::MilliSeconds(record.HasTimeout() ? record.GetTimeout() : DefaultTimeout); + return new TMessageBusLocalMKQL(msg, record, tabletId, withRetry, timeout, connectToFollower); -} - -}} +} + +}} diff --git a/ydb/core/client/server/msgbus_server_proxy.cpp b/ydb/core/client/server/msgbus_server_proxy.cpp index f35687982a..7f3146d21a 100644 --- a/ydb/core/client/server/msgbus_server_proxy.cpp +++ b/ydb/core/client/server/msgbus_server_proxy.cpp @@ -1,4 +1,4 @@ -#include "msgbus_server.h" +#include "msgbus_server.h" #include "msgbus_server_request.h" #include "msgbus_server_proxy.h" #include "msgbus_securereq.h" @@ -15,15 +15,15 @@ #include <ydb/core/tx/schemeshard/schemeshard.h> #include <ydb/library/yql/public/issue/yql_issue_message.h> #include <ydb/library/yql/public/issue/yql_issue_manager.h> - -namespace NKikimr { -namespace NMsgBusProxy { - + +namespace NKikimr { +namespace NMsgBusProxy { + template <typename ResponseType> class TMessageBusServerFlatDescribeRequest : public TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusServerFlatDescribeRequest<ResponseType>>> { using TBase = TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusServerFlatDescribeRequest<ResponseType>>>; THolder<TBusSchemeDescribe> Request; - NYql::TIssueManager IssueManager; + NYql::TIssueManager IssueManager; void Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr& ev, const TActorContext& ctx) { auto &mutableRecord = *ev->Get()->MutableRecord(); @@ -34,26 +34,26 @@ class TMessageBusServerFlatDescribeRequest : public TMessageBusSecureRequest<TMe response->Record.SetStatus(MSTATUS_OK); response->Record.SetPath(mutableRecord.GetPath()); response->Record.MutablePathDescription()->Swap(mutableRecord.MutablePathDescription()); - response->Record.SetStatusCode(NKikimrIssues::TStatusIds::SUCCESS); + response->Record.SetStatusCode(NKikimrIssues::TStatusIds::SUCCESS); } else { response->Record.SetStatus(MSTATUS_ERROR); response->Record.SetErrorReason(mutableRecord.GetReason()); - - switch (status) { + + switch (status) { case NKikimrScheme::StatusPathDoesNotExist: - response->Record.SetStatusCode(NKikimrIssues::TStatusIds::PATH_NOT_EXIST); - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::PATH_NOT_EXIST)); - break; - default: - response->Record.SetStatusCode(NKikimrIssues::TStatusIds::ERROR); - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::DEFAULT_ERROR)); - break; - } + response->Record.SetStatusCode(NKikimrIssues::TStatusIds::PATH_NOT_EXIST); + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::PATH_NOT_EXIST)); + break; + default: + response->Record.SetStatusCode(NKikimrIssues::TStatusIds::ERROR); + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::DEFAULT_ERROR)); + break; + } } - - if (IssueManager.GetIssues()) - IssuesToMessage(IssueManager.GetIssues(), response->Record.MutableIssues()); - + + if (IssueManager.GetIssues()) + IssuesToMessage(IssueManager.GetIssues(), response->Record.MutableIssues()); + TBase::SendReplyAutoPtr(response); Request.Destroy(); this->Die(ctx); @@ -61,7 +61,7 @@ class TMessageBusServerFlatDescribeRequest : public TMessageBusSecureRequest<TMe public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::FRONT_SCHEME_DESCRIBE; } - + TMessageBusServerFlatDescribeRequest(TEvBusProxy::TEvFlatDescribeRequest* msg) : TBase(msg->MsgContext) , Request(static_cast<TBusSchemeDescribe*>(msg->MsgContext.ReleaseMessage())) @@ -105,17 +105,17 @@ IActor* CreateMessageBusServerProxy( std::shared_ptr<IPersQueueGetReadSessionsInfoWorkerFactory> pqReadSessionsInfoWorkerFactory ) { return new TMessageBusServerProxy(server, pqReadSessionsInfoWorkerFactory); -} - +} + TBusResponse* ProposeTransactionStatusToResponse(EResponseStatus status, - const NKikimrTxUserProxy::TEvProposeTransactionStatus &result) { + const NKikimrTxUserProxy::TEvProposeTransactionStatus &result) { TAutoPtr<TBusResponse> response(new TBusResponse()); response->Record.SetStatus(status); response->Record.SetProxyErrorCode(result.GetStatus()); - response->Record.SetStatusCode(result.GetStatusCode()); - response->Record.MutableIssues()->CopyFrom(result.GetIssues()); - + response->Record.SetStatusCode(result.GetStatusCode()); + response->Record.MutableIssues()->CopyFrom(result.GetIssues()); + if (result.HasExecutionEngineStatus()) response->Record.SetExecutionEngineStatus(result.GetExecutionEngineStatus()); if (result.HasExecutionEngineResponseStatus()) @@ -147,7 +147,7 @@ TBusResponse* ProposeTransactionStatusToResponse(EResponseStatus status, response->Record.MutableProxyTimings()->CopyFrom(result.GetTimings()); return response.Release(); -} +} //void TMessageBusServerProxy::Handle(TEvBusProxy::TEvRequest::TPtr& ev, const TActorContext& ctx); // see msgbus_server_request.cpp diff --git a/ydb/core/client/server/msgbus_server_request.cpp b/ydb/core/client/server/msgbus_server_request.cpp index cfdd592788..9223bea9f1 100644 --- a/ydb/core/client/server/msgbus_server_request.cpp +++ b/ydb/core/client/server/msgbus_server_request.cpp @@ -11,67 +11,67 @@ #include <ydb/library/yql/minikql/mkql_node_serialization.h> #include <ydb/library/yql/public/issue/yql_issue_message.h> - -namespace NKikimr { -namespace NMsgBusProxy { - + +namespace NKikimr { +namespace NMsgBusProxy { + class TMessageBusServerRequest : public TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusServerRequest>> { using TBase = TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusServerRequest>>; THolder<TBusRequest> Request; TVector<TString*> WriteResolvedKeysTo; TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> Proposal; TAutoPtr<NKikimrTxUserProxy::TEvProposeTransactionStatus> ProposalStatus; - + size_t InFlyRequests; THashMap<TString, ui64> CompileResolveCookies; TString TextProgramForCompilation; - bool CompilationRetried; - + bool CompilationRetried; + void ReplyWithResult(EResponseStatus status, NKikimrTxUserProxy::TEvProposeTransactionStatus &result, const TActorContext &ctx); - bool RetryResolve(const TActorContext &ctx); + bool RetryResolve(const TActorContext &ctx); void FinishReply(const TActorContext &ctx); void TryToAllocateQuota(const TActorContext &ctx); - + void Handle(TMiniKQLCompileServiceEvents::TEvCompileStatus::TPtr &ev, const TActorContext &ctx); - void Handle(TEvTxUserProxy::TEvProposeTransactionStatus::TPtr &ev, const TActorContext &ctx); + void Handle(TEvTxUserProxy::TEvProposeTransactionStatus::TPtr &ev, const TActorContext &ctx); void Handle(TEvDataShard::TEvGetReadTableStreamStateRequest::TPtr &ev, const TActorContext &ctx); bool AllRequestsCompleted(const TActorContext& ctx); bool AllRequestsCompletedMKQL(const TActorContext& ctx); bool AllRequestsCompletedReadTable(const TActorContext& ctx); -public: +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::FRONT_MKQL_REQUEST; - } - + } + TMessageBusServerRequest(TEvBusProxy::TEvRequest* msg) : TBase(msg->MsgContext) , Request(static_cast<TBusRequest*>(msg->MsgContext.ReleaseMessage())) , InFlyRequests(0) - , CompilationRetried(false) + , CompilationRetried(false) { TBase::SetSecurityToken(Request->Record.GetSecurityToken()); TBase::SetRequireAdminAccess(true); // MiniKQL and ReadTable execution required administative access } - + //STFUNC(StateWork) void StateWork(TAutoPtr<NActors::IEventHandle> &ev, const NActors::TActorContext &ctx) { - switch (ev->GetTypeRewrite()) { + switch (ev->GetTypeRewrite()) { HFunc(TMiniKQLCompileServiceEvents::TEvCompileStatus, Handle); - HFunc(TEvTxUserProxy::TEvProposeTransactionStatus, Handle); + HFunc(TEvTxUserProxy::TEvProposeTransactionStatus, Handle); HFunc(TEvDataShard::TEvGetReadTableStreamStateRequest, Handle); - } - } - + } + } + void Bootstrap(const TActorContext &ctx) { TBase::Become(&TMessageBusServerRequest::StateWork); ProposalStatus.Reset(new NKikimrTxUserProxy::TEvProposeTransactionStatus()); Proposal.Reset(new TEvTxUserProxy::TEvProposeTransaction()); NKikimrTxUserProxy::TEvProposeTransaction &record = Proposal->Record; - + // Transaction protobuf structure might be very heavy (if it has a batch of parameters) // so we don't want to copy it, just move its contents record.MutableTransaction()->Swap(Request->Record.MutableTransaction()); @@ -98,17 +98,17 @@ public: } if (mkqlTx.HasProgram() && mkqlTx.GetProgram().HasText()) { - TextProgramForCompilation = mkqlTx.GetProgram().GetText(); - const bool forceRefresh = (mkqlTx.GetMode() == NKikimrTxUserProxy::TMiniKQLTransaction::COMPILE); - auto* compEv = new TMiniKQLCompileServiceEvents::TEvCompile(TextProgramForCompilation); - compEv->ForceRefresh = forceRefresh; - + TextProgramForCompilation = mkqlTx.GetProgram().GetText(); + const bool forceRefresh = (mkqlTx.GetMode() == NKikimrTxUserProxy::TMiniKQLTransaction::COMPILE); + auto* compEv = new TMiniKQLCompileServiceEvents::TEvCompile(TextProgramForCompilation); + compEv->ForceRefresh = forceRefresh; + ctx.Send(GetMiniKQLCompileServiceID(), compEv); ++InFlyRequests; } if (mkqlTx.HasParams()) { if (mkqlTx.GetParams().HasText()) { - auto* compEv = new TMiniKQLCompileServiceEvents::TEvCompile(mkqlTx.GetParams().GetText()); + auto* compEv = new TMiniKQLCompileServiceEvents::TEvCompile(mkqlTx.GetParams().GetText()); ctx.Send(GetMiniKQLCompileServiceID(), compEv); // todo: handle undelivery (with warns atleast) ++InFlyRequests; } else @@ -141,26 +141,26 @@ public: } }; -bool TMessageBusServerRequest::RetryResolve(const TActorContext &ctx) { - if (CompilationRetried || !TextProgramForCompilation) - return false; - - auto *compEv = new TMiniKQLCompileServiceEvents::TEvCompile(TextProgramForCompilation); - compEv->ForceRefresh = false; - compEv->CompileResolveCookies = std::move(CompileResolveCookies); - ctx.Send(GetMiniKQLCompileServiceID(), compEv); - ++InFlyRequests; - - CompilationRetried = true; - return true; -} - +bool TMessageBusServerRequest::RetryResolve(const TActorContext &ctx) { + if (CompilationRetried || !TextProgramForCompilation) + return false; + + auto *compEv = new TMiniKQLCompileServiceEvents::TEvCompile(TextProgramForCompilation); + compEv->ForceRefresh = false; + compEv->CompileResolveCookies = std::move(CompileResolveCookies); + ctx.Send(GetMiniKQLCompileServiceID(), compEv); + ++InFlyRequests; + + CompilationRetried = true; + return true; +} + void TMessageBusServerRequest::ReplyWithResult(EResponseStatus status, NKikimrTxUserProxy::TEvProposeTransactionStatus &result, const TActorContext &ctx) { - TAutoPtr<TBusResponse> response(ProposeTransactionStatusToResponse(status, result)); - + TAutoPtr<TBusResponse> response(ProposeTransactionStatusToResponse(status, result)); + if (result.HasExecutionEngineEvaluatedResponse()) { response->Record.MutableExecutionEngineEvaluatedResponse()->Swap(result.MutableExecutionEngineEvaluatedResponse()); } @@ -170,7 +170,7 @@ void TMessageBusServerRequest::ReplyWithResult(EResponseStatus status, if (result.HasStatus()) { response->Record.SetProxyErrorCode(result.GetStatus()); } - + if (result.HasTxStats()) { response->Record.MutableTxStats()->Swap(result.MutableTxStats()); } @@ -186,20 +186,20 @@ void TMessageBusServerRequest::FinishReply(const TActorContext &ctx) AsyncDestroy(Proposal, ctx, AppData(ctx)->UserPoolId); Die(ctx); -} - +} + void TMessageBusServerRequest::Handle(TMiniKQLCompileServiceEvents::TEvCompileStatus::TPtr &ev, const TActorContext &ctx) { auto* mkqlTx = Proposal->Record.MutableTransaction()->MutableMiniKQLTransaction(); const auto& result = ev->Get()->Result; - const bool need2CompileProgram = (bool)TextProgramForCompilation; + const bool need2CompileProgram = (bool)TextProgramForCompilation; const bool need2CompileParams = mkqlTx->HasParams() && mkqlTx->GetParams().HasText(); const TString& pgm = ev->Get()->Program; - Y_VERIFY((need2CompileProgram && TextProgramForCompilation == pgm) // TODO: do not check texts, trust cookies + Y_VERIFY((need2CompileProgram && TextProgramForCompilation == pgm) // TODO: do not check texts, trust cookies || (need2CompileParams && mkqlTx->GetParams().GetText() == pgm)); - if (need2CompileProgram && TextProgramForCompilation == pgm) { + if (need2CompileProgram && TextProgramForCompilation == pgm) { auto* compileResults = ProposalStatus->MutableMiniKQLCompileResults(); auto* pgm = mkqlTx->MutableProgram(); if (result.Errors.Empty()) { @@ -210,7 +210,7 @@ void TMessageBusServerRequest::Handle(TMiniKQLCompileServiceEvents::TEvCompileSt NYql::IssuesToMessage(result.Errors, compileResults->MutableProgramCompileErrors()); } --InFlyRequests; - CompileResolveCookies = std::move(ev->Get()->CompileResolveCookies); + CompileResolveCookies = std::move(ev->Get()->CompileResolveCookies); } if (need2CompileParams && mkqlTx->GetParams().GetText() == pgm) { @@ -261,8 +261,8 @@ bool TMessageBusServerRequest::AllRequestsCompletedMKQL(const TActorContext& ctx switch (mkqlTx->GetMode()) { case NKikimrTxUserProxy::TMiniKQLTransaction::COMPILE_AND_EXEC: { - TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> ev = new TEvTxUserProxy::TEvProposeTransaction(); - ev->Record.CopyFrom(Proposal->Record); + TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> ev = new TEvTxUserProxy::TEvProposeTransaction(); + ev->Record.CopyFrom(Proposal->Record); ctx.Send(MakeTxProxyID(), ev.Release()); return true; } @@ -275,56 +275,56 @@ bool TMessageBusServerRequest::AllRequestsCompletedMKQL(const TActorContext& ctx } } -void TMessageBusServerRequest::Handle(TEvTxUserProxy::TEvProposeTransactionStatus::TPtr &ev, const TActorContext &ctx) { - TEvTxUserProxy::TEvProposeTransactionStatus *msg = ev->Get(); - - const TEvTxUserProxy::TEvProposeTransactionStatus::EStatus status = static_cast<TEvTxUserProxy::TEvProposeTransactionStatus::EStatus>(msg->Record.GetStatus()); - switch (status) { - case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyAccepted: - case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyResolved: - case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyPrepared: - case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorPlanned: - // transitional statuses - return; - case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecComplete: - case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecAlready: - // completion +void TMessageBusServerRequest::Handle(TEvTxUserProxy::TEvProposeTransactionStatus::TPtr &ev, const TActorContext &ctx) { + TEvTxUserProxy::TEvProposeTransactionStatus *msg = ev->Get(); + + const TEvTxUserProxy::TEvProposeTransactionStatus::EStatus status = static_cast<TEvTxUserProxy::TEvProposeTransactionStatus::EStatus>(msg->Record.GetStatus()); + switch (status) { + case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyAccepted: + case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyResolved: + case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyPrepared: + case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorPlanned: + // transitional statuses + return; + case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecComplete: + case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecAlready: + // completion return ReplyWithResult(MSTATUS_OK, msg->Record, ctx); - case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecTimeout: - return ReplyWithResult(MSTATUS_INPROGRESS, msg->Record, ctx); + case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecTimeout: + return ReplyWithResult(MSTATUS_INPROGRESS, msg->Record, ctx); case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyNotReady: - return HandleError(MSTATUS_NOTREADY, status, ctx); + return HandleError(MSTATUS_NOTREADY, status, ctx); case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecAborted: - return HandleError(MSTATUS_ABORTED, status, ctx); - case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::EmptyAffectedSet: + return HandleError(MSTATUS_ABORTED, status, ctx); + case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::EmptyAffectedSet: case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecError: case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::AccessDenied: case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::DomainLocalityError: case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecResultUnavailable: case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecCancelled: case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest: - return ReplyWithResult(MSTATUS_ERROR, msg->Record, ctx); - case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError: - if (!RetryResolve(ctx)) - ReplyWithResult(MSTATUS_ERROR, msg->Record, ctx); - return; - case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardNotAvailable: + return ReplyWithResult(MSTATUS_ERROR, msg->Record, ctx); + case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError: + if (!RetryResolve(ctx)) + ReplyWithResult(MSTATUS_ERROR, msg->Record, ctx); + return; + case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardNotAvailable: if (!RetryResolve(ctx)) // TODO: retry if partitioning changed due to split/merge - ReplyWithResult(MSTATUS_REJECTED, msg->Record, ctx); - return; - case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardUnknown: - return ReplyWithResult(MSTATUS_TIMEOUT, msg->Record, ctx); - case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardTryLater: - case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardOverloaded: - case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorDeclined: - case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorAborted: - case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorOutdated: - return ReplyWithResult(MSTATUS_REJECTED, msg->Record, ctx); - default: - return ReplyWithResult(MSTATUS_INTERNALERROR, msg->Record, ctx); - } -} - + ReplyWithResult(MSTATUS_REJECTED, msg->Record, ctx); + return; + case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardUnknown: + return ReplyWithResult(MSTATUS_TIMEOUT, msg->Record, ctx); + case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardTryLater: + case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardOverloaded: + case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorDeclined: + case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorAborted: + case TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorOutdated: + return ReplyWithResult(MSTATUS_REJECTED, msg->Record, ctx); + default: + return ReplyWithResult(MSTATUS_INTERNALERROR, msg->Record, ctx); + } +} + void TMessageBusServerRequest::Handle(TEvDataShard::TEvGetReadTableStreamStateRequest::TPtr &ev, const TActorContext &ctx) { auto *response = new TEvDataShard::TEvGetReadTableStreamStateResponse; @@ -337,7 +337,7 @@ void TMessageBusServerRequest::Handle(TEvDataShard::TEvGetReadTableStreamStateRe void TMessageBusServerProxy::Handle(TEvBusProxy::TEvRequest::TPtr& ev, const TActorContext& ctx) { ctx.Register(new TMessageBusServerRequest(ev->Get())); -} +} } } diff --git a/ydb/core/client/server/msgbus_server_scheme_initroot.cpp b/ydb/core/client/server/msgbus_server_scheme_initroot.cpp index a1f9575161..a8538eea1c 100644 --- a/ydb/core/client/server/msgbus_server_scheme_initroot.cpp +++ b/ydb/core/client/server/msgbus_server_scheme_initroot.cpp @@ -7,10 +7,10 @@ #include <ydb/core/base/appdata.h> #include <ydb/core/base/tablet_pipe.h> #include <ydb/core/base/ticket_parser.h> - -namespace NKikimr { -namespace NMsgBusProxy { - + +namespace NKikimr { +namespace NMsgBusProxy { + using namespace NSchemeShard; class TMessageBusSchemeInitRoot : public TMessageBusSecureRequest<TMessageBusServerRequestBase<TMessageBusSchemeInitRoot>> { @@ -28,17 +28,17 @@ class TMessageBusSchemeInitRoot : public TMessageBusSecureRequest<TMessageBusSer } void Handle(TEvSchemeShard::TEvInitRootShardResult::TPtr& ev, const TActorContext& ctx) { - const NKikimrTxScheme::TEvInitRootShardResult &record = ev->Get()->Record; + const NKikimrTxScheme::TEvInitRootShardResult &record = ev->Get()->Record; const auto status = (TEvSchemeShard::TEvInitRootShardResult::EStatus)record.GetStatus(); - switch (status) { + switch (status) { case TEvSchemeShard::TEvInitRootShardResult::StatusSuccess: case TEvSchemeShard::TEvInitRootShardResult::StatusAlreadyInitialized: return ReplyWithResult(MSTATUS_OK, status, ctx); - default: + default: return ReplyWithResult(MSTATUS_ERROR, status, ctx); - } - } - + } + } + void Die(const TActorContext &ctx) override { if (PipeClient) { NTabletPipe::CloseClient(ctx, PipeClient); @@ -88,12 +88,12 @@ public: ReplyWithResult(MSTATUS_ERROR, TEvSchemeShard::TEvInitRootShardResult::StatusBadArgument, ctx); } } -}; - +}; + void TMessageBusServerProxy::Handle(TEvBusProxy::TEvInitRoot::TPtr& ev, const TActorContext& ctx) { TEvBusProxy::TEvInitRoot *msg = ev->Get(); ctx.Register(new TMessageBusSchemeInitRoot(msg)); -} - -} -} +} + +} +} diff --git a/ydb/core/client/server/msgbus_server_scheme_request.cpp b/ydb/core/client/server/msgbus_server_scheme_request.cpp index b8d2894b95..7df5e262d0 100644 --- a/ydb/core/client/server/msgbus_server_scheme_request.cpp +++ b/ydb/core/client/server/msgbus_server_scheme_request.cpp @@ -66,7 +66,7 @@ class TMessageBusServerSchemeRequest : public TMessageBusSecureRequest<TMessageB public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::FRONT_SCHEME_REQUEST; } - + template <TEvBusProxy::EEv EvId> TMessageBusServerSchemeRequest(TEvBusProxy::TEvMsgBusRequest<EvId>* msg) : TBase(msg->MsgContext) @@ -158,14 +158,14 @@ void TMessageBusServerSchemeRequest<TBusSchemeOperation>::SendProposeRequest(con TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> req(new TEvTxUserProxy::TEvProposeTransaction()); NKikimrTxUserProxy::TEvProposeTransaction &record = req->Record; - if (!Request->Record.HasTransaction()) { + if (!Request->Record.HasTransaction()) { return HandleError(MSTATUS_ERROR, TEvTxUserProxy::TResultStatus::Unknown, "Malformed request: no modify scheme transaction provided", ctx); - } + } - if (!Request->Record.GetTransaction().HasModifyScheme()) { + if (!Request->Record.GetTransaction().HasModifyScheme()) { return HandleError(MSTATUS_ERROR, TEvTxUserProxy::TResultStatus::Unknown, "Malformed request: no modify scheme request body provided", ctx); - } - + } + bool needAdminCheck = false; switch (Request->Record.GetTransaction().GetModifyScheme().GetOperationType()) { case NKikimrSchemeOp::ESchemeOpSplitMergeTablePartitions: diff --git a/ydb/core/client/server/msgbus_server_tablet_kill.cpp b/ydb/core/client/server/msgbus_server_tablet_kill.cpp index 4dca5bc5f5..62da8569e2 100644 --- a/ydb/core/client/server/msgbus_server_tablet_kill.cpp +++ b/ydb/core/client/server/msgbus_server_tablet_kill.cpp @@ -7,7 +7,7 @@ namespace NMsgBusProxy { class TMessageBusTabletKillRequest : public TMessageBusSimpleTabletRequest<TMessageBusTabletKillRequest, TEvTablet::TEvTabletDead, NKikimrServices::TActivity::FRONT_POISON_TABLET> { public: TMessageBusTabletKillRequest(TBusMessageContext &msg) - : TMessageBusSimpleTabletRequest(msg, static_cast<TBusTabletKillRequest*>(msg.GetMessage())->Record.GetTabletID(), false, TDuration::Seconds(60), false) + : TMessageBusSimpleTabletRequest(msg, static_cast<TBusTabletKillRequest*>(msg.GetMessage())->Record.GetTabletID(), false, TDuration::Seconds(60), false) {} TEvents::TEvPoisonPill* MakeReq(const TActorContext &ctx) { diff --git a/ydb/core/client/server/msgbus_server_tracer.cpp b/ydb/core/client/server/msgbus_server_tracer.cpp index 4b0f57f2f4..ff93f8d1cb 100644 --- a/ydb/core/client/server/msgbus_server_tracer.cpp +++ b/ydb/core/client/server/msgbus_server_tracer.cpp @@ -151,7 +151,7 @@ namespace { const ui32 DefaultTimeout = 90000; } -template <typename TDerived> +template <typename TDerived> class TMessageBusTraceSimpleActor : public NMsgBusProxy::TMessageBusLocalServiceRequest<TDerived, NKikimrServices::TActivity::MSGBUS_TRACER_ACTOR> { public: TMessageBusTraceSimpleActor(NMsgBusProxy::TBusMessageContext &msg) diff --git a/ydb/core/client/server/msgbus_servicereq.h b/ydb/core/client/server/msgbus_servicereq.h index 49ae7d1738..704a231dd1 100644 --- a/ydb/core/client/server/msgbus_servicereq.h +++ b/ydb/core/client/server/msgbus_servicereq.h @@ -51,8 +51,8 @@ public: } static constexpr auto ActorActivityType() { - return Activity; - } + return Activity; + } }; } diff --git a/ydb/core/client/server/msgbus_tabletreq.h b/ydb/core/client/server/msgbus_tabletreq.h index 21b4c76fef..f173ae9097 100644 --- a/ydb/core/client/server/msgbus_tabletreq.h +++ b/ydb/core/client/server/msgbus_tabletreq.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "msgbus_server.h" #include <ydb/public/lib/base/msgbus.h> #include <ydb/core/base/tablet.h> @@ -9,136 +9,136 @@ #include <ydb/core/protos/services.pb.h> #include <util/generic/hash_set.h> #include <util/generic/vector.h> - + #define CHECK_PROTOBUF_FIELD_PRESENCE(pb, field, errslist) \ if (!pb.Has##field()) { \ errslist.push_back( #field );\ } -namespace NKikimr { -namespace NMsgBusProxy { - -template<typename TDerived, typename TTabletReplyEvent> +namespace NKikimr { +namespace NMsgBusProxy { + +template<typename TDerived, typename TTabletReplyEvent> class TMessageBusTabletRequest : public TActorBootstrapped<TDerived>, public TMessageBusSessionIdentHolder { - -protected: - const TDuration Timeout; - const bool WithRetry; + +protected: + const TDuration Timeout; + const bool WithRetry; const bool ConnectToFollower; - -private: + +private: TActorId PipeClient; ui64 TabletId = 0; - - void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx) { - TEvTabletPipe::TEvClientConnected *msg = ev->Get(); - if (msg->Status != NKikimrProto::OK) { + + void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx) { + TEvTabletPipe::TEvClientConnected *msg = ev->Get(); + if (msg->Status != NKikimrProto::OK) { PipeClient = TActorId(); return SendReplyAndDie(CreateErrorReply(MSTATUS_ERROR, ctx, - Sprintf("Tablet pipe client connected with status# %s for tablet %" PRIu64 " Marker# MBT3", + Sprintf("Tablet pipe client connected with status# %s for tablet %" PRIu64 " Marker# MBT3", NKikimrProto::EReplyStatus_Name(msg->Status).data(), msg->TabletId)), ctx); - } - } - - void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx) { + } + } + + void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx) { Y_UNUSED(ev); PipeClient = TActorId(); SendReplyMove(CreateErrorReply(MSTATUS_ERROR, ctx, "Tablet pipe client destroyed Marker# MBT2")); return Die(ctx); - } - - void HandleTimeout(const TActorContext &ctx) { + } + + void HandleTimeout(const TActorContext &ctx) { return SendReplyAndDie(CreateErrorReply(MSTATUS_TIMEOUT, ctx, "Tablet request timed out Marker# MBT4"), ctx); - } -protected: - void Die(const TActorContext &ctx) override { - if (PipeClient) { - NTabletPipe::CloseClient(ctx, PipeClient); + } +protected: + void Die(const TActorContext &ctx) override { + if (PipeClient) { + NTabletPipe::CloseClient(ctx, PipeClient); PipeClient = TActorId(); - } - TActorBootstrapped<TDerived>::Die(ctx); - } - + } + TActorBootstrapped<TDerived>::Die(ctx); + } + virtual NBus::TBusMessage* CreateErrorReply(EResponseStatus status, const TActorContext &ctx, const TString& text = TString()) { LOG_ERROR_S(ctx, NKikimrServices::MSGBUS_REQUEST, "TabletRequest TabletId# " << TabletId << " status# " << status << " text# \"" << text << "\"" << Endl); return new TBusResponseStatus(status, text); - } - - void SendReplyAndDie(NBus::TBusMessage *reply, const TActorContext &ctx) { + } + + void SendReplyAndDie(NBus::TBusMessage *reply, const TActorContext &ctx) { SendReplyMove(reply); - return Die(ctx); - } - + return Die(ctx); + } + TMessageBusTabletRequest(TBusMessageContext &msg, bool withRetry, TDuration timeout, bool connectToFollower) : TMessageBusSessionIdentHolder(msg) - , Timeout(timeout) - , WithRetry(withRetry) + , Timeout(timeout) + , WithRetry(withRetry) , ConnectToFollower(connectToFollower) - { - } - -public: + { + } + +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::MSGBUS_COMMON; } - void Bootstrap(const TActorContext &ctx) { - NTabletPipe::TClientConfig clientConfig; - if (WithRetry) { + void Bootstrap(const TActorContext &ctx) { + NTabletPipe::TClientConfig clientConfig; + if (WithRetry) { clientConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries(); - } - + } + if (ConnectToFollower) { clientConfig.AllowFollower = true; clientConfig.ForceFollower = true; - } - + } + std::pair<ui64, TAutoPtr<IEventBase>> reqPair = static_cast<TDerived *>(this)->MakeReqPair(ctx); TabletId = reqPair.first; - - if (reqPair.first) { + + if (reqPair.first) { PipeClient = ctx.RegisterWithSameMailbox(NTabletPipe::CreateClient(ctx.SelfID, reqPair.first, clientConfig)); - NTabletPipe::SendData(ctx, PipeClient, reqPair.second.Release()); - - this->Become(&TDerived::StateFunc, ctx, Timeout, new TEvents::TEvWakeup()); - } else { + NTabletPipe::SendData(ctx, PipeClient, reqPair.second.Release()); + + this->Become(&TDerived::StateFunc, ctx, Timeout, new TEvents::TEvWakeup()); + } else { return SendReplyAndDie(CreateErrorReply(MSTATUS_ERROR, ctx, "Unable to obtain TabletId Marker# MBT1"), ctx); - } - } - - STFUNC(StateFunc) { - switch (ev->GetTypeRewrite()) { - HTemplFunc(TTabletReplyEvent, static_cast<TDerived *>(this)->Handle); - HFunc(TEvTabletPipe::TEvClientDestroyed, Handle); - HFunc(TEvTabletPipe::TEvClientConnected, Handle); - CFunc(TEvents::TSystem::Wakeup, HandleTimeout); - } - } -}; - + } + } + + STFUNC(StateFunc) { + switch (ev->GetTypeRewrite()) { + HTemplFunc(TTabletReplyEvent, static_cast<TDerived *>(this)->Handle); + HFunc(TEvTabletPipe::TEvClientDestroyed, Handle); + HFunc(TEvTabletPipe::TEvClientConnected, Handle); + CFunc(TEvents::TSystem::Wakeup, HandleTimeout); + } + } +}; + template<typename TDerived, typename TTabletReplyEvent, NKikimrServices::TActivity::EType Activity> -class TMessageBusSimpleTabletRequest : public TMessageBusTabletRequest<TDerived, TTabletReplyEvent> { -protected: - const ui64 TabletID; +class TMessageBusSimpleTabletRequest : public TMessageBusTabletRequest<TDerived, TTabletReplyEvent> { +protected: + const ui64 TabletID; TMessageBusSimpleTabletRequest(TBusMessageContext &msg, ui64 tabletId, bool withRetry, TDuration timeout, bool connectToFollower) : TMessageBusTabletRequest<TDerived, TTabletReplyEvent>(msg, withRetry, timeout, connectToFollower) - , TabletID(tabletId) - {} - -public: + , TabletID(tabletId) + {} + +public: std::pair<ui64, TAutoPtr<IEventBase>> MakeReqPair(const TActorContext &ctx) { return std::pair<ui64, TAutoPtr<IEventBase>>(TabletID, static_cast<TDerived *>(this)->MakeReq(ctx)); - } - + } + static constexpr auto ActorActivityType() { - return Activity; - } -}; - + return Activity; + } +}; + -} -} +} +} diff --git a/ydb/core/client/server/ya.make b/ydb/core/client/server/ya.make index 6e73ee7a06..8cbeec21b7 100644 --- a/ydb/core/client/server/ya.make +++ b/ydb/core/client/server/ya.make @@ -36,7 +36,7 @@ SRCS( msgbus_server_ic_debug.cpp msgbus_server_load.cpp msgbus_server_local_enumerate_tablets.cpp - msgbus_server_local_minikql.cpp + msgbus_server_local_minikql.cpp msgbus_server_local_scheme_tx.cpp msgbus_server_node_registration.cpp msgbus_server_proxy.cpp diff --git a/ydb/core/client/ya.make b/ydb/core/client/ya.make index ff68c7c55d..cd39222ad1 100644 --- a/ydb/core/client/ya.make +++ b/ydb/core/client/ya.make @@ -1,11 +1,11 @@ -LIBRARY() - +LIBRARY() + OWNER( ddoarn g:kikimr ) - -PEERDIR( + +PEERDIR( library/cpp/grpc/server ydb/core/base ydb/core/client/scheme_cache_lib diff --git a/ydb/core/cms/cluster_info.cpp b/ydb/core/cms/cluster_info.cpp index 4a8681f767..a1dc8a0b95 100644 --- a/ydb/core/cms/cluster_info.cpp +++ b/ydb/core/cms/cluster_info.cpp @@ -4,13 +4,13 @@ #include <util/string/builder.h> #include <util/system/hostname.h> -#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR -#error log macro definition clash -#endif - -#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::CMS, stream) -#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::CMS, stream) - +#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR +#error log macro definition clash +#endif + +#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::CMS, stream) +#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::CMS, stream) + namespace NKikimr { namespace NCms { @@ -436,7 +436,7 @@ void TClusterInfo::AddPDisk(const NKikimrBlobStorage::TBaseConfig::TPDisk &info) void TClusterInfo::UpdatePDiskState(const TPDiskID &id, const NKikimrWhiteboard::TPDiskStateInfo &info) { if (!HasPDisk(id)) { - BLOG_ERROR("Cannot update state for unknown PDisk " << id.ToString()); + BLOG_ERROR("Cannot update state for unknown PDisk " << id.ToString()); return; } @@ -449,7 +449,7 @@ void TClusterInfo::AddVDisk(const NKikimrBlobStorage::TBaseConfig::TVSlot &info) ui32 nodeId = info.GetVSlotId().GetNodeId(); Y_VERIFY_DEBUG(HasNode(nodeId)); if (!HasNode(nodeId)) { - BLOG_ERROR("Got VDisk info from BSC base config for unknown node " << nodeId); + BLOG_ERROR("Got VDisk info from BSC base config for unknown node " << nodeId); return; } @@ -469,7 +469,7 @@ void TClusterInfo::AddVDisk(const NKikimrBlobStorage::TBaseConfig::TVSlot &info) Y_VERIFY_DEBUG(HasPDisk(vdisk->PDiskId)); if (!HasPDisk(vdisk->PDiskId)) { - BLOG_ERROR("Got VDisk info from BSC base config for unknown PDisk " << vdisk->PDiskId.ToString()); + BLOG_ERROR("Got VDisk info from BSC base config for unknown PDisk " << vdisk->PDiskId.ToString()); PDisks.emplace(vdisk->PDiskId, new TPDiskInfo(vdisk->PDiskId)); } @@ -492,7 +492,7 @@ void TClusterInfo::UpdateVDiskState(const TVDiskID &id, const NKikimrWhiteboard: return; } - BLOG_ERROR("Cannot update state for unknown VDisk " << id.ToString()); + BLOG_ERROR("Cannot update state for unknown VDisk " << id.ToString()); return; } @@ -513,14 +513,14 @@ void TClusterInfo::AddBSGroup(const NKikimrBlobStorage::TBaseConfig::TGroup &inf TPDiskID pdiskId = {vdisk.GetNodeId(), vdisk.GetPDiskId()}; Y_VERIFY_DEBUG(HasPDisk(pdiskId)); if (!HasPDisk(pdiskId)) { - BLOG_ERROR("Group " << bsgroup.GroupId << " refers unknown pdisk " << pdiskId.ToString()); + BLOG_ERROR("Group " << bsgroup.GroupId << " refers unknown pdisk " << pdiskId.ToString()); return; } auto &pdisk = PDiskRef(pdiskId); Y_VERIFY_DEBUG(pdisk.VSlots.contains(vdisk.GetVSlotId())); if (!pdisk.VSlots.contains(vdisk.GetVSlotId())) { - BLOG_ERROR("Group " << bsgroup.GroupId << " refers unknown slot " << + BLOG_ERROR("Group " << bsgroup.GroupId << " refers unknown slot " << vdisk.GetVSlotId() << " in disk " << pdiskId.ToString()); return; } diff --git a/ydb/core/cms/console/configs_dispatcher.cpp b/ydb/core/cms/console/configs_dispatcher.cpp index a4d86176d5..8e50754239 100644 --- a/ydb/core/cms/console/configs_dispatcher.cpp +++ b/ydb/core/cms/console/configs_dispatcher.cpp @@ -14,17 +14,17 @@ #include <util/generic/ptr.h> #include <util/string/join.h> -#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR || defined BLOG_TRACE -#error log macro definition clash -#endif - -#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::CONFIGS_DISPATCHER, stream) +#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR || defined BLOG_TRACE +#error log macro definition clash +#endif + +#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::CONFIGS_DISPATCHER, stream) #define BLOG_N(stream) LOG_NOTICE_S(*TlsActivationContext, NKikimrServices::CONFIGS_DISPATCHER, stream) -#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::CONFIGS_DISPATCHER, stream) +#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::CONFIGS_DISPATCHER, stream) #define BLOG_W(stream) LOG_WARN_S(*TlsActivationContext, NKikimrServices::CONFIGS_DISPATCHER, stream) -#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::CONFIGS_DISPATCHER, stream) -#define BLOG_TRACE(stream) LOG_TRACE_S(*TlsActivationContext, NKikimrServices::CONFIGS_DISPATCHER, stream) - +#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::CONFIGS_DISPATCHER, stream) +#define BLOG_TRACE(stream) LOG_TRACE_S(*TlsActivationContext, NKikimrServices::CONFIGS_DISPATCHER, stream) + namespace NKikimr { namespace NConsole { @@ -84,10 +84,10 @@ public: TConfigsDispatcher(const NKikimrConfig::TAppConfig &config); - void Bootstrap(); + void Bootstrap(); - void EnqueueEvent(TAutoPtr<IEventHandle> &ev); - void ProcessEnqueuedEvents(); + void EnqueueEvent(TAutoPtr<IEventHandle> &ev); + void ProcessEnqueuedEvents(); TDynBitMap KindsToBitMap(const TVector<ui32> &kinds) const; TString KindsToString(const TDynBitMap &kinds) const; @@ -98,8 +98,8 @@ public: * another protobuf. It's assumed that source config doesn't * have fields not listed in kinds. */ - void ReplaceConfigItems(const NKikimrConfig::TAppConfig &from, NKikimrConfig::TAppConfig &to, const TDynBitMap &kinds) const; - bool CompareConfigs(const NKikimrConfig::TAppConfig &lhs, const NKikimrConfig::TAppConfig &rhs); + void ReplaceConfigItems(const NKikimrConfig::TAppConfig &from, NKikimrConfig::TAppConfig &to, const TDynBitMap &kinds) const; + bool CompareConfigs(const NKikimrConfig::TAppConfig &lhs, const NKikimrConfig::TAppConfig &rhs); TSubscription::TPtr FindSubscription(ui64 id); TSubscription::TPtr FindSubscription(const TDynBitMap &kinds); @@ -108,28 +108,28 @@ public: void SendNotificationResponse(TEvConsole::TEvConfigNotificationRequest::TPtr &ev); - void MaybeSendNotificationResponse(TSubscription::TPtr subscription); + void MaybeSendNotificationResponse(TSubscription::TPtr subscription); - void CreateSubscriberActor(ui32 kind, bool replace); - void CreateSubscriberActor(const TDynBitMap &kinds, bool replace); + void CreateSubscriberActor(ui32 kind, bool replace); + void CreateSubscriberActor(const TDynBitMap &kinds, bool replace); /** * Send config notification to a subscriber. Called for subscriptions * having config update being processed. */ - + void SendUpdateToSubscriber(TSubscription::TPtr subscription, TActorId subscriber); /** * Remove subscriber and all his subscriptions. */ - void RemoveSubscriber(TSubscriber::TPtr subscriber); - + void RemoveSubscriber(TSubscriber::TPtr subscriber); + /** * Remove subscription from own data and CMS. It should be called * for confirmed CMS subscriptions which have no more local * subscribers. */ - void RemoveSubscription(TSubscription::TPtr subscription); - + void RemoveSubscription(TSubscription::TPtr subscription); + /** * Create subscription for subscriber. If subscription with similar * config kinds already exists then just re-use it. Otherwise @@ -137,48 +137,48 @@ public: * then deliver it to the new subscriber. */ void AddSubscription(TActorId subscriber, const TDynBitMap &kinds, bool replace); - + /** * This is called on start and on tenant change to clean up old config * subscriptions. It also adds subscription for own config. */ - void CleanUpSubscriptions(); + void CleanUpSubscriptions(); /** * Process successfull subscription registration in CMS. Send * corresponsing notifications to subscribers. If no more subscribers * left for this subscription then remove it. */ - - void ProcessAddedSubscription(TSubscription::TPtr subscription, ui64 id); - + + void ProcessAddedSubscription(TSubscription::TPtr subscription, ui64 id); + /** * This method is used to process notifications sent to self. */ - void ProcessLocalCacheUpdate(TEvConsole::TEvConfigNotificationRequest::TPtr &ev); - - void Handle(NMon::TEvHttpInfo::TPtr &ev); - void Handle(TEvConfigsDispatcher::TEvGetConfigRequest::TPtr &ev); - void Handle(TEvConfigsDispatcher::TEvSetConfigSubscriptionRequest::TPtr &ev); - void Handle(TEvConsole::TEvAddConfigSubscriptionResponse::TPtr &ev); - void Handle(TEvConsole::TEvConfigNotificationResponse::TPtr &ev); - void Handle(TEvConsole::TEvConfigNotificationRequest::TPtr &ev); - void Handle(TEvConsole::TEvGetNodeConfigResponse::TPtr &ev); - void Handle(TEvConsole::TEvReplaceConfigSubscriptionsResponse::TPtr &ev); - void Handle(TEvTenantPool::TEvTenantPoolStatus::TPtr &ev); + void ProcessLocalCacheUpdate(TEvConsole::TEvConfigNotificationRequest::TPtr &ev); + + void Handle(NMon::TEvHttpInfo::TPtr &ev); + void Handle(TEvConfigsDispatcher::TEvGetConfigRequest::TPtr &ev); + void Handle(TEvConfigsDispatcher::TEvSetConfigSubscriptionRequest::TPtr &ev); + void Handle(TEvConsole::TEvAddConfigSubscriptionResponse::TPtr &ev); + void Handle(TEvConsole::TEvConfigNotificationResponse::TPtr &ev); + void Handle(TEvConsole::TEvConfigNotificationRequest::TPtr &ev); + void Handle(TEvConsole::TEvGetNodeConfigResponse::TPtr &ev); + void Handle(TEvConsole::TEvReplaceConfigSubscriptionsResponse::TPtr &ev); + void Handle(TEvTenantPool::TEvTenantPoolStatus::TPtr &ev); /** * Initial state when we just get status from tenant pool to collect assigned * tenants. It's possible we start before tenant pool and therefore might have * to retry request. */ - STATEFN(StateInit) { + STATEFN(StateInit) { TRACE_EVENT(NKikimrServices::CONFIGS_DISPATCHER); switch (ev->GetTypeRewrite()) { - hFuncTraced(NMon::TEvHttpInfo, Handle); - hFuncTraced(TEvTenantPool::TEvTenantPoolStatus, Handle); + hFuncTraced(NMon::TEvHttpInfo, Handle); + hFuncTraced(TEvTenantPool::TEvTenantPoolStatus, Handle); default: - EnqueueEvent(ev); + EnqueueEvent(ev); break; } } @@ -187,14 +187,14 @@ public: * In this state we remove all old service subscriptions and install a new * one for own config. */ - STATEFN(StateConfigure) { + STATEFN(StateConfigure) { TRACE_EVENT(NKikimrServices::CONFIGS_DISPATCHER); switch (ev->GetTypeRewrite()) { - hFuncTraced(NMon::TEvHttpInfo, Handle); - hFuncTraced(TEvConsole::TEvReplaceConfigSubscriptionsResponse, Handle); + hFuncTraced(NMon::TEvHttpInfo, Handle); + hFuncTraced(TEvConsole::TEvReplaceConfigSubscriptionsResponse, Handle); default: - EnqueueEvent(ev); + EnqueueEvent(ev); break; } } @@ -202,17 +202,17 @@ public: /** * Primary state for subscriptions and notifications processing. */ - STATEFN(StateWork) { + STATEFN(StateWork) { TRACE_EVENT(NKikimrServices::CONFIGS_DISPATCHER); switch (ev->GetTypeRewrite()) { - hFuncTraced(NMon::TEvHttpInfo, Handle); - hFuncTraced(TEvConfigsDispatcher::TEvGetConfigRequest, Handle); - hFuncTraced(TEvConfigsDispatcher::TEvSetConfigSubscriptionRequest, Handle); - hFuncTraced(TEvConsole::TEvAddConfigSubscriptionResponse, Handle); - hFuncTraced(TEvConsole::TEvConfigNotificationResponse, Handle); - hFuncTraced(TEvConsole::TEvConfigNotificationRequest, Handle); - hFuncTraced(TEvConsole::TEvGetNodeConfigResponse, Handle); - hFuncTraced(TEvTenantPool::TEvTenantPoolStatus, Handle); + hFuncTraced(NMon::TEvHttpInfo, Handle); + hFuncTraced(TEvConfigsDispatcher::TEvGetConfigRequest, Handle); + hFuncTraced(TEvConfigsDispatcher::TEvSetConfigSubscriptionRequest, Handle); + hFuncTraced(TEvConsole::TEvAddConfigSubscriptionResponse, Handle); + hFuncTraced(TEvConsole::TEvConfigNotificationResponse, Handle); + hFuncTraced(TEvConsole::TEvConfigNotificationRequest, Handle); + hFuncTraced(TEvConsole::TEvGetNodeConfigResponse, Handle); + hFuncTraced(TEvTenantPool::TEvTenantPoolStatus, Handle); IgnoreFunc(TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse); default: @@ -230,7 +230,7 @@ private: THashMap<ui64, TSubscription::TPtr> SubscriptionsById; THashMap<TDynBitMap, TSubscription::TPtr> SubscriptionsByKinds; THashMap<TActorId, TSubscriber::TPtr> Subscribers; - + // Messages that had an unknown subscription id at the time they are received THashMap<ui64, TEvConsole::TEvConfigNotificationRequest::TPtr> OutOfOrderConfigNotifications; @@ -238,7 +238,7 @@ private: THashMap<ui64, TDynBitMap> RequestCookies; ui64 NextRequestCookie; THashSet<TString> CurrentTenants; - + // Structures to process config requests. THashMap<ui64, THolder<IEventHandle>> ConfigRequests; THashMap<TDynBitMap, std::shared_ptr<NKikimrConfig::TAppConfig>> ConfigsCache; @@ -251,32 +251,32 @@ TConfigsDispatcher::TConfigsDispatcher(const NKikimrConfig::TAppConfig &config) { } -void TConfigsDispatcher::Bootstrap() +void TConfigsDispatcher::Bootstrap() { - BLOG_D("TConfigsDispatcher Bootstrap"); + BLOG_D("TConfigsDispatcher Bootstrap"); - NActors::TMon *mon = AppData()->Mon; + NActors::TMon *mon = AppData()->Mon; if (mon) { NMonitoring::TIndexMonPage *actorsMonPage = mon->RegisterIndexPage("actors", "Actors"); - mon->RegisterActorPage(actorsMonPage, "configs_dispatcher", "Configs Dispatcher", false, TlsActivationContext->ExecutorThread.ActorSystem, SelfId()); + mon->RegisterActorPage(actorsMonPage, "configs_dispatcher", "Configs Dispatcher", false, TlsActivationContext->ExecutorThread.ActorSystem, SelfId()); } Become(&TThis::StateInit); Send(MakeTenantPoolRootID(), new TEvents::TEvSubscribe); } -void TConfigsDispatcher::EnqueueEvent(TAutoPtr<IEventHandle> &ev) +void TConfigsDispatcher::EnqueueEvent(TAutoPtr<IEventHandle> &ev) { - BLOG_D("Enqueue event type: " << ev->GetTypeRewrite()); + BLOG_D("Enqueue event type: " << ev->GetTypeRewrite()); EventsQueue.push_back(ev); } -void TConfigsDispatcher::ProcessEnqueuedEvents() +void TConfigsDispatcher::ProcessEnqueuedEvents() { while (!EventsQueue.empty()) { TAutoPtr<IEventHandle> &ev = EventsQueue.front(); - BLOG_D("Dequeue event type: " << ev->GetTypeRewrite()); - TlsActivationContext->Send(ev.Release()); + BLOG_D("Dequeue event type: " << ev->GetTypeRewrite()); + TlsActivationContext->Send(ev.Release()); EventsQueue.pop_front(); } } @@ -325,12 +325,12 @@ void TConfigsDispatcher::ReplaceConfigItems(const NKikimrConfig::TAppConfig &fro to.MergeFrom(from); } -bool TConfigsDispatcher::CompareConfigs(const NKikimrConfig::TAppConfig &lhs, const NKikimrConfig::TAppConfig &rhs) +bool TConfigsDispatcher::CompareConfigs(const NKikimrConfig::TAppConfig &lhs, const NKikimrConfig::TAppConfig &rhs) { TString str1, str2; Y_PROTOBUF_SUPPRESS_NODISCARD lhs.SerializeToString(&str1); Y_PROTOBUF_SUPPRESS_NODISCARD rhs.SerializeToString(&str2); - return (str1 == str2); + return (str1 == str2); } TConfigsDispatcher::TSubscription::TPtr TConfigsDispatcher::FindSubscription(ui64 id) @@ -367,18 +367,18 @@ void TConfigsDispatcher::SendNotificationResponse(TEvConsole::TEvConfigNotificat Send(ev->Sender, resp.Release(), 0, ev->Cookie); } -void TConfigsDispatcher::MaybeSendNotificationResponse(TSubscription::TPtr subscription) +void TConfigsDispatcher::MaybeSendNotificationResponse(TSubscription::TPtr subscription) { - if (!subscription->UpdateInProcess || !subscription->SubscribersToUpdate.empty()) + if (!subscription->UpdateInProcess || !subscription->SubscribersToUpdate.empty()) return; auto &rec = subscription->UpdateInProcess->Get()->Record; subscription->CurrentConfig.Config.Swap(rec.MutableConfig()); subscription->CurrentConfig.ConfigId.Load(rec.GetConfigId()); - ReplaceConfigItems(subscription->CurrentConfig.Config, CurrentConfig, subscription->Kinds); + ReplaceConfigItems(subscription->CurrentConfig.Config, CurrentConfig, subscription->Kinds); - BLOG_D("Got all confirmations for config update" + BLOG_D("Got all confirmations for config update" << " subscriptionid=" << subscription->SubscriptionId << " configid=" << TConfigId(rec.GetConfigId()).ToString()); @@ -387,23 +387,23 @@ void TConfigsDispatcher::MaybeSendNotificationResponse(TSubscription::TPtr subsc subscription->UpdateInProcess = nullptr; } -void TConfigsDispatcher::CreateSubscriberActor(ui32 kind, bool replace) +void TConfigsDispatcher::CreateSubscriberActor(ui32 kind, bool replace) { TDynBitMap kinds; kinds.Set(kind); - CreateSubscriberActor(kinds, replace); + CreateSubscriberActor(kinds, replace); } -void TConfigsDispatcher::CreateSubscriberActor(const TDynBitMap &kinds, bool replace) +void TConfigsDispatcher::CreateSubscriberActor(const TDynBitMap &kinds, bool replace) { - BLOG_D("Create new subscriber kinds=" << KindsToString(kinds)); + BLOG_D("Create new subscriber kinds=" << KindsToString(kinds)); - auto *subscriber = CreateConfigSubscriber(MakeConfigsDispatcherID(SelfId().NodeId()), + auto *subscriber = CreateConfigSubscriber(MakeConfigsDispatcherID(SelfId().NodeId()), KindsToVector(kinds), - SelfId(), + SelfId(), replace, NextRequestCookie); - Register(subscriber); + Register(subscriber); RequestCookies[NextRequestCookie] = kinds; ++NextRequestCookie; } @@ -418,15 +418,15 @@ void TConfigsDispatcher::SendUpdateToSubscriber(TSubscription::TPtr subscription auto notification = MakeHolder<TEvConsole::TEvConfigNotificationRequest>(); notification->Record.CopyFrom(subscription->UpdateInProcess->Get()->Record); - BLOG_TRACE("Send TEvConsole::TEvConfigNotificationRequest to " << subscriber + BLOG_TRACE("Send TEvConsole::TEvConfigNotificationRequest to " << subscriber << ": " << notification->Record.ShortDebugString()); - Send(subscriber, notification.Release(), 0, subscription->UpdateInProcess->Cookie); + Send(subscriber, notification.Release(), 0, subscription->UpdateInProcess->Cookie); } -void TConfigsDispatcher::RemoveSubscriber(TSubscriber::TPtr subscriber) +void TConfigsDispatcher::RemoveSubscriber(TSubscriber::TPtr subscriber) { - BLOG_D("Remove subscriber " << subscriber->Subscriber); + BLOG_D("Remove subscriber " << subscriber->Subscriber); for (auto subscription : subscriber->Subscriptions) { Y_VERIFY(subscription->Subscribers.contains(subscriber->Subscriber)); @@ -434,36 +434,36 @@ void TConfigsDispatcher::RemoveSubscriber(TSubscriber::TPtr subscriber) if (subscription->UpdateInProcess) { subscription->SubscribersToUpdate.erase(subscriber->Subscriber); - MaybeSendNotificationResponse(subscription); + MaybeSendNotificationResponse(subscription); } // If there are no more subscribers using this subscription then // it can be removed. Don't remove subscriptions which are not // yet confirmed by CMS. if (subscription->Subscribers.empty() && subscription->SubscriptionId) - RemoveSubscription(subscription); + RemoveSubscription(subscription); } Subscribers.erase(subscriber->Subscriber); } -void TConfigsDispatcher::RemoveSubscription(TSubscription::TPtr subscription) +void TConfigsDispatcher::RemoveSubscription(TSubscription::TPtr subscription) { Subscriptions.erase(subscription); SubscriptionsById.erase(subscription->SubscriptionId); SubscriptionsByKinds.erase(subscription->Kinds); - BLOG_D("Remove subscription id=" << subscription->SubscriptionId + BLOG_D("Remove subscription id=" << subscription->SubscriptionId << " kinds=" << KindsToString(subscription->Kinds)); - Register(CreateSubscriptionEraser(subscription->SubscriptionId)); + Register(CreateSubscriptionEraser(subscription->SubscriptionId)); } void TConfigsDispatcher::AddSubscription(TActorId subscriber, const TDynBitMap &kinds, - bool replace) + bool replace) { - BLOG_D("Add subscription for " << subscriber << " kinds=" << KindsToString(kinds)); + BLOG_D("Add subscription for " << subscriber << " kinds=" << KindsToString(kinds)); // If there is a subscription for required config kinds then // re-use it for new subscriber. Otherwise create a new one. @@ -475,7 +475,7 @@ void TConfigsDispatcher::AddSubscription(TActorId subscriber, Subscriptions.insert(subscription); SubscriptionsByKinds.emplace(kinds, subscription); - CreateSubscriberActor(kinds, replace); + CreateSubscriberActor(kinds, replace); } subscription->Subscribers.insert(subscriber); @@ -495,17 +495,17 @@ void TConfigsDispatcher::AddSubscription(TActorId subscriber, Y_VERIFY(!replace); auto resp = MakeHolder<TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse>(); - BLOG_TRACE("Send TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse to " + BLOG_TRACE("Send TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse to " << subscriber); - Send(subscriber, resp.Release()); + Send(subscriber, resp.Release()); } // If there is an ongoing config update then include new subscriber into // the process. if (subscription->UpdateInProcess) { Y_VERIFY(!replace); - SendUpdateToSubscriber(subscription, subscriber); + SendUpdateToSubscriber(subscription, subscriber); } else if (!subscription->FirstUpdate) { // If subscription already had an update notification then send corresponding // notification to the subscriber using current config. @@ -516,13 +516,13 @@ void TConfigsDispatcher::AddSubscription(TActorId subscriber, subscription->CurrentConfig.ConfigId.Serialize(*notification->Record.MutableConfigId()); notification->Record.MutableConfig()->CopyFrom(subscription->CurrentConfig.Config); - BLOG_TRACE("Send TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse to "<< subscriber); + BLOG_TRACE("Send TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse to "<< subscriber); - Send(subscriber, notification.Release()); + Send(subscriber, notification.Release()); } } -void TConfigsDispatcher::CleanUpSubscriptions() +void TConfigsDispatcher::CleanUpSubscriptions() { BLOG_N("Cleaning up all current subscriptions"); @@ -547,15 +547,15 @@ void TConfigsDispatcher::CleanUpSubscriptions() kinds.Set(NKikimrConsole::TConfigItem::ConfigsDispatcherConfigItem); auto subscription = FindSubscription(kinds); if (subscription) { - CreateSubscriberActor(kinds, true); + CreateSubscriberActor(kinds, true); } else { - AddSubscription(SelfId(), kinds, true); + AddSubscription(SelfId(), kinds, true); } Become(&TThis::StateConfigure); } -void TConfigsDispatcher::ProcessAddedSubscription(TSubscription::TPtr subscription, ui64 id) +void TConfigsDispatcher::ProcessAddedSubscription(TSubscription::TPtr subscription, ui64 id) { BLOG_N("Confirmed CMS subscription" << " kinds=" << KindsToString(subscription->Kinds) @@ -566,9 +566,9 @@ void TConfigsDispatcher::ProcessAddedSubscription(TSubscription::TPtr subscripti SubscriptionsById[id] = subscription; for (auto &subscriber : subscription->Subscribers) { - BLOG_TRACE("Send TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse to " << subscriber); + BLOG_TRACE("Send TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse to " << subscriber); - Send(subscriber, new TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse); + Send(subscriber, new TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse); } auto it = OutOfOrderConfigNotifications.find(id); @@ -588,33 +588,33 @@ void TConfigsDispatcher::ProcessAddedSubscription(TSubscription::TPtr subscripti // Probably there are no more subscribers for this subscription. // In that case it should be removed. if (subscription->Subscribers.empty()) - RemoveSubscription(subscription); + RemoveSubscription(subscription); } -void TConfigsDispatcher::ProcessLocalCacheUpdate(TEvConsole::TEvConfigNotificationRequest::TPtr &ev) +void TConfigsDispatcher::ProcessLocalCacheUpdate(TEvConsole::TEvConfigNotificationRequest::TPtr &ev) { auto &rec = ev->Get()->Record; - BLOG_D("Got new config: " << rec.ShortDebugString()); + BLOG_D("Got new config: " << rec.ShortDebugString()); auto subscription = FindSubscription(rec.GetSubscriptionId()); if (!subscription) { - BLOG_ERROR("Cannot find subscription for configs cache update subscriptionid=" << rec.GetSubscriptionId()); + BLOG_ERROR("Cannot find subscription for configs cache update subscriptionid=" << rec.GetSubscriptionId()); return; } - BLOG_D("Update local cache for kinds=" << KindsToString(subscription->Kinds) + BLOG_D("Update local cache for kinds=" << KindsToString(subscription->Kinds) << " config='" << rec.GetConfig().ShortDebugString() << "'"); ConfigsCache[subscription->Kinds].reset(new NKikimrConfig::TAppConfig(rec.GetConfig())); auto resp = MakeHolder<TEvConsole::TEvConfigNotificationResponse>(rec); - BLOG_TRACE("Send TEvConsole::TEvConfigNotificationResponse to self: " << resp->Record.ShortDebugString()); + BLOG_TRACE("Send TEvConsole::TEvConfigNotificationResponse to self: " << resp->Record.ShortDebugString()); - Send(ev->Sender, resp.Release(), 0, ev->Cookie); + Send(ev->Sender, resp.Release(), 0, ev->Cookie); } -void TConfigsDispatcher::Handle(NMon::TEvHttpInfo::TPtr &ev) +void TConfigsDispatcher::Handle(NMon::TEvHttpInfo::TPtr &ev) { TStringStream str; str << NMonitoring::HTTPOKHTML; @@ -687,18 +687,18 @@ void TConfigsDispatcher::Handle(NMon::TEvHttpInfo::TPtr &ev) } } - Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom)); + Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom)); } -void TConfigsDispatcher::Handle(TEvConfigsDispatcher::TEvGetConfigRequest::TPtr &ev) +void TConfigsDispatcher::Handle(TEvConfigsDispatcher::TEvGetConfigRequest::TPtr &ev) { auto kinds = KindsToBitMap(ev->Get()->ConfigItemKinds); if (ev->Get()->Cache && !kinds.Empty()) { auto subscription = FindSubscription(kinds); - if (!subscription || !subscription->Subscribers.contains(SelfId())) { - BLOG_D("Add subscription for local cache kinds=" << KindsToString(kinds)); - AddSubscription(SelfId(), kinds, false); + if (!subscription || !subscription->Subscribers.contains(SelfId())) { + BLOG_D("Add subscription for local cache kinds=" << KindsToString(kinds)); + AddSubscription(SelfId(), kinds, false); } } @@ -706,17 +706,17 @@ void TConfigsDispatcher::Handle(TEvConfigsDispatcher::TEvGetConfigRequest::TPtr auto resp = MakeHolder<TEvConfigsDispatcher::TEvGetConfigResponse>(); resp->Config = ConfigsCache.at(kinds); - BLOG_TRACE("Send TEvConfigsDispatcher::TEvGetConfigResponse" - " to " << ev->Sender << ": " << resp->Config->ShortDebugString()); + BLOG_TRACE("Send TEvConfigsDispatcher::TEvGetConfigResponse" + " to " << ev->Sender << ": " << resp->Config->ShortDebugString()); - Send(ev->Sender, std::move(resp), 0, ev->Cookie); + Send(ev->Sender, std::move(resp), 0, ev->Cookie); } else { - Register(CreateNodeConfigCourier(ev->Get()->ConfigItemKinds, SelfId(), NextRequestCookie)); + Register(CreateNodeConfigCourier(ev->Get()->ConfigItemKinds, SelfId(), NextRequestCookie)); ConfigRequests[NextRequestCookie++] = THolder<IEventHandle>(ev.Release()); } } -void TConfigsDispatcher::Handle(TEvConfigsDispatcher::TEvSetConfigSubscriptionRequest::TPtr &ev) +void TConfigsDispatcher::Handle(TEvConfigsDispatcher::TEvSetConfigSubscriptionRequest::TPtr &ev) { auto kinds = KindsToBitMap(ev->Get()->ConfigItemKinds); auto subscriber = FindSubscriber(ev->Sender); @@ -726,31 +726,31 @@ void TConfigsDispatcher::Handle(TEvConfigsDispatcher::TEvSetConfigSubscriptionRe auto subscription = *subscriber->Subscriptions.begin(); if (subscription->Kinds == kinds) { - BLOG_D("Nothing to change for " << subscriber->Subscriber); - BLOG_TRACE("Send TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse to " << subscriber->Subscriber); - - Send(subscriber->Subscriber, new TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse); + BLOG_D("Nothing to change for " << subscriber->Subscriber); + BLOG_TRACE("Send TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse to " << subscriber->Subscriber); + + Send(subscriber->Subscriber, new TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse); return; } - // something changed so refresh subscription - RemoveSubscriber(subscriber); + // something changed so refresh subscription + RemoveSubscriber(subscriber); } - if (!kinds.Empty()) { - AddSubscription(ev->Sender, kinds, false); - } else { - BLOG_TRACE("Send TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse to " << ev->Sender); + if (!kinds.Empty()) { + AddSubscription(ev->Sender, kinds, false); + } else { + BLOG_TRACE("Send TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse to " << ev->Sender); - Send(ev->Sender, new TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse); + Send(ev->Sender, new TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse); } } -void TConfigsDispatcher::Handle(TEvConsole::TEvAddConfigSubscriptionResponse::TPtr &ev) +void TConfigsDispatcher::Handle(TEvConsole::TEvAddConfigSubscriptionResponse::TPtr &ev) { auto it = RequestCookies.find(ev->Cookie); if (it == RequestCookies.end()) { - BLOG_I("Cookie mismatch for TEvAddConfigSubscriptionResponse"); + BLOG_I("Cookie mismatch for TEvAddConfigSubscriptionResponse"); return; } auto kinds = it->second; @@ -758,39 +758,39 @@ void TConfigsDispatcher::Handle(TEvConsole::TEvAddConfigSubscriptionResponse::TP auto &rec = ev->Get()->Record; if (rec.GetStatus().GetCode() != Ydb::StatusIds::SUCCESS) { - LOG_CRIT_S(*TlsActivationContext, NKikimrServices::CONFIGS_DISPATCHER, + LOG_CRIT_S(*TlsActivationContext, NKikimrServices::CONFIGS_DISPATCHER, "Cannot get config subscription for " << KindsToString(kinds) << " code=" << rec.GetStatus().GetCode() << " reason= " << rec.GetStatus().GetReason()); - CreateSubscriberActor(kinds, false); + CreateSubscriberActor(kinds, false); return; } auto subscription = FindSubscription(kinds); Y_VERIFY(subscription); - ProcessAddedSubscription(subscription, rec.GetSubscriptionId()); + ProcessAddedSubscription(subscription, rec.GetSubscriptionId()); } -void TConfigsDispatcher::Handle(TEvConsole::TEvConfigNotificationResponse::TPtr &ev) +void TConfigsDispatcher::Handle(TEvConsole::TEvConfigNotificationResponse::TPtr &ev) { auto rec = ev->Get()->Record; auto subscription = FindSubscription(rec.GetSubscriptionId()); // Probably subscription was cleared up due to tenant's change. if (!subscription) { - BLOG_I("Got notification response for unknown subscription " << rec.GetSubscriptionId()); + BLOG_I("Got notification response for unknown subscription " << rec.GetSubscriptionId()); return; } if (!subscription->UpdateInProcess) { - BLOG_D("Notification was ignored for subscription " + BLOG_D("Notification was ignored for subscription " << rec.GetSubscriptionId()); return; } if (ev->Cookie != subscription->UpdateInProcess->Cookie) { - BLOG_ERROR("Notification cookie mismatch for subscription " << rec.GetSubscriptionId()); + BLOG_ERROR("Notification cookie mismatch for subscription " << rec.GetSubscriptionId()); return; } @@ -798,12 +798,12 @@ void TConfigsDispatcher::Handle(TEvConsole::TEvConfigNotificationResponse::TPtr TConfigId id2(rec.GetConfigId()); // This might be outdated notification response. if (id1 != id2) { - BLOG_I("Config id mismatch in notification response for subscription " << rec.GetSubscriptionId()); + BLOG_I("Config id mismatch in notification response for subscription " << rec.GetSubscriptionId()); return; } if (!subscription->SubscribersToUpdate.contains(ev->Sender)) { - BLOG_ERROR("Notification from unexpected subscriber for subscription " << rec.GetSubscriptionId()); + BLOG_ERROR("Notification from unexpected subscriber for subscription " << rec.GetSubscriptionId()); return; } @@ -811,14 +811,14 @@ void TConfigsDispatcher::Handle(TEvConsole::TEvConfigNotificationResponse::TPtr // If all subscribers responded then send response to CMS. subscription->SubscribersToUpdate.erase(ev->Sender); - MaybeSendNotificationResponse(subscription); + MaybeSendNotificationResponse(subscription); } -void TConfigsDispatcher::Handle(TEvConsole::TEvConfigNotificationRequest::TPtr &ev) +void TConfigsDispatcher::Handle(TEvConsole::TEvConfigNotificationRequest::TPtr &ev) { // Process local update sent by own local subscription. - if (ev->Sender == SelfId()) { - ProcessLocalCacheUpdate(ev); + if (ev->Sender == SelfId()) { + ProcessLocalCacheUpdate(ev); return; } @@ -843,7 +843,7 @@ void TConfigsDispatcher::Handle(TEvConsole::TEvConfigNotificationRequest::TPtr & } if (subscription->UpdateInProcess) { - BLOG_D("Drop previous unfinished notification for subscription id=" + BLOG_D("Drop previous unfinished notification for subscription id=" << subscription->SubscriptionId); subscription->UpdateInProcess = nullptr; subscription->SubscribersToUpdate.clear(); @@ -855,67 +855,67 @@ void TConfigsDispatcher::Handle(TEvConsole::TEvConfigNotificationRequest::TPtr & * Avoid notifications in case only config id changed and * config body is equal to currently used one. */ - if (subscription->FirstUpdate || !CompareConfigs(subscription->CurrentConfig.Config, rec.GetConfig())) { + if (subscription->FirstUpdate || !CompareConfigs(subscription->CurrentConfig.Config, rec.GetConfig())) { for (auto &subscriber : subscription->Subscribers) - SendUpdateToSubscriber(subscription, subscriber); + SendUpdateToSubscriber(subscription, subscriber); } else { - MaybeSendNotificationResponse(subscription); + MaybeSendNotificationResponse(subscription); } subscription->FirstUpdate = false; } -void TConfigsDispatcher::Handle(TEvConsole::TEvGetNodeConfigResponse::TPtr &ev) +void TConfigsDispatcher::Handle(TEvConsole::TEvGetNodeConfigResponse::TPtr &ev) { auto it = ConfigRequests.find(ev->Cookie); if (it == ConfigRequests.end()) { - BLOG_ERROR("Node config response for unknown request cookie=" << ev->Cookie); + BLOG_ERROR("Node config response for unknown request cookie=" << ev->Cookie); return; } auto resp = MakeHolder<TEvConfigsDispatcher::TEvGetConfigResponse>(); resp->Config.reset(new NKikimrConfig::TAppConfig(ev->Get()->Record.GetConfig())); - BLOG_TRACE("Send TEvConfigsDispatcher::TEvGetConfigResponse" - " to " << ev->Sender - << ": " << resp->Config->ShortDebugString()); + BLOG_TRACE("Send TEvConfigsDispatcher::TEvGetConfigResponse" + " to " << ev->Sender + << ": " << resp->Config->ShortDebugString()); - Send(it->second->Sender, resp.Release(), 0, it->second->Cookie); + Send(it->second->Sender, resp.Release(), 0, it->second->Cookie); ConfigRequests.erase(it); } -void TConfigsDispatcher::Handle(TEvConsole::TEvReplaceConfigSubscriptionsResponse::TPtr &ev) +void TConfigsDispatcher::Handle(TEvConsole::TEvReplaceConfigSubscriptionsResponse::TPtr &ev) { auto it = RequestCookies.find(ev->Cookie); if (it == RequestCookies.end()) { - BLOG_ERROR("Cookie mismatch for TEvReplaceConfigSubscriptionsResponse"); + BLOG_ERROR("Cookie mismatch for TEvReplaceConfigSubscriptionsResponse"); return; } auto &rec = ev->Get()->Record; if (rec.GetStatus().GetCode() != Ydb::StatusIds::SUCCESS) { - LOG_CRIT_S(*TlsActivationContext, NKikimrServices::CONFIGS_DISPATCHER, + LOG_CRIT_S(*TlsActivationContext, NKikimrServices::CONFIGS_DISPATCHER, "Cannot initialize subscription: " << rec.GetStatus().GetReason()); - CleanUpSubscriptions(); + CleanUpSubscriptions(); return; } auto subscription = FindSubscription(it->second); Y_VERIFY(subscription); - ProcessAddedSubscription(subscription, rec.GetSubscriptionId()); + ProcessAddedSubscription(subscription, rec.GetSubscriptionId()); // Register other subscriptions in CMS. for (auto subscription : Subscriptions) if (!subscription->SubscriptionId) - CreateSubscriberActor(subscription->Kinds, false); + CreateSubscriberActor(subscription->Kinds, false); Become(&TThis::StateWork); - ProcessEnqueuedEvents(); + ProcessEnqueuedEvents(); } -void TConfigsDispatcher::Handle(TEvTenantPool::TEvTenantPoolStatus::TPtr &ev) +void TConfigsDispatcher::Handle(TEvTenantPool::TEvTenantPoolStatus::TPtr &ev) { auto &rec = ev->Get()->Record; @@ -931,7 +931,7 @@ void TConfigsDispatcher::Handle(TEvTenantPool::TEvTenantPoolStatus::TPtr &ev) BLOG_N("Update list of assigned tenants: " << JoinSeq(", ", CurrentTenants)); - CleanUpSubscriptions(); + CleanUpSubscriptions(); } } diff --git a/ydb/core/cms/console/console_configs_provider.cpp b/ydb/core/cms/console/console_configs_provider.cpp index 6dabfc1267..4ba6f46033 100644 --- a/ydb/core/cms/console/console_configs_provider.cpp +++ b/ydb/core/cms/console/console_configs_provider.cpp @@ -178,7 +178,7 @@ public: "TServiceConfigSender(" << Subscription->Id << ") Die"); auto nodeId = Subscription->Subscriber.ServiceId.NodeId(); - ctx.Send(TActivationContext::InterconnectProxy(nodeId), + ctx.Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe); TBase::Die(ctx); } diff --git a/ydb/core/cms/console/console_tenants_manager.cpp b/ydb/core/cms/console/console_tenants_manager.cpp index baf25e22a7..0db3f5dced 100644 --- a/ydb/core/cms/console/console_tenants_manager.cpp +++ b/ydb/core/cms/console/console_tenants_manager.cpp @@ -9,17 +9,17 @@ #include <ydb/core/util/pb.h> #include <ydb/public/lib/operation_id/operation_id.h> -#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR || defined BLOG_NOTICE -#error log macro definition clash -#endif - -#define BLOG_TRACE(stream) LOG_TRACE_S(*TlsActivationContext, NKikimrServices::CMS_TENANTS, stream) -#define BLOG_NOTICE(stream) LOG_NOTICE_S(*TlsActivationContext, NKikimrServices::CMS_TENANTS, stream) -#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::CMS_TENANTS, stream) -#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::CMS_TENANTS, stream) -#define BLOG_CRIT(stream) LOG_CRIT_S(*TlsActivationContext, NKikimrServices::CMS_TENANTS, stream) - - +#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR || defined BLOG_NOTICE +#error log macro definition clash +#endif + +#define BLOG_TRACE(stream) LOG_TRACE_S(*TlsActivationContext, NKikimrServices::CMS_TENANTS, stream) +#define BLOG_NOTICE(stream) LOG_NOTICE_S(*TlsActivationContext, NKikimrServices::CMS_TENANTS, stream) +#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::CMS_TENANTS, stream) +#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::CMS_TENANTS, stream) +#define BLOG_CRIT(stream) LOG_CRIT_S(*TlsActivationContext, NKikimrServices::CMS_TENANTS, stream) + + namespace NKikimr { namespace NConsole { @@ -79,7 +79,7 @@ public: void OnPipeDestroyed(const TActorContext &ctx) { - BLOG_D(LogPrefix << "pipe destroyed"); + BLOG_D(LogPrefix << "pipe destroyed"); if (BSControllerPipe) { NTabletPipe::CloseClient(ctx, BSControllerPipe); @@ -111,7 +111,7 @@ public: read.SetBoxId(Pool->Config.GetBoxId()); read.AddName(Pool->Config.GetName()); - BLOG_D(LogPrefix << "read pool state: " << request->Record.ShortDebugString()); + BLOG_D(LogPrefix << "read pool state: " << request->Record.ShortDebugString()); NTabletPipe::SendData(ctx, BSControllerPipe, request.Release()); } @@ -121,7 +121,7 @@ public: auto request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>(); request->Record.MutableRequest()->AddCommand()->MutableDefineStoragePool()->CopyFrom(Pool->Config); - BLOG_D(LogPrefix << "send pool request: " << request->Record.ShortDebugString()); + BLOG_D(LogPrefix << "send pool request: " << request->Record.ShortDebugString()); NTabletPipe::SendData(ctx, BSControllerPipe, request.Release()); } @@ -129,7 +129,7 @@ public: void DeletePool(const TActorContext &ctx) { if (!PoolId) { - BLOG_D(LogPrefix << "cannot delete missing pool " << Pool->Config.GetName()); + BLOG_D(LogPrefix << "cannot delete missing pool " << Pool->Config.GetName()); ctx.Send(OwnerId, new TTenantsManager::TEvPrivate::TEvPoolDeleted(Tenant, Pool)); Die(ctx); return; @@ -141,14 +141,14 @@ public: del.SetStoragePoolId(PoolId); del.SetItemConfigGeneration(Pool->Config.GetItemConfigGeneration()); - BLOG_D(LogPrefix << "send pool request: " << request->Record.ShortDebugString()); + BLOG_D(LogPrefix << "send pool request: " << request->Record.ShortDebugString()); NTabletPipe::SendData(ctx, BSControllerPipe, request.Release()); } void Bootstrap(const TActorContext &ctx) { - BLOG_D(LogPrefix << "Bootstrap"); + BLOG_D(LogPrefix << "Bootstrap"); Become(&TThis::StateRead); @@ -158,7 +158,7 @@ public: void ReplyAndDie(IEventBase *resp, const TActorContext &ctx) { - BLOG_D(LogPrefix << "reply with " << resp->ToString()); + BLOG_D(LogPrefix << "reply with " << resp->ToString()); ctx.Send(OwnerId, resp); Die(ctx); } @@ -188,9 +188,9 @@ public: { auto &rec = ev->Get()->Record.GetResponse(); - BLOG_D(LogPrefix << "got read response: " << rec.ShortDebugString()); + BLOG_D(LogPrefix << "got read response: " << rec.ShortDebugString()); - if (!CheckReadStatus(rec)) { + if (!CheckReadStatus(rec)) { ReplyAndDie(new TTenantsManager::TEvPrivate::TEvPoolFailed(Tenant, Pool, Pool->Issue), ctx); return; } @@ -214,14 +214,14 @@ public: DoWork(ctx); } - bool CheckReadStatus(const NKikimrBlobStorage::TConfigResponse &resp) + bool CheckReadStatus(const NKikimrBlobStorage::TConfigResponse &resp) { if (!resp.GetSuccess() || !resp.GetStatus(0).GetSuccess()) { TString error = resp.GetErrorDescription(); if (resp.StatusSize() && resp.GetStatus(0).GetErrorDescription()) error = resp.GetStatus(0).GetErrorDescription(); - BLOG_D(LogPrefix << "cannot read pool '" << Pool->Config.GetName() << "' (" + BLOG_D(LogPrefix << "cannot read pool '" << Pool->Config.GetName() << "' (" << Pool->Config.GetStoragePoolId() << "): " << error); Pool->Issue = error; return false; @@ -234,14 +234,14 @@ public: { auto &rec = ev->Get()->Record.GetResponse(); - BLOG_D(LogPrefix << "got config response: " << rec.ShortDebugString()); + BLOG_D(LogPrefix << "got config response: " << rec.ShortDebugString()); if (!rec.GetSuccess() || !rec.GetStatus(0).GetSuccess()) { TString error = rec.GetErrorDescription(); if (rec.StatusSize() && rec.GetStatus(0).GetErrorDescription()) error = rec.GetStatus(0).GetErrorDescription(); - BLOG_ERROR(LogPrefix << "cannot create pool '" << Pool->Config.GetName() << "' (" + BLOG_ERROR(LogPrefix << "cannot create pool '" << Pool->Config.GetName() << "' (" << Pool->Config.GetStoragePoolId() << "): " << error); Pool->Issue = error; ReplyAndDie(new TTenantsManager::TEvPrivate::TEvPoolFailed(Tenant, Pool, error), ctx); @@ -266,22 +266,22 @@ public: { auto &rec = ev->Get()->Record.GetResponse(); - BLOG_D(LogPrefix << "got check response: " << rec.ShortDebugString()); + BLOG_D(LogPrefix << "got check response: " << rec.ShortDebugString()); - if (!CheckReadStatus(rec)) { + if (!CheckReadStatus(rec)) { ReplyAndDie(new TTenantsManager::TEvPrivate::TEvPoolFailed(Tenant, Pool, Pool->Issue), ctx); return; } if (rec.GetStatus(0).StoragePoolSize() == 0) { - BLOG_ERROR(LogPrefix << "check response misses pool status"); + BLOG_ERROR(LogPrefix << "check response misses pool status"); ReplyAndDie(new TTenantsManager::TEvPrivate::TEvPoolFailed(Tenant, Pool, Pool->Issue), ctx); return; } const auto &scope = rec.GetStatus(0).GetStoragePool(0).GetScopeId(); if (TTenantsManager::TDomainId(scope.GetX1(), scope.GetX2()) != Tenant->DomainId) { - BLOG_ERROR(LogPrefix << "scope id check failure " + BLOG_ERROR(LogPrefix << "scope id check failure " << Tenant->DomainId << " vs " << scope.ShortDebugString()); ReplyAndDie(new TTenantsManager::TEvPrivate::TEvPoolFailed(Tenant, Pool, Pool->Issue), ctx); @@ -296,14 +296,14 @@ public: { auto &rec = ev->Get()->Record.GetResponse(); - BLOG_D(LogPrefix << "got config response: " << rec.ShortDebugString()); + BLOG_D(LogPrefix << "got config response: " << rec.ShortDebugString()); if (!rec.GetSuccess() || !rec.GetStatus(0).GetSuccess()) { TString error = rec.GetErrorDescription(); if (rec.StatusSize() && rec.GetStatus(0).GetErrorDescription()) error = rec.GetStatus(0).GetErrorDescription(); - BLOG_ERROR(LogPrefix << "cannot delete pool '" + BLOG_ERROR(LogPrefix << "cannot delete pool '" << Pool->Config.GetName() << "' (" << Pool->Config.GetStoragePoolId() << "): " << error); Pool->Issue = error; @@ -539,7 +539,7 @@ public: void AlterSubdomain(const TActorContext &ctx) { - BLOG_D("TSubDomainManip(" << Tenant->Path << ") alter subdomain version " << Version); + BLOG_D("TSubDomainManip(" << Tenant->Path << ") alter subdomain version " << Version); auto request = MakeHolder<TEvTxUserProxy::TEvProposeTransaction>(); request->Record.SetDatabaseName(TString(ExtractDomain(Subdomain.first))); @@ -559,7 +559,7 @@ public: tx.SetOperationType(NKikimrSchemeOp::ESchemeOpAlterSubDomain); } - BLOG_TRACE("TSubdomainManip(" << Tenant->Path << ") send alter subdomain cmd: " + BLOG_TRACE("TSubdomainManip(" << Tenant->Path << ") send alter subdomain cmd: " << request->ToString()); ctx.Send(MakeTxProxyID(), request.Release()); @@ -567,7 +567,7 @@ public: void CreateSubdomain(const TActorContext &ctx) { - BLOG_D("TSubDomainManip(" << Tenant->Path << ") create subdomain"); + BLOG_D("TSubDomainManip(" << Tenant->Path << ") create subdomain"); auto request = MakeHolder<TEvTxUserProxy::TEvProposeTransaction>(); request->Record.SetDatabaseName(TString(ExtractDomain(Subdomain.first))); @@ -585,7 +585,7 @@ public: if (Tenant->Attributes.UserAttributesSize()) tx.MutableAlterUserAttributes()->CopyFrom(Tenant->Attributes); - BLOG_TRACE("TSubdomainManip(" << Tenant->Path << ") send subdomain creation cmd: " + BLOG_TRACE("TSubdomainManip(" << Tenant->Path << ") send subdomain creation cmd: " << request->ToString()); ctx.Send(MakeTxProxyID(), request.Release()); @@ -593,7 +593,7 @@ public: void DropSubdomain(const TActorContext &ctx) { - BLOG_D("TSubDomainManip(" << Tenant->Path << ") drop subdomain"); + BLOG_D("TSubDomainManip(" << Tenant->Path << ") drop subdomain"); auto request = MakeHolder<TEvTxUserProxy::TEvProposeTransaction>(); request->Record.SetDatabaseName(TString(ExtractDomain(Subdomain.first))); @@ -609,7 +609,7 @@ public: tx.SetWorkingDir(Subdomain.first); tx.MutableDrop()->SetName(Subdomain.second); - BLOG_TRACE("TSubdomainManip(" << Tenant->Path << ") send subdomain drop cmd: " + BLOG_TRACE("TSubdomainManip(" << Tenant->Path << ") send subdomain drop cmd: " << request->ToString()); ctx.Send(MakeTxProxyID(), request.Release()); @@ -620,7 +620,7 @@ public: auto *domain = AppData(ctx)->DomainsInfo->GetDomainByName(ExtractDomain(Tenant->Path)); if (!domain) { TString error = "cannot find domain info"; - BLOG_CRIT("TSubdomainManip(" << Tenant->Path << ") " << error); + BLOG_CRIT("TSubdomainManip(" << Tenant->Path << ") " << error); ReplyAndDie(new TTenantsManager::TEvPrivate::TEvSubdomainFailed(Tenant, error), ctx); return; } @@ -646,7 +646,7 @@ public: void ReplyAndDie(const TActorContext &ctx) { - BLOG_D("TSubdomainManip(" << Tenant->Path << ") done"); + BLOG_D("TSubdomainManip(" << Tenant->Path << ") done"); if (Action == CREATE) ReplyAndDie(new TTenantsManager::TEvPrivate::TEvSubdomainCreated(Tenant, SchemeshardId, PathId), ctx); else if (Action == CONFIGURE || Action == CONFIGURE_ATTR) @@ -662,7 +662,7 @@ public: void ReplyAndDie(IEventBase *resp, const TActorContext &ctx) { - BLOG_D("TSubdomainManip(" << Tenant->Path << ") reply with " << resp->ToString()); + BLOG_D("TSubdomainManip(" << Tenant->Path << ") reply with " << resp->ToString()); ctx.Send(OwnerId, resp); Die(ctx); } @@ -694,7 +694,7 @@ public: auto request = MakeHolder<TEvSchemeShard::TEvNotifyTxCompletion>(); request->Record.SetTxId(TxId); - BLOG_TRACE("TSubdomainManip(" << Tenant->Path << ") send notification request: " << request->ToString()); + BLOG_TRACE("TSubdomainManip(" << Tenant->Path << ") send notification request: " << request->ToString()); NTabletPipe::SendData(ctx, Pipe, request.Release()); } @@ -710,7 +710,7 @@ public: } void Bootstrap(const TActorContext &ctx) { - BLOG_D("TSubdomainManip(" << Tenant->Path << ")::Bootstrap"); + BLOG_D("TSubdomainManip(" << Tenant->Path << ")::Bootstrap"); if (Action == CREATE) { Become(&TThis::StateSubdomain); @@ -729,12 +729,12 @@ public: } void Handle(TEvSchemeShard::TEvNotifyTxCompletionRegistered::TPtr &ev, const TActorContext&) { - BLOG_D("TSubdomainManip(" << Tenant->Path << ") got TEvNotifyTxCompletionRegistered: " + BLOG_D("TSubdomainManip(" << Tenant->Path << ") got TEvNotifyTxCompletionRegistered: " << ev->Get()->Record.ShortDebugString()); } void Handle(TEvSchemeShard::TEvNotifyTxCompletionResult::TPtr &ev, const TActorContext& ctx) { - BLOG_D("TSubdomainManip(" << Tenant->Path << ") got TEvNotifyTxCompletionResult: " + BLOG_D("TSubdomainManip(" << Tenant->Path << ") got TEvNotifyTxCompletionResult: " << ev->Get()->Record.ShortDebugString()); if (Action == CONFIGURE && Tenant->Attributes.UserAttributesSize()) { @@ -757,7 +757,7 @@ public: void HandleSubdomain(TEvTxUserProxy::TEvProposeTransactionStatus::TPtr& ev, const TActorContext& ctx) { - BLOG_D("TSubdomainManip(" << Tenant->Path << ") got propose result: " + BLOG_D("TSubdomainManip(" << Tenant->Path << ") got propose result: " << ev->Get()->Record.ShortDebugString()); auto &rec = ev->Get()->Record; @@ -788,7 +788,7 @@ public: // Check if removal finished or in-progress. if (rec.GetSchemeShardStatus() == NKikimrScheme::StatusPathDoesNotExist || rec.GetSchemeShardStatus() == NKikimrScheme::StatusMultipleModifications) { - BLOG_D("TSubdomainManip(" << Tenant->Path << ") consider dubdomain is removed"); + BLOG_D("TSubdomainManip(" << Tenant->Path << ") consider dubdomain is removed"); ActionFinished(ctx); break; } @@ -806,7 +806,7 @@ public: { const auto &rec = ev->Get()->GetRecord(); - BLOG_D("TSubdomainManip(" << Tenant->Path << ") got describe result: " + BLOG_D("TSubdomainManip(" << Tenant->Path << ") got describe result: " << rec.ShortDebugString()); if (Action == REMOVE) { @@ -826,7 +826,7 @@ public: } if (rec.GetStatus() != NKikimrScheme::EStatus::StatusSuccess) { - BLOG_ERROR("TSubdomainManip(" << Tenant->Path << ") " + BLOG_ERROR("TSubdomainManip(" << Tenant->Path << ") " << "Receive TEvDescribeSchemeResult with bad status " << NKikimrScheme::EStatus_Name(rec.GetStatus()) << " reason is <" << rec.GetReason() << ">" << @@ -839,7 +839,7 @@ public: auto pathType = rec.GetPathDescription().GetSelf().GetPathType(); auto expectedPathType = Tenant->IsExternalSubdomain ? NKikimrSchemeOp::EPathTypeExtSubDomain : NKikimrSchemeOp::EPathTypeSubDomain; if (pathType != expectedPathType) { - BLOG_ERROR("TSubdomainManip(" << Tenant->Path << ") " + BLOG_ERROR("TSubdomainManip(" << Tenant->Path << ") " << "Resolve subdomain fail, tenant path " << Tenant->Path << " has invalid path type " << NKikimrSchemeOp::EPathType_Name(pathType) @@ -1324,7 +1324,7 @@ void TTenantsManager::ClearState() void TTenantsManager::Bootstrap(const TActorContext &ctx) { - BLOG_D("TTenantsManager::Bootstrap"); + BLOG_D("TTenantsManager::Bootstrap"); Become(&TThis::StateWork); TxProcessor = Self.GetTxProcessor()->GetSubProcessor("tenants", ctx, @@ -1546,7 +1546,7 @@ bool TTenantsManager::CheckComputationalUnitsQuota(const TUnitsCount &units, if (Config.TotalComputationalUnitsQuota && Config.TotalComputationalUnitsQuota < stats.Total.Allocated) { - BLOG_NOTICE("Cluster computational units quota is exceeded (" + BLOG_NOTICE("Cluster computational units quota is exceeded (" << stats.Total.Allocated << "/" << Config.TotalComputationalUnitsQuota << ")"); Counters.Inc(COUNTER_COMPUTATIONAL_QUOTA_EXCEEDED); @@ -1560,7 +1560,7 @@ bool TTenantsManager::CheckComputationalUnitsQuota(const TUnitsCount &units, ui64 cur = pr.second.Allocated * 100; ui64 quota = pr.second.Connected * Config.TotalComputationalUnitsLoadQuota; if (cur > quota) { - BLOG_NOTICE("Cluster computational units load quota (" + BLOG_NOTICE("Cluster computational units load quota (" << Config.TotalComputationalUnitsLoadQuota << "%) is exceeded for slots '" << pr.first << "' (" << pr.second.Allocated @@ -1575,7 +1575,7 @@ bool TTenantsManager::CheckComputationalUnitsQuota(const TUnitsCount &units, ui64 cur = stats.Total.Allocated * 100; ui64 quota = stats.Total.Connected * Config.TotalComputationalUnitsLoadQuota; if (cur > quota) { - BLOG_NOTICE("Cluster computational units load quota (" + BLOG_NOTICE("Cluster computational units load quota (" << Config.TotalComputationalUnitsLoadQuota << "%) is exceeded (" << stats.Total.Allocated << "/" << stats.Total.Connected << ")"); diff --git a/ydb/core/cms/console/net_classifier_updater.cpp b/ydb/core/cms/console/net_classifier_updater.cpp index 9e96c3ce2b..121a65efc3 100644 --- a/ydb/core/cms/console/net_classifier_updater.cpp +++ b/ydb/core/cms/console/net_classifier_updater.cpp @@ -10,16 +10,16 @@ #include <util/stream/zlib.h> -#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR || defined BLOG_NOTICE -#error log macro definition clash -#endif - -#define BLOG_TRACE(stream) LOG_TRACE_S(*TlsActivationContext, NKikimrServices::CMS_CONFIGS, stream) -#define BLOG_NOTICE(stream) LOG_NOTICE_S(*TlsActivationContext, NKikimrServices::CMS_CONFIGS, stream) -#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::CMS_CONFIGS, stream) -#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::CMS_CONFIGS, stream) - - +#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR || defined BLOG_NOTICE +#error log macro definition clash +#endif + +#define BLOG_TRACE(stream) LOG_TRACE_S(*TlsActivationContext, NKikimrServices::CMS_CONFIGS, stream) +#define BLOG_NOTICE(stream) LOG_NOTICE_S(*TlsActivationContext, NKikimrServices::CMS_CONFIGS, stream) +#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::CMS_CONFIGS, stream) +#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::CMS_CONFIGS, stream) + + namespace NKikimr::NNetClassifierUpdater { using namespace NConsole; @@ -74,14 +74,14 @@ public: return NKikimrServices::TActivity::NET_CLASSIFIER_UPDATER; } - void Bootstrap() { + void Bootstrap() { Become(&TThis::Initing); - Send(SelfId(), new TEvents::TEvWakeup); + Send(SelfId(), new TEvents::TEvWakeup); } private: const auto& UpdaterConfig() const { - return AppData()->NetClassifierConfig.GetUpdaterConfig(); + return AppData()->NetClassifierConfig.GetUpdaterConfig(); } void HandleWhileIniting(TEvents::TEvWakeup::TPtr&) { @@ -90,7 +90,7 @@ private: } void RequestCurrentConfigViaCookie() { - BLOG_D("NetClassifierUpdater requested distributable config item via cookie"); + BLOG_D("NetClassifierUpdater requested distributable config item via cookie"); auto event = MakeHolder<TEvConsole::TEvGetConfigItemsRequest>(); @@ -101,7 +101,7 @@ private: } void InitDefaultConfiguration() { - LOG_INFO_S(*TlsActivationContext, NKikimrServices::CMS_CONFIGS, + LOG_INFO_S(*TlsActivationContext, NKikimrServices::CMS_CONFIGS, "NetClassifierUpdate is adding distributable config item with cookie"); auto event = MakeHolder<TEvConsole::TEvConfigureRequest>(); @@ -120,10 +120,10 @@ private: void HandleWhileIniting(TEvConsole::TEvConfigureResponse::TPtr& ev) { const auto& record = ev->Get()->Record; if (record.GetStatus().GetCode() == Ydb::StatusIds::SUCCESS) { - BLOG_D("NetClassifierUpdater created a new distributable config item"); + BLOG_D("NetClassifierUpdater created a new distributable config item"); CompleteInitialization(); } else { - BLOG_ERROR("NetClassifierUpdater failed to add config item: " << record.ShortDebugString()); + BLOG_ERROR("NetClassifierUpdater failed to add config item: " << record.ShortDebugString()); InitializeAgain(); } } @@ -137,12 +137,12 @@ private: } else { Y_VERIFY(record.ConfigItemsSize() == 1); // only one config item should have the cookie - BLOG_D("NetClassifierUpdater found the distributable config via cookie"); + BLOG_D("NetClassifierUpdater found the distributable config via cookie"); CompleteInitialization(); } } else { - BLOG_ERROR("NetClassifierUpdater failed get current distributable config version: " << record.ShortDebugString()); + BLOG_ERROR("NetClassifierUpdater failed get current distributable config version: " << record.ShortDebugString()); InitializeAgain(); } } @@ -157,10 +157,10 @@ private: } void CompleteInitialization() { - BLOG_D("NetClassifierUpdater has been initialized"); + BLOG_D("NetClassifierUpdater has been initialized"); Become(&TThis::Working); - Send(SelfId(), new TEvents::TEvWakeup); + Send(SelfId(), new TEvents::TEvWakeup); } STATEFN(Working) { @@ -273,7 +273,7 @@ private: // hurray! the update is finished ScheduleNextUpdate(); } else { - BLOG_ERROR("NetClassifierUpdater failed to update distributable config: " << record.ShortDebugString()); + BLOG_ERROR("NetClassifierUpdater failed to update distributable config: " << record.ShortDebugString()); InitializeAgain(); } } @@ -297,7 +297,7 @@ private: Send(LocalConsole, event.Release()); } else { - BLOG_ERROR("NetClassifierUpdater failed to get current distributable config version: " << record.ShortDebugString()); + BLOG_ERROR("NetClassifierUpdater failed to get current distributable config version: " << record.ShortDebugString()); InitializeAgain(); } } diff --git a/ydb/core/cms/json_proxy_operations.h b/ydb/core/cms/json_proxy_operations.h index 4187f16a40..6bce70054d 100644 --- a/ydb/core/cms/json_proxy_operations.h +++ b/ydb/core/cms/json_proxy_operations.h @@ -18,17 +18,17 @@ public: ui64 GetTabletId(const TActorContext &) const override { const TCgiParameters &cgi = this->RequestEvent->Get()->Request.GetParams(); - ui64 tabletId = 0; - - if (cgi.Has("tabletid")) { - TryFromString(cgi.Get("tabletid"), tabletId); - } - + ui64 tabletId = 0; + + if (cgi.Has("tabletid")) { + TryFromString(cgi.Get("tabletid"), tabletId); + } + if (!tabletId && cgi.Has("followerid")) { TryFromString(cgi.Get("followerid"), tabletId); - } - - return tabletId; + } + + return tabletId; } TString GetTabletName() const override diff --git a/ydb/core/driver_lib/cli_base/cli_cmds_discovery.cpp b/ydb/core/driver_lib/cli_base/cli_cmds_discovery.cpp index e725ebec4a..729ae432c3 100644 --- a/ydb/core/driver_lib/cli_base/cli_cmds_discovery.cpp +++ b/ydb/core/driver_lib/cli_base/cli_cmds_discovery.cpp @@ -1,17 +1,17 @@ -#include "cli_cmds.h" - -namespace NKikimr { -namespace NDriverClient { - +#include "cli_cmds.h" + +namespace NKikimr { +namespace NDriverClient { + TClientCommandDiscoveryBase::TClientCommandDiscoveryBase(const TString& name, const TString& description) : TClientGRpcCommand(name, {}, description) {} - + int TClientCommandDiscoveryBase::Run(TConfig &config) { GRpcRequest.set_database(Database); return TClientGRpcCommand::Run(config); -} - +} + //using TClientGRpcCommand::PrintResponse; void TClientCommandDiscoveryBase::PrintResponse(const Ydb::Operations::Operation &response) { if (response.status() != Ydb::StatusIds::SUCCESS) { @@ -28,35 +28,35 @@ void TClientCommandDiscoveryBase::PrintResponse(const Ydb::Operations::Operation if (endpoint.serviceSize()) { for (auto &x : endpoint.Getservice()) Cout << " #" << x; - } + } Cout << Endl; - } - } + } + } } - + // Old kikimr behavior: // ./kikimr discovery list -d <database> struct TClientCommandDiscoveryListEndpoints : TClientCommandDiscoveryBase { - TClientCommandDiscoveryListEndpoints() + TClientCommandDiscoveryListEndpoints() : TClientCommandDiscoveryBase("list", "List existing tenants") - {} - + {} + void Config(TConfig &config) override { - TClientCommand::Config(config); - Database = ""; - config.Opts->AddLongOption('d', "db", "Set target database") - .RequiredArgument("NAME").StoreResult(&Database); - } -}; - -TClientCommandDiscovery::TClientCommandDiscovery() - : TClientCommandTree("discovery", {}, "Endpoint discovery") -{ + TClientCommand::Config(config); + Database = ""; + config.Opts->AddLongOption('d', "db", "Set target database") + .RequiredArgument("NAME").StoreResult(&Database); + } +}; + +TClientCommandDiscovery::TClientCommandDiscovery() + : TClientCommandTree("discovery", {}, "Endpoint discovery") +{ AddCommand(std::make_unique<TClientCommandDiscoveryListEndpoints>()); -} - +} + // New YDB behavior: // ./ydb discover <database> @@ -68,12 +68,12 @@ void TClientCommandDiscoveryLite::Config(TConfig& config) { TClientCommand::Config(config); config.SetFreeArgsNum(1); SetFreeArgTitle(0, "<database>", "Database to discover"); -} +} void TClientCommandDiscoveryLite::Parse(TConfig& config) { TClientGRpcCommand::Parse(config); Database = config.ParseResult->GetFreeArgs().at(0); -} +} } } diff --git a/ydb/core/driver_lib/cli_utils/cli.cpp b/ydb/core/driver_lib/cli_utils/cli.cpp index f8c792bc3c..f84f6784df 100644 --- a/ydb/core/driver_lib/cli_utils/cli.cpp +++ b/ydb/core/driver_lib/cli_utils/cli.cpp @@ -1,31 +1,31 @@ -#include "cli.h" +#include "cli.h" #include <ydb/core/tx/tx_proxy/proxy.h> - -namespace NKikimr { -namespace NDriverClient { - + +namespace NKikimr { +namespace NDriverClient { + void DumpProxyErrorCodes(IOutputStream &o, const NKikimrClient::TResponse &response) { - o << "status: " << response.GetStatus() << Endl; - o << "status transcript: " << static_cast<NMsgBusProxy::EResponseStatus>(response.GetStatus()) << Endl; - if (response.HasProxyErrorCode()) { - o << "proxy error code: " << response.GetProxyErrorCode() << Endl; - o << "proxy error code transcript: " << static_cast<TEvTxUserProxy::TEvProposeTransactionStatus::EStatus>(response.GetProxyErrorCode()) << Endl; - } -} - + o << "status: " << response.GetStatus() << Endl; + o << "status transcript: " << static_cast<NMsgBusProxy::EResponseStatus>(response.GetStatus()) << Endl; + if (response.HasProxyErrorCode()) { + o << "proxy error code: " << response.GetProxyErrorCode() << Endl; + o << "proxy error code transcript: " << static_cast<TEvTxUserProxy::TEvProposeTransactionStatus::EStatus>(response.GetProxyErrorCode()) << Endl; + } +} + void HideOptions(NLastGetopt::TOpts& opts, const TString& prefix) { for (auto opt : opts.Opts_) { if (opt.Get()->GetName().StartsWith(prefix)) { opt.Get()->Hidden_ = true; } } -} +} void HideOptions(NLastGetopt::TOpts& opts) { for (auto opt : opts.Opts_) { opt.Get()->Hidden_ = true; } -} +} } } diff --git a/ydb/core/driver_lib/cli_utils/cli.h b/ydb/core/driver_lib/cli_utils/cli.h index 25b3a5fb60..099664792e 100644 --- a/ydb/core/driver_lib/cli_utils/cli.h +++ b/ydb/core/driver_lib/cli_utils/cli.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "cli_cmd_config.h" @@ -7,7 +7,7 @@ #include <library/cpp/actors/interconnect/poller_tcp.h> #include <ydb/public/lib/deprecated/client/msgbus_client.h> - + #include <library/cpp/deprecated/enum_codegen/enum_codegen.h> #include <util/stream/file.h> #include <util/stream/format.h> @@ -20,15 +20,15 @@ #include <google/protobuf/text_format.h> namespace NKikimr { - + namespace NDriverClient { void DumpProxyErrorCodes(IOutputStream &o, const NKikimrClient::TResponse &response); void DumpSchemeErrorCode(IOutputStream &o, const NKikimrClient::TResponse &response); - - int SchemeInitRoot(TCommandConfig &cmdConf, int argc, char** argv); - int BSAdmCreateVSlots(TCommandConfig &cmdConf, int argc, char **argv); - int BSAdmCreateGroup(TCommandConfig &cmdConf, int argc, char **argv); + + int SchemeInitRoot(TCommandConfig &cmdConf, int argc, char** argv); + int BSAdmCreateVSlots(TCommandConfig &cmdConf, int argc, char **argv); + int BSAdmCreateGroup(TCommandConfig &cmdConf, int argc, char **argv); int CompileAndExecMiniKQL(TCommandConfig &cmdConf, int argc, char **argv); int MessageBusTrace(TCommandConfig &cmdConf, int argc, char** argv); int KeyValueRequest(TCommandConfig &cmdConf, int argc, char **argv); @@ -36,10 +36,10 @@ namespace NDriverClient { int PersQueueStress(TCommandConfig &cmdConf, int argc, char **argv); int PersQueueDiscoverClustersRequest(TCommandConfig &cmdConf, int argc, char **argv); int LoadRequest(TCommandConfig &cmdConf, int argc, char **argv); - int ActorsysPerfTest(TCommandConfig &cmdConf, int argc, char **argv); + int ActorsysPerfTest(TCommandConfig &cmdConf, int argc, char **argv); void HideOptions(NLastGetopt::TOpts& opts, const TString& prefix); void HideOptions(NLastGetopt::TOpts& opts); int NewClient(int argc, char** argv, std::shared_ptr<TModuleFactories> factories); TString NewClientCommandsDescription(std::shared_ptr<TModuleFactories> factories); -} -} +} +} diff --git a/ydb/core/driver_lib/cli_utils/cli_actorsystem_perftest.cpp b/ydb/core/driver_lib/cli_utils/cli_actorsystem_perftest.cpp index 9c597866bc..a26faf4262 100644 --- a/ydb/core/driver_lib/cli_utils/cli_actorsystem_perftest.cpp +++ b/ydb/core/driver_lib/cli_utils/cli_actorsystem_perftest.cpp @@ -1,68 +1,68 @@ -#include "cli.h" +#include "cli.h" #include <ydb/core/actorlib_impl/mad_squirrel.h> #include <library/cpp/actors/core/actorsystem.h> #include <library/cpp/actors/core/scheduler_basic.h> #include <library/cpp/actors/core/executor_pool_basic.h> - -namespace NKikimr { -namespace NDriverClient { - -struct TCmdActorsysPerfConfig : public TCliCmdConfig { - ui32 Threads = 3; - ui32 Duration = 60; - - void Parse(int argc, char **argv) { - using namespace NLastGetopt; - TOpts opts = TOpts::Default(); - opts.AddLongOption('t', "threads", "size of thread pool to measure").DefaultValue(3).StoreResult(&Threads); - opts.AddLongOption('d', "duration", "duration of test in seconds").DefaultValue(60).StoreResult(&Duration); - - ConfigureBaseLastGetopt(opts); - TOptsParseResult res(&opts, argc, argv); - } -}; - -int ActorsysPerfTest(TCommandConfig &cmdConf, int argc, char **argv) { - Y_UNUSED(cmdConf); - using namespace NActors; - - TCmdActorsysPerfConfig config; - config.Parse(argc, argv); - - if (config.Threads < 1 || config.Threads > 1000) { - Cerr << "Thread pool size must be in [1, 1000] range"; - return EXIT_FAILURE; - } - - THolder<TActorSystemSetup> setup(new TActorSystemSetup()); - setup->NodeId = 1; - setup->ExecutorsCount = 1; - setup->Executors.Reset(new TAutoPtr<IExecutorPool>[1]); - setup->Executors[0].Reset(new TBasicExecutorPool(0, config.Threads, 0)); - setup->Scheduler.Reset(new TBasicSchedulerThread(TSchedulerConfig(1024, 0, 100000, false))); - - Cerr << "Starting test for " << TDuration::Seconds(config.Duration).ToString() << " with " << config.Threads << " threads" << Endl; - - TActorSystem actorSys(setup, nullptr); - TVector<TExecutorThreadStats> stats(1); - TExecutorPoolStats poolStats; - - TVector<std::pair<ui32, double>> lineProfile = {{ 0, .0 }, { 0, .0 }, { 0, .0 }, { 0, .0 }, { 0, .0 }, { 0, .0 }, { 0, 0 }, { 0, .0 }}; - - actorSys.Start(); - actorSys.Register(CreateGopherMother(lineProfile, 1000, 2)); - Sleep(TDuration::Seconds(config.Duration)); - actorSys.GetPoolStats(0, poolStats, stats); - actorSys.Stop(); - - ui64 sentEvents = 0; - for (auto &x : stats) - sentEvents += x.SentEvents; - - Cerr << "Produced " << sentEvents << " signals at rate " << sentEvents/config.Duration << " per second " << sentEvents/config.Duration/config.Threads << " per thread" << Endl; - - return EXIT_SUCCESS; -} - -} -} + +namespace NKikimr { +namespace NDriverClient { + +struct TCmdActorsysPerfConfig : public TCliCmdConfig { + ui32 Threads = 3; + ui32 Duration = 60; + + void Parse(int argc, char **argv) { + using namespace NLastGetopt; + TOpts opts = TOpts::Default(); + opts.AddLongOption('t', "threads", "size of thread pool to measure").DefaultValue(3).StoreResult(&Threads); + opts.AddLongOption('d', "duration", "duration of test in seconds").DefaultValue(60).StoreResult(&Duration); + + ConfigureBaseLastGetopt(opts); + TOptsParseResult res(&opts, argc, argv); + } +}; + +int ActorsysPerfTest(TCommandConfig &cmdConf, int argc, char **argv) { + Y_UNUSED(cmdConf); + using namespace NActors; + + TCmdActorsysPerfConfig config; + config.Parse(argc, argv); + + if (config.Threads < 1 || config.Threads > 1000) { + Cerr << "Thread pool size must be in [1, 1000] range"; + return EXIT_FAILURE; + } + + THolder<TActorSystemSetup> setup(new TActorSystemSetup()); + setup->NodeId = 1; + setup->ExecutorsCount = 1; + setup->Executors.Reset(new TAutoPtr<IExecutorPool>[1]); + setup->Executors[0].Reset(new TBasicExecutorPool(0, config.Threads, 0)); + setup->Scheduler.Reset(new TBasicSchedulerThread(TSchedulerConfig(1024, 0, 100000, false))); + + Cerr << "Starting test for " << TDuration::Seconds(config.Duration).ToString() << " with " << config.Threads << " threads" << Endl; + + TActorSystem actorSys(setup, nullptr); + TVector<TExecutorThreadStats> stats(1); + TExecutorPoolStats poolStats; + + TVector<std::pair<ui32, double>> lineProfile = {{ 0, .0 }, { 0, .0 }, { 0, .0 }, { 0, .0 }, { 0, .0 }, { 0, .0 }, { 0, 0 }, { 0, .0 }}; + + actorSys.Start(); + actorSys.Register(CreateGopherMother(lineProfile, 1000, 2)); + Sleep(TDuration::Seconds(config.Duration)); + actorSys.GetPoolStats(0, poolStats, stats); + actorSys.Stop(); + + ui64 sentEvents = 0; + for (auto &x : stats) + sentEvents += x.SentEvents; + + Cerr << "Produced " << sentEvents << " signals at rate " << sentEvents/config.Duration << " per second " << sentEvents/config.Duration/config.Threads << " per thread" << Endl; + + return EXIT_SUCCESS; +} + +} +} diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp index ae65857a53..361e757ca1 100644 --- a/ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp +++ b/ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp @@ -104,11 +104,11 @@ public: virtual void Parse(TConfig& config) override { TClientCommand::Parse(config); - + Program = GetMiniKQL(config.ParseResult->GetFreeArgs().at(0)); if (config.ParseResult->GetFreeArgCount() > 1) Params = GetMiniKQL(config.ParseResult->GetFreeArgs().at(1)); - + Request = new NMsgBusProxy::TBusTabletLocalMKQL; Request->Record.SetTabletID(config.TabletId); auto* pgm = Request->Record.MutableProgram(); @@ -117,7 +117,7 @@ public: } else { pgm->MutableProgram()->SetBin(Program); } - + if (!Params.empty()) { if (IsMiniKQL(Params)) { pgm->MutableParams()->SetText(Params); @@ -125,7 +125,7 @@ public: pgm->MutableParams()->SetBin(Params); } } - + Request->Record.SetConnectToFollower(config.ParseResult->Has("follower")); config.JsonUi64AsText = config.ParseResult->Has("json-ui64-as-string"); config.JsonBinaryAsBase64 = config.ParseResult->Has("json-binary-as-base64"); diff --git a/ydb/core/driver_lib/cli_utils/cli_fakeinitshard.cpp b/ydb/core/driver_lib/cli_utils/cli_fakeinitshard.cpp index 2a99cfa03c..00c4820330 100644 --- a/ydb/core/driver_lib/cli_utils/cli_fakeinitshard.cpp +++ b/ydb/core/driver_lib/cli_utils/cli_fakeinitshard.cpp @@ -1 +1 @@ -#include "cli.h" +#include "cli.h" diff --git a/ydb/core/driver_lib/cli_utils/cli_faketx.cpp b/ydb/core/driver_lib/cli_utils/cli_faketx.cpp index 2a99cfa03c..00c4820330 100644 --- a/ydb/core/driver_lib/cli_utils/cli_faketx.cpp +++ b/ydb/core/driver_lib/cli_utils/cli_faketx.cpp @@ -1 +1 @@ -#include "cli.h" +#include "cli.h" diff --git a/ydb/core/driver_lib/cli_utils/cli_inspect.cpp b/ydb/core/driver_lib/cli_utils/cli_inspect.cpp index 2a99cfa03c..00c4820330 100644 --- a/ydb/core/driver_lib/cli_utils/cli_inspect.cpp +++ b/ydb/core/driver_lib/cli_utils/cli_inspect.cpp @@ -1 +1 @@ -#include "cli.h" +#include "cli.h" diff --git a/ydb/core/driver_lib/cli_utils/cli_minikql_compile_and_exec.cpp b/ydb/core/driver_lib/cli_utils/cli_minikql_compile_and_exec.cpp index 1609a1f7ec..b4429d5721 100644 --- a/ydb/core/driver_lib/cli_utils/cli_minikql_compile_and_exec.cpp +++ b/ydb/core/driver_lib/cli_utils/cli_minikql_compile_and_exec.cpp @@ -51,7 +51,7 @@ int CompileAndExecMiniKQL(TCommandConfig &cmdConf, int argc, char **argv) { mkqlTx->MutableProgram()->SetBin(pgmBin); } else if (config.PathToTextPgm) { TString pgmText = TFileInput(config.PathToTextPgm).ReadAll(); - mkqlTx->MutableProgram()->SetText(pgmText); + mkqlTx->MutableProgram()->SetText(pgmText); } if (config.PathToBinParams) { @@ -59,7 +59,7 @@ int CompileAndExecMiniKQL(TCommandConfig &cmdConf, int argc, char **argv) { mkqlTx->MutableParams()->SetBin(paramsBin); } else if (config.PathToTextParams) { TString paramsText = TFileInput(config.PathToTextParams).ReadAll(); - mkqlTx->MutableParams()->SetText(paramsText); + mkqlTx->MutableParams()->SetText(paramsText); } mkqlTx->SetFlatMKQL(true); diff --git a/ydb/core/driver_lib/cli_utils/cli_scheme_initroot.cpp b/ydb/core/driver_lib/cli_utils/cli_scheme_initroot.cpp index 0e7d19f720..ebca272cc4 100644 --- a/ydb/core/driver_lib/cli_utils/cli_scheme_initroot.cpp +++ b/ydb/core/driver_lib/cli_utils/cli_scheme_initroot.cpp @@ -1,94 +1,94 @@ -#include "cli.h" +#include "cli.h" #include <ydb/public/lib/deprecated/client/msgbus_client.h> #include <ydb/core/scheme/tablet_scheme.h> #include <ydb/core/scheme/scheme_types_defs.h> #include <ydb/core/scheme/scheme_type_registry.h> - -namespace NKikimr { -namespace NDriverClient { - -struct TCmdSchemeInitShardConfig : public TCliCmdConfig { + +namespace NKikimr { +namespace NDriverClient { + +struct TCmdSchemeInitShardConfig : public TCliCmdConfig { TString TagName; - - TAutoPtr<NKikimrTxScheme::TConfig> GlobalConfig; - - TCmdSchemeInitShardConfig(); - - void Parse(int argc, char **argv); -}; - -int SchemeInitRoot(TCommandConfig &cmdConf, int argc, char** argv) { + + TAutoPtr<NKikimrTxScheme::TConfig> GlobalConfig; + + TCmdSchemeInitShardConfig(); + + void Parse(int argc, char **argv); +}; + +int SchemeInitRoot(TCommandConfig &cmdConf, int argc, char** argv) { Y_UNUSED(cmdConf); - -#ifdef _win32_ - WSADATA dummy; - WSAStartup(MAKEWORD(2, 2), &dummy); -#endif - - TCmdSchemeInitShardConfig schemeInitShardConfig; - schemeInitShardConfig.Parse(argc, argv); - + +#ifdef _win32_ + WSADATA dummy; + WSAStartup(MAKEWORD(2, 2), &dummy); +#endif + + TCmdSchemeInitShardConfig schemeInitShardConfig; + schemeInitShardConfig.Parse(argc, argv); + TAutoPtr<NMsgBusProxy::TBusSchemeInitRoot> request(new NMsgBusProxy::TBusSchemeInitRoot()); - - request->Record.SetTagName(schemeInitShardConfig.TagName); - - if (schemeInitShardConfig.GlobalConfig) - request->Record.MutableGlobalConfig()->MergeFrom(*schemeInitShardConfig.GlobalConfig); - - TAutoPtr<NBus::TBusMessage> reply; + + request->Record.SetTagName(schemeInitShardConfig.TagName); + + if (schemeInitShardConfig.GlobalConfig) + request->Record.MutableGlobalConfig()->MergeFrom(*schemeInitShardConfig.GlobalConfig); + + TAutoPtr<NBus::TBusMessage> reply; NBus::EMessageStatus status = schemeInitShardConfig.SyncCall(request, reply); - - switch (status) { - case NBus::MESSAGE_OK: - { + + switch (status) { + case NBus::MESSAGE_OK: + { const NKikimrClient::TResponse &response = static_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record; - Cout << "status: " << response.GetStatus() << Endl; - Cout << "status transcript: " << static_cast<NMsgBusProxy::EResponseStatus>(response.GetStatus()) << Endl; - if (response.HasTabletId()) - Cout << "tabletid: " << response.GetTabletId() << Endl; + Cout << "status: " << response.GetStatus() << Endl; + Cout << "status transcript: " << static_cast<NMsgBusProxy::EResponseStatus>(response.GetStatus()) << Endl; + if (response.HasTabletId()) + Cout << "tabletid: " << response.GetTabletId() << Endl; return response.GetStatus() == NMsgBusProxy::MSTATUS_OK ? 0 : 1; - } - default: - { - const char *description = NBus::MessageStatusDescription(status); - Cerr << description << Endl; - } + } + default: + { + const char *description = NBus::MessageStatusDescription(status); + Cerr << description << Endl; + } return 1; - } -} - -TCmdSchemeInitShardConfig::TCmdSchemeInitShardConfig() - : TagName() -{} - -void TCmdSchemeInitShardConfig::Parse(int argc, char **argv) { - using namespace NLastGetopt; - + } +} + +TCmdSchemeInitShardConfig::TCmdSchemeInitShardConfig() + : TagName() +{} + +void TCmdSchemeInitShardConfig::Parse(int argc, char **argv) { + using namespace NLastGetopt; + TString configPb; TString configPbFile; - - TOpts opts = TOpts::Default(); - opts.AddLongOption('n', "name", "domain name").Required().RequiredArgument("STR").StoreResult(&TagName); - opts.AddLongOption("config", "apply global config").RequiredArgument("STR").StoreResult(&configPb); + + TOpts opts = TOpts::Default(); + opts.AddLongOption('n', "name", "domain name").Required().RequiredArgument("STR").StoreResult(&TagName); + opts.AddLongOption("config", "apply global config").RequiredArgument("STR").StoreResult(&configPb); opts.AddLongOption("config-file", "load global config from file").RequiredArgument("PATH").StoreResult(&configPbFile); - - ConfigureBaseLastGetopt(opts); - TOptsParseResult res(&opts, argc, argv); + + ConfigureBaseLastGetopt(opts); + TOptsParseResult res(&opts, argc, argv); ConfigureMsgBusLastGetopt(res, argc, argv); - + #if 0 - if (!configPbFile.empty()) { - GlobalConfig.Reset(new NKikimrTxScheme::TConfig); + if (!configPbFile.empty()) { + GlobalConfig.Reset(new NKikimrTxScheme::TConfig); Y_VERIFY(ParsePBFromFile(configPbFile, GlobalConfig.Get())); - } else if (!configPb.empty()) { - GlobalConfig.Reset(new NKikimrTxScheme::TConfig); + } else if (!configPb.empty()) { + GlobalConfig.Reset(new NKikimrTxScheme::TConfig); Y_VERIFY(::google::protobuf::TextFormat::ParseFromString(configPb, GlobalConfig.Get())); - } + } #else Cout << "config options for init-root are not used anymore (deprecated)" << Endl; #endif -} - -} -} +} + +} +} diff --git a/ydb/core/driver_lib/cli_utils/cli_scheme_navigate.cpp b/ydb/core/driver_lib/cli_utils/cli_scheme_navigate.cpp index 2a99cfa03c..00c4820330 100644 --- a/ydb/core/driver_lib/cli_utils/cli_scheme_navigate.cpp +++ b/ydb/core/driver_lib/cli_utils/cli_scheme_navigate.cpp @@ -1 +1 @@ -#include "cli.h" +#include "cli.h" diff --git a/ydb/core/driver_lib/cli_utils/ya.make b/ydb/core/driver_lib/cli_utils/ya.make index c72c409c42..cb1f9670be 100644 --- a/ydb/core/driver_lib/cli_utils/ya.make +++ b/ydb/core/driver_lib/cli_utils/ya.make @@ -3,9 +3,9 @@ LIBRARY(cli_utils) OWNER(g:kikimr) SRCS( - cli.cpp + cli.cpp cli.h - cli_actorsystem_perftest.cpp + cli_actorsystem_perftest.cpp cli_cmd_config.h cli_cmd_config.cpp cli_cmds.h diff --git a/ydb/core/driver_lib/run/config.cpp b/ydb/core/driver_lib/run/config.cpp index 2f13c1310c..01f82b98ed 100644 --- a/ydb/core/driver_lib/run/config.cpp +++ b/ydb/core/driver_lib/run/config.cpp @@ -1,7 +1,7 @@ -#include "config.h" - -namespace NKikimr { - +#include "config.h" + +namespace NKikimr { + TKikimrRunConfig::TKikimrRunConfig(NKikimrConfig::TAppConfig& appConfig, ui32 nodeId, const TKikimrScopeId& scopeId) : AppConfig(appConfig) , NodeId(nodeId) diff --git a/ydb/core/driver_lib/run/config.h b/ydb/core/driver_lib/run/config.h index ab42354f76..faf1797413 100644 --- a/ydb/core/driver_lib/run/config.h +++ b/ydb/core/driver_lib/run/config.h @@ -1,15 +1,15 @@ -#pragma once - +#pragma once + #include <ydb/core/protos/config.pb.h> #include <ydb/core/base/event_filter.h> #include <ydb/core/driver_lib/cli_config_base/config_base.h> - + #include <util/generic/hash.h> #include <google/protobuf/text_format.h> - -namespace NKikimr { - + +namespace NKikimr { + union TBasicKikimrServicesMask { struct { bool EnableBasicServices:1; @@ -18,7 +18,7 @@ union TBasicKikimrServicesMask { bool EnableBSNodeWarden:1; bool EnableStateStorageService:1; bool EnableLocalService:1; - bool EnableSharedCache:1; + bool EnableSharedCache:1; bool EnableBlobCache:1; bool EnableLogger:1; bool EnableSchedulerActor:1; @@ -52,7 +52,7 @@ union TBasicKikimrServicesMask { bool EnableConfigsDispatcher:1; bool EnableSecurityServices:1; bool EnableTabletInfo:1; - bool EnableQuoterService:1; + bool EnableQuoterService:1; bool EnablePersQueueClusterDiscovery:1; bool EnableNetClassifier:1; bool EnablePersQueueClusterTracker:1; @@ -88,11 +88,11 @@ struct TKikimrRunConfig { NKikimrConfig::TAppConfig& AppConfig; ui32 NodeId; TKikimrScopeId ScopeId; - + TString PathToConfigCacheFile; TKikimrRunConfig(NKikimrConfig::TAppConfig& appConfig, ui32 nodeId = 0, const TKikimrScopeId& scopeId = {}); }; - -} + +} diff --git a/ydb/core/driver_lib/run/driver.h b/ydb/core/driver_lib/run/driver.h index 93a1085362..7ad96718d1 100644 --- a/ydb/core/driver_lib/run/driver.h +++ b/ydb/core/driver_lib/run/driver.h @@ -23,7 +23,7 @@ namespace NKikimr { XX(EDM_BS, "bs", "admin running kikimr") \ XX(EDM_BLOBSTORAGE, "blobstorage", "admin running kikimr") \ XX(EDM_CMS, "cms", "admin running kikimr") \ - XX(EDM_DISCOVERY, "discovery", "discover endpoints") \ + XX(EDM_DISCOVERY, "discovery", "discover endpoints") \ XX(EDM_WHOAMI, "whoami", "admin running kikimr") \ XX(EDM_FORMAT_INFO, "format-info", "read pdisk format info") \ XX(EDM_FORMAT_UTIL, "format-util", "query blob storage format configuration file") \ @@ -35,8 +35,8 @@ namespace NKikimr { XX(EDM_PERSQUEUE_REQUEST, "persqueue-request", "send protobuf request to a persqueue tablet") \ XX(EDM_PERSQUEUE_STRESS, "persqueue-stress", "stress read or write to a persqueue tablet") \ XX(EDM_PERSQUEUE_DISCOVER_CLUSTERS, "persqueue-discover-clusters", "persqueue session clusters discovery") \ - XX(EDM_LOAD_REQUEST, "bs-load-test", "send protobuf request to blobstorage test load actor (https://wiki.yandex-team.ru/kikimr/developers/BSLoadTest/)") \ - XX(EDM_ACTORSYS_PERFTEST, "actorsys-perf-test", "make actorsystem performance test") \ + XX(EDM_LOAD_REQUEST, "bs-load-test", "send protobuf request to blobstorage test load actor (https://wiki.yandex-team.ru/kikimr/developers/BSLoadTest/)") \ + XX(EDM_ACTORSYS_PERFTEST, "actorsys-perf-test", "make actorsystem performance test") \ CLI_MODES_IMPL(EDriverMode, EDM_NO, MODE_MAP); diff --git a/ydb/core/driver_lib/run/dummy.cpp b/ydb/core/driver_lib/run/dummy.cpp index 87e5362934..12624df93a 100644 --- a/ydb/core/driver_lib/run/dummy.cpp +++ b/ydb/core/driver_lib/run/dummy.cpp @@ -1,58 +1,58 @@ -#include "dummy.h" +#include "dummy.h" #include <ydb/core/base/blobstorage_grouptype.h> - -TAutoPtr<NKikimrConfig::TActorSystemConfig> DummyActorSystemConfig() { - TAutoPtr<NKikimrConfig::TActorSystemConfig> ret(new NKikimrConfig::TActorSystemConfig()); - - NKikimrConfig::TActorSystemConfig::TScheduler *sched = ret->MutableScheduler(); - sched->SetResolution(512); - sched->SetSpinThreshold(0); - sched->SetProgressThreshold(10000); - - NKikimrConfig::TActorSystemConfig::TExecutor *exec1 = ret->AddExecutor(); - NKikimrConfig::TActorSystemConfig::TExecutor *exec2 = ret->AddExecutor(); - NKikimrConfig::TActorSystemConfig::TExecutor *exec3 = ret->AddExecutor(); - - exec1->SetType(NKikimrConfig::TActorSystemConfig::TExecutor::BASIC); - exec1->SetThreads(1); - exec1->SetSpinThreshold(50); - - exec2->SetType(NKikimrConfig::TActorSystemConfig::TExecutor::BASIC); - exec2->SetThreads(2); - exec2->SetSpinThreshold(50); - - exec3->SetType(NKikimrConfig::TActorSystemConfig::TExecutor::IO); - exec3->SetThreads(10); - - ret->SetSysExecutor(0); - ret->SetUserExecutor(1); - ret->SetBatchExecutor(1); - ret->SetIoExecutor(2); - - return ret; -} - -TAutoPtr<NKikimrConfig::TChannelProfileConfig> DummyChannelProfileConfig() { - TAutoPtr<NKikimrConfig::TChannelProfileConfig> ret(new NKikimrConfig::TChannelProfileConfig()); - - auto *profile = ret->AddProfile(); - profile->SetProfileId(0); - - auto *channel0 = profile->AddChannel(); - auto *channel1 = profile->AddChannel(); - auto *channel2 = profile->AddChannel(); - - channel0->SetErasureSpecies(NKikimr::TBlobStorageGroupType::ErasureName[NKikimr::TBlobStorageGroupType::ErasureMirror3]); - channel0->SetPDiskCategory(0); - - channel1->SetErasureSpecies(NKikimr::TBlobStorageGroupType::ErasureName[NKikimr::TBlobStorageGroupType::ErasureMirror3]); - channel1->SetPDiskCategory(0); - - channel2->SetErasureSpecies(NKikimr::TBlobStorageGroupType::ErasureName[NKikimr::TBlobStorageGroupType::ErasureMirror3]); - channel2->SetPDiskCategory(0); - - return ret; -} + +TAutoPtr<NKikimrConfig::TActorSystemConfig> DummyActorSystemConfig() { + TAutoPtr<NKikimrConfig::TActorSystemConfig> ret(new NKikimrConfig::TActorSystemConfig()); + + NKikimrConfig::TActorSystemConfig::TScheduler *sched = ret->MutableScheduler(); + sched->SetResolution(512); + sched->SetSpinThreshold(0); + sched->SetProgressThreshold(10000); + + NKikimrConfig::TActorSystemConfig::TExecutor *exec1 = ret->AddExecutor(); + NKikimrConfig::TActorSystemConfig::TExecutor *exec2 = ret->AddExecutor(); + NKikimrConfig::TActorSystemConfig::TExecutor *exec3 = ret->AddExecutor(); + + exec1->SetType(NKikimrConfig::TActorSystemConfig::TExecutor::BASIC); + exec1->SetThreads(1); + exec1->SetSpinThreshold(50); + + exec2->SetType(NKikimrConfig::TActorSystemConfig::TExecutor::BASIC); + exec2->SetThreads(2); + exec2->SetSpinThreshold(50); + + exec3->SetType(NKikimrConfig::TActorSystemConfig::TExecutor::IO); + exec3->SetThreads(10); + + ret->SetSysExecutor(0); + ret->SetUserExecutor(1); + ret->SetBatchExecutor(1); + ret->SetIoExecutor(2); + + return ret; +} + +TAutoPtr<NKikimrConfig::TChannelProfileConfig> DummyChannelProfileConfig() { + TAutoPtr<NKikimrConfig::TChannelProfileConfig> ret(new NKikimrConfig::TChannelProfileConfig()); + + auto *profile = ret->AddProfile(); + profile->SetProfileId(0); + + auto *channel0 = profile->AddChannel(); + auto *channel1 = profile->AddChannel(); + auto *channel2 = profile->AddChannel(); + + channel0->SetErasureSpecies(NKikimr::TBlobStorageGroupType::ErasureName[NKikimr::TBlobStorageGroupType::ErasureMirror3]); + channel0->SetPDiskCategory(0); + + channel1->SetErasureSpecies(NKikimr::TBlobStorageGroupType::ErasureName[NKikimr::TBlobStorageGroupType::ErasureMirror3]); + channel1->SetPDiskCategory(0); + + channel2->SetErasureSpecies(NKikimr::TBlobStorageGroupType::ErasureName[NKikimr::TBlobStorageGroupType::ErasureMirror3]); + channel2->SetPDiskCategory(0); + + return ret; +} TAutoPtr<NKikimrConfig::TAllocatorConfig> DummyAllocatorConfig() { TAutoPtr<NKikimrConfig::TAllocatorConfig> ret(new NKikimrConfig::TAllocatorConfig()); diff --git a/ydb/core/driver_lib/run/dummy.h b/ydb/core/driver_lib/run/dummy.h index 21dc11c05e..3b546cc1b9 100644 --- a/ydb/core/driver_lib/run/dummy.h +++ b/ydb/core/driver_lib/run/dummy.h @@ -1,7 +1,7 @@ -#pragma once -#include <util/generic/ptr.h> +#pragma once +#include <util/generic/ptr.h> #include <ydb/core/protos/config.pb.h> - -TAutoPtr<NKikimrConfig::TActorSystemConfig> DummyActorSystemConfig(); -TAutoPtr<NKikimrConfig::TChannelProfileConfig> DummyChannelProfileConfig(); + +TAutoPtr<NKikimrConfig::TActorSystemConfig> DummyActorSystemConfig(); +TAutoPtr<NKikimrConfig::TChannelProfileConfig> DummyChannelProfileConfig(); TAutoPtr<NKikimrConfig::TAllocatorConfig> DummyAllocatorConfig(); diff --git a/ydb/core/driver_lib/run/kikimr_services_initializers.cpp b/ydb/core/driver_lib/run/kikimr_services_initializers.cpp index ff94357227..819c1478d1 100644 --- a/ydb/core/driver_lib/run/kikimr_services_initializers.cpp +++ b/ydb/core/driver_lib/run/kikimr_services_initializers.cpp @@ -655,8 +655,8 @@ void TBasicServicesInitializer::InitializeServices(NActors::TActorSystemSetup* s if (icConfig.GetEnforceScopeValidation()) { icCommon->EventFilter = std::make_shared<TEventFilter>(); - RegisterBlobStorageEventScopes(icCommon->EventFilter); - RegisterStateStorageEventScopes(icCommon->EventFilter); + RegisterBlobStorageEventScopes(icCommon->EventFilter); + RegisterStateStorageEventScopes(icCommon->EventFilter); } if (const auto& whiteboardId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(NodeId)) { @@ -825,17 +825,17 @@ void TBSNodeWardenInitializer::InitializeServices(NActors::TActorSystemSetup* se // TStateStorageServiceInitializer -template<typename TCreateFunc> -void StartLocalStateStorageReplicas(TCreateFunc createFunc, TStateStorageInfo *info, ui32 poolId, TActorSystemSetup &setup) { - ui32 index = 0; - for (auto &ring : info->Rings) { +template<typename TCreateFunc> +void StartLocalStateStorageReplicas(TCreateFunc createFunc, TStateStorageInfo *info, ui32 poolId, TActorSystemSetup &setup) { + ui32 index = 0; + for (auto &ring : info->Rings) { for (TActorId replica : ring.Replicas) { - if (replica.NodeId() == setup.NodeId) { - setup.LocalServices.emplace_back( - replica, - TActorSetupCmd(createFunc(info, index), TMailboxType::ReadAsFilled, poolId)); + if (replica.NodeId() == setup.NodeId) { + setup.LocalServices.emplace_back( + replica, + TActorSetupCmd(createFunc(info, index), TMailboxType::ReadAsFilled, poolId)); } - ++index; + ++index; } } } @@ -854,16 +854,16 @@ void TStateStorageServiceInitializer::InitializeServices(NActors::TActorSystemSe Y_VERIFY(ssid <= maxssid); knownss[ssid] = true; - TIntrusivePtr<TStateStorageInfo> ssrInfo; - TIntrusivePtr<TStateStorageInfo> ssbInfo; - TIntrusivePtr<TStateStorageInfo> sbrInfo; + TIntrusivePtr<TStateStorageInfo> ssrInfo; + TIntrusivePtr<TStateStorageInfo> ssbInfo; + TIntrusivePtr<TStateStorageInfo> sbrInfo; + + BuildStateStorageInfos(ssconf, ssrInfo, ssbInfo, sbrInfo); + + StartLocalStateStorageReplicas(CreateStateStorageReplica, ssrInfo.Get(), appData->SystemPoolId, *setup); + StartLocalStateStorageReplicas(CreateStateStorageBoardReplica, ssbInfo.Get(), appData->SystemPoolId, *setup); + StartLocalStateStorageReplicas(CreateSchemeBoardReplica, sbrInfo.Get(), appData->SystemPoolId, *setup); - BuildStateStorageInfos(ssconf, ssrInfo, ssbInfo, sbrInfo); - - StartLocalStateStorageReplicas(CreateStateStorageReplica, ssrInfo.Get(), appData->SystemPoolId, *setup); - StartLocalStateStorageReplicas(CreateStateStorageBoardReplica, ssbInfo.Get(), appData->SystemPoolId, *setup); - StartLocalStateStorageReplicas(CreateSchemeBoardReplica, sbrInfo.Get(), appData->SystemPoolId, *setup); - setup->LocalServices.push_back(std::pair<TActorId, TActorSetupCmd>(MakeStateStorageProxyID(ssid), TActorSetupCmd(CreateStateStorageProxy(ssrInfo.Get(), ssbInfo.Get(), sbrInfo.Get()), TMailboxType::ReadAsFilled, @@ -876,11 +876,11 @@ void TStateStorageServiceInitializer::InitializeServices(NActors::TActorSystemSe TMailboxType::HTSwap, appData->SystemPoolId))); } - - setup->LocalServices.emplace_back( + + setup->LocalServices.emplace_back( TActorId(), - TActorSetupCmd(CreateTenantNodeEnumerationPublisher(), TMailboxType::HTSwap, appData->SystemPoolId) - ); + TActorSetupCmd(CreateTenantNodeEnumerationPublisher(), TMailboxType::HTSwap, appData->SystemPoolId) + ); } // TLocalServiceInitializer @@ -942,7 +942,7 @@ void TLocalServiceInitializer::InitializeServices( } } - setup->LocalServices.push_back(std::make_pair(MakeTenantPoolRootID(), + setup->LocalServices.push_back(std::make_pair(MakeTenantPoolRootID(), TActorSetupCmd(CreateTenantPool(tenantPoolConfig), TMailboxType::ReadAsFilled, 0))); setup->LocalServices.push_back(std::make_pair( @@ -956,45 +956,45 @@ void TLocalServiceInitializer::InitializeServices( NKesus::AddKesusProbesList(); } -// TSharedCacheInitializer - -TSharedCacheInitializer::TSharedCacheInitializer(const TKikimrRunConfig& runConfig) - : IKikimrServicesInitializer(runConfig) -{} - -void TSharedCacheInitializer::InitializeServices( - NActors::TActorSystemSetup* setup, - const NKikimr::TAppData* appData) { +// TSharedCacheInitializer + +TSharedCacheInitializer::TSharedCacheInitializer(const TKikimrRunConfig& runConfig) + : IKikimrServicesInitializer(runConfig) +{} + +void TSharedCacheInitializer::InitializeServices( + NActors::TActorSystemSetup* setup, + const NKikimr::TAppData* appData) { auto config = MakeIntrusive<TSharedPageCacheConfig>(); - + NKikimrSharedCache::TSharedCacheConfig cfg; - if (Config.HasBootstrapConfig() && Config.GetBootstrapConfig().HasSharedCacheConfig()) { + if (Config.HasBootstrapConfig() && Config.GetBootstrapConfig().HasSharedCacheConfig()) { cfg.MergeFrom(Config.GetBootstrapConfig().GetSharedCacheConfig()); - } + } if (Config.HasSharedCacheConfig()) { cfg.MergeFrom(Config.GetSharedCacheConfig()); } - + config->TotalAsyncQueueInFlyLimit = cfg.GetAsyncQueueInFlyLimit(); config->TotalScanQueueInFlyLimit = cfg.GetScanQueueInFlyLimit(); TIntrusivePtr<NMonitoring::TDynamicCounters> tabletGroup = GetServiceCounters(appData->Counters, "tablets"); - TIntrusivePtr<NMonitoring::TDynamicCounters> sausageGroup = tabletGroup->GetSubgroup("type", "S_CACHE"); - + TIntrusivePtr<NMonitoring::TDynamicCounters> sausageGroup = tabletGroup->GetSubgroup("type", "S_CACHE"); + config->CacheConfig = new TCacheCacheConfig(cfg.GetMemoryLimit(), - sausageGroup->GetCounter("fresh"), - sausageGroup->GetCounter("staging"), - sausageGroup->GetCounter("warm")); + sausageGroup->GetCounter("fresh"), + sausageGroup->GetCounter("staging"), + sausageGroup->GetCounter("warm")); config->Counters = new TSharedPageCacheCounters(sausageGroup); - + setup->LocalServices.push_back(std::pair<TActorId, TActorSetupCmd>(MakeSharedPageCacheId(0), TActorSetupCmd(CreateSharedPageCache(config.Get()), TMailboxType::ReadAsFilled, appData->UserPoolId))); auto *configurator = NConsole::CreateSharedCacheConfigurator(); setup->LocalServices.emplace_back(TActorId(), TActorSetupCmd(configurator, TMailboxType::HTSwap, appData->UserPoolId)); -} - +} + // TBlobCacheInitializer TBlobCacheInitializer::TBlobCacheInitializer(const TKikimrRunConfig& runConfig) @@ -1214,14 +1214,14 @@ TTabletCountersAggregatorInitializer::TTabletCountersAggregatorInitializer(const void TTabletCountersAggregatorInitializer::InitializeServices( NActors::TActorSystemSetup* setup, const NKikimr::TAppData* appData) { - { - TActorSetupCmd tabletCountersAggregatorSetup(CreateTabletCountersAggregator(false), TMailboxType::ReadAsFilled, appData->UserPoolId); + { + TActorSetupCmd tabletCountersAggregatorSetup(CreateTabletCountersAggregator(false), TMailboxType::ReadAsFilled, appData->UserPoolId); setup->LocalServices.push_back(std::pair<TActorId, TActorSetupCmd>(MakeTabletCountersAggregatorID(NodeId, false), tabletCountersAggregatorSetup)); - } - { - TActorSetupCmd tabletCountersAggregatorSetup(CreateTabletCountersAggregator(true), TMailboxType::ReadAsFilled, appData->UserPoolId); + } + { + TActorSetupCmd tabletCountersAggregatorSetup(CreateTabletCountersAggregator(true), TMailboxType::ReadAsFilled, appData->UserPoolId); setup->LocalServices.push_back(std::pair<TActorId, TActorSetupCmd>(MakeTabletCountersAggregatorID(NodeId, true), tabletCountersAggregatorSetup)); - } + } } //TGRpcProxyStatusInitializer @@ -1275,7 +1275,7 @@ static TIntrusivePtr<TTabletSetupInfo> CreateTablet( if (tabletInfo->TabletType == TTabletTypes::TYPE_INVALID) { tabletInfo->TabletType = tabletType; } - + return tabletSetup; } @@ -1291,37 +1291,37 @@ void TBootstrapperInitializer::InitializeServices( const NKikimr::TAppData* appData) { if (Config.HasBootstrapConfig()) { for (const auto &boot : Config.GetBootstrapConfig().GetTablet()) { - if (boot.GetAllowDynamicConfiguration()) { + if (boot.GetAllowDynamicConfiguration()) { setup->LocalServices.push_back(std::pair<TActorId, TActorSetupCmd>( TActorId(), - TActorSetupCmd(CreateConfiguredTabletBootstrapper(boot), TMailboxType::HTSwap, appData->SystemPoolId))); - } else { - const bool standby = boot.HasStandBy() && boot.GetStandBy(); - for (const ui32 bootstrapperNode : boot.GetNode()) { - if (bootstrapperNode == NodeId) { + TActorSetupCmd(CreateConfiguredTabletBootstrapper(boot), TMailboxType::HTSwap, appData->SystemPoolId))); + } else { + const bool standby = boot.HasStandBy() && boot.GetStandBy(); + for (const ui32 bootstrapperNode : boot.GetNode()) { + if (bootstrapperNode == NodeId) { TIntrusivePtr<TTabletStorageInfo> info(TabletStorageInfoFromProto(boot.GetInfo())); - auto tabletType = BootstrapperTypeToTabletType(boot.GetType()); + auto tabletType = BootstrapperTypeToTabletType(boot.GetType()); - auto tabletSetupInfo = CreateTablet( + auto tabletSetupInfo = CreateTablet( TTabletTypes::TypeToStr(tabletType), info, appData); - TIntrusivePtr<TBootstrapperInfo> bi = new TBootstrapperInfo(tabletSetupInfo.Get()); + TIntrusivePtr<TBootstrapperInfo> bi = new TBootstrapperInfo(tabletSetupInfo.Get()); - if (boot.NodeSize() != 1) { - bi->OtherNodes.reserve(boot.NodeSize() - 1); - for (ui32 x : boot.GetNode()) - if (x != NodeId) - bi->OtherNodes.push_back(x); - if (boot.HasWatchThreshold()) - bi->WatchThreshold = TDuration::MilliSeconds(boot.GetWatchThreshold()); + if (boot.NodeSize() != 1) { + bi->OtherNodes.reserve(boot.NodeSize() - 1); + for (ui32 x : boot.GetNode()) + if (x != NodeId) + bi->OtherNodes.push_back(x); + if (boot.HasWatchThreshold()) + bi->WatchThreshold = TDuration::MilliSeconds(boot.GetWatchThreshold()); if (boot.HasStartFollowers()) bi->StartFollowers = boot.GetStartFollowers(); - } - + } + setup->LocalServices.push_back(std::pair<TActorId, TActorSetupCmd>(MakeBootstrapperID(info->TabletID, bootstrapperNode), TActorSetupCmd(CreateBootstrapper(info.Get(), bi.Get(), standby), TMailboxType::HTSwap, appData->SystemPoolId))); } } @@ -1520,24 +1520,24 @@ void TGRpcServicesInitializer::InitializeServices(NActors::TActorSystemSetup* se TActorSetupCmd(proxy, TMailboxType::ReadAsFilled, appData->UserPoolId)); } } - - if (Config.HasGRpcConfig() && Config.GetGRpcConfig().GetStartGRpcProxy()) { - // logical copy from TKikimrRunner::InitializeGrpc - const auto &config = Config.GetGRpcConfig(); - + + if (Config.HasGRpcConfig() && Config.GetGRpcConfig().GetStartGRpcProxy()) { + // logical copy from TKikimrRunner::InitializeGrpc + const auto &config = Config.GetGRpcConfig(); + if (appData->Mon) { setup->LocalServices.emplace_back(NGRpcService::GrpcMonServiceId(), TActorSetupCmd(NGRpcService::CreateGrpcMonService(), TMailboxType::ReadAsFilled, appData->UserPoolId) ); } - TVector<TString> rootDomains; - for (auto &domain : appData->DomainsInfo->Domains) - rootDomains.emplace_back("/" + domain.second->Name); - - const bool ignoreServeRootDomain = ScopeId.IsTenantScope(); - const bool serveRootDomain = !ignoreServeRootDomain && config.GetServeRootDomains(); - + TVector<TString> rootDomains; + for (auto &domain : appData->DomainsInfo->Domains) + rootDomains.emplace_back("/" + domain.second->Name); + + const bool ignoreServeRootDomain = ScopeId.IsTenantScope(); + const bool serveRootDomain = !ignoreServeRootDomain && config.GetServeRootDomains(); + auto stringsFromProto = [](TVector<TString>& vec, const auto& proto) { if (!proto.empty()) { vec.reserve(proto.size()); @@ -1548,78 +1548,78 @@ void TGRpcServicesInitializer::InitializeServices(NActors::TActorSystemSetup* se }; TVector<TIntrusivePtr<NGRpcService::TGrpcEndpointDescription>> endpoints; - const TString &address = config.GetHost() && config.GetHost() != "[::]" ? config.GetHost() : FQDNHostName(); - if (const ui32 port = config.GetPort()) { - TIntrusivePtr<NGRpcService::TGrpcEndpointDescription> desc = new NGRpcService::TGrpcEndpointDescription(); + const TString &address = config.GetHost() && config.GetHost() != "[::]" ? config.GetHost() : FQDNHostName(); + if (const ui32 port = config.GetPort()) { + TIntrusivePtr<NGRpcService::TGrpcEndpointDescription> desc = new NGRpcService::TGrpcEndpointDescription(); desc->Address = config.GetPublicHost() ? config.GetPublicHost() : address; desc->Port = config.GetPublicPort() ? config.GetPublicPort() : port; - desc->Ssl = false; - + desc->Ssl = false; + stringsFromProto(desc->AddressesV4, config.GetPublicAddressesV4()); stringsFromProto(desc->AddressesV6, config.GetPublicAddressesV6()); - if (serveRootDomain) - desc->ServedDatabases.insert(desc->ServedDatabases.end(), rootDomains.begin(), rootDomains.end()); - desc->ServedServices.insert(desc->ServedServices.end(), config.GetServices().begin(), config.GetServices().end()); + if (serveRootDomain) + desc->ServedDatabases.insert(desc->ServedDatabases.end(), rootDomains.begin(), rootDomains.end()); + desc->ServedServices.insert(desc->ServedServices.end(), config.GetServices().begin(), config.GetServices().end()); endpoints.push_back(std::move(desc)); - } - - if (const ui32 sslPort = config.GetSslPort()) { - TIntrusivePtr<NGRpcService::TGrpcEndpointDescription> desc = new NGRpcService::TGrpcEndpointDescription(); + } + + if (const ui32 sslPort = config.GetSslPort()) { + TIntrusivePtr<NGRpcService::TGrpcEndpointDescription> desc = new NGRpcService::TGrpcEndpointDescription(); desc->Address = config.GetPublicHost() ? config.GetPublicHost() : address; desc->Port = config.GetPublicSslPort() ? config.GetPublicSslPort() : sslPort; - desc->Ssl = true; - + desc->Ssl = true; + stringsFromProto(desc->AddressesV4, config.GetPublicAddressesV4()); stringsFromProto(desc->AddressesV6, config.GetPublicAddressesV6()); desc->TargetNameOverride = config.GetPublicTargetNameOverride(); - if (serveRootDomain) - desc->ServedDatabases.insert(desc->ServedDatabases.end(), rootDomains.begin(), rootDomains.end()); - - desc->ServedServices.insert(desc->ServedServices.end(), config.GetServices().begin(), config.GetServices().end()); + if (serveRootDomain) + desc->ServedDatabases.insert(desc->ServedDatabases.end(), rootDomains.begin(), rootDomains.end()); + + desc->ServedServices.insert(desc->ServedServices.end(), config.GetServices().begin(), config.GetServices().end()); endpoints.push_back(std::move(desc)); - } - - for (auto &sx : config.GetExtEndpoints()) { - const TString &localAddress = sx.GetHost() ? (sx.GetHost() != "[::]" ? sx.GetHost() : FQDNHostName()) : address; - if (const ui32 port = sx.GetPort()) { - TIntrusivePtr<NGRpcService::TGrpcEndpointDescription> desc = new NGRpcService::TGrpcEndpointDescription(); + } + + for (auto &sx : config.GetExtEndpoints()) { + const TString &localAddress = sx.GetHost() ? (sx.GetHost() != "[::]" ? sx.GetHost() : FQDNHostName()) : address; + if (const ui32 port = sx.GetPort()) { + TIntrusivePtr<NGRpcService::TGrpcEndpointDescription> desc = new NGRpcService::TGrpcEndpointDescription(); desc->Address = sx.GetPublicHost() ? sx.GetPublicHost() : localAddress; desc->Port = sx.GetPublicPort() ? sx.GetPublicPort() : port; - desc->Ssl = false; - + desc->Ssl = false; + stringsFromProto(desc->AddressesV4, sx.GetPublicAddressesV4()); stringsFromProto(desc->AddressesV6, sx.GetPublicAddressesV6()); - if (serveRootDomain) - desc->ServedDatabases.insert(desc->ServedDatabases.end(), rootDomains.begin(), rootDomains.end()); - desc->ServedServices.insert(desc->ServedServices.end(), sx.GetServices().begin(), sx.GetServices().end()); + if (serveRootDomain) + desc->ServedDatabases.insert(desc->ServedDatabases.end(), rootDomains.begin(), rootDomains.end()); + desc->ServedServices.insert(desc->ServedServices.end(), sx.GetServices().begin(), sx.GetServices().end()); endpoints.push_back(std::move(desc)); - } - - if (const ui32 sslPort = sx.GetSslPort()) { - TIntrusivePtr<NGRpcService::TGrpcEndpointDescription> desc = new NGRpcService::TGrpcEndpointDescription(); + } + + if (const ui32 sslPort = sx.GetSslPort()) { + TIntrusivePtr<NGRpcService::TGrpcEndpointDescription> desc = new NGRpcService::TGrpcEndpointDescription(); desc->Address = sx.GetPublicHost() ? sx.GetPublicHost() : localAddress; desc->Port = sx.GetPublicSslPort() ? sx.GetPublicSslPort() : sslPort; - desc->Ssl = true; - + desc->Ssl = true; + stringsFromProto(desc->AddressesV4, sx.GetPublicAddressesV4()); stringsFromProto(desc->AddressesV6, sx.GetPublicAddressesV6()); desc->TargetNameOverride = sx.GetPublicTargetNameOverride(); - if (serveRootDomain) - desc->ServedDatabases.insert(desc->ServedDatabases.end(), rootDomains.begin(), rootDomains.end()); - desc->ServedServices.insert(desc->ServedServices.end(), sx.GetServices().begin(), sx.GetServices().end()); + if (serveRootDomain) + desc->ServedDatabases.insert(desc->ServedDatabases.end(), rootDomains.begin(), rootDomains.end()); + desc->ServedServices.insert(desc->ServedServices.end(), sx.GetServices().begin(), sx.GetServices().end()); endpoints.push_back(std::move(desc)); - } - } + } + } setup->LocalServices.emplace_back( NGRpcService::CreateGrpcPublisherServiceActorId(), TActorSetupCmd(CreateGrpcPublisherServiceActor(std::move(endpoints)), TMailboxType::ReadAsFilled, appData->UserPoolId) ); - } + } } #ifdef ACTORSLIB_COLLECT_EXEC_STATS @@ -1915,18 +1915,18 @@ void TMemoryTrackerInitializer::InitializeServices( ); } -TQuoterServiceInitializer::TQuoterServiceInitializer(const TKikimrRunConfig& runConfig) - : IKikimrServicesInitializer(runConfig) -{} - -void TQuoterServiceInitializer::InitializeServices(NActors::TActorSystemSetup* setup, const NKikimr::TAppData* appData) { - Y_UNUSED(appData); - setup->LocalServices.push_back(std::make_pair( - MakeQuoterServiceID(), - TActorSetupCmd(CreateQuoterService(), TMailboxType::HTSwap, appData->SystemPoolId)) - ); -} - +TQuoterServiceInitializer::TQuoterServiceInitializer(const TKikimrRunConfig& runConfig) + : IKikimrServicesInitializer(runConfig) +{} + +void TQuoterServiceInitializer::InitializeServices(NActors::TActorSystemSetup* setup, const NKikimr::TAppData* appData) { + Y_UNUSED(appData); + setup->LocalServices.push_back(std::make_pair( + MakeQuoterServiceID(), + TActorSetupCmd(CreateQuoterService(), TMailboxType::HTSwap, appData->SystemPoolId)) + ); +} + TKqpServiceInitializer::TKqpServiceInitializer( const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories> factories) diff --git a/ydb/core/driver_lib/run/kikimr_services_initializers.h b/ydb/core/driver_lib/run/kikimr_services_initializers.h index 47d4691032..407ce1bb7b 100644 --- a/ydb/core/driver_lib/run/kikimr_services_initializers.h +++ b/ydb/core/driver_lib/run/kikimr_services_initializers.h @@ -84,13 +84,13 @@ public: void InitializeServices(NActors::TActorSystemSetup *setup, const NKikimr::TAppData *appData) override; }; -class TSharedCacheInitializer : public IKikimrServicesInitializer { -public: +class TSharedCacheInitializer : public IKikimrServicesInitializer { +public: TSharedCacheInitializer(const TKikimrRunConfig& runConfig); - + void InitializeServices(NActors::TActorSystemSetup *setup, const NKikimr::TAppData *appData) override; -}; - +}; + class TBlobCacheInitializer : public IKikimrServicesInitializer { public: TBlobCacheInitializer(const TKikimrRunConfig& runConfig); @@ -371,13 +371,13 @@ public: void InitializeServices(NActors::TActorSystemSetup* setup, const NKikimr::TAppData* appData) override; }; -class TQuoterServiceInitializer : public IKikimrServicesInitializer { -public: - TQuoterServiceInitializer(const TKikimrRunConfig& runConfig); +class TQuoterServiceInitializer : public IKikimrServicesInitializer { +public: + TQuoterServiceInitializer(const TKikimrRunConfig& runConfig); + + void InitializeServices(NActors::TActorSystemSetup* setup, const NKikimr::TAppData* appData) override; +}; - void InitializeServices(NActors::TActorSystemSetup* setup, const NKikimr::TAppData* appData) override; -}; - class TKqpServiceInitializer : public IKikimrServicesInitializer { public: TKqpServiceInitializer(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories> factories); diff --git a/ydb/core/driver_lib/run/main.cpp b/ydb/core/driver_lib/run/main.cpp index 66497a9a0e..f0a9315685 100644 --- a/ydb/core/driver_lib/run/main.cpp +++ b/ydb/core/driver_lib/run/main.cpp @@ -1,11 +1,11 @@ #include "main.h" #include "driver.h" - + // add support for base utils #include <ydb/core/driver_lib/base_utils/format_info.h> #include <ydb/core/driver_lib/base_utils/format_util.h> #include <ydb/core/driver_lib/base_utils/node_by_host.h> - + // add support for CLI utils #include <ydb/core/driver_lib/cli_utils/cli.h> @@ -21,7 +21,7 @@ #include <sys/mman.h> #endif -namespace NKikimr { +namespace NKikimr { int MainRun(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories> factories) { #ifdef _win32_ @@ -57,11 +57,11 @@ int MainRun(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories> #endif using namespace NLastGetopt; using TDriverModeParser = TCliCommands<EDriverMode>; - + NKikimrConfig::TAppConfig appConfig; TCommandConfig cmdConf; TKikimrRunConfig runConfig(appConfig); - + TRunCommandConfigParser configParser(runConfig); TOpts opts = TOpts::Default(); @@ -103,7 +103,7 @@ int MainRun(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories> configParser.ParseGlobalOpts(res); switch (mode) { - case EDM_RUN: + case EDM_RUN: { configParser.ParseRunOpts(argc, argv); configParser.ApplyParsedOptions(); @@ -117,7 +117,7 @@ int MainRun(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories> case EDM_BLOBSTORAGE: case EDM_SERVER: case EDM_CMS: - case EDM_DISCOVERY: + case EDM_DISCOVERY: case EDM_WHOAMI: return NDriverClient::NewClient(argc + freeArgsPos, argv - freeArgsPos, factories); case EDM_FORMAT_INFO: @@ -126,8 +126,8 @@ int MainRun(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories> return MainFormatUtil(cmdConf, argc, argv); case EDM_NODE_BY_HOST: return MainNodeByHost(cmdConf, argc, argv); - case EDM_SCHEME_INITROOT: - return NDriverClient::SchemeInitRoot(cmdConf, argc, argv); + case EDM_SCHEME_INITROOT: + return NDriverClient::SchemeInitRoot(cmdConf, argc, argv); case EDM_COMPILE_AND_EXEC_MINIKQL: return NDriverClient::CompileAndExecMiniKQL(cmdConf, argc, argv); case EDM_TRACE: @@ -142,14 +142,14 @@ int MainRun(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories> return NDriverClient::PersQueueDiscoverClustersRequest(cmdConf, argc, argv); case EDM_LOAD_REQUEST: return NDriverClient::LoadRequest(cmdConf, argc, argv); - case EDM_ACTORSYS_PERFTEST: - return NDriverClient::ActorsysPerfTest(cmdConf, argc, argv); - default: + case EDM_ACTORSYS_PERFTEST: + return NDriverClient::ActorsysPerfTest(cmdConf, argc, argv); + default: Y_FAIL("Not Happens"); - } - } + } + } } // NKikimr - + namespace { std::terminate_handler defaultTerminateHandler; } @@ -172,7 +172,7 @@ void SetupTerminateHandler() { } int ParameterizedMain(int argc, char **argv, std::shared_ptr<NKikimr::TModuleFactories> factories) { - try { + try { return NKikimr::Main(argc, argv, std::move(factories)); } catch (const NYdb::NConsoleClient::TMissUseException& e) { @@ -181,8 +181,8 @@ int ParameterizedMain(int argc, char **argv, std::shared_ptr<NKikimr::TModuleFac return 1; } catch (const yexception& e) { - Cerr << "Caught exception: " << e.what() << Endl; - return 1; - } -} + Cerr << "Caught exception: " << e.what() << Endl; + return 1; + } +} diff --git a/ydb/core/driver_lib/run/run.cpp b/ydb/core/driver_lib/run/run.cpp index 74cd67ca5e..a4f74aa4e0 100644 --- a/ydb/core/driver_lib/run/run.cpp +++ b/ydb/core/driver_lib/run/run.cpp @@ -1,8 +1,8 @@ -#include "run.h" -#include "dummy.h" +#include "run.h" +#include "dummy.h" #include "service_initializer.h" #include "kikimr_services_initializers.h" - + #include <library/cpp/actors/core/events.h> #include <library/cpp/actors/core/hfunc.h> #include <library/cpp/actors/core/event_local.h> @@ -36,13 +36,13 @@ #include <ydb/core/mon_alloc/profiler.h> #include <library/cpp/actors/util/affinity.h> - + #include <ydb/core/base/appdata.h> #include <ydb/core/base/counters.h> #include <ydb/core/base/tabletid.h> #include <ydb/core/base/statestorage_impl.h> #include <ydb/core/protos/services.pb.h> - + #include <ydb/core/mind/local.h> #include <ydb/core/mind/tenant_pool.h> #include <ydb/core/base/hive.h> @@ -55,16 +55,16 @@ #include <ydb/core/tablet/tablet_list_renderer.h> #include <ydb/core/tablet/tablet_monitoring_proxy.h> #include <ydb/core/tablet/tablet_counters_aggregator.h> - + #include <ydb/core/tx/tx.h> #include <ydb/core/tx/datashard/datashard.h> #include <ydb/core/tx/tx_proxy/proxy.h> #include <ydb/core/tx/time_cast/time_cast.h> - + #include <ydb/core/tablet_flat/tablet_flat_executed.h> - + #include <ydb/core/mind/bscontroller/bsc.h> - + #include <ydb/core/blobstorage/other/mon_get_blob_page.h> #include <ydb/core/blobstorage/other/mon_blob_range_page.h> #include <ydb/core/blobstorage/other/mon_vdisk_stream.h> @@ -108,7 +108,7 @@ #include <library/cpp/sighandler/async_signals_handler.h> #include <library/cpp/svnversion/svnversion.h> #include <library/cpp/malloc/api/malloc.h> - + #include <ydb/core/util/sig.h> #include <ydb/core/node_whiteboard/node_whiteboard.h> @@ -125,17 +125,17 @@ #include <ydb/core/tracing/tablet_info.h> -namespace NKikimr { - +namespace NKikimr { + class TDomainsInitializer : public IAppDataInitializer { const NKikimrConfig::TAppConfig& Config; - + public: TDomainsInitializer(const TKikimrRunConfig& runConfig) : Config(runConfig.AppConfig) { } - + virtual void Initialize(NKikimr::TAppData* appData) override { // setup domain info @@ -150,18 +150,18 @@ public: Y_VERIFY(!poolTypes.contains(type.GetKind()), "duplicated slot type"); poolTypes[type.GetKind()] = type.GetPoolConfig(); } - + bool isExplicitTabletIds = domain.ExplicitCoordinatorsSize() + domain.ExplicitMediatorsSize() + domain.ExplicitAllocatorsSize(); - const ui32 defaultSSId = domainId; - const ui32 schemeBoardSSId = (domain.HasSchemeBoardSSId() && domain.GetSchemeBoardSSId()) ? domain.GetSchemeBoardSSId() : defaultSSId; - Y_VERIFY(Find(domain.GetSSId(), defaultSSId) != domain.GetSSId().end()); - Y_VERIFY(Find(domain.GetSSId(), schemeBoardSSId) != domain.GetSSId().end()); - + const ui32 defaultSSId = domainId; + const ui32 schemeBoardSSId = (domain.HasSchemeBoardSSId() && domain.GetSchemeBoardSSId()) ? domain.GetSchemeBoardSSId() : defaultSSId; + Y_VERIFY(Find(domain.GetSSId(), defaultSSId) != domain.GetSSId().end()); + Y_VERIFY(Find(domain.GetSSId(), schemeBoardSSId) != domain.GetSSId().end()); + TDomainsInfo::TDomain::TPtr domainPtr = nullptr; if (isExplicitTabletIds) { domainPtr = TDomainsInfo::TDomain::ConstructDomainWithExplicitTabletIds(domainName, domainId, schemeRoot, - defaultSSId, schemeBoardSSId, domain.GetSSId(), + defaultSSId, schemeBoardSSId, domain.GetSSId(), domainId, domain.GetHiveUid(), planResolution, domain.GetExplicitCoordinators(), @@ -170,7 +170,7 @@ public: poolTypes); } else { domainPtr = TDomainsInfo::TDomain::ConstructDomain(domainName, domainId, schemeRoot, - defaultSSId, schemeBoardSSId, domain.GetSSId(), + defaultSSId, schemeBoardSSId, domain.GetSSId(), domainId, domain.GetHiveUid(), planResolution, domain.GetCoordinator(), domain.GetMediator(), @@ -207,18 +207,18 @@ public: appData->CompactionConfig = Config.GetCompactionConfig(); } -}; - - +}; + + class TChannelProfilesInitializer : public IAppDataInitializer { const NKikimrConfig::TAppConfig& Config; - + public: TChannelProfilesInitializer(const TKikimrRunConfig& runConfig) : Config(runConfig.AppConfig) { } - + virtual void Initialize(NKikimr::TAppData* appData) override { if (!Config.HasChannelProfileConfig()) { @@ -254,9 +254,9 @@ public: outProfile.Channels.push_back(TChannelProfiles::TProfile::TChannel(erasure, pDiskCategory, vDiskCategory, kind)); ++channelIdx; } - } - } - + } + } + }; @@ -276,11 +276,11 @@ public: appData->ProxySchemeCacheNodes = Config.GetBootstrapConfig().GetProxySchemeCacheNodes(); if (Config.GetBootstrapConfig().HasProxySchemeCacheDistNodes()) appData->ProxySchemeCacheDistrNodes = Config.GetBootstrapConfig().GetProxySchemeCacheDistNodes(); - } - } + } + } }; - - + + class TDynamicNameserviceInitializer : public IAppDataInitializer { const NKikimrConfig::TAppConfig& Config; @@ -337,7 +337,7 @@ TKikimrRunner::~TKikimrRunner() { ActorSystem.Destroy(); } } - + void TKikimrRunner::InitializeMonitoring(const TKikimrRunConfig& runConfig, bool includeHostName) { @@ -461,9 +461,9 @@ void TKikimrRunner::InitializeMessageBus( BusMonPage.Reset(new NMonitoring::TBusNgMonPage()); Monitoring->Register(BusMonPage.Get()); } - } + } } - + static TString ReadFile(const TString& fileName) { TFileInput f(fileName); return f.ReadAll(); @@ -489,17 +489,17 @@ void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) { std::unordered_map<TString, bool*> names; - bool hasLegacy = opts.SslData.Empty() && services.empty(); + bool hasLegacy = opts.SslData.Empty() && services.empty(); names["legacy"] = &hasLegacy; - bool hasScripting = services.empty(); + bool hasScripting = services.empty(); names["scripting"] = &hasScripting; - bool hasCms = services.empty(); + bool hasCms = services.empty(); names["cms"] = &hasCms; - bool hasKesus = services.empty(); + bool hasKesus = services.empty(); names["locking"] = names["kesus"] = &hasKesus; bool hasMonitoring = services.empty(); names["monitoring"] = &hasMonitoring; - bool hasDiscovery = services.empty(); + bool hasDiscovery = services.empty(); names["discovery"] = &hasDiscovery; bool hasTableService = services.empty(); names["table_service"] = &hasTableService; @@ -509,7 +509,7 @@ void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) { names["yql"] = &hasYql; bool hasYqlInternal = services.empty(); names["yql_internal"] = &hasYqlInternal; - bool hasPQ = services.empty(); + bool hasPQ = services.empty(); names["pq"] = &hasPQ; bool hasPQv1 = false; names["pqv1"] = &hasPQv1; @@ -543,11 +543,11 @@ void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) { std::unordered_set<TString> enabled; for (const auto& name : services) { enabled.insert(name); - } + } for (const auto& name : grpcConfig.GetServicesEnabled()) { enabled.insert(name); } - + std::unordered_set<TString> disabled; for (const auto& name : grpcConfig.GetServicesDisabled()) { disabled.insert(name); @@ -601,30 +601,30 @@ void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) { } } - const auto grpcRequestProxyId = NGRpcService::CreateGRpcRequestProxyId(); - - if (hasLegacy) { - // start legacy service - auto grpcService = new NGRpcProxy::TGRpcService(); + const auto grpcRequestProxyId = NGRpcService::CreateGRpcRequestProxyId(); + + if (hasLegacy) { + // start legacy service + auto grpcService = new NGRpcProxy::TGRpcService(); auto future = grpcService->Prepare(ActorSystem.Get(), NMsgBusProxy::CreatePersQueueMetaCacheV2Id(), NMsgBusProxy::CreateMsgBusProxyId(), Counters); - auto startCb = [grpcService](NThreading::TFuture<void> result) { - if (result.HasException()) { - try { - result.GetValue(); - } - catch (const std::exception& ex) { - Y_FAIL("Unable to prepare GRpc service: %s", ex.what()); - } - } - else { - grpcService->Start(); - } - }; - - future.Subscribe(startCb); - server.AddService(grpcService); - } - + auto startCb = [grpcService](NThreading::TFuture<void> result) { + if (result.HasException()) { + try { + result.GetValue(); + } + catch (const std::exception& ex) { + Y_FAIL("Unable to prepare GRpc service: %s", ex.what()); + } + } + else { + grpcService->Start(); + } + }; + + future.Subscribe(startCb); + server.AddService(grpcService); + } + if (hasTableService) { server.AddService(new NGRpcService::TGRpcYdbTableService(ActorSystem.Get(), Counters, grpcRequestProxyId)); } @@ -642,13 +642,13 @@ void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) { if (hasS3Internal) { server.AddService(new NGRpcService::TGRpcYdbS3InternalService(ActorSystem.Get(), Counters, grpcRequestProxyId)); - } - - if (hasScripting) { - server.AddService(new NGRpcService::TGRpcYdbScriptingService(ActorSystem.Get(), Counters, - grpcRequestProxyId)); - } - + } + + if (hasScripting) { + server.AddService(new NGRpcService::TGRpcYdbScriptingService(ActorSystem.Get(), Counters, + grpcRequestProxyId)); + } + if (hasLongTx) { server.AddService(new NGRpcService::TGRpcYdbLongTxService(ActorSystem.Get(), Counters, grpcRequestProxyId)); } @@ -667,12 +667,12 @@ void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) { if (hasImport) { server.AddService(new NGRpcService::TGRpcYdbImportService(ActorSystem.Get(), Counters, grpcRequestProxyId)); - } - - if (hasKesus) { - server.AddService(new NKesus::TKesusGRpcService(ActorSystem.Get(), Counters, grpcRequestProxyId)); - } - + } + + if (hasKesus) { + server.AddService(new NKesus::TKesusGRpcService(ActorSystem.Get(), Counters, grpcRequestProxyId)); + } + if (hasPQv1) { server.AddService(new NGRpcService::V1::TGRpcPersQueueService(ActorSystem.Get(), Counters, NMsgBusProxy::CreatePersQueueMetaCacheV2Id(), grpcRequestProxyId)); } @@ -689,13 +689,13 @@ void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) { )); } - if (hasCms) { - server.AddService(new NGRpcService::TGRpcCmsService(ActorSystem.Get(), Counters, grpcRequestProxyId)); - } - - if (hasDiscovery) { - server.AddService(new NGRpcService::TGRpcDiscoveryService(ActorSystem.Get(), Counters, grpcRequestProxyId)); - } + if (hasCms) { + server.AddService(new NGRpcService::TGRpcCmsService(ActorSystem.Get(), Counters, grpcRequestProxyId)); + } + + if (hasDiscovery) { + server.AddService(new NGRpcService::TGRpcDiscoveryService(ActorSystem.Get(), Counters, grpcRequestProxyId)); + } if (hasRateLimiter) { server.AddService(new NQuoter::TRateLimiterGRpcService(ActorSystem.Get(), Counters, grpcRequestProxyId)); @@ -727,8 +727,8 @@ void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) { server.AddService(service); } } - }; - + }; + if (appConfig.HasGRpcConfig() && appConfig.GetGRpcConfig().GetStartGRpcProxy()) { const auto& grpcConfig = appConfig.GetGRpcConfig(); @@ -745,7 +745,7 @@ void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) { if (appConfig.HasDomainsConfig() && appConfig.GetDomainsConfig().HasSecurityConfig() && appConfig.GetDomainsConfig().GetSecurityConfig().HasEnforceUserTokenRequirement()) { - opts.SetUseAuth(appConfig.GetDomainsConfig().GetSecurityConfig().GetEnforceUserTokenRequirement()); + opts.SetUseAuth(appConfig.GetDomainsConfig().GetSecurityConfig().GetEnforceUserTokenRequirement()); } if (grpcConfig.HasKeepAliveEnable()) { @@ -757,8 +757,8 @@ void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) { opts.SetKeepAliveIdleTimeoutTriggerSec(grpcConfig.GetKeepAliveIdleTimeoutTriggerSec()); opts.SetKeepAliveMaxProbeCount(grpcConfig.GetKeepAliveMaxProbeCount()); opts.SetKeepAliveProbeIntervalSec(grpcConfig.GetKeepAliveProbeIntervalSec()); - } - else { + } + else { opts.SetKeepAliveEnable(false); } } @@ -776,48 +776,48 @@ void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) { sslOpts.SetSslData(sslData); GRpcServers.push_back({ "grpcs", new NGrpc::TGRpcServer(sslOpts) }); - + fillFn(grpcConfig, *GRpcServers.back().second, sslOpts); } if (grpcConfig.GetPort()) { GRpcServers.push_back({ "grpc", new NGrpc::TGRpcServer(opts) }); - + fillFn(grpcConfig, *GRpcServers.back().second, opts); } - - for (auto &ex : grpcConfig.GetExtEndpoints()) { - // todo: check uniq - if (ex.GetPort()) { + + for (auto &ex : grpcConfig.GetExtEndpoints()) { + // todo: check uniq + if (ex.GetPort()) { NGrpc::TServerOptions xopts = opts; - xopts.SetPort(ex.GetPort()); - - if (ex.GetHost()) - xopts.SetHost(ex.GetHost()); - + xopts.SetPort(ex.GetPort()); + + if (ex.GetHost()) + xopts.SetHost(ex.GetHost()); + GRpcServers.push_back({ "grpc", new NGrpc::TGRpcServer(xopts) }); fillFn(ex, *GRpcServers.back().second, xopts); } - if (ex.HasSslPort() && ex.GetSslPort()) { + if (ex.HasSslPort() && ex.GetSslPort()) { NGrpc::TServerOptions xopts = opts; - xopts.SetPort(ex.GetSslPort()); - - + xopts.SetPort(ex.GetSslPort()); + + NGrpc::TSslData sslData; - sslData.Root = ex.HasCA() ? ReadFile(ex.GetCA()) : ReadFile(grpcConfig.GetCA()); - sslData.Cert = ex.HasCert() ? ReadFile(ex.GetCert()) : ReadFile(grpcConfig.GetCert()); - sslData.Key = ex.HasKey() ? ReadFile(ex.GetKey()) : ReadFile(grpcConfig.GetKey()); - xopts.SetSslData(sslData); - - Y_VERIFY(xopts.SslData->Root, "CA not set"); - Y_VERIFY(xopts.SslData->Cert, "Cert not set"); - Y_VERIFY(xopts.SslData->Key, "Key not set"); - + sslData.Root = ex.HasCA() ? ReadFile(ex.GetCA()) : ReadFile(grpcConfig.GetCA()); + sslData.Cert = ex.HasCert() ? ReadFile(ex.GetCert()) : ReadFile(grpcConfig.GetCert()); + sslData.Key = ex.HasKey() ? ReadFile(ex.GetKey()) : ReadFile(grpcConfig.GetKey()); + xopts.SetSslData(sslData); + + Y_VERIFY(xopts.SslData->Root, "CA not set"); + Y_VERIFY(xopts.SslData->Cert, "Cert not set"); + Y_VERIFY(xopts.SslData->Key, "Key not set"); + GRpcServers.push_back({ "grpcs", new NGrpc::TGRpcServer(xopts) }); fillFn(ex, *GRpcServers.back().second, xopts); - } - } + } + } } } @@ -1162,9 +1162,9 @@ TIntrusivePtr<TServiceInitializersList> TKikimrRunner::CreateServiceInitializers if (serviceMask.EnableLocalService) { sil->AddServiceInitializer(new TLocalServiceInitializer(runConfig)); } - if (serviceMask.EnableSharedCache) { - sil->AddServiceInitializer(new TSharedCacheInitializer(runConfig)); - } + if (serviceMask.EnableSharedCache) { + sil->AddServiceInitializer(new TSharedCacheInitializer(runConfig)); + } if (serviceMask.EnableBlobCache) { sil->AddServiceInitializer(new TBlobCacheInitializer(runConfig)); } @@ -1295,10 +1295,10 @@ TIntrusivePtr<TServiceInitializersList> TKikimrRunner::CreateServiceInitializers sil->AddServiceInitializer(new TLeaseHolderInitializer(runConfig)); sil->AddServiceInitializer(new TConfigValidatorsInitializer(runConfig)); - if (serviceMask.EnableQuoterService) { - sil->AddServiceInitializer(new TQuoterServiceInitializer(runConfig)); - } - + if (serviceMask.EnableQuoterService) { + sil->AddServiceInitializer(new TQuoterServiceInitializer(runConfig)); + } + if (serviceMask.EnableSysViewService) { sil->AddServiceInitializer(new TSysViewServiceInitializer(runConfig)); } @@ -1384,7 +1384,7 @@ void TKikimrRunner::KikimrStart() { EnableActorCallstack(); ThreadSigmask(SIG_UNBLOCK); } - + void TKikimrRunner::KikimrStop(bool graceful) { Y_UNUSED(graceful); @@ -1476,14 +1476,14 @@ void TKikimrRunner::KikimrStop(bool graceful) { Bus->Stop(); Bus.Drop(); } - + if (YqSharedResources) { YqSharedResources->Stop(); } - if (ActorSystem) { - ActorSystem->Cleanup(); - } + if (ActorSystem) { + ActorSystem->Cleanup(); + } if (ModuleFactories) { if (ModuleFactories->DataShardExportFactory) { @@ -1493,18 +1493,18 @@ void TKikimrRunner::KikimrStop(bool graceful) { } void TKikimrRunner::BusyLoop() { - auto shouldContinueState = KikimrShouldContinue.PollState(); - while (shouldContinueState == TProgramShouldContinue::Continue) { + auto shouldContinueState = KikimrShouldContinue.PollState(); + while (shouldContinueState == TProgramShouldContinue::Continue) { // TODO make this interval configurable - Sleep(TDuration::MilliSeconds(10)); - shouldContinueState = KikimrShouldContinue.PollState(); - } + Sleep(TDuration::MilliSeconds(10)); + shouldContinueState = KikimrShouldContinue.PollState(); + } } - -TProgramShouldContinue TKikimrRunner::KikimrShouldContinue; + +TProgramShouldContinue TKikimrRunner::KikimrShouldContinue; void TKikimrRunner::OnTerminate(int) { - KikimrShouldContinue.ShouldStop(0); + KikimrShouldContinue.ShouldStop(0); } diff --git a/ydb/core/driver_lib/run/run.h b/ydb/core/driver_lib/run/run.h index 9973b8c3d3..dfd93a24e7 100644 --- a/ydb/core/driver_lib/run/run.h +++ b/ydb/core/driver_lib/run/run.h @@ -1,5 +1,5 @@ -#pragma once -#include "config.h" +#pragma once +#include "config.h" #include "factories.h" #include "service_initializer.h" @@ -22,11 +22,11 @@ #include <library/cpp/monlib/dynamic_counters/counters.h> -namespace NKikimr { - +namespace NKikimr { + class TKikimrRunner : public virtual TThrRefBase { protected: - static TProgramShouldContinue KikimrShouldContinue; + static TProgramShouldContinue KikimrShouldContinue; static void OnTerminate(int); std::shared_ptr<TModuleFactories> ModuleFactories; @@ -116,5 +116,5 @@ public: }; int MainRun(const TKikimrRunConfig &runConfig, std::shared_ptr<TModuleFactories> factories); - -} + +} diff --git a/ydb/core/engine/minikql/flat_local_minikql_host.h b/ydb/core/engine/minikql/flat_local_minikql_host.h index 071556758c..edfd182286 100644 --- a/ydb/core/engine/minikql/flat_local_minikql_host.h +++ b/ydb/core/engine/minikql/flat_local_minikql_host.h @@ -1,13 +1,13 @@ -#pragma once +#pragma once #include "flat_local_tx_factory.h" -#include "minikql_engine_host.h" - -namespace NKikimr { +#include "minikql_engine_host.h" + +namespace NKikimr { namespace NMiniKQL { - -class TLocalMiniKQLHost : public TEngineHost { -public: + +class TLocalMiniKQLHost : public TEngineHost { +public: TLocalMiniKQLHost( NTable::TDatabase &db, TEngineHostCounters& counters, @@ -17,7 +17,7 @@ public: , Factory(factory) {} -private: +private: bool IsMyKey(const TTableId& tableId, const TArrayRef<const TCell>& row) const override { Y_UNUSED(row); @@ -41,6 +41,6 @@ private: private: const TMiniKQLFactory* const Factory; -}; - -}} +}; + +}} diff --git a/ydb/core/engine/minikql/flat_local_tx_factory.h b/ydb/core/engine/minikql/flat_local_tx_factory.h index dbf638d8a9..200d21b369 100644 --- a/ydb/core/engine/minikql/flat_local_tx_factory.h +++ b/ydb/core/engine/minikql/flat_local_tx_factory.h @@ -9,7 +9,7 @@ namespace NKikimr { namespace NMiniKQL { struct TMiniKQLFactory : NTabletFlatExecutor::IMiniKQLFactory { - using ITransaction = NTabletFlatExecutor::ITransaction; + using ITransaction = NTabletFlatExecutor::ITransaction; TAutoPtr<ITransaction> Make(TEvTablet::TEvLocalMKQL::TPtr&) override; TAutoPtr<ITransaction> Make(TEvTablet::TEvLocalSchemeTx::TPtr&) override; diff --git a/ydb/core/engine/minikql/flat_local_tx_minikql.h b/ydb/core/engine/minikql/flat_local_tx_minikql.h index 914f607288..0feabf20e6 100644 --- a/ydb/core/engine/minikql/flat_local_tx_minikql.h +++ b/ydb/core/engine/minikql/flat_local_tx_minikql.h @@ -1,7 +1,7 @@ #pragma once #include "flat_local_tx_factory.h" -#include "flat_local_minikql_host.h" +#include "flat_local_minikql_host.h" #include <ydb/core/tablet_flat/tablet_flat_executed.h> #include <ydb/core/tablet/tablet_exception.h> #include <ydb/core/engine/mkql_engine_flat.h> @@ -10,10 +10,10 @@ #include <ydb/library/yql/minikql/mkql_node_serialization.h> #include <ydb/library/yql/public/issue/yql_issue_message.h> #include <ydb/core/base/appdata.h> - -namespace NKikimr { + +namespace NKikimr { namespace NMiniKQL { - + class TLocalDbSchemeResolver : public NYql::IDbSchemeResolver { public: TLocalDbSchemeResolver(const NTable::TScheme& scheme, ui64 tabletId) @@ -70,81 +70,81 @@ private: const ui64 TabletId; }; -class TFlatLocalMiniKQL : public NTabletFlatExecutor::ITransaction { +class TFlatLocalMiniKQL : public NTabletFlatExecutor::ITransaction { ui64 TabletId = Max<ui64>(); const TActorId Sender; - const TLocalMiniKQLProgram SourceProgram; + const TLocalMiniKQLProgram SourceProgram; const TMiniKQLFactory* const Factory; - + TString SerializedMiniKQLProgram; TString SerializedMiniKQLParams; - - TAutoPtr<NYql::TMiniKQLCompileResult> ProgramCompileResult; - + + TAutoPtr<NYql::TMiniKQLCompileResult> ProgramCompileResult; + IEngineFlat::EResult EngineResultStatusCode; IEngineFlat::EStatus EngineResponseStatus; - TAutoPtr<NKikimrMiniKQL::TResult> EngineEvaluatedResponse; + TAutoPtr<NKikimrMiniKQL::TResult> EngineEvaluatedResponse; ui64 PageFaultCount = 0; - + bool ParseProgram(TStringBuf program, NYql::TIssues &errors, NYql::TExprContainer &expr) { - NYql::TAstParseResult astResult = NYql::ParseAst(program); - if (!astResult.Root) { + NYql::TAstParseResult astResult = NYql::ParseAst(program); + if (!astResult.Root) { errors = astResult.Issues; - return false; - } + return false; + } expr.Context.IssueManager.AddIssues(astResult.Issues); - + if (!NYql::CompileExpr(*astResult.Root, expr.Root, expr.Context, nullptr)) { errors = expr.Context.IssueManager.GetIssues(); - return false; - } - - return true; - } - + return false; + } + + return true; + } + bool PrepareParams(TTransactionContext &txc, const TAppData *appData) { Y_UNUSED(txc); - if (SourceProgram.Params.Binary) { - SerializedMiniKQLParams = SourceProgram.Program.Binary; - return true; - } - + if (SourceProgram.Params.Binary) { + SerializedMiniKQLParams = SourceProgram.Program.Binary; + return true; + } + if (SourceProgram.Params.Text) { ProgramCompileResult = new NYql::TMiniKQLCompileResult(); - + NYql::TExprContainer::TPtr expr = new NYql::TExprContainer(); NYql::TMiniKQLCompileResult parseResult; if (!ParseProgram(SourceProgram.Params.Text, parseResult.Errors, *expr)) { ProgramCompileResult->Errors.AddIssues(parseResult.Errors); return false; } - + TAlignedPagePoolCounters counters(appData->Counters, "local_tx"); TScopedAlloc alloc(counters, appData->FunctionRegistry->SupportsSizedAllocators()); TTypeEnvironment typeEnv(alloc); auto future = ConvertToMiniKQL(expr, appData->FunctionRegistry, &typeEnv, nullptr); future.Wait(); NYql::TConvertResult compileResult = future.GetValue(); - + if (!compileResult.Errors.Empty()) { ProgramCompileResult->Errors.AddIssues(compileResult.Errors); return false; - } + } } return true; - } - + } + bool PrepareProgram(TTransactionContext &txc, const TAppData *appData) { - // simple case - everything prepared for us and no params - if (SourceProgram.Program.Binary) { - SerializedMiniKQLProgram = SourceProgram.Program.Binary; - return true; - } - - // so we must prepare program - ProgramCompileResult = new NYql::TMiniKQLCompileResult(); - + // simple case - everything prepared for us and no params + if (SourceProgram.Program.Binary) { + SerializedMiniKQLProgram = SourceProgram.Program.Binary; + return true; + } + + // so we must prepare program + ProgramCompileResult = new NYql::TMiniKQLCompileResult(); + NYql::TExprContainer::TPtr expr = new NYql::TExprContainer(); NYql::TMiniKQLCompileResult parseResult; if (!ParseProgram(SourceProgram.Program.Text, parseResult.Errors, *expr)) { @@ -168,81 +168,81 @@ class TFlatLocalMiniKQL : public NTabletFlatExecutor::ITransaction { ProgramCompileResult->CompiledProgram = SerializeRuntimeNode(compileResult.Node, typeEnv); SerializedMiniKQLProgram = ProgramCompileResult->CompiledProgram; return true; - } - - void ClearResponse() { + } + + void ClearResponse() { EngineResultStatusCode = IEngineFlat::EResult::Unknown; EngineResponseStatus = IEngineFlat::EStatus::Unknown; - EngineEvaluatedResponse.Destroy(); - } - - bool MakeCompileResponse(const TActorContext &ctx) { - TAutoPtr<TEvTablet::TEvLocalMKQLResponse> response = new TEvTablet::TEvLocalMKQLResponse(); - auto &record = response->Record; + EngineEvaluatedResponse.Destroy(); + } + + bool MakeCompileResponse(const TActorContext &ctx) { + TAutoPtr<TEvTablet::TEvLocalMKQLResponse> response = new TEvTablet::TEvLocalMKQLResponse(); + auto &record = response->Record; record.SetOrigin(TabletId); - - if (ProgramCompileResult) { - auto *compileResults = record.MutableCompileResults(); - if (ProgramCompileResult->Errors.Empty()) { - record.SetStatus(NKikimrProto::OK); - compileResults->SetCompiledProgram(ProgramCompileResult->CompiledProgram); - } else { + + if (ProgramCompileResult) { + auto *compileResults = record.MutableCompileResults(); + if (ProgramCompileResult->Errors.Empty()) { + record.SetStatus(NKikimrProto::OK); + compileResults->SetCompiledProgram(ProgramCompileResult->CompiledProgram); + } else { NYql::IssuesToMessage(ProgramCompileResult->Errors, compileResults->MutableProgramCompileErrors()); record.SetStatus(NKikimrProto::ERROR); - } - } else { - record.SetStatus(NKikimrProto::ERROR); - } - - ctx.Send(Sender, response.Release()); - return true; - } - + } + } else { + record.SetStatus(NKikimrProto::ERROR); + } + + ctx.Send(Sender, response.Release()); + return true; + } + bool MakeResponse(IEngineFlat *engine, const TActorContext &ctx) { - TAutoPtr<TEvTablet::TEvLocalMKQLResponse> response = new TEvTablet::TEvLocalMKQLResponse(); - auto &record = response->Record; + TAutoPtr<TEvTablet::TEvLocalMKQLResponse> response = new TEvTablet::TEvLocalMKQLResponse(); + auto &record = response->Record; record.SetOrigin(TabletId); - - record.SetStatus((EngineResultStatusCode == IEngineFlat::EResult::Ok && EngineResponseStatus != IEngineFlat::EStatus::Error) ? NKikimrProto::OK : NKikimrProto::ERROR); - if (EngineResultStatusCode != IEngineFlat::EResult::Unknown) - record.SetEngineStatus(static_cast<ui32>(EngineResultStatusCode)); - if (EngineResponseStatus != IEngineFlat::EStatus::Unknown) - record.SetEngineResponseStatus(static_cast<ui32>(EngineResponseStatus)); - - if (EngineEvaluatedResponse) - *record.MutableExecutionEngineEvaluatedResponse() = *EngineEvaluatedResponse; - - if (engine && engine->GetErrors()) - record.SetMiniKQLErrors(engine->GetErrors()); - - ctx.Send(Sender, response.Release()); - - EngineResultStatusCode = IEngineFlat::EResult::Unknown; - return true; - } - - bool Execute(TTransactionContext &txc, const TActorContext &ctx) override { - ClearResponse(); - + + record.SetStatus((EngineResultStatusCode == IEngineFlat::EResult::Ok && EngineResponseStatus != IEngineFlat::EStatus::Error) ? NKikimrProto::OK : NKikimrProto::ERROR); + if (EngineResultStatusCode != IEngineFlat::EResult::Unknown) + record.SetEngineStatus(static_cast<ui32>(EngineResultStatusCode)); + if (EngineResponseStatus != IEngineFlat::EStatus::Unknown) + record.SetEngineResponseStatus(static_cast<ui32>(EngineResponseStatus)); + + if (EngineEvaluatedResponse) + *record.MutableExecutionEngineEvaluatedResponse() = *EngineEvaluatedResponse; + + if (engine && engine->GetErrors()) + record.SetMiniKQLErrors(engine->GetErrors()); + + ctx.Send(Sender, response.Release()); + + EngineResultStatusCode = IEngineFlat::EResult::Unknown; + return true; + } + + bool Execute(TTransactionContext &txc, const TActorContext &ctx) override { + ClearResponse(); + TabletId = txc.Tablet; - const TAppData *appData = AppData(ctx); - const auto functionRegistry = appData->FunctionRegistry; - - if (!SerializedMiniKQLProgram) { + const TAppData *appData = AppData(ctx); + const auto functionRegistry = appData->FunctionRegistry; + + if (!SerializedMiniKQLProgram) { if (!PrepareProgram(txc, appData)) - return MakeCompileResponse(ctx); - - if (SourceProgram.CompileOnly) - return MakeCompileResponse(ctx); - } - - if (!SerializedMiniKQLParams) { + return MakeCompileResponse(ctx); + + if (SourceProgram.CompileOnly) + return MakeCompileResponse(ctx); + } + + if (!SerializedMiniKQLParams) { if (!PrepareParams(txc, appData)) - return MakeResponse(nullptr, ctx); - } - - try { + return MakeResponse(nullptr, ctx); + } + + try { TAlignedPagePoolCounters poolCounters(appData->Counters, "local_tx"); TEngineFlatSettings proxySettings( @@ -251,42 +251,42 @@ class TFlatLocalMiniKQL : public NTabletFlatExecutor::ITransaction { *TAppData::RandomProvider, *TAppData::TimeProvider, nullptr, poolCounters ); - proxySettings.EvaluateResultType = true; - proxySettings.EvaluateResultValue = true; - + proxySettings.EvaluateResultType = true; + proxySettings.EvaluateResultValue = true; + TAutoPtr<IEngineFlat> proxyEngine = CreateEngineFlat(proxySettings); - EngineResultStatusCode = proxyEngine->SetProgram(SerializedMiniKQLProgram, SerializedMiniKQLParams); - if (EngineResultStatusCode != IEngineFlat::EResult::Ok) - return MakeResponse(proxyEngine.Get(), ctx); - - for (auto &key : proxyEngine->GetDbKeys()) { - key->Status = TKeyDesc::EStatus::Ok; + EngineResultStatusCode = proxyEngine->SetProgram(SerializedMiniKQLProgram, SerializedMiniKQLParams); + if (EngineResultStatusCode != IEngineFlat::EResult::Ok) + return MakeResponse(proxyEngine.Get(), ctx); + + for (auto &key : proxyEngine->GetDbKeys()) { + key->Status = TKeyDesc::EStatus::Ok; key->Partitions.push_back(TKeyDesc::TPartitionInfo(TabletId)); - for (const auto &x : key->Columns) { - key->ColumnInfos.push_back({x.Column, x.ExpectedType, 0, TKeyDesc::EStatus::Ok}); // type-check - } - } - + for (const auto &x : key->Columns) { + key->ColumnInfos.push_back({x.Column, x.ExpectedType, 0, TKeyDesc::EStatus::Ok}); // type-check + } + } + EngineResultStatusCode = proxyEngine->PrepareShardPrograms(IEngineFlat::TShardLimits(1, 0)); - if (EngineResultStatusCode != IEngineFlat::EResult::Ok) - return MakeResponse(proxyEngine.Get(), ctx); - - const ui32 affectedShardCount = proxyEngine->GetAffectedShardCount(); - - if (affectedShardCount == 0) { - proxyEngine->AfterShardProgramsExtracted(); - } else { + if (EngineResultStatusCode != IEngineFlat::EResult::Ok) + return MakeResponse(proxyEngine.Get(), ctx); + + const ui32 affectedShardCount = proxyEngine->GetAffectedShardCount(); + + if (affectedShardCount == 0) { + proxyEngine->AfterShardProgramsExtracted(); + } else { Y_VERIFY(affectedShardCount == 1); - - IEngineFlat::TShardData shardData; - EngineResultStatusCode = proxyEngine->GetAffectedShard(0, shardData); - if (EngineResultStatusCode != IEngineFlat::EResult::Ok) - return MakeResponse(proxyEngine.Get(), ctx); - + + IEngineFlat::TShardData shardData; + EngineResultStatusCode = proxyEngine->GetAffectedShard(0, shardData); + if (EngineResultStatusCode != IEngineFlat::EResult::Ok) + return MakeResponse(proxyEngine.Get(), ctx); + const TString shardProgram = shardData.Program; - proxyEngine->AfterShardProgramsExtracted(); - + proxyEngine->AfterShardProgramsExtracted(); + TEngineHostCounters hostCounters; TLocalMiniKQLHost host(txc.DB, hostCounters, TEngineHostSettings(TabletId, false), Factory); TEngineFlatSettings engineSettings( @@ -296,74 +296,74 @@ class TFlatLocalMiniKQL : public NTabletFlatExecutor::ITransaction { &host, poolCounters ); TAutoPtr<IEngineFlat> engine = CreateEngineFlat(engineSettings); - EngineResultStatusCode = engine->AddProgram(TabletId, shardProgram); - if (EngineResultStatusCode != IEngineFlat::EResult::Ok) - return MakeResponse(engine.Get(), ctx); - + EngineResultStatusCode = engine->AddProgram(TabletId, shardProgram); + if (EngineResultStatusCode != IEngineFlat::EResult::Ok) + return MakeResponse(engine.Get(), ctx); + IEngineFlat::TValidationInfo validationInfo; EngineResultStatusCode = engine->Validate(validationInfo); - if (EngineResultStatusCode != IEngineFlat::EResult::Ok) - return MakeResponse(engine.Get(), ctx); - + if (EngineResultStatusCode != IEngineFlat::EResult::Ok) + return MakeResponse(engine.Get(), ctx); + EngineResultStatusCode = engine->PinPages(PageFaultCount); - if (EngineResultStatusCode != IEngineFlat::EResult::Ok) - return MakeResponse(engine.Get(), ctx); - - EngineResultStatusCode = engine->PrepareOutgoingReadsets(); - if (EngineResultStatusCode != IEngineFlat::EResult::Ok) - return MakeResponse(engine.Get(), ctx); - + if (EngineResultStatusCode != IEngineFlat::EResult::Ok) + return MakeResponse(engine.Get(), ctx); + + EngineResultStatusCode = engine->PrepareOutgoingReadsets(); + if (EngineResultStatusCode != IEngineFlat::EResult::Ok) + return MakeResponse(engine.Get(), ctx); + Y_VERIFY(engine->GetOutgoingReadsetsCount() == 0); - engine->AfterOutgoingReadsetsExtracted(); - - EngineResultStatusCode = engine->PrepareIncomingReadsets(); - if (EngineResultStatusCode != IEngineFlat::EResult::Ok) - return MakeResponse(engine.Get(), ctx); - + engine->AfterOutgoingReadsetsExtracted(); + + EngineResultStatusCode = engine->PrepareIncomingReadsets(); + if (EngineResultStatusCode != IEngineFlat::EResult::Ok) + return MakeResponse(engine.Get(), ctx); + Y_VERIFY(engine->GetExpectedIncomingReadsetsCount() == 0); - - EngineResultStatusCode = engine->Execute(); - if (EngineResultStatusCode != IEngineFlat::EResult::Ok) - return MakeResponse(engine.Get(), ctx); - + + EngineResultStatusCode = engine->Execute(); + if (EngineResultStatusCode != IEngineFlat::EResult::Ok) + return MakeResponse(engine.Get(), ctx); + const TString shardEngineReply = engine->GetShardReply(TabletId); proxyEngine->AddShardReply(TabletId, shardEngineReply); - proxyEngine->FinalizeOriginReplies(TabletId); - } - - proxyEngine->BuildResult(); - EngineResponseStatus = proxyEngine->GetStatus(); - - if (EngineResponseStatus == IEngineFlat::EStatus::Complete || EngineResponseStatus == IEngineFlat::EStatus::Aborted) { - EngineEvaluatedResponse = new NKikimrMiniKQL::TResult(); - proxyEngine->FillResultValue(*EngineEvaluatedResponse); - } else - return MakeResponse(proxyEngine.Get(), ctx); - - return true; - } catch (const TNotReadyTabletException& ex) { + proxyEngine->FinalizeOriginReplies(TabletId); + } + + proxyEngine->BuildResult(); + EngineResponseStatus = proxyEngine->GetStatus(); + + if (EngineResponseStatus == IEngineFlat::EStatus::Complete || EngineResponseStatus == IEngineFlat::EStatus::Aborted) { + EngineEvaluatedResponse = new NKikimrMiniKQL::TResult(); + proxyEngine->FillResultValue(*EngineEvaluatedResponse); + } else + return MakeResponse(proxyEngine.Get(), ctx); + + return true; + } catch (const TNotReadyTabletException& ex) { Y_UNUSED(ex); ++PageFaultCount; - return false; - } catch (...) { + return false; + } catch (...) { Y_FAIL("there must be no leaked exceptions"); - } - } - - void Complete(const TActorContext &ctx) override { + } + } + + void Complete(const TActorContext &ctx) override { if (EngineResultStatusCode != IEngineFlat::EResult::Unknown) - MakeResponse(nullptr, ctx); - } + MakeResponse(nullptr, ctx); + } -public: +public: TFlatLocalMiniKQL( TActorId sender, const TLocalMiniKQLProgram &program, const TMiniKQLFactory* factory) : Sender(sender) - , SourceProgram(program) + , SourceProgram(program) , Factory(factory) - {} -}; - -}} + {} +}; + +}} diff --git a/ydb/core/engine/minikql/flat_local_tx_scheme.h b/ydb/core/engine/minikql/flat_local_tx_scheme.h index 243a404522..c70476a0cd 100644 --- a/ydb/core/engine/minikql/flat_local_tx_scheme.h +++ b/ydb/core/engine/minikql/flat_local_tx_scheme.h @@ -14,7 +14,7 @@ namespace NKikimr { namespace NMiniKQL { -class TFlatLocalSchemeTx : public NTabletFlatExecutor::ITransaction { +class TFlatLocalSchemeTx : public NTabletFlatExecutor::ITransaction { public: TFlatLocalSchemeTx(TActorId sender, TEvTablet::TEvLocalSchemeTx::TPtr &ev) : Sender(sender) diff --git a/ydb/core/engine/mkql_engine_flat.cpp b/ydb/core/engine/mkql_engine_flat.cpp index 9211a17890..c7fe388eef 100644 --- a/ydb/core/engine/mkql_engine_flat.cpp +++ b/ydb/core/engine/mkql_engine_flat.cpp @@ -16,7 +16,7 @@ #include <util/string/printf.h> #include <util/string/vector.h> -#include <util/generic/set.h> +#include <util/generic/set.h> namespace NKikimr { namespace NMiniKQL { diff --git a/ydb/core/grpc_services/base/base.h b/ydb/core/grpc_services/base/base.h index b7167962e4..44b25c4a5f 100644 --- a/ydb/core/grpc_services/base/base.h +++ b/ydb/core/grpc_services/base/base.h @@ -79,8 +79,8 @@ struct TRpcServices { EvBeginTransaction, EvCommitTransaction, EvRollbackTransaction, - EvModifyPermissions, - EvListEndpoints, + EvModifyPermissions, + EvListEndpoints, EvDescribeTenantOptions, EvDescribeTableOptions, EvCreateCoordinationNode, diff --git a/ydb/core/grpc_services/defs.h b/ydb/core/grpc_services/defs.h index d07ce14ce9..9925f73cc9 100644 --- a/ydb/core/grpc_services/defs.h +++ b/ydb/core/grpc_services/defs.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once // unique tag to fix pragma once gcc glueing: ./ydb/core/grpc_services/defs.h #include <ydb/core/base/defs.h> #include <ydb/core/base/events.h> diff --git a/ydb/core/grpc_services/grpc_helper.h b/ydb/core/grpc_services/grpc_helper.h index e5bf4f8cf8..9a2a673c7b 100644 --- a/ydb/core/grpc_services/grpc_helper.h +++ b/ydb/core/grpc_services/grpc_helper.h @@ -1,5 +1,5 @@ #pragma once -#include "defs.h" +#include "defs.h" #include "grpc_mon.h" #include <ydb/core/control/immediate_control_board_impl.h> diff --git a/ydb/core/grpc_services/grpc_request_proxy.cpp b/ydb/core/grpc_services/grpc_request_proxy.cpp index 4786c54517..a1e7accb87 100644 --- a/ydb/core/grpc_services/grpc_request_proxy.cpp +++ b/ydb/core/grpc_services/grpc_request_proxy.cpp @@ -10,7 +10,7 @@ #include <ydb/core/mind/tenant_pool.h> #include <ydb/core/tx/tx_proxy/proxy.h> #include <ydb/core/tx/scheme_board/scheme_board.h> - + namespace NKikimr { namespace NGRpcService { @@ -276,14 +276,14 @@ private: for (auto& [database, queue] : DeferredEvents) { for (TEventReqHolder& req : queue) { req.Ctx->ReplyUnavaliable(); - } - } + } + } for (const auto& [database, actor] : Subscribers) { Send(actor, new TEvents::TEvPoisonPill()); - } + } TBase::PassAway(); - } - + } + std::unordered_map<TString, TDatabaseInfo> Databases; std::unordered_map<TString, std::deque<TEventReqHolder>> DeferredEvents; // Events deferred to handle after getting database info std::unordered_map<TString, TActorId> Subscribers; diff --git a/ydb/core/grpc_services/grpc_request_proxy.h b/ydb/core/grpc_services/grpc_request_proxy.h index 5344782177..97315f6e9f 100644 --- a/ydb/core/grpc_services/grpc_request_proxy.h +++ b/ydb/core/grpc_services/grpc_request_proxy.h @@ -47,33 +47,33 @@ public: }; protected: - void Handle(TEvAlterTableRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvCreateTableRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvDropTableRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvCopyTableRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvAlterTableRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvCreateTableRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvDropTableRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvCopyTableRequest::TPtr& ev, const TActorContext& ctx); void Handle(TEvCopyTablesRequest::TPtr& ev, const TActorContext& ctx); void Handle(TEvRenameTablesRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvDescribeTableRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvGetOperationRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvDescribeTableRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvGetOperationRequest::TPtr& ev, const TActorContext& ctx); void Handle(TEvCancelOperationRequest::TPtr& ev, const TActorContext& ctx); void Handle(TEvForgetOperationRequest::TPtr& ev, const TActorContext& ctx); void Handle(TEvListOperationsRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvCreateSessionRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvKeepAliveRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvDeleteSessionRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvReadTableRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvExplainDataQueryRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvPrepareDataQueryRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvExecuteDataQueryRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvExecuteSchemeQueryRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvCreateTenantRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvAlterTenantRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvGetTenantStatusRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvListTenantsRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvRemoveTenantRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvBeginTransactionRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvCommitTransactionRequest::TPtr& ev, const TActorContext& ctx); - void Handle(TEvRollbackTransactionRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvCreateSessionRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvKeepAliveRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvDeleteSessionRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvReadTableRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvExplainDataQueryRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvPrepareDataQueryRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvExecuteDataQueryRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvExecuteSchemeQueryRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvCreateTenantRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvAlterTenantRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvGetTenantStatusRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvListTenantsRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvRemoveTenantRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvBeginTransactionRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvCommitTransactionRequest::TPtr& ev, const TActorContext& ctx); + void Handle(TEvRollbackTransactionRequest::TPtr& ev, const TActorContext& ctx); void Handle(TEvListEndpointsRequest::TPtr& ev, const TActorContext& ctx); void Handle(TEvDescribeTenantOptionsRequest::TPtr& ev, const TActorContext& ctx); void Handle(TEvDescribeTableOptionsRequest::TPtr& ev, const TActorContext& ctx); @@ -151,7 +151,7 @@ protected: void Handle(TEvDataStreamsSplitShardRequest::TPtr& ev, const TActorContext& ctx); void Handle(TEvDataStreamsStartStreamEncryptionRequest::TPtr& ev, const TActorContext& ctx); void Handle(TEvDataStreamsStopStreamEncryptionRequest::TPtr& ev, const TActorContext& ctx); - + TActorId DiscoveryCacheActorID; }; diff --git a/ydb/core/grpc_services/rpc_calls.h b/ydb/core/grpc_services/rpc_calls.h index b2234ddd3f..43136c2f4a 100644 --- a/ydb/core/grpc_services/rpc_calls.h +++ b/ydb/core/grpc_services/rpc_calls.h @@ -1,5 +1,5 @@ #pragma once -#include "defs.h" +#include "defs.h" #include "local_rate_limiter.h" diff --git a/ydb/core/grpc_services/rpc_create_session.cpp b/ydb/core/grpc_services/rpc_create_session.cpp index 748053a24f..2f6e9fae26 100644 --- a/ydb/core/grpc_services/rpc_create_session.cpp +++ b/ydb/core/grpc_services/rpc_create_session.cpp @@ -64,7 +64,7 @@ private: Send(NKqp::MakeKqpProxyID(SelfId().NodeId()), ev.Release()); } - void StateWork(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) { + void StateWork(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) { switch (ev->GetTypeRewrite()) { HFunc(NKqp::TEvKqp::TEvCreateSessionResponse, Handle); HFunc(TEvents::TEvWakeup, Handle); diff --git a/ydb/core/grpc_services/rpc_deferrable.h b/ydb/core/grpc_services/rpc_deferrable.h index 3217b7cb1c..644e7b84c4 100644 --- a/ydb/core/grpc_services/rpc_deferrable.h +++ b/ydb/core/grpc_services/rpc_deferrable.h @@ -1,6 +1,6 @@ #pragma once -#include "defs.h" +#include "defs.h" #include "grpc_request_proxy.h" #include "rpc_common.h" diff --git a/ydb/core/grpc_services/rpc_discovery.cpp b/ydb/core/grpc_services/rpc_discovery.cpp index 9210f1191a..75550f92ac 100644 --- a/ydb/core/grpc_services/rpc_discovery.cpp +++ b/ydb/core/grpc_services/rpc_discovery.cpp @@ -1,234 +1,234 @@ -#include "grpc_request_proxy.h" - -#include "rpc_calls.h" -#include "rpc_kqp_base.h" - +#include "grpc_request_proxy.h" + +#include "rpc_calls.h" +#include "rpc_kqp_base.h" + #include <ydb/core/base/statestorage.h> #include <ydb/core/base/appdata.h> #include <ydb/core/base/path.h> #include <ydb/core/base/location.h> #include <ydb/core/tx/scheme_cache/scheme_cache.h> - + #include <ydb/library/yql/public/issue/yql_issue_message.h> #include <ydb/library/yql/public/issue/yql_issue.h> - + #include <library/cpp/actors/core/interconnect.h> #include <library/cpp/actors/interconnect/interconnect.h> #include <library/cpp/actors/core/hfunc.h> - -#include <util/random/shuffle.h> - -namespace NKikimr { -namespace NGRpcService { - -using namespace NActors; -using namespace Ydb; -using namespace NKqp; - -namespace NDiscoveryPrivate { - struct TEvPrivate { - enum EEv { - EvRequest = EventSpaceBegin(TKikimrEvents::ES_PRIVATE), - EvEnd - }; - - struct TEvRequest : public TEventLocal<TEvRequest, EvRequest> { - const TString Database; - const ui32 StateStorageId; - - TEvRequest(const TString &db, ui32 stateStorageId) - : Database(db) - , StateStorageId(stateStorageId) - {} - }; - }; - - class TDiscoveryCache : public TActor<TDiscoveryCache> { - THashMap<TString, THolder<TEvStateStorage::TEvBoardInfo>> OldInfo; - THashMap<TString, THolder<TEvStateStorage::TEvBoardInfo>> NewInfo; - + +#include <util/random/shuffle.h> + +namespace NKikimr { +namespace NGRpcService { + +using namespace NActors; +using namespace Ydb; +using namespace NKqp; + +namespace NDiscoveryPrivate { + struct TEvPrivate { + enum EEv { + EvRequest = EventSpaceBegin(TKikimrEvents::ES_PRIVATE), + EvEnd + }; + + struct TEvRequest : public TEventLocal<TEvRequest, EvRequest> { + const TString Database; + const ui32 StateStorageId; + + TEvRequest(const TString &db, ui32 stateStorageId) + : Database(db) + , StateStorageId(stateStorageId) + {} + }; + }; + + class TDiscoveryCache : public TActor<TDiscoveryCache> { + THashMap<TString, THolder<TEvStateStorage::TEvBoardInfo>> OldInfo; + THashMap<TString, THolder<TEvStateStorage::TEvBoardInfo>> NewInfo; + struct TWaiter { TActorId ActorId; ui64 Cookie; }; THashMap<TString, TVector<TWaiter>> Requested; - bool Scheduled; - - void Handle(TEvStateStorage::TEvBoardInfo::TPtr &ev) { - THolder<TEvStateStorage::TEvBoardInfo> msg = ev->Release(); - const TString &path = msg->Path; - - auto vecIt = Requested.find(path); - if (vecIt != Requested.end()) { - for (auto &x : vecIt->second) + bool Scheduled; + + void Handle(TEvStateStorage::TEvBoardInfo::TPtr &ev) { + THolder<TEvStateStorage::TEvBoardInfo> msg = ev->Release(); + const TString &path = msg->Path; + + auto vecIt = Requested.find(path); + if (vecIt != Requested.end()) { + for (auto &x : vecIt->second) Send(x.ActorId, new TEvStateStorage::TEvBoardInfo(*msg), 0, x.Cookie); - Requested.erase(vecIt); - } - - NewInfo.emplace(path, std::move(msg)); - - if (!Scheduled) { - Scheduled = true; - Schedule(TDuration::Seconds(1), new TEvents::TEvWakeup()); - } - } - - void Wakeup() { - OldInfo.swap(NewInfo); - NewInfo.clear(); - - if (!OldInfo.empty()) { - Scheduled = true; - Schedule(TDuration::Seconds(1), new TEvents::TEvWakeup()); - } else { - Scheduled = false; - } - } - - void Handle(TEvPrivate::TEvRequest::TPtr &ev) { - auto *msg = ev->Get(); - if (auto *x = OldInfo.FindPtr(msg->Database)) { + Requested.erase(vecIt); + } + + NewInfo.emplace(path, std::move(msg)); + + if (!Scheduled) { + Scheduled = true; + Schedule(TDuration::Seconds(1), new TEvents::TEvWakeup()); + } + } + + void Wakeup() { + OldInfo.swap(NewInfo); + NewInfo.clear(); + + if (!OldInfo.empty()) { + Scheduled = true; + Schedule(TDuration::Seconds(1), new TEvents::TEvWakeup()); + } else { + Scheduled = false; + } + } + + void Handle(TEvPrivate::TEvRequest::TPtr &ev) { + auto *msg = ev->Get(); + if (auto *x = OldInfo.FindPtr(msg->Database)) { Send(ev->Sender, new TEvStateStorage::TEvBoardInfo(**x), 0, ev->Cookie); - return; - } - - if (auto *x = NewInfo.FindPtr(msg->Database)) { + return; + } + + if (auto *x = NewInfo.FindPtr(msg->Database)) { Send(ev->Sender, new TEvStateStorage::TEvBoardInfo(**x), 0, ev->Cookie); - return; - } - - auto &rqstd = Requested[msg->Database]; - if (rqstd.empty()) { - Register(CreateBoardLookupActor(msg->Database, SelfId(), msg->StateStorageId, EBoardLookupMode::Second, false, false)); - } - + return; + } + + auto &rqstd = Requested[msg->Database]; + if (rqstd.empty()) { + Register(CreateBoardLookupActor(msg->Database, SelfId(), msg->StateStorageId, EBoardLookupMode::Second, false, false)); + } + rqstd.push_back({ev->Sender, ev->Cookie}); - } - public: - static constexpr NKikimrServices::TActivity::EType ActorActivityType() { - return NKikimrServices::TActivity::GRPC_REQ; - } - - TDiscoveryCache() - : TActor(&TThis::StateWork) - , Scheduled(false) - {} - - STFUNC(StateWork) { - Y_UNUSED(ctx); - switch (ev->GetTypeRewrite()) { - hFunc(TEvPrivate::TEvRequest, Handle); - hFunc(TEvStateStorage::TEvBoardInfo, Handle); - cFunc(TEvents::TEvWakeup::EventType, Wakeup); - } - } - }; -} - -class TListEndpointsRPC : public TActorBootstrapped<TListEndpointsRPC> { - THolder<TEvListEndpointsRequest> Request; + } + public: + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { + return NKikimrServices::TActivity::GRPC_REQ; + } + + TDiscoveryCache() + : TActor(&TThis::StateWork) + , Scheduled(false) + {} + + STFUNC(StateWork) { + Y_UNUSED(ctx); + switch (ev->GetTypeRewrite()) { + hFunc(TEvPrivate::TEvRequest, Handle); + hFunc(TEvStateStorage::TEvBoardInfo, Handle); + cFunc(TEvents::TEvWakeup::EventType, Wakeup); + } + } + }; +} + +class TListEndpointsRPC : public TActorBootstrapped<TListEndpointsRPC> { + THolder<TEvListEndpointsRequest> Request; const TActorId CacheId; - - const bool RequestScheme = true; - - THolder<TEvStateStorage::TEvBoardInfo> LookupResponse; - THolder<TEvInterconnect::TEvNodeInfo> NameserviceResponse; - THolder<TEvTxProxySchemeCache::TEvNavigateKeySetResult> SchemeCacheResponse; + + const bool RequestScheme = true; + + THolder<TEvStateStorage::TEvBoardInfo> LookupResponse; + THolder<TEvInterconnect::TEvNodeInfo> NameserviceResponse; + THolder<TEvTxProxySchemeCache::TEvNavigateKeySetResult> SchemeCacheResponse; bool ResolveResources = false; ui64 LookupCookie = 0; -public: +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::GRPC_REQ; } TListEndpointsRPC(TEvListEndpointsRequest::TPtr &msg, TActorId cacheId) - : Request(msg->Release().Release()) - , CacheId(cacheId) - {} - - void Bootstrap() { - // request endpoints + : Request(msg->Release().Release()) + , CacheId(cacheId) + {} + + void Bootstrap() { + // request endpoints Lookup(Request->GetProtoRequest()->database()); - - // request self node info + + // request self node info Send(GetNameserviceActorId(), new TEvInterconnect::TEvGetNode(SelfId().NodeId())); - - // request path info - if (RequestScheme) { + + // request path info + if (RequestScheme) { Navigate(Request->GetProtoRequest()->database()); - } - - Become(&TThis::StateWait); - } - - STFUNC(StateWait) { - Y_UNUSED(ctx); - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvBoardInfo, Handle); - hFunc(TEvInterconnect::TEvNodeInfo, Handle); - hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle); - hFunc(TEvents::TEvUndelivered, Handle); - } - } - - void Handle(TEvStateStorage::TEvBoardInfo::TPtr &ev) { + } + + Become(&TThis::StateWait); + } + + STFUNC(StateWait) { + Y_UNUSED(ctx); + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvBoardInfo, Handle); + hFunc(TEvInterconnect::TEvNodeInfo, Handle); + hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle); + hFunc(TEvents::TEvUndelivered, Handle); + } + } + + void Handle(TEvStateStorage::TEvBoardInfo::TPtr &ev) { if (ev->Cookie != LookupCookie) { return; } LookupResponse = THolder<TEvStateStorage::TEvBoardInfo>(ev->Release().Release()); - - TryReplyAndDie(); - } - - void Handle(TEvInterconnect::TEvNodeInfo::TPtr &ev) { + + TryReplyAndDie(); + } + + void Handle(TEvInterconnect::TEvNodeInfo::TPtr &ev) { NameserviceResponse = THolder<TEvInterconnect::TEvNodeInfo>(ev->Release().Release()); - - TryReplyAndDie(); - } - - void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev) { + + TryReplyAndDie(); + } + + void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev) { SchemeCacheResponse = THolder<TEvTxProxySchemeCache::TEvNavigateKeySetResult>(ev->Release().Release()); - - TEvTxProxySchemeCache::TEvNavigateKeySetResult *msg = SchemeCacheResponse.Get(); - NSchemeCache::TSchemeCacheNavigate *navigate = msg->Request.Get(); - - Y_VERIFY(navigate->ResultSet.size() == 1); - const auto &entry = navigate->ResultSet.front(); - + + TEvTxProxySchemeCache::TEvNavigateKeySetResult *msg = SchemeCacheResponse.Get(); + NSchemeCache::TSchemeCacheNavigate *navigate = msg->Request.Get(); + + Y_VERIFY(navigate->ResultSet.size() == 1); + const auto &entry = navigate->ResultSet.front(); + LOG_TRACE_S(*TlsActivationContext, NKikimrServices::GRPC_PROXY, "TListEndpointsRPC: handle TEvNavigateKeySetResult" << ", entry: " << entry.ToString()); - if (navigate->ErrorCount > 0) { - switch (entry.Status) { - case NSchemeCache::TSchemeCacheNavigate::EStatus::PathErrorUnknown: - case NSchemeCache::TSchemeCacheNavigate::EStatus::RootUnknown: - { - auto issue = MakeIssue(NKikimrIssues::TIssuesIds::DATABASE_NOT_EXIST, "Requested database not exists"); - google::protobuf::RepeatedPtrField<TYdbIssueMessageType> issueMessages; - NYql::IssueToMessage(issue, issueMessages.Add()); - Request->SendResult(Ydb::StatusIds::NOT_FOUND, issueMessages); - return PassAway(); - } - default: - { + if (navigate->ErrorCount > 0) { + switch (entry.Status) { + case NSchemeCache::TSchemeCacheNavigate::EStatus::PathErrorUnknown: + case NSchemeCache::TSchemeCacheNavigate::EStatus::RootUnknown: + { + auto issue = MakeIssue(NKikimrIssues::TIssuesIds::DATABASE_NOT_EXIST, "Requested database not exists"); + google::protobuf::RepeatedPtrField<TYdbIssueMessageType> issueMessages; + NYql::IssueToMessage(issue, issueMessages.Add()); + Request->SendResult(Ydb::StatusIds::NOT_FOUND, issueMessages); + return PassAway(); + } + default: + { LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::GRPC_PROXY, "TListEndpointsRPC: GENERIC_RESOLVE_ERROR" << ", entry: " << entry.ToString()); - auto issue = MakeIssue(NKikimrIssues::TIssuesIds::GENERIC_RESOLVE_ERROR, "Database resolve failed with no certain result"); - google::protobuf::RepeatedPtrField<TYdbIssueMessageType> issueMessages; - NYql::IssueToMessage(issue, issueMessages.Add()); - Request->SendResult(Ydb::StatusIds::UNAVAILABLE, issueMessages); - return PassAway(); - } - } - } - + auto issue = MakeIssue(NKikimrIssues::TIssuesIds::GENERIC_RESOLVE_ERROR, "Database resolve failed with no certain result"); + google::protobuf::RepeatedPtrField<TYdbIssueMessageType> issueMessages; + NYql::IssueToMessage(issue, issueMessages.Add()); + Request->SendResult(Ydb::StatusIds::UNAVAILABLE, issueMessages); + return PassAway(); + } + } + } + if (!entry.DomainInfo) { LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::GRPC_PROXY, "TListEndpointsRPC: GENERIC_RESOLVE_ERROR (empty domain info)" @@ -254,36 +254,36 @@ public: Lookup(CanonizePath(entry.Path)); } - TryReplyAndDie(); - } - - void Handle(TEvents::TEvUndelivered::TPtr &ev) { - Y_UNUSED(ev); - auto issue = MakeIssue(NKikimrIssues::TIssuesIds::UNEXPECTED, "Unexpected error while resolving database"); - google::protobuf::RepeatedPtrField<TYdbIssueMessageType> issueMessages; - NYql::IssueToMessage(issue, issueMessages.Add()); - Request->SendResult(Ydb::StatusIds::INTERNAL_ERROR, issueMessages); - return PassAway(); - } - - bool CheckServices(const TSet<TString> &req, const NKikimrStateStorage::TEndpointBoardEntry &entry) { - if (req.empty()) - return true; - - for (const auto &x : entry.GetServices()) - if (req.count(x)) - return true; - - return false; - } - - void TryReplyAndDie() { - if (!NameserviceResponse || !LookupResponse || (RequestScheme && !SchemeCacheResponse)) - return; - - if (RequestScheme) { - // check presence of database (acl should be checked here too) - const auto &entry = SchemeCacheResponse->Request->ResultSet.front(); + TryReplyAndDie(); + } + + void Handle(TEvents::TEvUndelivered::TPtr &ev) { + Y_UNUSED(ev); + auto issue = MakeIssue(NKikimrIssues::TIssuesIds::UNEXPECTED, "Unexpected error while resolving database"); + google::protobuf::RepeatedPtrField<TYdbIssueMessageType> issueMessages; + NYql::IssueToMessage(issue, issueMessages.Add()); + Request->SendResult(Ydb::StatusIds::INTERNAL_ERROR, issueMessages); + return PassAway(); + } + + bool CheckServices(const TSet<TString> &req, const NKikimrStateStorage::TEndpointBoardEntry &entry) { + if (req.empty()) + return true; + + for (const auto &x : entry.GetServices()) + if (req.count(x)) + return true; + + return false; + } + + void TryReplyAndDie() { + if (!NameserviceResponse || !LookupResponse || (RequestScheme && !SchemeCacheResponse)) + return; + + if (RequestScheme) { + // check presence of database (acl should be checked here too) + const auto &entry = SchemeCacheResponse->Request->ResultSet.front(); if (entry.Path.size() != 1 && (entry.Kind != NSchemeCache::TSchemeCacheNavigate::KindSubdomain && entry.Kind != NSchemeCache::TSchemeCacheNavigate::KindExtSubdomain)) { @@ -292,38 +292,38 @@ public: << ", entry.Path: " << CanonizePath(entry.Path) << ", entry.Kind: " << (ui64)entry.Kind); - auto issue = MakeIssue(NKikimrIssues::TIssuesIds::ACCESS_DENIED, "Requested path is not database name"); - google::protobuf::RepeatedPtrField<TYdbIssueMessageType> issueMessages; - NYql::IssueToMessage(issue, issueMessages.Add()); - Request->SendResult(Ydb::StatusIds::NOT_FOUND, issueMessages); - return PassAway(); - } - } - - if (LookupResponse->Status != TEvStateStorage::TEvBoardInfo::EStatus::Ok) { + auto issue = MakeIssue(NKikimrIssues::TIssuesIds::ACCESS_DENIED, "Requested path is not database name"); + google::protobuf::RepeatedPtrField<TYdbIssueMessageType> issueMessages; + NYql::IssueToMessage(issue, issueMessages.Add()); + Request->SendResult(Ydb::StatusIds::NOT_FOUND, issueMessages); + return PassAway(); + } + } + + if (LookupResponse->Status != TEvStateStorage::TEvBoardInfo::EStatus::Ok) { LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::GRPC_PROXY, "TListEndpointsRPC: LookupResponse in not OK" << ", LookupResponse->Status: " << ui64(LookupResponse->Status)); auto issue = MakeIssue(NKikimrIssues::TIssuesIds::GENERIC_RESOLVE_ERROR, "Database nodes resolve failed with no certain result"); - google::protobuf::RepeatedPtrField<TYdbIssueMessageType> issueMessages; - NYql::IssueToMessage(issue, issueMessages.Add()); - Request->SendResult(Ydb::StatusIds::UNAVAILABLE, issueMessages); - return PassAway(); - } - - TStackVec<const TString*> entries; - entries.reserve(LookupResponse->InfoEntries.size()); + google::protobuf::RepeatedPtrField<TYdbIssueMessageType> issueMessages; + NYql::IssueToMessage(issue, issueMessages.Add()); + Request->SendResult(Ydb::StatusIds::UNAVAILABLE, issueMessages); + return PassAway(); + } + + TStackVec<const TString*> entries; + entries.reserve(LookupResponse->InfoEntries.size()); for (auto &xpair : LookupResponse->InfoEntries) - entries.emplace_back(&xpair.second.Payload); - Shuffle(entries.begin(), entries.end()); - + entries.emplace_back(&xpair.second.Payload); + Shuffle(entries.begin(), entries.end()); + auto *result = TEvListEndpointsRequest::AllocateResult<Ydb::Discovery::ListEndpointsResult>(Request); result->mutable_endpoints()->Reserve(LookupResponse->InfoEntries.size()); - - const TSet<TString> services(Request->GetProtoRequest()->Getservice().begin(), Request->GetProtoRequest()->Getservice().end()); + + const TSet<TString> services(Request->GetProtoRequest()->Getservice().begin(), Request->GetProtoRequest()->Getservice().end()); const bool sslServer = Request->SslServer(); - + using TEndpointKey = std::pair<TString, ui32>; struct TEndpointState { int Index = -1; @@ -334,12 +334,12 @@ public: }; THashMap<TEndpointKey, TEndpointState> states; - NKikimrStateStorage::TEndpointBoardEntry entry; - for (const TString *xpayload : entries) { + NKikimrStateStorage::TEndpointBoardEntry entry; + for (const TString *xpayload : entries) { Y_PROTOBUF_SUPPRESS_NODISCARD entry.ParseFromString(*xpayload); - if (!CheckServices(services, entry)) - continue; - + if (!CheckServices(services, entry)) + continue; + if (entry.GetSsl() != sslServer) continue; @@ -387,33 +387,33 @@ public: } } - for (auto &service : entry.GetServices()) { + for (auto &service : entry.GetServices()) { if (state.Services.insert(service).second) { xres->add_service(service); } - } - } - - auto &nodeInfo = NameserviceResponse->Node; + } + } + + auto &nodeInfo = NameserviceResponse->Node; if (nodeInfo && nodeInfo->Location.GetDataCenterId()) { const auto &location = nodeInfo->Location.GetDataCenterId(); - if (IsSafeLocationMarker(location)) + if (IsSafeLocationMarker(location)) result->set_self_location(location); - } - - + } + + Request->SendResult(*result, Ydb::StatusIds::SUCCESS); - PassAway(); - } - - bool IsSafeLocationMarker(TStringBuf location) { + PassAway(); + } + + bool IsSafeLocationMarker(TStringBuf location) { const ui8* isrc = reinterpret_cast<const ui8*>(location.data()); - for (auto idx : xrange(location.size())) { - if (isrc[idx] >= 0x80) - return false; - } - return true; - } + for (auto idx : xrange(location.size())) { + if (isrc[idx] >= 0x80) + return false; + } + return true; + } void Lookup(const TString& db) { TVector<TString> path = NKikimr::SplitPath(db); @@ -474,14 +474,14 @@ public: Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(request.Release()), IEventHandle::FlagTrackDelivery); SchemeCacheResponse.Reset(); } -}; - +}; + void TGRpcRequestProxy::Handle(TEvListEndpointsRequest::TPtr& ev, const TActorContext& ctx) { - if (!DiscoveryCacheActorID) + if (!DiscoveryCacheActorID) DiscoveryCacheActorID = ctx.Register(new NDiscoveryPrivate::TDiscoveryCache()); - + ctx.Register(new TListEndpointsRPC(ev, DiscoveryCacheActorID)); -} - -} // namespace NGRpcService -} // namespace NKikimr +} + +} // namespace NGRpcService +} // namespace NKikimr diff --git a/ydb/core/grpc_services/rpc_keep_alive.cpp b/ydb/core/grpc_services/rpc_keep_alive.cpp index 55c69c940a..e4188c8ab9 100644 --- a/ydb/core/grpc_services/rpc_keep_alive.cpp +++ b/ydb/core/grpc_services/rpc_keep_alive.cpp @@ -28,7 +28,7 @@ public: Become(&TKeepAliveRPC::StateWork); } private: - void StateWork(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) { + void StateWork(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) { switch (ev->GetTypeRewrite()) { HFunc(NKqp::TEvKqp::TEvProcessResponse, Handle); HFunc(NKqp::TEvKqp::TEvPingSessionResponse, Handle); diff --git a/ydb/core/grpc_services/rpc_kqp_base.h b/ydb/core/grpc_services/rpc_kqp_base.h index 410a90005f..2811a49e78 100644 --- a/ydb/core/grpc_services/rpc_kqp_base.h +++ b/ydb/core/grpc_services/rpc_kqp_base.h @@ -1,5 +1,5 @@ #pragma once -#include "defs.h" +#include "defs.h" #include "rpc_deferrable.h" diff --git a/ydb/core/grpc_services/rpc_read_table.cpp b/ydb/core/grpc_services/rpc_read_table.cpp index 36eed2909b..bbb8790728 100644 --- a/ydb/core/grpc_services/rpc_read_table.cpp +++ b/ydb/core/grpc_services/rpc_read_table.cpp @@ -95,7 +95,7 @@ static void ConvertKeyRange(const Ydb::Table::KeyRange& keyRange, const TGetOutp } } -class TReadTableRPC : public TActorBootstrapped<TReadTableRPC> { +class TReadTableRPC : public TActorBootstrapped<TReadTableRPC> { enum EWakeupTag : ui64 { TimeoutTimer = 0, RlSendAllowed = 1, diff --git a/ydb/core/grpc_services/ya.make b/ydb/core/grpc_services/ya.make index de82c16279..05b156bf04 100644 --- a/ydb/core/grpc_services/ya.make +++ b/ydb/core/grpc_services/ya.make @@ -15,52 +15,52 @@ SRCS( operation_helpers.cpp resolve_local_db_table.cpp rpc_alter_coordination_node.cpp - rpc_alter_table.cpp + rpc_alter_table.cpp rpc_begin_transaction.cpp - rpc_calls.cpp + rpc_calls.cpp rpc_cancel_operation.cpp rpc_cms.cpp rpc_commit_transaction.cpp - rpc_copy_table.cpp + rpc_copy_table.cpp rpc_copy_tables.cpp rpc_export.cpp rpc_create_coordination_node.cpp rpc_create_session.cpp - rpc_create_table.cpp + rpc_create_table.cpp rpc_delete_session.cpp rpc_describe_coordination_node.cpp - rpc_describe_path.cpp - rpc_describe_table.cpp + rpc_describe_path.cpp + rpc_describe_table.cpp rpc_describe_table_options.cpp rpc_drop_coordination_node.cpp - rpc_drop_table.cpp - rpc_discovery.cpp + rpc_drop_table.cpp + rpc_discovery.cpp rpc_execute_data_query.cpp rpc_execute_scheme_query.cpp rpc_execute_yql_script.cpp rpc_explain_yql_script.cpp rpc_explain_data_query.cpp rpc_forget_operation.cpp - rpc_get_operation.cpp + rpc_get_operation.cpp rpc_get_shard_locations.cpp rpc_import.cpp rpc_import_data.cpp rpc_keep_alive.cpp rpc_kh_describe.cpp rpc_kh_snapshots.cpp - rpc_kqp_base.cpp + rpc_kqp_base.cpp rpc_list_operations.cpp rpc_login.cpp rpc_load_rows.cpp rpc_log_store.cpp rpc_long_tx.cpp - rpc_make_directory.cpp - rpc_modify_permissions.cpp + rpc_make_directory.cpp + rpc_modify_permissions.cpp rpc_monitoring.cpp rpc_prepare_data_query.cpp rpc_rate_limiter_api.cpp rpc_read_columns.cpp - rpc_read_table.cpp + rpc_read_table.cpp rpc_remove_directory.cpp rpc_rename_tables.cpp rpc_rollback_transaction.cpp diff --git a/ydb/core/kesus/tablet/tablet_impl.h b/ydb/core/kesus/tablet/tablet_impl.h index 93d3a99f1c..1607e352d0 100644 --- a/ydb/core/kesus/tablet/tablet_impl.h +++ b/ydb/core/kesus/tablet/tablet_impl.h @@ -332,8 +332,8 @@ private: bool OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext& ctx) override; private: - NTabletFlatExecutor::ITransaction* CreateTxInitSchema(); - NTabletFlatExecutor::ITransaction* CreateTxInit(); + NTabletFlatExecutor::ITransaction* CreateTxInitSchema(); + NTabletFlatExecutor::ITransaction* CreateTxInit(); private: void ResetState(); diff --git a/ydb/core/kesus/tablet/tx_init.cpp b/ydb/core/kesus/tablet/tx_init.cpp index 7072f9255c..1f3f96ff9f 100644 --- a/ydb/core/kesus/tablet/tx_init.cpp +++ b/ydb/core/kesus/tablet/tx_init.cpp @@ -279,7 +279,7 @@ struct TKesusTablet::TTxInit : public TTxBase { } }; -NTabletFlatExecutor::ITransaction* TKesusTablet::CreateTxInit() { +NTabletFlatExecutor::ITransaction* TKesusTablet::CreateTxInit() { return new TTxInit(this); } diff --git a/ydb/core/kesus/tablet/tx_init_schema.cpp b/ydb/core/kesus/tablet/tx_init_schema.cpp index 7047aac063..92554789c7 100644 --- a/ydb/core/kesus/tablet/tx_init_schema.cpp +++ b/ydb/core/kesus/tablet/tx_init_schema.cpp @@ -23,7 +23,7 @@ struct TKesusTablet::TTxInitSchema : public TTxBase { } }; -NTabletFlatExecutor::ITransaction* TKesusTablet::CreateTxInitSchema() { +NTabletFlatExecutor::ITransaction* TKesusTablet::CreateTxInitSchema() { return new TTxInitSchema(this); } diff --git a/ydb/core/keyvalue/channel_balancer.h b/ydb/core/keyvalue/channel_balancer.h index b49ef0afd7..36c3bea5ab 100644 --- a/ydb/core/keyvalue/channel_balancer.h +++ b/ydb/core/keyvalue/channel_balancer.h @@ -135,10 +135,10 @@ namespace NKikimr::NKeyValue { const TActorId ActorId; public: - static constexpr NKikimrServices::TActivity::EType ActorActivityType() { - return NKikimrServices::TActivity::KEYVALUE_ACTOR; - } - + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { + return NKikimrServices::TActivity::KEYVALUE_ACTOR; + } + TChannelBalancer(ui8 numChannels, TActorId actorId) : ChannelInfo(numChannels) , ActorId(actorId) diff --git a/ydb/core/keyvalue/keyvalue_flat_impl.h b/ydb/core/keyvalue/keyvalue_flat_impl.h index d4f252e6be..292f2feff9 100644 --- a/ydb/core/keyvalue/keyvalue_flat_impl.h +++ b/ydb/core/keyvalue/keyvalue_flat_impl.h @@ -1,7 +1,7 @@ #pragma once #include "defs.h" #include "keyvalue.h" - + #include "keyvalue_collector.h" #include "keyvalue_scheme_flat.h" #include "keyvalue_simple_db.h" @@ -29,9 +29,9 @@ // Uncomment the following macro to enable consistency check before every transactions in TTxRequest //#define KIKIMR_KEYVALUE_CONSISTENCY_CHECKS -namespace NKikimr { +namespace NKikimr { namespace NKeyValue { - + constexpr ui64 CollectorErrorInitialBackoffMs = 10; constexpr ui64 CollectorErrorMaxBackoffMs = 5000; constexpr ui64 CollectorMaxErrors = 20; @@ -39,7 +39,7 @@ constexpr ui64 PeriodicRefreshMs = 15000; class TKeyValueFlat : public TActor<TKeyValueFlat>, public NTabletFlatExecutor::TTabletExecutedFlat { protected: - struct TTxInit : public NTabletFlatExecutor::ITransaction { + struct TTxInit : public NTabletFlatExecutor::ITransaction { TActorId KeyValueActorId; TKeyValueFlat &Self; @@ -103,7 +103,7 @@ protected: if (state.GetIsDamaged()) { return true; } - } + } return iter->Last() != NTable::EReady::Page; } @@ -114,7 +114,7 @@ protected: } }; - struct TTxRequest : public NTabletFlatExecutor::ITransaction { + struct TTxRequest : public NTabletFlatExecutor::ITransaction { THolder<TIntermediate> Intermediate; TKeyValueFlat *Self; @@ -140,13 +140,13 @@ protected: } TSimpleDbFlat db(txc.DB); Self->State.RequestExecute(Intermediate, db, ctx, Self->Info()); - return true; - } - - void Complete(const TActorContext &ctx) override { + return true; + } + + void Complete(const TActorContext &ctx) override { LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << Self->TabletID() << " TTxRequest Complete"); Self->State.RequestComplete(Intermediate, ctx, Self->Info()); - } + } bool CheckConsistency(NTabletFlatExecutor::TTransactionContext &txc) { #ifdef KIKIMR_KEYVALUE_CONSISTENCY_CHECKS @@ -163,13 +163,13 @@ protected: return true; #endif } - }; - - struct TTxMonitoring : public NTabletFlatExecutor::ITransaction { + }; + + struct TTxMonitoring : public NTabletFlatExecutor::ITransaction { const THolder<NMon::TEvRemoteHttpInfo> Event; const TActorId RespondTo; TKeyValueFlat *Self; - + TTxMonitoring(THolder<NMon::TEvRemoteHttpInfo> event, const TActorId &respondTo, TKeyValueFlat *keyValue) : Event(std::move(event)) , RespondTo(respondTo) @@ -204,7 +204,7 @@ protected: } }; - struct TTxStoreCollect : public NTabletFlatExecutor::ITransaction { + struct TTxStoreCollect : public NTabletFlatExecutor::ITransaction { TKeyValueFlat *Self; TTxStoreCollect(TKeyValueFlat *keyValueFlat) @@ -225,7 +225,7 @@ protected: } }; - struct TTxEraseCollect : public NTabletFlatExecutor::ITransaction { + struct TTxEraseCollect : public NTabletFlatExecutor::ITransaction { TKeyValueFlat *Self; TTxEraseCollect(TKeyValueFlat *keyValueFlat) @@ -249,25 +249,25 @@ protected: TKeyValueState State; TDeque<TAutoPtr<IEventHandle>> InitialEventsQueue; TActorId CollectorActorId; - + void OnDetach(const TActorContext &ctx) override { LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << TabletID() << " OnDetach"); HandleDie(ctx); - } - + } + void OnTabletDead(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext &ctx) override { LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << TabletID() << " OnTabletDead " << ev->Get()->ToString()); HandleDie(ctx); - } - - void OnActivateExecutor(const TActorContext &ctx) override { + } + + void OnActivateExecutor(const TActorContext &ctx) override { Executor()->RegisterExternalTabletCounters(State.TakeTabletCounters()); State.SetupResourceMetrics(Executor()->GetResourceMetrics()); ctx.Schedule(TDuration::MilliSeconds(PeriodicRefreshMs), new TEvKeyValue::TEvPeriodicRefresh); Execute(new TTxInit(ctx.SelfID, *this), ctx); - } - + } + void Enqueue(STFUNC_SIG) override { SetActivityType(NKikimrServices::TActivity::KEYVALUE_ACTOR); LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE, @@ -275,8 +275,8 @@ protected: << " Enqueue, event type# " << (ui32)ev->GetTypeRewrite() << " event# " << (ev->HasEvent() ? ev->GetBase()->ToString().c_str() : "serialized?")); InitialEventsQueue.push_back(ev); - } - + } + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // gRPC @@ -372,7 +372,7 @@ protected: State.RegisterInitialCollectResult(ctx); } - void Handle(TEvKeyValue::TEvRequest::TPtr ev, const TActorContext &ctx) { + void Handle(TEvKeyValue::TEvRequest::TPtr ev, const TActorContext &ctx) { LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << TabletID() << " Handle TEvRequest " << ev->Get()->ToString()); UpdateTabletYellow(); @@ -390,18 +390,18 @@ protected: State.OnUpdateWeights(ev); } - bool OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext &ctx) override { - if (!Executor() || !Executor()->GetStats().IsActive) - return false; - - if (!ev) - return true; - + bool OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext &ctx) override { + if (!Executor() || !Executor()->GetStats().IsActive) + return false; + + if (!ev) + return true; + LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << TabletID() << " Handle TEvRemoteHttpInfo: %s" << ev->Get()->Query.data()); Execute(new TTxMonitoring(ev->Release(), ev->Sender, this), ctx); - - return true; + + return true; } void Handle(TEvents::TEvPoisonPill::TPtr &ev, const TActorContext &ctx) { @@ -409,19 +409,19 @@ protected: Y_UNUSED(ev); Become(&TThis::StateBroken); ctx.Send(Tablet(), new TEvents::TEvPoisonPill); - } - + } + void RestoreActorActivity() { SetActivityType(NKikimrServices::TActivity::KEYVALUE_ACTOR); } -public: +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::KEYVALUE_ACTOR; } TKeyValueFlat(const TActorId &tablet, TTabletStorageInfo *info) - : TActor(&TThis::StateInit) + : TActor(&TThis::StateInit) , TTabletExecutedFlat(info, tablet, new NMiniKQL::TMiniKQLFactory) { TAutoPtr<TTabletCountersBase> counters( @@ -434,7 +434,7 @@ public: State.SetupTabletCounters(counters); State.Clear(); } - + virtual void HandleDie(const TActorContext &ctx) { if (CollectorActorId) { @@ -456,19 +456,19 @@ public: return false; } - STFUNC(StateInit) { + STFUNC(StateInit) { RestoreActorActivity(); LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << TabletID() << " StateInit flat event type# " << (ui32)ev->GetTypeRewrite() << " event# " << (ev->HasEvent() ? ev->GetBase()->ToString().data() : "serialized?")); - StateInitImpl(ev, ctx); - } - - STFUNC(StateWork) { + StateInitImpl(ev, ctx); + } + + STFUNC(StateWork) { if (HandleHook(ev, ctx)) return; RestoreActorActivity(); - switch (ev->GetTypeRewrite()) { + switch (ev->GetTypeRewrite()) { hFunc(TEvKeyValue::TEvRead, Handle); hFunc(TEvKeyValue::TEvReadRange, Handle); hFunc(TEvKeyValue::TEvExecuteTransaction, Handle); @@ -486,28 +486,28 @@ public: HFunc(TEvBlobStorage::TEvCollectGarbageResult, Handle); HFunc(TEvents::TEvPoisonPill, Handle); - default: + default: if (!HandleDefaultEvents(ev, ctx)) { LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << TabletID() << " StateWork unexpected event type# " << (ui32)ev->GetTypeRewrite() << " event# " << (ev->HasEvent() ? ev->GetBase()->ToString().data() : "serialized?")); } - break; - } - } - - STFUNC(StateBroken) { + break; + } + } + + STFUNC(StateBroken) { RestoreActorActivity(); - switch (ev->GetTypeRewrite()) { - HFunc(TEvTablet::TEvTabletDead, HandleTabletDead) + switch (ev->GetTypeRewrite()) { + HFunc(TEvTablet::TEvTabletDead, HandleTabletDead) default: LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << TabletID() << " BrokenState unexpected event type# " << (ui32)ev->GetTypeRewrite() << " event# " << (ev->HasEvent() ? ev->GetBase()->ToString().data() : "serialized?")); break; - } - } + } + } void InitSchemeComplete(const TActorContext &ctx) { Become(&TThis::StateWork); @@ -538,8 +538,8 @@ public: bool ReassignChannelsEnabled() const override { return true; } -}; - - +}; + + }// NKeyValue }// NKikimr diff --git a/ydb/core/keyvalue/keyvalue_storage_request.cpp b/ydb/core/keyvalue/keyvalue_storage_request.cpp index 27c4c05177..e9032d2ed3 100644 --- a/ydb/core/keyvalue/keyvalue_storage_request.cpp +++ b/ydb/core/keyvalue/keyvalue_storage_request.cpp @@ -568,13 +568,13 @@ public: readQueries[queryIdx].Set(readItem.LogoBlobId, readItem.BlobOffset, readItem.BlobSize); ++queryIdx; - const ui32 group = TabletInfo->GroupFor(readItem.LogoBlobId.Channel(), readItem.LogoBlobId.Generation()); + const ui32 group = TabletInfo->GroupFor(readItem.LogoBlobId.Channel(), readItem.LogoBlobId.Generation()); Y_VERIFY(group != Max<ui32>(), "Get Blob# %s is mapped to an invalid group (-1)!", readItem.LogoBlobId.ToString().c_str()); - if (prevGroup != Max<ui32>()) { + if (prevGroup != Max<ui32>()) { Y_VERIFY(prevGroup == group); } else { - prevGroup = group; + prevGroup = group; } } @@ -587,7 +587,7 @@ public: Y_VERIFY(queryIdx == readQueryCount); SendToBSProxy( - ctx, prevGroup, + ctx, prevGroup, new TEvBlobStorage::TEvGet(readQueries, readQueryCount, IntermediateResults->Deadline, handleClass, false), cookie); diff --git a/ydb/core/kqp/kqp_ic_gateway.cpp b/ydb/core/kqp/kqp_ic_gateway.cpp index c5851dc65f..47489a9bd5 100644 --- a/ydb/core/kqp/kqp_ic_gateway.cpp +++ b/ydb/core/kqp/kqp_ic_gateway.cpp @@ -800,7 +800,7 @@ public: result.SetSuccess(); Promise.SetValue(std::move(result)); - NTabletPipe::CloseClient(ctx, ShemePipeActorId); + NTabletPipe::CloseClient(ctx, ShemePipeActorId); this->Die(ctx); } diff --git a/ydb/core/mind/bscontroller/impl.h b/ydb/core/mind/bscontroller/impl.h index 822c790f57..ba311a254c 100644 --- a/ydb/core/mind/bscontroller/impl.h +++ b/ydb/core/mind/bscontroller/impl.h @@ -19,7 +19,7 @@ namespace NKikimr { namespace NBsController { using NTabletFlatExecutor::TTabletExecutedFlat; -using NTabletFlatExecutor::ITransaction; +using NTabletFlatExecutor::ITransaction; using NTabletFlatExecutor::TTransactionBase; using NTabletFlatExecutor::TTransactionContext; @@ -1635,8 +1635,8 @@ private: void ProcessSelectGroupsQueueItem(TList<TSelectGroupsQueueItem>::iterator it); void NotifyNodesAwaitingKeysForGroups(ui32 groupId); - ITransaction* CreateTxInitScheme(); - ITransaction* CreateTxMigrate(); + ITransaction* CreateTxInitScheme(); + ITransaction* CreateTxMigrate(); ITransaction* CreateTxLoadEverything(); ITransaction* CreateTxUpdateSeenOperational(TVector<TGroupId> groups); ITransaction* CreateTxUpdateLastSeenReady(std::vector<std::pair<TVSlotId, TInstant>> lastSeenReadyQ); diff --git a/ydb/core/mind/bscontroller/init_scheme.cpp b/ydb/core/mind/bscontroller/init_scheme.cpp index 334f31d09f..0a7779a131 100644 --- a/ydb/core/mind/bscontroller/init_scheme.cpp +++ b/ydb/core/mind/bscontroller/init_scheme.cpp @@ -47,7 +47,7 @@ public: } }; -ITransaction* TBlobStorageController::CreateTxInitScheme() { +ITransaction* TBlobStorageController::CreateTxInitScheme() { return new TTxInitScheme(this); } diff --git a/ydb/core/mind/bscontroller/migrate.cpp b/ydb/core/mind/bscontroller/migrate.cpp index d66bdbd3f0..20d10f8b62 100644 --- a/ydb/core/mind/bscontroller/migrate.cpp +++ b/ydb/core/mind/bscontroller/migrate.cpp @@ -209,7 +209,7 @@ public: } }; -ITransaction* TBlobStorageController::CreateTxMigrate() { +ITransaction* TBlobStorageController::CreateTxMigrate() { return new TTxMigrate(this); } diff --git a/ydb/core/mind/configured_tablet_bootstrapper.cpp b/ydb/core/mind/configured_tablet_bootstrapper.cpp index 856922ace6..008acd2b40 100644 --- a/ydb/core/mind/configured_tablet_bootstrapper.cpp +++ b/ydb/core/mind/configured_tablet_bootstrapper.cpp @@ -1,10 +1,10 @@ -#include "configured_tablet_bootstrapper.h" - +#include "configured_tablet_bootstrapper.h" + #include <ydb/core/tablet/bootstrapper.h> #include <ydb/core/cms/console/configs_dispatcher.h> #include <library/cpp/actors/core/actor_bootstrapped.h> - -// for 'create' funcs + +// for 'create' funcs #include <ydb/core/mind/bscontroller/bsc.h> #include <ydb/core/base/hive.h> #include <ydb/core/tx/coordinator/coordinator.h> @@ -22,195 +22,195 @@ #include <ydb/core/kesus/tablet/tablet.h> #include <ydb/core/sys_view/processor/processor.h> #include <ydb/core/test_tablet/test_tablet.h> - + #include <library/cpp/actors/core/hfunc.h> - -namespace NKikimr { - -class TConfiguredTabletBootstrapper : public TActorBootstrapped<TConfiguredTabletBootstrapper> { - const ui64 TabletId; - const ::NKikimrConfig::TBootstrap::TTablet DefaultConfig; + +namespace NKikimr { + +class TConfiguredTabletBootstrapper : public TActorBootstrapped<TConfiguredTabletBootstrapper> { + const ui64 TabletId; + const ::NKikimrConfig::TBootstrap::TTablet DefaultConfig; TActorId BootstrapperInstance; - TString CurrentConfig; - - void Handle(NConsole::TEvConsole::TEvConfigNotificationRequest::TPtr &ev) { - const auto &record = ev->Get()->Record; - - NKikimrConfig::TBootstrap::TTablet tabletConfig; - if (record.GetConfig().HasBootstrapConfig()) { - for (const NKikimrConfig::TBootstrap::TTablet &x : record.GetConfig().GetBootstrapConfig().GetTablet()) { - if (x.GetInfo().GetTabletID() == TabletId) { - tabletConfig.CopyFrom(x); - break; - } - } - } - - CheckChanged(tabletConfig); - - Send(ev->Sender, new NConsole::TEvConsole::TEvConfigNotificationResponse(record), 0, ev->Cookie); - } - - void CheckChanged(const NKikimrConfig::TBootstrap::TTablet &config) { - TString x = config.SerializeAsString(); - if (CurrentConfig == x) - return; - - if (BootstrapperInstance) { - Send(BootstrapperInstance, new TEvents::TEvPoisonPill()); + TString CurrentConfig; + + void Handle(NConsole::TEvConsole::TEvConfigNotificationRequest::TPtr &ev) { + const auto &record = ev->Get()->Record; + + NKikimrConfig::TBootstrap::TTablet tabletConfig; + if (record.GetConfig().HasBootstrapConfig()) { + for (const NKikimrConfig::TBootstrap::TTablet &x : record.GetConfig().GetBootstrapConfig().GetTablet()) { + if (x.GetInfo().GetTabletID() == TabletId) { + tabletConfig.CopyFrom(x); + break; + } + } + } + + CheckChanged(tabletConfig); + + Send(ev->Sender, new NConsole::TEvConsole::TEvConfigNotificationResponse(record), 0, ev->Cookie); + } + + void CheckChanged(const NKikimrConfig::TBootstrap::TTablet &config) { + TString x = config.SerializeAsString(); + if (CurrentConfig == x) + return; + + if (BootstrapperInstance) { + Send(BootstrapperInstance, new TEvents::TEvPoisonPill()); TlsActivationContext->ExecutorThread.ActorSystem->RegisterLocalService(MakeBootstrapperID(TabletId, SelfId().NodeId()), TActorId()); BootstrapperInstance = TActorId(); - } - - CurrentConfig = x; - - // not apply config - const ui32 selfNode = SelfId().NodeId(); - if (Find(config.GetNode(), selfNode) != config.GetNode().end()) { + } + + CurrentConfig = x; + + // not apply config + const ui32 selfNode = SelfId().NodeId(); + if (Find(config.GetNode(), selfNode) != config.GetNode().end()) { TIntrusivePtr<TTabletStorageInfo> storageInfo = TabletStorageInfoFromProto(config.GetInfo()); - const auto *appData = AppData(); - - // extract from kikimr_services_initializer - const TTabletTypes::EType tabletType = BootstrapperTypeToTabletType(config.GetType()); - - if (storageInfo->TabletType == TTabletTypes::TYPE_INVALID) - storageInfo->TabletType = tabletType; - - TIntrusivePtr<TTabletSetupInfo> tabletSetupInfo = MakeTabletSetupInfo(tabletType, appData->UserPoolId, appData->SystemPoolId); - - TIntrusivePtr<TBootstrapperInfo> bi = new TBootstrapperInfo(tabletSetupInfo.Get()); - if (config.NodeSize() != 1) { - for (ui32 node : config.GetNode()) { - if (node != selfNode) - bi->OtherNodes.emplace_back(node); - } - if (config.HasWatchThreshold()) - bi->WatchThreshold = TDuration::MilliSeconds(config.GetWatchThreshold()); + const auto *appData = AppData(); + + // extract from kikimr_services_initializer + const TTabletTypes::EType tabletType = BootstrapperTypeToTabletType(config.GetType()); + + if (storageInfo->TabletType == TTabletTypes::TYPE_INVALID) + storageInfo->TabletType = tabletType; + + TIntrusivePtr<TTabletSetupInfo> tabletSetupInfo = MakeTabletSetupInfo(tabletType, appData->UserPoolId, appData->SystemPoolId); + + TIntrusivePtr<TBootstrapperInfo> bi = new TBootstrapperInfo(tabletSetupInfo.Get()); + if (config.NodeSize() != 1) { + for (ui32 node : config.GetNode()) { + if (node != selfNode) + bi->OtherNodes.emplace_back(node); + } + if (config.HasWatchThreshold()) + bi->WatchThreshold = TDuration::MilliSeconds(config.GetWatchThreshold()); if (config.HasStartFollowers()) bi->StartFollowers = config.GetStartFollowers(); - } - - BootstrapperInstance = Register(CreateBootstrapper(storageInfo.Get(), bi.Get(), false), TMailboxType::HTSwap, appData->SystemPoolId); - - TlsActivationContext->ExecutorThread.ActorSystem->RegisterLocalService(MakeBootstrapperID(TabletId, SelfId().NodeId()), BootstrapperInstance); - } - } - -public: - static constexpr NKikimrServices::TActivity::EType ActorActivityType() { - return NKikimrServices::TActivity::CONFIGURED_BOOTSTRAPPER; - } - - TConfiguredTabletBootstrapper(const ::NKikimrConfig::TBootstrap::TTablet &defaultConfig) - : TabletId(defaultConfig.GetInfo().GetTabletID()) - , DefaultConfig(defaultConfig) - {} - - void Bootstrap() { - // start with initial config (as we can start CMS itself - it could be not possible to get actual config at all) - CheckChanged(DefaultConfig); - - // and subscribe for changes - Send(NConsole::MakeConfigsDispatcherID(SelfId().NodeId()), - new NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionRequest(NKikimrConsole::TConfigItem::BootstrapConfigItem)); - Become(&TThis::StateWork); - } - - STATEFN(StateWork) { - switch (ev->GetTypeRewrite()) { - hFunc(NConsole::TEvConsole::TEvConfigNotificationRequest, Handle); - } - } -}; - - -TTabletTypes::EType BootstrapperTypeToTabletType(ui32 type) { - switch (type) { - case NKikimrConfig::TBootstrap::TX_DUMMY: - return TTabletTypes::TX_DUMMY; - case NKikimrConfig::TBootstrap::HIVE: - case NKikimrConfig::TBootstrap::FLAT_HIVE: - return TTabletTypes::FLAT_HIVE; - case NKikimrConfig::TBootstrap::TX_COORDINATOR: - case NKikimrConfig::TBootstrap::FLAT_TX_COORDINATOR: - return TTabletTypes::FLAT_TX_COORDINATOR; - case NKikimrConfig::TBootstrap::TX_MEDIATOR: - return TTabletTypes::TX_MEDIATOR; - case NKikimrConfig::TBootstrap::BS_DOMAINCONTROLLER: - case NKikimrConfig::TBootstrap::FLAT_BS_CONTROLLER: - return TTabletTypes::FLAT_BS_CONTROLLER; - case NKikimrConfig::TBootstrap::DATASHARD: - case NKikimrConfig::TBootstrap::FAKE_DATASHARD: - return TTabletTypes::FLAT_DATASHARD; - case NKikimrConfig::TBootstrap::SCHEMESHARD: - case NKikimrConfig::TBootstrap::FLAT_SCHEMESHARD: - return TTabletTypes::FLAT_SCHEMESHARD; - case NKikimrConfig::TBootstrap::KEYVALUEFLAT: - return TTabletTypes::KEYVALUEFLAT; - case NKikimrConfig::TBootstrap::TX_PROXY: - case NKikimrConfig::TBootstrap::FLAT_TX_PROXY: - case NKikimrConfig::TBootstrap::TX_ALLOCATOR: - return TTabletTypes::TX_ALLOCATOR; - case NKikimrConfig::TBootstrap::CMS: - return TTabletTypes::CMS; - case NKikimrConfig::TBootstrap::NODE_BROKER: - return TTabletTypes::NODE_BROKER; - case NKikimrConfig::TBootstrap::TENANT_SLOT_BROKER: - return TTabletTypes::TENANT_SLOT_BROKER; - case NKikimrConfig::TBootstrap::CONSOLE: - return TTabletTypes::CONSOLE; - default: - Y_FAIL("unknown tablet type"); - } - return TTabletTypes::TYPE_INVALID; -} - -TIntrusivePtr<TTabletSetupInfo> MakeTabletSetupInfo( - TTabletTypes::EType tabletType, - ui32 poolId, ui32 tabletPoolId) -{ - TTabletSetupInfo::TTabletCreationFunc createFunc; - - switch (tabletType) { - case TTabletTypes::BSController: - createFunc = &CreateFlatBsController; - break; - case TTabletTypes::Hive: - createFunc = &CreateDefaultHive; - break; - case TTabletTypes::Coordinator: - createFunc = &CreateFlatTxCoordinator; - break; - case TTabletTypes::Mediator: - createFunc = &CreateTxMediator; - break; - case TTabletTypes::TxAllocator: - createFunc = &CreateTxAllocator; - break; - case TTabletTypes::DataShard: + } + + BootstrapperInstance = Register(CreateBootstrapper(storageInfo.Get(), bi.Get(), false), TMailboxType::HTSwap, appData->SystemPoolId); + + TlsActivationContext->ExecutorThread.ActorSystem->RegisterLocalService(MakeBootstrapperID(TabletId, SelfId().NodeId()), BootstrapperInstance); + } + } + +public: + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { + return NKikimrServices::TActivity::CONFIGURED_BOOTSTRAPPER; + } + + TConfiguredTabletBootstrapper(const ::NKikimrConfig::TBootstrap::TTablet &defaultConfig) + : TabletId(defaultConfig.GetInfo().GetTabletID()) + , DefaultConfig(defaultConfig) + {} + + void Bootstrap() { + // start with initial config (as we can start CMS itself - it could be not possible to get actual config at all) + CheckChanged(DefaultConfig); + + // and subscribe for changes + Send(NConsole::MakeConfigsDispatcherID(SelfId().NodeId()), + new NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionRequest(NKikimrConsole::TConfigItem::BootstrapConfigItem)); + Become(&TThis::StateWork); + } + + STATEFN(StateWork) { + switch (ev->GetTypeRewrite()) { + hFunc(NConsole::TEvConsole::TEvConfigNotificationRequest, Handle); + } + } +}; + + +TTabletTypes::EType BootstrapperTypeToTabletType(ui32 type) { + switch (type) { + case NKikimrConfig::TBootstrap::TX_DUMMY: + return TTabletTypes::TX_DUMMY; + case NKikimrConfig::TBootstrap::HIVE: + case NKikimrConfig::TBootstrap::FLAT_HIVE: + return TTabletTypes::FLAT_HIVE; + case NKikimrConfig::TBootstrap::TX_COORDINATOR: + case NKikimrConfig::TBootstrap::FLAT_TX_COORDINATOR: + return TTabletTypes::FLAT_TX_COORDINATOR; + case NKikimrConfig::TBootstrap::TX_MEDIATOR: + return TTabletTypes::TX_MEDIATOR; + case NKikimrConfig::TBootstrap::BS_DOMAINCONTROLLER: + case NKikimrConfig::TBootstrap::FLAT_BS_CONTROLLER: + return TTabletTypes::FLAT_BS_CONTROLLER; + case NKikimrConfig::TBootstrap::DATASHARD: + case NKikimrConfig::TBootstrap::FAKE_DATASHARD: + return TTabletTypes::FLAT_DATASHARD; + case NKikimrConfig::TBootstrap::SCHEMESHARD: + case NKikimrConfig::TBootstrap::FLAT_SCHEMESHARD: + return TTabletTypes::FLAT_SCHEMESHARD; + case NKikimrConfig::TBootstrap::KEYVALUEFLAT: + return TTabletTypes::KEYVALUEFLAT; + case NKikimrConfig::TBootstrap::TX_PROXY: + case NKikimrConfig::TBootstrap::FLAT_TX_PROXY: + case NKikimrConfig::TBootstrap::TX_ALLOCATOR: + return TTabletTypes::TX_ALLOCATOR; + case NKikimrConfig::TBootstrap::CMS: + return TTabletTypes::CMS; + case NKikimrConfig::TBootstrap::NODE_BROKER: + return TTabletTypes::NODE_BROKER; + case NKikimrConfig::TBootstrap::TENANT_SLOT_BROKER: + return TTabletTypes::TENANT_SLOT_BROKER; + case NKikimrConfig::TBootstrap::CONSOLE: + return TTabletTypes::CONSOLE; + default: + Y_FAIL("unknown tablet type"); + } + return TTabletTypes::TYPE_INVALID; +} + +TIntrusivePtr<TTabletSetupInfo> MakeTabletSetupInfo( + TTabletTypes::EType tabletType, + ui32 poolId, ui32 tabletPoolId) +{ + TTabletSetupInfo::TTabletCreationFunc createFunc; + + switch (tabletType) { + case TTabletTypes::BSController: + createFunc = &CreateFlatBsController; + break; + case TTabletTypes::Hive: + createFunc = &CreateDefaultHive; + break; + case TTabletTypes::Coordinator: + createFunc = &CreateFlatTxCoordinator; + break; + case TTabletTypes::Mediator: + createFunc = &CreateTxMediator; + break; + case TTabletTypes::TxAllocator: + createFunc = &CreateTxAllocator; + break; + case TTabletTypes::DataShard: createFunc = &CreateDataShard; - break; - case TTabletTypes::SchemeShard: - createFunc = &CreateFlatTxSchemeShard; - break; - case TTabletTypes::KeyValue: - createFunc = &CreateKeyValueFlat; - break; - case TTabletTypes::CMS: - createFunc = &NCms::CreateCms; - break; - case TTabletTypes::NodeBroker: - createFunc = &NNodeBroker::CreateNodeBroker; - break; - case TTabletTypes::TenantSlotBroker: - createFunc = &NTenantSlotBroker::CreateTenantSlotBroker; - break; - case TTabletTypes::Console: - createFunc = &NConsole::CreateConsole; - break; - case TTabletTypes::Kesus: - createFunc = &NKesus::CreateKesusTablet; - break; + break; + case TTabletTypes::SchemeShard: + createFunc = &CreateFlatTxSchemeShard; + break; + case TTabletTypes::KeyValue: + createFunc = &CreateKeyValueFlat; + break; + case TTabletTypes::CMS: + createFunc = &NCms::CreateCms; + break; + case TTabletTypes::NodeBroker: + createFunc = &NNodeBroker::CreateNodeBroker; + break; + case TTabletTypes::TenantSlotBroker: + createFunc = &NTenantSlotBroker::CreateTenantSlotBroker; + break; + case TTabletTypes::Console: + createFunc = &NConsole::CreateConsole; + break; + case TTabletTypes::Kesus: + createFunc = &NKesus::CreateKesusTablet; + break; case TTabletTypes::SysViewProcessor: createFunc = &NSysView::CreateSysViewProcessor; break; @@ -223,15 +223,15 @@ TIntrusivePtr<TTabletSetupInfo> MakeTabletSetupInfo( case TTabletTypes::ReplicationController: createFunc = &NReplication::CreateController; break; - default: - return nullptr; - } - - return new TTabletSetupInfo(createFunc, TMailboxType::ReadAsFilled, poolId, TMailboxType::ReadAsFilled, tabletPoolId); -} - -IActor* CreateConfiguredTabletBootstrapper(const ::NKikimrConfig::TBootstrap::TTablet &defaultConfig) { - return new TConfiguredTabletBootstrapper(defaultConfig); -} - -} + default: + return nullptr; + } + + return new TTabletSetupInfo(createFunc, TMailboxType::ReadAsFilled, poolId, TMailboxType::ReadAsFilled, tabletPoolId); +} + +IActor* CreateConfiguredTabletBootstrapper(const ::NKikimrConfig::TBootstrap::TTablet &defaultConfig) { + return new TConfiguredTabletBootstrapper(defaultConfig); +} + +} diff --git a/ydb/core/mind/configured_tablet_bootstrapper.h b/ydb/core/mind/configured_tablet_bootstrapper.h index bb9664c3bf..6b30b86954 100644 --- a/ydb/core/mind/configured_tablet_bootstrapper.h +++ b/ydb/core/mind/configured_tablet_bootstrapper.h @@ -1,15 +1,15 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include <ydb/core/tablet/tablet_setup.h> #include <ydb/core/base/tablet_types.h> #include <ydb/core/base/appdata.h> #include <ydb/core/protos/config.pb.h> - -namespace NKikimr { - - // would subscribe to boot config and instantiate tablet bootstrapper if configured for this node - IActor* CreateConfiguredTabletBootstrapper(const ::NKikimrConfig::TBootstrap::TTablet &defaultConfig); - - TTabletTypes::EType BootstrapperTypeToTabletType(ui32 type); - TIntrusivePtr<TTabletSetupInfo> MakeTabletSetupInfo(TTabletTypes::EType tabletType, ui32 poolId, ui32 tabletPoolId); -} + +namespace NKikimr { + + // would subscribe to boot config and instantiate tablet bootstrapper if configured for this node + IActor* CreateConfiguredTabletBootstrapper(const ::NKikimrConfig::TBootstrap::TTablet &defaultConfig); + + TTabletTypes::EType BootstrapperTypeToTabletType(ui32 type); + TIntrusivePtr<TTabletSetupInfo> MakeTabletSetupInfo(TTabletTypes::EType tabletType, ui32 poolId, ui32 tabletPoolId); +} diff --git a/ydb/core/mind/defs.h b/ydb/core/mind/defs.h index c2d8cb0bce..a746b59cd3 100644 --- a/ydb/core/mind/defs.h +++ b/ydb/core/mind/defs.h @@ -1,10 +1,10 @@ -#pragma once +#pragma once // unique tag to fix pragma once gcc glueing: ./ydb/core/mind/defs.h #include <ydb/core/base/defs.h> #include <ydb/core/base/events.h> - -namespace NKikimr { - + +namespace NKikimr { + // ensure that the type of passed variable is the same as given one template<typename T, typename U> inline T EnsureType(U &&value) { @@ -12,4 +12,4 @@ namespace NKikimr { return std::move(value); } -} +} diff --git a/ydb/core/mind/dynamic_nameserver.cpp b/ydb/core/mind/dynamic_nameserver.cpp index 253586f4a7..6f4f147982 100644 --- a/ydb/core/mind/dynamic_nameserver.cpp +++ b/ydb/core/mind/dynamic_nameserver.cpp @@ -9,7 +9,7 @@ namespace NNodeBroker { static void ResetInterconnectProxyConfig(ui32 nodeId, const TActorContext &ctx) { - auto aid = TActivationContext::InterconnectProxy(nodeId); + auto aid = TActivationContext::InterconnectProxy(nodeId); if (!aid) return; ctx.Send(aid, new TEvInterconnect::TEvDisconnect); @@ -30,9 +30,9 @@ void TDynamicNodeResolverBase::Bootstrap(const TActorContext &ctx) .MinRetryTime = TDuration::MilliSeconds(50), .MaxRetryTime = TDuration::Seconds(2) }; - + ui32 group = dinfo->GetDefaultStateStorageGroup(domain); - auto pipe = NTabletPipe::CreateClient(ctx.SelfID, MakeNodeBrokerID(group), NTabletPipe::TClientConfig(retryPolicy)); + auto pipe = NTabletPipe::CreateClient(ctx.SelfID, MakeNodeBrokerID(group), NTabletPipe::TClientConfig(retryPolicy)); NodeBrokerPipe = ctx.RegisterWithSameMailbox(pipe); TAutoPtr<TEvNodeBroker::TEvResolveNode> request = new TEvNodeBroker::TEvResolveNode; diff --git a/ydb/core/mind/hive/hive.h b/ydb/core/mind/hive/hive.h index 44e18374d7..cce565aecd 100644 --- a/ydb/core/mind/hive/hive.h +++ b/ydb/core/mind/hive/hive.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include <bitset> #include <util/generic/queue.h> @@ -22,7 +22,7 @@ #include <ydb/core/tablet/tablet_pipe_client_cache.h> #include <ydb/core/tablet/pipe_tracker.h> #include <ydb/core/tablet/tablet_impl.h> - + #include <ydb/core/tablet_flat/flat_executor_counters.h> #include <library/cpp/actors/core/interconnect.h> @@ -30,9 +30,9 @@ #include <ydb/core/tablet/tablet_metrics.h> -namespace NKikimr { +namespace NKikimr { namespace NHive { - + using NTabletFlatExecutor::TTabletExecutedFlat; using NTabletFlatExecutor::TTransactionContext; using NTabletFlatExecutor::TExecutorCounters; @@ -52,7 +52,7 @@ using TResourceNormalizedValues = std::tuple<double, double, double, double>; using TOwnerIdxType = NScheme::TPairUi64Ui64; static constexpr std::size_t MAX_TABLET_CHANNELS = 256; - + enum class ETabletState : ui64 { Unknown = 0, GroupAssignment = 50, diff --git a/ydb/core/mind/hive/hive_impl.cpp b/ydb/core/mind/hive/hive_impl.cpp index 5a7b00aaf4..58ca2ac3e4 100644 --- a/ydb/core/mind/hive/hive_impl.cpp +++ b/ydb/core/mind/hive/hive_impl.cpp @@ -20,9 +20,9 @@ inline IOutputStream& operator <<(IOutputStream& out, const TArrayRef<const NKik return out; } -namespace NKikimr { +namespace NKikimr { namespace NHive { - + void THive::Handle(TEvHive::TEvCreateTablet::TPtr& ev) { NKikimrHive::TEvCreateTablet& rec = ev->Get()->Record; if (rec.HasOwner() && rec.HasOwnerIdx() && rec.HasTabletType() && rec.BindedChannelsSize() != 0) { @@ -41,8 +41,8 @@ void THive::Handle(TEvHive::TEvCreateTablet::TPtr& ev) { } Send(ev->Sender, reply.Release(), 0, ev->Cookie); } -} - +} + void THive::Handle(TEvHive::TEvAdoptTablet::TPtr& ev) { BLOG_D("Handle TEvHive::TEvAdoptTablet"); NKikimrHive::TEvAdoptTablet& rec = ev->Get()->Record; @@ -129,16 +129,16 @@ void THive::Handle(TEvLocal::TEvRegisterNode::TPtr& ev) { } bool THive::OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext& ctx) { - if (!Executor() || !Executor()->GetStats().IsActive) - return false; - + if (!Executor() || !Executor()->GetStats().IsActive) + return false; + if (!ev) return true; CreateEvMonitoring(ev, ctx); return true; -} - +} + void THive::Handle(TEvHive::TEvStopTablet::TPtr& ev) { BLOG_D("Handle StopTablet"); NKikimrHive::TEvStopTablet& rec = ev->Get()->Record; @@ -501,13 +501,13 @@ void THive::OnDetach(const TActorContext&) { Cleanup(); PassAway(); } - + void THive::OnTabletDead(TEvTablet::TEvTabletDead::TPtr&, const TActorContext&) { BLOG_I("OnTabletDead: " << TabletID()); Cleanup(); return PassAway(); -} - +} + void THive::BuildLocalConfig() { LocalConfig.Clear(); if (ResourceProfiles) @@ -541,23 +541,23 @@ void THive::Cleanup() { } PipeClientCache->Detach(DEPRECATED_CTX); - + if (BSControllerPipeClient) { NTabletPipe::CloseClient(SelfId(), BSControllerPipeClient); BSControllerPipeClient = TActorId(); } - + if (RootHivePipeClient) { NTabletPipe::CloseClient(SelfId(), RootHivePipeClient); RootHivePipeClient = TActorId(); } - if (ResponsivenessPinger) { + if (ResponsivenessPinger) { ResponsivenessPinger->Detach(TlsActivationContext->ActorContextFor(ResponsivenessActorID)); - ResponsivenessPinger = nullptr; - } + ResponsivenessPinger = nullptr; + } } - + void THive::Handle(TEvLocal::TEvStatus::TPtr& ev) { BLOG_D("Handle TEvLocal::TEvStatus for Node " << ev->Sender.NodeId() << ": " << ev->Get()->Record.ShortDebugString()); Execute(CreateStatus(ev->Sender, ev->Get()->Record)); @@ -609,7 +609,7 @@ void THive::Handle(TEvInterconnect::TEvNodeConnected::TPtr &ev) { BLOG_W("Handle TEvInterconnect::TEvNodeConnected, NodeId " << nodeId); Send(GetNameserviceActorId(), new TEvInterconnect::TEvGetNode(nodeId)); } - + void THive::Handle(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) { BLOG_W("Handle TEvInterconnect::TEvNodeDisconnected, NodeId " << ev->Get()->NodeId); Execute(CreateDisconnectNode(THolder<TEvInterconnect::TEvNodeDisconnected>(ev->Release().Release()))); @@ -662,8 +662,8 @@ void THive::ScheduleDisconnectNode(THolder<TEvPrivate::TEvProcessDisconnectNode> } else { KillNode(event->NodeId, event->Local); } -} - +} + void THive::Handle(TEvPrivate::TEvKickTablet::TPtr &ev) { TFullTabletId tabletId(ev->Get()->TabletId); TTabletInfo* tablet = FindTablet(tabletId); @@ -843,16 +843,16 @@ void THive::OnActivateExecutor(const TActorContext&) { Send(NConsole::MakeConfigsDispatcherID(SelfId().NodeId()), new NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionRequest(NKikimrConsole::TConfigItem::HiveConfigItem)); Execute(CreateInitScheme()); - if (!ResponsivenessPinger) { - ResponsivenessPinger = new TTabletResponsivenessPinger(TabletCounters->Simple()[NHive::COUNTER_RESPONSE_TIME_USEC], TDuration::Seconds(1)); + if (!ResponsivenessPinger) { + ResponsivenessPinger = new TTabletResponsivenessPinger(TabletCounters->Simple()[NHive::COUNTER_RESPONSE_TIME_USEC], TDuration::Seconds(1)); ResponsivenessActorID = RegisterWithSameMailbox(ResponsivenessPinger); - } -} - + } +} + void THive::DefaultSignalTabletActive(const TActorContext& ctx) { Y_UNUSED(ctx); } - + void THive::AssignTabletGroups(TLeaderTabletInfo& tablet) { ui32 channels = tablet.GetChannelCount(); @@ -1567,16 +1567,16 @@ bool THive::IsTabletMoveExpedient(const TTabletInfo& tablet, const TNodeInfo& no } void THive::FillTabletInfo(NKikimrHive::TEvResponseHiveInfo& response, ui64 tabletId, const TLeaderTabletInfo *info, const NKikimrHive::TEvRequestHiveInfo &req) { - if (info) { + if (info) { auto& tabletInfo = *response.AddTablets(); tabletInfo.SetTabletID(tabletId); - tabletInfo.SetTabletType(info->Type); - tabletInfo.SetState(static_cast<ui32>(info->State)); + tabletInfo.SetTabletType(info->Type); + tabletInfo.SetState(static_cast<ui32>(info->State)); tabletInfo.SetTabletBootMode(info->BootMode); tabletInfo.SetVolatileState(info->GetVolatileState()); - tabletInfo.SetNodeID(info->NodeId); - tabletInfo.MutableTabletOwner()->SetOwner(info->Owner.first); - tabletInfo.MutableTabletOwner()->SetOwnerIdx(info->Owner.second); + tabletInfo.SetNodeID(info->NodeId); + tabletInfo.MutableTabletOwner()->SetOwner(info->Owner.first); + tabletInfo.MutableTabletOwner()->SetOwnerIdx(info->Owner.second); tabletInfo.SetGeneration(info->KnownGeneration); tabletInfo.MutableObjectDomain()->CopyFrom(info->ObjectDomain); if (!info->IsRunning()) { @@ -1590,14 +1590,14 @@ void THive::FillTabletInfo(NKikimrHive::TEvResponseHiveInfo& response, ui64 tabl for (const auto& follower : info->Followers) { if (req.HasFollowerID() && req.GetFollowerID() != follower.Id) continue; - NKikimrHive::TTabletInfo& tabletInfo = *response.AddTablets(); - tabletInfo.SetTabletID(tabletId); - tabletInfo.SetTabletType(info->Type); + NKikimrHive::TTabletInfo& tabletInfo = *response.AddTablets(); + tabletInfo.SetTabletID(tabletId); + tabletInfo.SetTabletType(info->Type); tabletInfo.SetFollowerID(follower.Id); tabletInfo.SetVolatileState(follower.GetVolatileState()); tabletInfo.SetNodeID(follower.NodeId); - tabletInfo.MutableTabletOwner()->SetOwner(info->Owner.first); - tabletInfo.MutableTabletOwner()->SetOwnerIdx(info->Owner.second); + tabletInfo.MutableTabletOwner()->SetOwner(info->Owner.first); + tabletInfo.MutableTabletOwner()->SetOwnerIdx(info->Owner.second); tabletInfo.MutableObjectDomain()->CopyFrom(info->ObjectDomain); if (!follower.IsRunning()) { tabletInfo.SetLastAliveTimestamp(follower.Statistics.GetLastAliveTimestamp()); @@ -1609,13 +1609,13 @@ void THive::FillTabletInfo(NKikimrHive::TEvResponseHiveInfo& response, ui64 tabl } } } -} - +} + void THive::Handle(TEvHive::TEvRequestHiveInfo::TPtr& ev) { - const auto& record = ev->Get()->Record; - TAutoPtr<TEvHive::TEvResponseHiveInfo> response = new TEvHive::TEvResponseHiveInfo(); + const auto& record = ev->Get()->Record; + TAutoPtr<TEvHive::TEvResponseHiveInfo> response = new TEvHive::TEvResponseHiveInfo(); TInstant now = TlsActivationContext->Now(); - if (record.HasTabletID()) { + if (record.HasTabletID()) { TTabletId tabletId = record.GetTabletID(); NKikimrHive::TForwardRequest forwardRequest; if (CheckForForwardTabletRequest(tabletId, forwardRequest)) { @@ -1628,20 +1628,20 @@ void THive::Handle(TEvHive::TEvRequestHiveInfo::TPtr& ev) { } else { BLOG_W("Can't find the tablet from RequestHiveInfo(TabletID=" << tabletId << ")"); } - } else { - response->Record.MutableTablets()->Reserve(Tablets.size()); - for (auto it = Tablets.begin(); it != Tablets.end(); ++it) { + } else { + response->Record.MutableTablets()->Reserve(Tablets.size()); + for (auto it = Tablets.begin(); it != Tablets.end(); ++it) { if (record.HasTabletType() && record.GetTabletType() != it->second.Type) { - continue; + continue; } if (it->second.IsDeleting()) { continue; } it->second.ActualizeTabletStatistics(now); - FillTabletInfo(response->Record, it->first, &it->second, record); - } - } - + FillTabletInfo(response->Record, it->first, &it->second, record); + } + } + Send(ev->Sender, response.Release(), 0, ev->Cookie); } @@ -2626,6 +2626,6 @@ TString THive::GetLogPrefix() const { IActor* CreateDefaultHive(const TActorId &tablet, TTabletStorageInfo *info) { return new NHive::THive(info, tablet); -} - +} + } // NKikimr diff --git a/ydb/core/mind/hive/hive_impl.h b/ydb/core/mind/hive/hive_impl.h index 8fbb8d24ee..70c4530fee 100644 --- a/ydb/core/mind/hive/hive_impl.h +++ b/ydb/core/mind/hive/hive_impl.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include <bitset> #include <library/cpp/actors/core/interconnect.h> #include <ydb/core/base/hive.h> @@ -113,9 +113,9 @@ namespace std { }; } -namespace NKikimr { +namespace NKikimr { namespace NHive { - + struct TCompleteNotifications { TVector<THolder<IEventHandle>> Notifications; TActorId SelfID; @@ -180,7 +180,7 @@ protected: friend class TQueryMigrationWaitActor; friend class TReleaseTabletsWaitActor; friend class TDrainNodeWaitActor; - + friend class TTxInitScheme; friend class TTxDeleteTablet; friend class TTxDeleteOwnerTablets; @@ -260,19 +260,19 @@ protected: TFollowerId followerId, TEvLocal::TEvTabletStatus::EStatus status, TEvTablet::TEvTabletDead::EReason reason); - ITransaction* CreateBootTablet(TTabletId tabletId); + ITransaction* CreateBootTablet(TTabletId tabletId); ITransaction* CreateKillNode(TNodeId nodeId, const TActorId& local); ITransaction* CreateUpdateTabletGroups(TTabletId tabletId, TVector<NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters> groups = {}); - ITransaction* CreateCheckTablets(); + ITransaction* CreateCheckTablets(); ITransaction* CreateSyncTablets(const TActorId &local, NKikimrLocal::TEvSyncTablets& rec); ITransaction* CreateStopTablet(TTabletId tabletId, const TActorId& actorToNotify); ITransaction* CreateResumeTablet(TTabletId tabletId, const TActorId& actorToNotify); ITransaction* CreateStartTablet(TFullTabletId tabletId, const TActorId& local, ui64 cookie, bool external = false); - ITransaction* CreateUpdateTabletMetrics(TEvHive::TEvTabletMetrics::TPtr& ev); + ITransaction* CreateUpdateTabletMetrics(TEvHive::TEvTabletMetrics::TPtr& ev); ITransaction* CreateReassignGroups(TTabletId tabletId, const TActorId& actorToNotify, const std::bitset<MAX_TABLET_CHANNELS>& channelProfileNewGroup); ITransaction* CreateLockTabletExecution(const NKikimrHive::TEvLockTabletExecution& rec, const TActorId& sender, const ui64 cookie); ITransaction* CreateUnlockTabletExecution(const NKikimrHive::TEvUnlockTabletExecution& rec, const TActorId& sender, const ui64 cookie); - ITransaction* CreateUnlockTabletExecution(ui64 tabletId, ui64 seqNo); + ITransaction* CreateUnlockTabletExecution(ui64 tabletId, ui64 seqNo); ITransaction* CreateRequestTabletSequence(TEvHive::TEvRequestTabletIdSequence::TPtr event); ITransaction* CreateResponseTabletSequence(TEvHive::TEvResponseTabletIdSequence::TPtr event); ITransaction* CreateDisconnectNode(THolder<TEvInterconnect::TEvNodeDisconnected> event); @@ -286,24 +286,24 @@ protected: ITransaction* CreateConfigureSubdomain(TEvHive::TEvConfigureHive::TPtr event); ITransaction* CreateSwitchDrainOn(TNodeId nodeId, TDrainSettings settings, const TActorId& initiator); ITransaction* CreateSwitchDrainOff(TNodeId nodeId, TDrainSettings settings, NKikimrProto::EReplyStatus status, ui32 movements); - + public: TDomainsView DomainsView; - + protected: TActorId BSControllerPipeClient; TActorId RootHivePipeClient; - ui64 HiveUid; // Hive Personal Identifier - identifies a unique individual hive - ui32 HiveDomain; + ui64 HiveUid; // Hive Personal Identifier - identifies a unique individual hive + ui32 HiveDomain; TTabletId RootHiveId; TTabletId HiveId; ui64 HiveGeneration; TSubDomainKey RootDomainKey; TSubDomainKey PrimaryDomainKey; TString RootDomainName; - TIntrusivePtr<NTabletPipe::TBoundedClientCacheConfig> PipeClientCacheConfig; + TIntrusivePtr<NTabletPipe::TBoundedClientCacheConfig> PipeClientCacheConfig; THolder<NTabletPipe::IClientCache> PipeClientCache; - TPipeTracker PipeTracker; + TPipeTracker PipeTracker; NTabletPipe::TClientRetryPolicy PipeRetryPolicy; std::unordered_map<TNodeId, TNodeInfo> Nodes; std::unordered_map<TTabletId, TLeaderTabletInfo> Tablets; @@ -368,7 +368,7 @@ protected: NKikimrHive::TEvSeizeTablets MigrationFilter; TActorId ResponsivenessActorID; - TTabletResponsivenessPinger *ResponsivenessPinger; + TTabletResponsivenessPinger *ResponsivenessPinger; // remove after upgrade to sub hives ui64 NextTabletId = 0x10000; ///////////////////////////////////// @@ -498,41 +498,41 @@ protected: void Handle(NConsole::TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse::TPtr& ev); void Handle(NSysView::TEvSysView::TEvGetTabletIdsRequest::TPtr& ev); void Handle(NSysView::TEvSysView::TEvGetTabletsRequest::TPtr& ev); - -protected: + +protected: void RestartPipeTx(ui64 tabletId); - -public: + +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::HIVE_ACTOR; } THive(TTabletStorageInfo *info, const TActorId &tablet); - + protected: STATEFN(StateInit); STATEFN(StateWork); - + void SendToBSControllerPipe(IEventBase* payload); void SendToRootHivePipe(IEventBase* payload); void RestartBSControllerPipe(); void RestartRootHivePipe(); - + struct TBestNodeResult { TNodeInfo* BestNode; bool TryToContinue; - + TBestNodeResult(TNodeInfo& bestNode) : BestNode(&bestNode) , TryToContinue(true) {} - + TBestNodeResult(bool tryToContinue) : BestNode(nullptr) , TryToContinue(tryToContinue) {} }; - + TBestNodeResult FindBestNode(const TTabletInfo& tablet); struct TSelectedNode { @@ -793,8 +793,8 @@ protected: void ResolveDomain(TSubDomainKey domain); TString GetDomainName(TSubDomainKey domain); TSubDomainKey GetMySubDomainKey() const; -}; - +}; + } // NHive } // NKikimr diff --git a/ydb/core/mind/hive/hive_ut.cpp b/ydb/core/mind/hive/hive_ut.cpp index 7001052580..0383d49a12 100644 --- a/ydb/core/mind/hive/hive_ut.cpp +++ b/ydb/core/mind/hive/hive_ut.cpp @@ -2001,29 +2001,29 @@ Y_UNIT_TEST_SUITE(THiveTest) { Y_UNIT_TEST(PipeAlivenessOfDeadTablet) { TTestBasicRuntime runtime(1, false); - Setup(runtime, true); + Setup(runtime, true); TActorId sender = runtime.AllocateEdgeActor(); - const ui64 hiveTablet = MakeDefaultHiveID(0); - const ui64 testerTablet = 1; + const ui64 hiveTablet = MakeDefaultHiveID(0); + const ui64 testerTablet = 1; CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::FLAT_HIVE), &CreateDefaultHive); TTabletTypes::EType tabletType = TTabletTypes::Dummy; const ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, MakeHolder<TEvHive::TEvCreateTablet>(testerTablet, 0, tabletType, BINDED_CHANNELS), 0, true); - MakeSureTabletIsUp(runtime, tabletId, 0); + MakeSureTabletIsUp(runtime, tabletId, 0); if (!SendDeleteTestTablet(runtime, hiveTablet, MakeHolder<TEvHive::TEvDeleteTablet>(testerTablet, 0, 0))) { WaitEvDeleteTabletResult(runtime); } - MakeSureTabletIsDown(runtime, tabletId, 0); - - NTabletPipe::TClientConfig clientConfig; - clientConfig.CheckAliveness = true; + MakeSureTabletIsDown(runtime, tabletId, 0); + + NTabletPipe::TClientConfig clientConfig; + clientConfig.CheckAliveness = true; clientConfig.RetryPolicy = {.RetryLimitCount = 3}; - runtime.Register(NTabletPipe::CreateClient(sender, tabletId, clientConfig)); - TAutoPtr<IEventHandle> handle; - auto connectResult = runtime.GrabEdgeEventRethrow<TEvTabletPipe::TEvClientConnected>(handle); - UNIT_ASSERT(connectResult); - UNIT_ASSERT(connectResult->Dead == true); - } - + runtime.Register(NTabletPipe::CreateClient(sender, tabletId, clientConfig)); + TAutoPtr<IEventHandle> handle; + auto connectResult = runtime.GrabEdgeEventRethrow<TEvTabletPipe::TEvClientConnected>(handle); + UNIT_ASSERT(connectResult); + UNIT_ASSERT(connectResult->Dead == true); + } + Y_UNIT_TEST(TestCreateTabletBeforeLocal) { TTestBasicRuntime runtime(1, false); Setup(runtime, false); diff --git a/ydb/core/mind/hive/leader_tablet_info.cpp b/ydb/core/mind/hive/leader_tablet_info.cpp index 40f104fe51..13e1d5b2ee 100644 --- a/ydb/core/mind/hive/leader_tablet_info.cpp +++ b/ydb/core/mind/hive/leader_tablet_info.cpp @@ -6,13 +6,13 @@ namespace NHive { TString TLeaderTabletInfo::DEFAULT_STORAGE_POOL_NAME = "default"; TPathId TLeaderTabletInfo::GetTenant() const { - // todo: must be explicit TenantPathId + // todo: must be explicit TenantPathId if (!ObjectDomain) - return TPathId(); - + return TPathId(); + return TPathId(ObjectDomain.GetSchemeShard(), ObjectDomain.GetPathId()); -} - +} + bool TLeaderTabletInfo::IsSomeoneAliveOnNode(TNodeId nodeId) const { if (CanBeAlive() && Node->Id == nodeId) { return true; diff --git a/ydb/core/mind/hive/leader_tablet_info.h b/ydb/core/mind/hive/leader_tablet_info.h index a37d33a67c..88425b3cae 100644 --- a/ydb/core/mind/hive/leader_tablet_info.h +++ b/ydb/core/mind/hive/leader_tablet_info.h @@ -130,8 +130,8 @@ public: ui32 GetFollowersAliveOnDataCenter(TDataCenterId dataCenterId) const; ui32 GetFollowersAliveOnDataCenterExcludingFollower(TDataCenterId dataCenterId, const TTabletInfo& excludingFollower) const; - TPathId GetTenant() const; - + TPathId GetTenant() const; + bool IsAllAlive() const { if (!IsAlive()) return false; diff --git a/ydb/core/mind/hive/monitoring.cpp b/ydb/core/mind/hive/monitoring.cpp index 12fb52416e..7e9a83b354 100644 --- a/ydb/core/mind/hive/monitoring.cpp +++ b/ydb/core/mind/hive/monitoring.cpp @@ -9,44 +9,44 @@ #include "hive_schema.h" #include "hive_log.h" -namespace NKikimr { +namespace NKikimr { namespace NHive { - + class TTxMonEvent_DbState : public TTransactionBase<THive> { -public: - struct TTabletInfo { - ui32 KnownGeneration; - ui32 TabletType; +public: + struct TTabletInfo { + ui32 KnownGeneration; + ui32 TabletType; ui32 LeaderNode; ETabletState TabletState; - }; - - struct TNodeInfo { + }; + + struct TNodeInfo { TActorId Local; - ui64 TabletsOn; - - TNodeInfo() - : TabletsOn(0) - {} - }; - + ui64 TabletsOn; + + TNodeInfo() + : TabletsOn(0) + {} + }; + const TActorId Source; - + TMap<ui64, TTabletInfo> TabletInfo; TMap<ui32, TNodeInfo> NodeInfo; - + TTxMonEvent_DbState(const TActorId &source, TSelf *hive) - : TBase(hive) - , Source(source) - {} - + : TBase(hive) + , Source(source) + {} + TTxType GetTxType() const override { return NHive::TXTYPE_MON_DB_STATE; } bool Execute(TTransactionContext &txc, const TActorContext& ctx) override { - TabletInfo.clear(); - NodeInfo.clear(); + TabletInfo.clear(); + NodeInfo.clear(); NIceDb::TNiceDb db(txc.DB); - + { // read tablets from DB auto rowset = db.Table<Schema::Tablet>().Range().Select(); if (!rowset.IsReady()) @@ -57,40 +57,40 @@ public: const ui32 type = rowset.GetValue<Schema::Tablet::TabletType>(); const ui32 leaderNode = rowset.GetValue<Schema::Tablet::LeaderNode>(); const ETabletState tabletState = rowset.GetValue<Schema::Tablet::State>(); - + TabletInfo[tabletId] = {knownGen, type, leaderNode, tabletState}; ++NodeInfo[leaderNode].TabletsOn; // leaderNode could be zero, then - counter of tablets w/o leader node if (!rowset.Next()) return false; - } - } - - // read nodes - { + } + } + + // read nodes + { auto rowset = db.Table<Schema::Node>().Range().Select(); if (!rowset.IsReady()) return false; while (rowset.IsValid()) { const ui32 nodeId = rowset.GetValue<Schema::Node::ID>(); const TActorId local = rowset.GetValue<Schema::Node::Local>(); - - NodeInfo[nodeId].Local = local; + + NodeInfo[nodeId].Local = local; if (!rowset.Next()) return false; - } - } - - // todo: send result back - TStringStream str; - RenderHTMLPage(str); - ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(str.Str())); - return true; - } - + } + } + + // todo: send result back + TStringStream str; + RenderHTMLPage(str); + ctx.Send(Source, new NMon::TEvRemoteHttpInfoRes(str.Str())); + return true; + } + void Complete(const TActorContext& ctx) override { Y_UNUSED(ctx); - } - + } + void RenderHTMLPage(IOutputStream &out) { HTML(out) { UL_CLASS("nav nav-tabs") { @@ -362,9 +362,9 @@ public: } out << "</tbody>"; out << "</table>"; - } -}; - + } +}; + class TTxMonEvent_MemStateDomains : public TTransactionBase<THive> { public: const TActorId Source; @@ -1102,14 +1102,14 @@ public: void RenderHTMLPage(IOutputStream &out) { ui64 nodes = 0; ui64 tablets = 0; - ui64 runningTablets = 0; - ui64 aliveNodes = 0; + ui64 runningTablets = 0; + ui64 aliveNodes = 0; THashMap<ui32, TMap<TString, ui32>> tabletsByNodeByType; THashMap<TTabletTypes::EType, ui32> tabletTypesToChannels; for (const auto& pr : Self->Tablets) { if (pr.second.IsRunning()) { - ++runningTablets; + ++runningTablets; ++tabletsByNodeByType[pr.second.NodeId][GetTabletType(pr.second.Type)]; } for (const auto& sl : pr.second.Followers) { @@ -1130,7 +1130,7 @@ public: } for (const auto& pr : Self->Nodes) { if (pr.second.IsAlive()) { - ++aliveNodes; + ++aliveNodes; } if (!pr.second.IsUnknown()) { ++nodes; @@ -2874,10 +2874,10 @@ class TTxMonEvent_ResetTablet : public TTransactionBase<THive> { const ui32 KnownGeneration; public: - static constexpr NKikimrServices::TActivity::EType ActorActivityType() { - return NKikimrServices::TActivity::HIVE_MON_REQUEST; - } - + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { + return NKikimrServices::TActivity::HIVE_MON_REQUEST; + } + TResetter(TIntrusivePtr<TTabletStorageInfo> info, TActorId source, ui32 knownGeneration) : Info(std::move(info)) , Source(source) @@ -3444,7 +3444,7 @@ void THive::CreateEvMonitoring(NMon::TEvRemoteHttpInfo::TPtr& ev, const TActorCo return Execute(new TTxMonEvent_Storage(ev->Sender, ev, this), ctx); } return Execute(new TTxMonEvent_Landing(ev->Sender, ev, this), ctx); -} - +} + } // NHive } // NKikimr diff --git a/ydb/core/mind/hive/tablet_info.h b/ydb/core/mind/hive/tablet_info.h index 4adff1939c..dc360a30e4 100644 --- a/ydb/core/mind/hive/tablet_info.h +++ b/ydb/core/mind/hive/tablet_info.h @@ -235,13 +235,13 @@ public: return max(NormalizeRawValues(current, maximum)); } - void UpdateWeight() { + void UpdateWeight() { TResourceRawValues current = GetResourceCurrentValues(); TResourceRawValues maximum = GetResourceMaximumValues(); FilterRawValues(current); FilterRawValues(maximum); - Weight = GetUsage(current, maximum); + Weight = GetUsage(current, maximum); } void PostponeStart(TInstant nextStart) { diff --git a/ydb/core/mind/hive/tx__block_storage_result.cpp b/ydb/core/mind/hive/tx__block_storage_result.cpp index 967dafc004..28315ec93b 100644 --- a/ydb/core/mind/hive/tx__block_storage_result.cpp +++ b/ydb/core/mind/hive/tx__block_storage_result.cpp @@ -66,7 +66,7 @@ public: } }; -ITransaction* THive::CreateBlockStorageResult(TEvTabletBase::TEvBlockBlobStorageResult::TPtr& ev) { +ITransaction* THive::CreateBlockStorageResult(TEvTabletBase::TEvBlockBlobStorageResult::TPtr& ev) { return new TTxBlockStorageResult(ev, this); } diff --git a/ydb/core/mind/hive/tx__create_tablet.cpp b/ydb/core/mind/hive/tx__create_tablet.cpp index bdaae5ec5f..f3b27bfd9a 100644 --- a/ydb/core/mind/hive/tx__create_tablet.cpp +++ b/ydb/core/mind/hive/tx__create_tablet.cpp @@ -419,8 +419,8 @@ public: tablet.UpdateResourceUsage(resourceValues); tablet.BoundChannels.clear(); tablet.TabletStorageInfo.Reset(new TTabletStorageInfo(tablet.Id, tablet.Type)); - tablet.TabletStorageInfo->TenantPathId = tablet.GetTenant(); - + tablet.TabletStorageInfo->TenantPathId = tablet.GetTenant(); + UpdateChannelsBinding(tablet, db); for (const auto& srcFollowerGroup : FollowerGroups) { diff --git a/ydb/core/mind/hive/tx__cut_tablet_history.cpp b/ydb/core/mind/hive/tx__cut_tablet_history.cpp index 686c0f1892..9bf4c94b98 100644 --- a/ydb/core/mind/hive/tx__cut_tablet_history.cpp +++ b/ydb/core/mind/hive/tx__cut_tablet_history.cpp @@ -41,7 +41,7 @@ public: void Complete(const TActorContext&) override {} }; -ITransaction* THive::CreateCutTabletHistory(TEvHive::TEvCutTabletHistory::TPtr& ev) { +ITransaction* THive::CreateCutTabletHistory(TEvHive::TEvCutTabletHistory::TPtr& ev) { return new TTxCutTabletHistory(ev, this); } diff --git a/ydb/core/mind/hive/tx__delete_tablet.cpp b/ydb/core/mind/hive/tx__delete_tablet.cpp index db1435d8cc..6d481e695f 100644 --- a/ydb/core/mind/hive/tx__delete_tablet.cpp +++ b/ydb/core/mind/hive/tx__delete_tablet.cpp @@ -113,7 +113,7 @@ public: } }; -ITransaction* THive::CreateDeleteTablet(TEvHive::TEvDeleteTablet::TPtr& ev) { +ITransaction* THive::CreateDeleteTablet(TEvHive::TEvDeleteTablet::TPtr& ev) { return new TTxDeleteTablet(ev, this); } diff --git a/ydb/core/mind/hive/tx__delete_tablet_result.cpp b/ydb/core/mind/hive/tx__delete_tablet_result.cpp index 077df0477f..bbe89acae4 100644 --- a/ydb/core/mind/hive/tx__delete_tablet_result.cpp +++ b/ydb/core/mind/hive/tx__delete_tablet_result.cpp @@ -77,7 +77,7 @@ public: } }; -ITransaction* THive::CreateDeleteTabletResult(TEvTabletBase::TEvDeleteTabletResult::TPtr& ev) { +ITransaction* THive::CreateDeleteTabletResult(TEvTabletBase::TEvDeleteTabletResult::TPtr& ev) { return new TTxDeleteTabletResult(ev, this); } diff --git a/ydb/core/mind/hive/tx__init_scheme.cpp b/ydb/core/mind/hive/tx__init_scheme.cpp index 92020e7123..b65451f94a 100644 --- a/ydb/core/mind/hive/tx__init_scheme.cpp +++ b/ydb/core/mind/hive/tx__init_scheme.cpp @@ -99,7 +99,7 @@ public: } }; -ITransaction* THive::CreateInitScheme() { +ITransaction* THive::CreateInitScheme() { return new TTxInitScheme(this); } diff --git a/ydb/core/mind/hive/tx__load_everything.cpp b/ydb/core/mind/hive/tx__load_everything.cpp index 8a125e8498..e4c1cf1f51 100644 --- a/ydb/core/mind/hive/tx__load_everything.cpp +++ b/ydb/core/mind/hive/tx__load_everything.cpp @@ -506,8 +506,8 @@ public: { tablet.TabletStorageInfo.Reset(new TTabletStorageInfo(tabletId, tablet.Type)); tablet.TabletStorageInfo->Version = tabletRowset.GetValueOrDefault<Schema::Tablet::TabletStorageVersion>(); - tablet.TabletStorageInfo->TenantPathId = tablet.GetTenant(); - + tablet.TabletStorageInfo->TenantPathId = tablet.GetTenant(); + auto tabletChannelRowset = db.Table<Schema::TabletChannel>().Range(tabletId).Select(); if (!tabletChannelRowset.IsReady()) return false; @@ -643,7 +643,7 @@ public: } }; -ITransaction* THive::CreateLoadEverything() { +ITransaction* THive::CreateLoadEverything() { return new TTxLoadEverything(this); } diff --git a/ydb/core/mind/hive/tx__unlock_tablet.cpp b/ydb/core/mind/hive/tx__unlock_tablet.cpp index 748e7ef4ed..66786b43b2 100644 --- a/ydb/core/mind/hive/tx__unlock_tablet.cpp +++ b/ydb/core/mind/hive/tx__unlock_tablet.cpp @@ -113,7 +113,7 @@ ITransaction* THive::CreateUnlockTabletExecution(const NKikimrHive::TEvUnlockTab return new TTxUnlockTabletExecution(rec, sender, cookie, this); } -ITransaction* THive::CreateUnlockTabletExecution(ui64 tabletId, ui64 seqNo) { +ITransaction* THive::CreateUnlockTabletExecution(ui64 tabletId, ui64 seqNo) { return new TTxUnlockTabletExecution(tabletId, seqNo, this); } diff --git a/ydb/core/mind/hive/tx__update_tablet_metrics.cpp b/ydb/core/mind/hive/tx__update_tablet_metrics.cpp index e4262a1303..7e6150ec9a 100644 --- a/ydb/core/mind/hive/tx__update_tablet_metrics.cpp +++ b/ydb/core/mind/hive/tx__update_tablet_metrics.cpp @@ -74,7 +74,7 @@ public: } }; -ITransaction* THive::CreateUpdateTabletMetrics(TEvHive::TEvTabletMetrics::TPtr& ev) { +ITransaction* THive::CreateUpdateTabletMetrics(TEvHive::TEvTabletMetrics::TPtr& ev) { return new TTxUpdateTabletMetrics(ev, this); } diff --git a/ydb/core/mind/hive/tx__update_tablet_status.cpp b/ydb/core/mind/hive/tx__update_tablet_status.cpp index 30815578ed..7e682e857d 100644 --- a/ydb/core/mind/hive/tx__update_tablet_status.cpp +++ b/ydb/core/mind/hive/tx__update_tablet_status.cpp @@ -196,7 +196,7 @@ public: } }; -ITransaction* THive::CreateUpdateTabletStatus( +ITransaction* THive::CreateUpdateTabletStatus( TTabletId tabletId, const TActorId &local, ui32 generation, diff --git a/ydb/core/mind/hive/ya.make b/ydb/core/mind/hive/ya.make index 75ac32b558..171f26f1b5 100644 --- a/ydb/core/mind/hive/ya.make +++ b/ydb/core/mind/hive/ya.make @@ -1,11 +1,11 @@ -LIBRARY() - +LIBRARY() + OWNER( xenoxeno g:kikimr ) -SRCS( +SRCS( balancer.cpp balancer.h boot_queue.cpp @@ -76,9 +76,9 @@ SRCS( tx__update_tablet_groups.cpp tx__update_tablet_metrics.cpp tx__update_tablet_status.cpp -) - -PEERDIR( +) + +PEERDIR( library/cpp/actors/core library/cpp/actors/interconnect library/cpp/json @@ -93,9 +93,9 @@ PEERDIR( ydb/core/sys_view/common ydb/core/tablet ydb/core/tablet_flat -) - -END() +) + +END() RECURSE_FOR_TESTS( ut diff --git a/ydb/core/mind/lease_holder.cpp b/ydb/core/mind/lease_holder.cpp index 7c4ca38847..5d47d04c71 100644 --- a/ydb/core/mind/lease_holder.cpp +++ b/ydb/core/mind/lease_holder.cpp @@ -233,7 +233,7 @@ private: void StopNode(const TActorContext &ctx) { LOG_ERROR_S(ctx, NKikimrServices::NODE_BROKER, "Stop node upon lease expiration (exit code 2)"); - AppData(ctx)->KikimrShouldContinue->ShouldStop(2); + AppData(ctx)->KikimrShouldContinue->ShouldStop(2); } TString ToString(TInstant t) const diff --git a/ydb/core/mind/local.cpp b/ydb/core/mind/local.cpp index 7d8f7120e7..09fc15f76d 100644 --- a/ydb/core/mind/local.cpp +++ b/ydb/core/mind/local.cpp @@ -1,4 +1,4 @@ -#include "local.h" +#include "local.h" #include <ydb/core/base/appdata.h> #include <ydb/core/base/counters.h> @@ -18,47 +18,47 @@ #include <unordered_map> #include <unordered_set> - + template <> void Out<std::pair<ui64, ui32>>(IOutputStream& out, const std::pair<ui64, ui32>& p) { out << '(' << p.first << ',' << p.second << ')'; } -namespace NKikimr { -class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { - struct TEvPrivate { - enum EEv { - EvRegisterTimeout = EventSpaceBegin(TEvents::ES_PRIVATE), +namespace NKikimr { +class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { + struct TEvPrivate { + enum EEv { + EvRegisterTimeout = EventSpaceBegin(TEvents::ES_PRIVATE), EvSendTabletMetrics, EvUpdateSystemUsage, EvLocalDrainTimeout, - EvEnd - }; - + EvEnd + }; + static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)"); - - typedef TEventSchedulerEv<EvRegisterTimeout> TEvRegisterTimeout; + + typedef TEventSchedulerEv<EvRegisterTimeout> TEvRegisterTimeout; struct TEvSendTabletMetrics : TEventLocal<TEvSendTabletMetrics, EvSendTabletMetrics> {}; struct TEvUpdateSystemUsage : TEventLocal<TEvUpdateSystemUsage, EvUpdateSystemUsage> {}; struct TEvLocalDrainTimeout : TEventLocal<TEvLocalDrainTimeout, EvLocalDrainTimeout> {}; - }; - + }; + struct TTablet { TActorId Tablet; - ui32 Generation; + ui32 Generation; TTabletTypes::EType TabletType; NKikimrLocal::EBootMode BootMode; ui32 FollowerId; - + TTablet() - : Tablet() - , Generation(0) + : Tablet() + , Generation(0) , TabletType() , BootMode(NKikimrLocal::EBootMode::BOOT_MODE_LEADER) , FollowerId(0) - {} - }; - + {} + }; + struct TTabletEntry : TTablet { TInstant From; @@ -79,17 +79,17 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { const TActorId Owner; const ui64 HiveId; TVector<TSubDomainKey> ServicedDomains; - + TActorId HivePipeClient; - bool Connected; + bool Connected; + + TIntrusivePtr<TLocalConfig> Config; - TIntrusivePtr<TLocalConfig> Config; - TActorId BootQueue; ui32 HiveGeneration; - + TActorId KnownHiveLeader; - + using TTabletId = std::pair<ui64, ui32>; // <TTabletId, TFollowerId> TInstant StartTime; std::unordered_map<TTabletId, TTabletEntry> InbootTablets; @@ -117,46 +117,46 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { TSharedQuotaPtr TxCacheQuota; NMonitoring::TDynamicCounterPtr Counters; - NMonitoring::TDynamicCounters::TCounterPtr CounterStartAttempts; + NMonitoring::TDynamicCounters::TCounterPtr CounterStartAttempts; NMonitoring::TDynamicCounters::TCounterPtr CounterFollowerAttempts; - NMonitoring::TDynamicCounters::TCounterPtr CounterRestored; - NMonitoring::TDynamicCounters::TCounterPtr CounterCancelLocked; - NMonitoring::TDynamicCounters::TCounterPtr CounterCancelSSTimeout; - NMonitoring::TDynamicCounters::TCounterPtr CounterCancelRace; - NMonitoring::TDynamicCounters::TCounterPtr CounterCancelError; - NMonitoring::TDynamicCounters::TCounterPtr CounterCancelBootBSError; - NMonitoring::TDynamicCounters::TCounterPtr CounterCancelOutdated; - NMonitoring::TDynamicCounters::TCounterPtr CounterCancelBootSSError; - NMonitoring::TDynamicCounters::TCounterPtr CounterCancelPoisonPill; - NMonitoring::TDynamicCounters::TCounterPtr CounterCancelDemotedBySS; - NMonitoring::TDynamicCounters::TCounterPtr CounterCancelBSError; - NMonitoring::TDynamicCounters::TCounterPtr CounterCancelInconsistentCommit; - NMonitoring::TDynamicCounters::TCounterPtr CounterCancelIsolated; - NMonitoring::TDynamicCounters::TCounterPtr CounterCancelDemotedByBS; - NMonitoring::TDynamicCounters::TCounterPtr CounterCancelUnknownReason; - - void Die(const TActorContext &ctx) override { + NMonitoring::TDynamicCounters::TCounterPtr CounterRestored; + NMonitoring::TDynamicCounters::TCounterPtr CounterCancelLocked; + NMonitoring::TDynamicCounters::TCounterPtr CounterCancelSSTimeout; + NMonitoring::TDynamicCounters::TCounterPtr CounterCancelRace; + NMonitoring::TDynamicCounters::TCounterPtr CounterCancelError; + NMonitoring::TDynamicCounters::TCounterPtr CounterCancelBootBSError; + NMonitoring::TDynamicCounters::TCounterPtr CounterCancelOutdated; + NMonitoring::TDynamicCounters::TCounterPtr CounterCancelBootSSError; + NMonitoring::TDynamicCounters::TCounterPtr CounterCancelPoisonPill; + NMonitoring::TDynamicCounters::TCounterPtr CounterCancelDemotedBySS; + NMonitoring::TDynamicCounters::TCounterPtr CounterCancelBSError; + NMonitoring::TDynamicCounters::TCounterPtr CounterCancelInconsistentCommit; + NMonitoring::TDynamicCounters::TCounterPtr CounterCancelIsolated; + NMonitoring::TDynamicCounters::TCounterPtr CounterCancelDemotedByBS; + NMonitoring::TDynamicCounters::TCounterPtr CounterCancelUnknownReason; + + void Die(const TActorContext &ctx) override { if (HivePipeClient) { if (Connected) { NTabletPipe::SendData(ctx, HivePipeClient, new TEvLocal::TEvStatus(TEvLocal::TEvStatus::StatusDead)); } - NTabletPipe::CloseClient(ctx, HivePipeClient); + NTabletPipe::CloseClient(ctx, HivePipeClient); } HivePipeClient = TActorId(); - + for (const auto &xpair : OnlineTablets) { ctx.Send(xpair.second.Tablet, new TEvents::TEvPoisonPill()); } - OnlineTablets.clear(); - + OnlineTablets.clear(); + for (const auto &xpair : InbootTablets) { - ctx.Send(xpair.second.Tablet, new TEvents::TEvPoisonPill()); + ctx.Send(xpair.second.Tablet, new TEvents::TEvPoisonPill()); } - InbootTablets.clear(); - - TActor::Die(ctx); - } - + InbootTablets.clear(); + + TActor::Die(ctx); + } + void MarkDeadTablet(TTabletId tabletId, ui32 generation, TEvLocal::TEvTabletStatus::EStatus status, @@ -165,15 +165,15 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { if (Connected) { // must be 'connected' check NTabletPipe::SendData(ctx, HivePipeClient, new TEvLocal::TEvTabletStatus(status, reason, tabletId, generation)); } - } - - void TryToRegister(const TActorContext &ctx) { + } + + void TryToRegister(const TActorContext &ctx) { LOG_DEBUG(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::TryToRegister"); - + Y_VERIFY_DEBUG(!HivePipeClient); - + // pipe client is in use for convenience, real info update come from EvPing - NTabletPipe::TClientConfig pipeConfig; + NTabletPipe::TClientConfig pipeConfig; pipeConfig.RetryPolicy = { .MinRetryTime = TDuration::MilliSeconds(100), .MaxRetryTime = TDuration::Seconds(5), @@ -181,7 +181,7 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { .DoFirstRetryInstantly = true }; HivePipeClient = ctx.RegisterWithSameMailbox(NTabletPipe::CreateClient(ctx.SelfID, HiveId, pipeConfig)); - + THolder<TEvLocal::TEvRegisterNode> request = MakeHolder<TEvLocal::TEvRegisterNode>(HiveId); for (auto &domain: ServicedDomains) { *request->Record.AddServicedDomains() = NKikimrSubDomains::TDomainKey(domain); @@ -197,21 +197,21 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { NTabletPipe::SendData(ctx, HivePipeClient, request.Release()); LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::TryToRegister pipe to hive, pipe:" << HivePipeClient.ToString()); - } - - void HandlePipeDestroyed(const TActorContext &ctx) { + } + + void HandlePipeDestroyed(const TActorContext &ctx) { LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar HandlePipeDestroyed - DISCONNECTED"); HivePipeClient = TActorId(); - Connected = false; - TryToRegister(ctx); + Connected = false; + TryToRegister(ctx); if (SentDrainNode && !DrainResultReceived) { LOG_NOTICE_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: drain complete: hive pipe destroyed, hive id: " << HiveId); DrainResultReceived = true; LastDrainRequest->OnReceive(); UpdateEstimate(); } - } - + } + void Handle(TEvLocal::TEvEnumerateTablets::TPtr &ev, const TActorContext &ctx) { const NKikimrLocal::TEvEnumerateTablets &record = ev->Get()->Record; @@ -232,7 +232,7 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { info->SetTabletId(tablet.first.first); info->SetFollowerId(tablet.first.second); info->SetTabletType(tablet.second.TabletType); - info->SetBootMode(tablet.second.BootMode); + info->SetBootMode(tablet.second.BootMode); ++tabletIdx; } } @@ -240,31 +240,31 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { ctx.Send(ev->Sender, result.Release()); } - void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx) { - TEvTabletPipe::TEvClientConnected *msg = ev->Get(); + void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx) { + TEvTabletPipe::TEvClientConnected *msg = ev->Get(); LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TEvTabletPipe::TEvClientConnected {" << "TabletId=" << msg->TabletId << " Status=" << msg->Status << " ClientId=" << msg->ClientId); - if (msg->ClientId != HivePipeClient) - return; + if (msg->ClientId != HivePipeClient) + return; if (msg->Status == NKikimrProto::OK) { SendTabletMetricsInProgress = false; - return; + return; } - HandlePipeDestroyed(ctx); - } - - void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx) { - TEvTabletPipe::TEvClientDestroyed *msg = ev->Get(); + HandlePipeDestroyed(ctx); + } + + void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx) { + TEvTabletPipe::TEvClientDestroyed *msg = ev->Get(); LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TEvTabletPipe::TEvClientDestroyed {" << "TabletId=" << msg->TabletId << " ClientId=" << msg->ClientId); - if (msg->ClientId != HivePipeClient) - return; - HandlePipeDestroyed(ctx); - } - + if (msg->ClientId != HivePipeClient) + return; + HandlePipeDestroyed(ctx); + } + void SendStatusOk(const TActorContext &ctx) { LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar SendStatusOk"); TAutoPtr<TEvLocal::TEvStatus> eventStatus = new TEvLocal::TEvStatus(TEvLocal::TEvStatus::StatusOk); @@ -307,19 +307,19 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { } } - void Handle(TEvLocal::TEvPing::TPtr &ev, const TActorContext &ctx) { + void Handle(TEvLocal::TEvPing::TPtr &ev, const TActorContext &ctx) { LOG_DEBUG(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::Handle TEvLocal::TEvPing"); const TActorId &sender = ev->Sender; - const NKikimrLocal::TEvPing &record = ev->Get()->Record; + const NKikimrLocal::TEvPing &record = ev->Get()->Record; Y_VERIFY(HiveId == record.GetHiveId()); - + const ui32 hiveGen = record.GetHiveGeneration(); if (hiveGen < HiveGeneration) { LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::Handle TEvLocal::TEvPing - outdated"); - ctx.Send(sender, new TEvLocal::TEvStatus(TEvLocal::TEvStatus::StatusOutdated)); - return; - } - + ctx.Send(sender, new TEvLocal::TEvStatus(TEvLocal::TEvStatus::StatusOutdated)); + return; + } + if (!HivePipeClient) { TryToRegister(ctx); return; @@ -331,16 +331,16 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { ctx.Send(x.second.Tablet, new TEvents::TEvPoisonPill()); InbootTablets.clear(); } - + if (record.GetPurge()) { for (const auto &x : OnlineTablets) ctx.Send(x.second.Tablet, new TEvents::TEvPoisonPill()); OnlineTablets.clear(); } - + ResourceProfiles = new TResourceProfiles; ResourceProfiles->LoadProfiles(record.GetConfig().GetResourceProfiles()); - + // we send starting and running tablets TAutoPtr<TEvLocal::TEvSyncTablets> eventSyncTablets = new TEvLocal::TEvSyncTablets(); for (const auto& pr : InbootTablets) { @@ -374,10 +374,10 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { SendStatusOk(ctx); ScheduleSendTabletMetrics(ctx); - } - - void Handle(TEvLocal::TEvBootTablet::TPtr &ev, const TActorContext &ctx) { - NKikimrLocal::TEvBootTablet &record = ev->Get()->Record; + } + + void Handle(TEvLocal::TEvBootTablet::TPtr &ev, const TActorContext &ctx) { + NKikimrLocal::TEvBootTablet &record = ev->Get()->Record; TIntrusivePtr<TTabletStorageInfo> info(TabletStorageInfoFromProto(record.GetInfo())); info->HiveId = HiveId; TTabletId tabletId(info->TabletID, record.GetFollowerId()); @@ -390,32 +390,32 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { auto tabletType = info->TabletType; Y_VERIFY(tabletType != TTabletTypes::TypeInvalid); ui32 suggestedGen = record.GetSuggestedGeneration(); - - if (ev->Sender != BootQueue) { - LOG_NOTICE(ctx, NKikimrServices::LOCAL, + + if (ev->Sender != BootQueue) { + LOG_NOTICE(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvLocal::TEvBootTablet unexpected sender:%s", ev->Sender.ToString().c_str()); ctx.Send(ev->Sender, new TEvLocal::TEvTabletStatus( TEvLocal::TEvTabletStatus::StatusBootQueueUnknown, tabletId, suggestedGen)); - return; - } - + return; + } + LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvLocal::TEvBootTablet tabletType:" << tabletType << " tabletId:" << tabletId << " suggestedGen:" << suggestedGen); - + TMap<TTabletTypes::EType, TLocalConfig::TTabletClassInfo>::const_iterator it = Config->TabletClassInfo.find(tabletType); - if (it == Config->TabletClassInfo.end()) { + if (it == Config->TabletClassInfo.end()) { LOG_ERROR_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: boot-tablet unknown tablet type: " << tabletType << " for tablet: " << tabletId); - ctx.Send(ev->Sender, new TEvLocal::TEvTabletStatus( - TEvLocal::TEvTabletStatus::StatusTypeUnknown, tabletId, suggestedGen)); - return; + ctx.Send(ev->Sender, new TEvLocal::TEvTabletStatus( + TEvLocal::TEvTabletStatus::StatusTypeUnknown, tabletId, suggestedGen)); + return; } - - { - auto it = OnlineTablets.find(tabletId); - if (it != OnlineTablets.end()) { + + { + auto it = OnlineTablets.find(tabletId); + if (it != OnlineTablets.end()) { if (it->second.BootMode == NKikimrLocal::EBootMode::BOOT_MODE_FOLLOWER && record.GetBootMode() == NKikimrLocal::EBootMode::BOOT_MODE_LEADER) { // promote to leader @@ -435,20 +435,20 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { return; } ctx.Send(it->second.Tablet, new TEvTablet::TEvTabletStop(tabletId.first, TEvTablet::TEvTabletStop::ReasonStop)); - OnlineTablets.erase(it); - } - } - + OnlineTablets.erase(it); + } + } + TTabletEntry &entry = InbootTablets[tabletId]; if (entry.Tablet && entry.Generation != suggestedGen) { ctx.Send(entry.Tablet, new TEvents::TEvPoisonPill()); } - - TTabletSetupInfo *setupInfo = it->second.SetupInfo.Get(); + + TTabletSetupInfo *setupInfo = it->second.SetupInfo.Get(); switch (record.GetBootMode()) { case NKikimrLocal::BOOT_MODE_LEADER: entry.Tablet = setupInfo->Tablet(info.Get(), ctx.SelfID, ctx, suggestedGen, ResourceProfiles, TxCacheQuota); - CounterStartAttempts->Inc(); + CounterStartAttempts->Inc(); break; case NKikimrLocal::BOOT_MODE_FOLLOWER: entry.Tablet = setupInfo->Follower(info.Get(), ctx.SelfID, ctx, tabletId.second, ResourceProfiles, TxCacheQuota); @@ -456,20 +456,20 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { break; } - entry.Generation = suggestedGen; - entry.From = ctx.Now(); + entry.Generation = suggestedGen; + entry.From = ctx.Now(); entry.TabletType = tabletType; entry.BootMode = record.GetBootMode(); - + LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::Handle TEvLocal::TEvBootTablet tabletId:" << tabletId << " tablet entry created"); if (record.GetBootMode() == NKikimrLocal::BOOT_MODE_FOLLOWER) { MarkRunningTablet(tabletId, suggestedGen, ctx); } - } - - void Handle(TEvLocal::TEvStopTablet::TPtr &ev, const TActorContext &ctx) { - const NKikimrLocal::TEvStopTablet &record = ev->Get()->Record; + } + + void Handle(TEvLocal::TEvStopTablet::TPtr &ev, const TActorContext &ctx) { + const NKikimrLocal::TEvStopTablet &record = ev->Get()->Record; Y_VERIFY(record.HasTabletId()); TTabletId tabletId(record.GetTabletId(), record.GetFollowerId()); LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvStopTablet TabletId:" << tabletId); @@ -478,22 +478,22 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { if (onlineTabletIt != OnlineTablets.end()) { // Provide/check generation here ctx.Send(onlineTabletIt->second.Tablet, new TEvTablet::TEvTabletStop(tabletId.first, TEvTablet::TEvTabletStop::ReasonStop)); - } else { - auto inbootTabletIt = InbootTablets.find(tabletId); - if (inbootTabletIt != InbootTablets.end()) { - // Provide/check generation here + } else { + auto inbootTabletIt = InbootTablets.find(tabletId); + if (inbootTabletIt != InbootTablets.end()) { + // Provide/check generation here ctx.Send(inbootTabletIt->second.Tablet, new TEvTablet::TEvTabletStop(tabletId.first, TEvTablet::TEvTabletStop::ReasonStop)); - } + } } } - void Handle(TEvLocal::TEvDeadTabletAck::TPtr &ev, const TActorContext &ctx) { + void Handle(TEvLocal::TEvDeadTabletAck::TPtr &ev, const TActorContext &ctx) { const NKikimrLocal::TEvDeadTabletAck &record = ev->Get()->Record; Y_VERIFY(record.HasTabletId()); TTabletId tabletId(record.GetTabletId(), record.GetFollowerId()); LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvDeadTabletAck TabletId:" << tabletId); - } - + } + void Handle(TEvLocal::TEvTabletMetrics::TPtr& ev, const TActorContext& ctx) { TEvLocal::TEvTabletMetrics* msg = ev->Get(); const TTabletId tabletId(msg->TabletId, msg->FollowerId); @@ -685,14 +685,14 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { InbootTablets.erase(inbootIt); } - void Handle(TEvTablet::TEvRestored::TPtr &ev, const TActorContext &ctx) { - TEvTablet::TEvRestored *msg = ev->Get(); - + void Handle(TEvTablet::TEvRestored::TPtr &ev, const TActorContext &ctx) { + TEvTablet::TEvRestored *msg = ev->Get(); + if (msg->Follower) // ignore follower notifications - return; - - CounterRestored->Inc(); // always update counter for every tablet, even non-actual one. it's about tracking not resource allocation - + return; + + CounterRestored->Inc(); // always update counter for every tablet, even non-actual one. it's about tracking not resource allocation + const auto tabletId = msg->TabletID; LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvTablet::TEvRestored tablet " << tabletId @@ -701,9 +701,9 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { auto inbootIt = std::find_if(InbootTablets.begin(), InbootTablets.end(), [&](const auto& pr) -> bool { return pr.second.Tablet == ev->Sender; }); - if (inbootIt == InbootTablets.end()) - return; - TTabletEntry &entry = inbootIt->second; + if (inbootIt == InbootTablets.end()) + return; + TTabletEntry &entry = inbootIt->second; if (msg->Generation < entry.Generation) { LOG_WARN_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvTablet::TEvRestored tablet " << tabletId @@ -715,85 +715,85 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { return; } MarkRunningTablet(inbootIt->first, msg->Generation, ctx); - } - + } + void Handle(TEvTablet::TEvCutTabletHistory::TPtr &ev, const TActorContext &ctx) { if (Connected) // must be 'connected' check NTabletPipe::SendData(ctx, HivePipeClient, ev.Get()->Release().Release()); } - void Handle(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext &ctx) { - TEvTablet::TEvTabletDead *msg = ev->Get(); + void Handle(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext &ctx) { + TEvTablet::TEvTabletDead *msg = ev->Get(); const auto tabletId = msg->TabletID; - const ui32 generation = msg->Generation; + const ui32 generation = msg->Generation; LOG_DEBUG_S(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Handle TEvTablet::TEvTabletDead tabletId:" << tabletId << " generation:" << generation << " reason:" << (ui32)msg->Reason); - - switch (msg->Reason) { - case TEvTablet::TEvTabletDead::ReasonBootLocked: - CounterCancelLocked->Inc(); - break; - case TEvTablet::TEvTabletDead::ReasonBootSSTimeout: - CounterCancelSSTimeout->Inc(); - break; - case TEvTablet::TEvTabletDead::ReasonBootRace: - CounterCancelRace->Inc(); - break; - case TEvTablet::TEvTabletDead::ReasonBootBSError: - CounterCancelBootBSError->Inc(); - break; - case TEvTablet::TEvTabletDead::ReasonBootSuggestOutdated: - CounterCancelOutdated->Inc(); - break; - case TEvTablet::TEvTabletDead::ReasonBootSSError: - CounterCancelBootSSError->Inc(); - break; - case TEvTablet::TEvTabletDead::ReasonPill: - CounterCancelPoisonPill->Inc(); - break; - case TEvTablet::TEvTabletDead::ReasonDemotedByStateStorage: - CounterCancelDemotedBySS->Inc(); - break; - case TEvTablet::TEvTabletDead::ReasonBSError: - CounterCancelBSError->Inc(); - break; - case TEvTablet::TEvTabletDead::ReasonInconsistentCommit: - CounterCancelInconsistentCommit->Inc(); - break; - case TEvTablet::TEvTabletDead::ReasonIsolated: - CounterCancelIsolated->Inc(); - break; - case TEvTablet::TEvTabletDead::ReasonDemotedByBlobStorage: - CounterCancelDemotedByBS->Inc(); - break; - default: - CounterCancelUnknownReason->Inc(); - break; - } - - // known tablets should be in online-tablets or in inboot-tablets (with correct generation). + + switch (msg->Reason) { + case TEvTablet::TEvTabletDead::ReasonBootLocked: + CounterCancelLocked->Inc(); + break; + case TEvTablet::TEvTabletDead::ReasonBootSSTimeout: + CounterCancelSSTimeout->Inc(); + break; + case TEvTablet::TEvTabletDead::ReasonBootRace: + CounterCancelRace->Inc(); + break; + case TEvTablet::TEvTabletDead::ReasonBootBSError: + CounterCancelBootBSError->Inc(); + break; + case TEvTablet::TEvTabletDead::ReasonBootSuggestOutdated: + CounterCancelOutdated->Inc(); + break; + case TEvTablet::TEvTabletDead::ReasonBootSSError: + CounterCancelBootSSError->Inc(); + break; + case TEvTablet::TEvTabletDead::ReasonPill: + CounterCancelPoisonPill->Inc(); + break; + case TEvTablet::TEvTabletDead::ReasonDemotedByStateStorage: + CounterCancelDemotedBySS->Inc(); + break; + case TEvTablet::TEvTabletDead::ReasonBSError: + CounterCancelBSError->Inc(); + break; + case TEvTablet::TEvTabletDead::ReasonInconsistentCommit: + CounterCancelInconsistentCommit->Inc(); + break; + case TEvTablet::TEvTabletDead::ReasonIsolated: + CounterCancelIsolated->Inc(); + break; + case TEvTablet::TEvTabletDead::ReasonDemotedByBlobStorage: + CounterCancelDemotedByBS->Inc(); + break; + default: + CounterCancelUnknownReason->Inc(); + break; + } + + // known tablets should be in online-tablets or in inboot-tablets (with correct generation). auto onlineIt = std::find_if(OnlineTablets.begin(), OnlineTablets.end(), [&](const auto& pr) -> bool { return pr.second.Tablet == ev->Sender; }); if (onlineIt != OnlineTablets.end()) { // from online list MarkDeadTablet(onlineIt->first, generation, TEvLocal::TEvTabletStatus::StatusFailed, msg->Reason, ctx); - OnlineTablets.erase(onlineIt); + OnlineTablets.erase(onlineIt); UpdateEstimate(); - return; + return; } - + auto inbootIt = std::find_if(InbootTablets.begin(), InbootTablets.end(), [&](const auto& pr) -> bool { return pr.second.Tablet == ev->Sender; }); - if (inbootIt != InbootTablets.end() && inbootIt->second.Generation <= generation) { + if (inbootIt != InbootTablets.end() && inbootIt->second.Generation <= generation) { MarkDeadTablet(inbootIt->first, generation, TEvLocal::TEvTabletStatus::StatusBootFailed, msg->Reason, ctx); - InbootTablets.erase(inbootIt); - return; - } - - // deprecated tablet, we don't care - } - + InbootTablets.erase(inbootIt); + return; + } + + // deprecated tablet, we don't care + } + void HandlePoison(const TActorContext &ctx) { LOG_DEBUG(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: HandlePoison"); Die(ctx); @@ -856,7 +856,7 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> { TxCacheQuota->ChangeQuota(Max<i64>()); } -public: +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::LOCAL_ACTOR; } @@ -864,11 +864,11 @@ public: TLocalNodeRegistrar(const TActorId &owner, ui64 hiveId, TVector<TSubDomainKey> servicedDomains, const NKikimrTabletBase::TMetrics &resourceLimit, TIntrusivePtr<TLocalConfig> config, NMonitoring::TDynamicCounterPtr counters) - : Owner(owner) + : Owner(owner) , HiveId(hiveId) , ServicedDomains(std::move(servicedDomains)) - , Connected(false) - , Config(config) + , Connected(false) + , Config(config) , HiveGeneration(0) , SendTabletMetricsInProgress(false) , ResourceLimit(resourceLimit) @@ -877,51 +877,51 @@ public: Y_VERIFY(!ServicedDomains.empty()); TxCacheQuota = new TSharedQuota(Counters->GetCounter("UsedTxDataCache"), Counters->GetCounter("TxDataCacheSize")); - - CounterStartAttempts = Counters->GetCounter("Local_StartAttempts", true); + + CounterStartAttempts = Counters->GetCounter("Local_StartAttempts", true); CounterFollowerAttempts = Counters->GetCounter("Local_FollowerAttempts", true); - CounterRestored = Counters->GetCounter("Local_Restored", true); - CounterCancelLocked = Counters->GetCounter("Local_CancelLocked", true); - CounterCancelSSTimeout = Counters->GetCounter("Local_CancelSSTimeout", true); - CounterCancelRace = Counters->GetCounter("Local_CancelRace", true); - CounterCancelBootBSError = Counters->GetCounter("Local_CancelBootBSError", true); - CounterCancelOutdated = Counters->GetCounter("Local_CancelOutdated", true); - CounterCancelBootSSError = Counters->GetCounter("Local_CancelBootSSError", true); - CounterCancelPoisonPill = Counters->GetCounter("Local_CancelPoisonPill", true); - CounterCancelDemotedBySS = Counters->GetCounter("Local_CancelDemotedBySS", true); - CounterCancelBSError = Counters->GetCounter("Local_CancelBSError", true); - CounterCancelInconsistentCommit = Counters->GetCounter("Local_CancelInconsistentCommit", true); - CounterCancelIsolated = Counters->GetCounter("Local_CancelIsolated", true); - CounterCancelDemotedByBS = Counters->GetCounter("Local_CancelDemotedByBS", true); - CounterCancelUnknownReason = Counters->GetCounter("Local_CancelUnknownReason", true); - + CounterRestored = Counters->GetCounter("Local_Restored", true); + CounterCancelLocked = Counters->GetCounter("Local_CancelLocked", true); + CounterCancelSSTimeout = Counters->GetCounter("Local_CancelSSTimeout", true); + CounterCancelRace = Counters->GetCounter("Local_CancelRace", true); + CounterCancelBootBSError = Counters->GetCounter("Local_CancelBootBSError", true); + CounterCancelOutdated = Counters->GetCounter("Local_CancelOutdated", true); + CounterCancelBootSSError = Counters->GetCounter("Local_CancelBootSSError", true); + CounterCancelPoisonPill = Counters->GetCounter("Local_CancelPoisonPill", true); + CounterCancelDemotedBySS = Counters->GetCounter("Local_CancelDemotedBySS", true); + CounterCancelBSError = Counters->GetCounter("Local_CancelBSError", true); + CounterCancelInconsistentCommit = Counters->GetCounter("Local_CancelInconsistentCommit", true); + CounterCancelIsolated = Counters->GetCounter("Local_CancelIsolated", true); + CounterCancelDemotedByBS = Counters->GetCounter("Local_CancelDemotedByBS", true); + CounterCancelUnknownReason = Counters->GetCounter("Local_CancelUnknownReason", true); + UpdateCacheQuota(); } - - void Bootstrap(const TActorContext &ctx) { + + void Bootstrap(const TActorContext &ctx) { LOG_DEBUG(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar::Bootstrap"); Send(SelfId(), new TEvPrivate::TEvUpdateSystemUsage()); StartTime = ctx.Now(); - TryToRegister(ctx); + TryToRegister(ctx); Become(&TThis::StateWork); - } - - STFUNC(StateWork) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvTablet::TEvRestored, Handle); // tablet restored, notify queue about update - HFunc(TEvTablet::TEvTabletDead, Handle); // tablet dead, notify queue about update + } + + STFUNC(StateWork) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvTablet::TEvRestored, Handle); // tablet restored, notify queue about update + HFunc(TEvTablet::TEvTabletDead, Handle); // tablet dead, notify queue about update HFunc(TEvTablet::TEvCutTabletHistory, Handle); - HFunc(TEvLocal::TEvBootTablet, Handle); // command to boot tablet - HFunc(TEvLocal::TEvPing, Handle); // command to update link to per-local boot-queue - HFunc(TEvLocal::TEvStopTablet, Handle); // stop tablet - HFunc(TEvLocal::TEvDeadTabletAck, Handle); + HFunc(TEvLocal::TEvBootTablet, Handle); // command to boot tablet + HFunc(TEvLocal::TEvPing, Handle); // command to update link to per-local boot-queue + HFunc(TEvLocal::TEvStopTablet, Handle); // stop tablet + HFunc(TEvLocal::TEvDeadTabletAck, Handle); HFunc(TEvLocal::TEvEnumerateTablets, Handle); HFunc(TEvLocal::TEvTabletMetrics, Handle); HFunc(TEvLocal::TEvTabletMetricsAck, Handle); HFunc(TEvLocal::TEvAlterTenant, Handle); HFunc(TEvLocal::TEvReconnect, Handle); - HFunc(TEvTabletPipe::TEvClientConnected, Handle); - HFunc(TEvTabletPipe::TEvClientDestroyed, Handle); + HFunc(TEvTabletPipe::TEvClientConnected, Handle); + HFunc(TEvTabletPipe::TEvClientDestroyed, Handle); HFunc(TEvPrivate::TEvSendTabletMetrics, Handle); HFunc(TEvPrivate::TEvUpdateSystemUsage, Handle); HFunc(TEvPrivate::TEvLocalDrainTimeout, HandleDrainTimeout); @@ -933,11 +933,11 @@ public: LOG_DEBUG(ctx, NKikimrServices::LOCAL, "TLocalNodeRegistrar: Unhandled in StateWork type: %" PRIx32 " event: %s", ev->GetTypeRewrite(), ev->HasEvent() ? ev->GetBase()->ToString().data() : "serialized?"); break; - } - } - -}; - + } + } + +}; + class TDomainLocal : public TActorBootstrapped<TDomainLocal> { struct TResolveTask { TRegistrationInfo Info; @@ -1136,12 +1136,12 @@ class TDomainLocal : public TActorBootstrapped<TDomainLocal> { if (msg->Status != NKikimrProto::EReplyStatus::OK) { OpenPipe(ctx); return; - } - + } + for (auto &pr : ResolveTasks) SendResolveRequest(pr.second.Info, ctx); - } - + } + void HandlePipe(TEvTabletPipe::TEvClientDestroyed::TPtr ev, const TActorContext &ctx) { TEvTabletPipe::TEvClientDestroyed *msg = ev->Get(); @@ -1341,7 +1341,7 @@ class TDomainLocal : public TActorBootstrapped<TDomainLocal> { } SendStatus(info.TenantName, ev->Sender, ctx); - } + } public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { @@ -1391,8 +1391,8 @@ public: break; } } -}; - +}; + class TLocal : public TActorBootstrapped<TLocal> { TIntrusivePtr<TLocalConfig> Config; THashMap<TString, TActorId> DomainLocals; @@ -1503,8 +1503,8 @@ public: } }; -IActor* CreateLocal(TLocalConfig *config) { - return new TLocal(config); -} - -} +IActor* CreateLocal(TLocalConfig *config) { + return new TLocal(config); +} + +} diff --git a/ydb/core/mind/local.h b/ydb/core/mind/local.h index 66fdc5a8f3..05c9bdc48e 100644 --- a/ydb/core/mind/local.h +++ b/ydb/core/mind/local.h @@ -1,5 +1,5 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include <ydb/core/protos/local.pb.h> #include <ydb/core/tablet/tablet_setup.h> #include <ydb/core/base/events.h> @@ -7,10 +7,10 @@ #include <ydb/core/base/subdomain.h> #include <ydb/core/base/tablet.h> #include <ydb/core/base/blobstorage.h> -#include <util/generic/map.h> +#include <util/generic/map.h> #include <ydb/core/tablet/tablet_metrics.h> - -namespace NKikimr { + +namespace NKikimr { struct TRegistrationInfo { TString DomainName; @@ -68,23 +68,23 @@ struct TDrainProgress : public TThrRefBase { } }; -struct TEvLocal { - enum EEv { - EvRegisterNode = EventSpaceBegin(TKikimrEvents::ES_LOCAL), - EvPing, - EvBootTablet, - EvStopTablet, // must be here - EvDeadTabletAck, +struct TEvLocal { + enum EEv { + EvRegisterNode = EventSpaceBegin(TKikimrEvents::ES_LOCAL), + EvPing, + EvBootTablet, + EvStopTablet, // must be here + EvDeadTabletAck, EvEnumerateTablets, EvSyncTablets, EvTabletMetrics, EvReconnect, - - EvStatus = EvRegisterNode + 512, - EvTabletStatus, + + EvStatus = EvRegisterNode + 512, + EvTabletStatus, EvEnumerateTabletsResult, EvTabletMetricsAck, - + EvAddTenant = EvRegisterNode + 1024, EvRemoveTenant, EvAlterTenant, @@ -92,33 +92,33 @@ struct TEvLocal { EvLocalDrainNode, - EvEnd - }; - + EvEnd + }; + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_LOCAL), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_LOCAL)"); - + struct TEvRegisterNode : public TEventPB<TEvRegisterNode, NKikimrLocal::TEvRegisterNode, EvRegisterNode> { - TEvRegisterNode() - {} - + TEvRegisterNode() + {} + TEvRegisterNode(ui64 hiveId) { Record.SetHiveId(hiveId); - } - }; - + } + }; + struct TEvPing : public TEventPB<TEvPing, NKikimrLocal::TEvPing, EvPing> { - TEvPing() - {} - + TEvPing() + {} + TEvPing(ui64 hiveId, ui32 hiveGeneration, bool purge, const NKikimrLocal::TLocalConfig &config) { Record.SetHiveId(hiveId); Record.SetHiveGeneration(hiveGeneration); - Record.SetPurge(purge); + Record.SetPurge(purge); Record.MutableConfig()->CopyFrom(config); - } - }; - + } + }; + struct TEvReconnect : TEventPB<TEvReconnect, NKikimrLocal::TEvReconnect, EvReconnect> { TEvReconnect() = default; @@ -129,19 +129,19 @@ struct TEvLocal { }; struct TEvStatus : public TEventPB<TEvStatus, NKikimrLocal::TEvStatus, EvStatus> { - enum EStatus { - StatusOk, - StatusOutdated, - StatusDead, - }; - + enum EStatus { + StatusOk, + StatusOutdated, + StatusDead, + }; + TEvStatus() { - Record.SetStatus(StatusOk); - } - + Record.SetStatus(StatusOk); + } + TEvStatus(EStatus status) { - Record.SetStatus(status); - } + Record.SetStatus(status); + } TEvStatus(EStatus status, ui64 inbootTablets, ui64 onlineTablets, ui64 deadTablets) { Record.SetStatus(status); @@ -149,64 +149,64 @@ struct TEvLocal { Record.SetOnlineTablets(onlineTablets); Record.SetDeadTablets(deadTablets); } - }; - + }; + struct TEvBootTablet : public TEventPB<TEvBootTablet, NKikimrLocal::TEvBootTablet, EvBootTablet> { - TEvBootTablet() - {} - + TEvBootTablet() + {} + TEvBootTablet(const TTabletStorageInfo &info, ui32 followerId, ui32 suggestedGeneration) { - TabletStorageInfoToProto(info, Record.MutableInfo()); - Record.SetSuggestedGeneration(suggestedGeneration); + TabletStorageInfoToProto(info, Record.MutableInfo()); + Record.SetSuggestedGeneration(suggestedGeneration); Record.SetBootMode(NKikimrLocal::BOOT_MODE_LEADER); Record.SetFollowerId(followerId); - } + } TEvBootTablet(const TTabletStorageInfo &info, ui32 followerId) { TabletStorageInfoToProto(info, Record.MutableInfo()); Record.SetBootMode(NKikimrLocal::BOOT_MODE_FOLLOWER); Record.SetFollowerId(followerId); } - }; - - struct TEvStopTablet : public TEventPB<TEvStopTablet, NKikimrLocal::TEvStopTablet, EvStopTablet> { - TEvStopTablet() - {} - + }; + + struct TEvStopTablet : public TEventPB<TEvStopTablet, NKikimrLocal::TEvStopTablet, EvStopTablet> { + TEvStopTablet() + {} + TEvStopTablet(std::pair<ui64, ui32> tabletId) - { + { Record.SetTabletId(tabletId.first); Record.SetFollowerId(tabletId.second); - } - }; - - struct TEvDeadTabletAck : public TEventPB<TEvDeadTabletAck, NKikimrLocal::TEvDeadTabletAck, EvDeadTabletAck> { - TEvDeadTabletAck() - {} - + } + }; + + struct TEvDeadTabletAck : public TEventPB<TEvDeadTabletAck, NKikimrLocal::TEvDeadTabletAck, EvDeadTabletAck> { + TEvDeadTabletAck() + {} + TEvDeadTabletAck(std::pair<ui64, ui32> tabletId, ui32 generation) - { + { Record.SetTabletId(tabletId.first); Record.SetFollowerId(tabletId.second); - Record.SetGeneration(generation); - } - }; - + Record.SetGeneration(generation); + } + }; + struct TEvTabletStatus : public TEventPB<TEvTabletStatus, NKikimrLocal::TEvTabletStatus, EvTabletStatus> { - enum EStatus { - StatusOk, - StatusBootFailed, - StatusTypeUnknown, - StatusBSBootError, - StatusBSWriteError, - StatusFailed, - StatusBootQueueUnknown, + enum EStatus { + StatusOk, + StatusBootFailed, + StatusTypeUnknown, + StatusBSBootError, + StatusBSWriteError, + StatusFailed, + StatusBootQueueUnknown, StatusSupersededByLeader, - }; - - TEvTabletStatus() - {} - + }; + + TEvTabletStatus() + {} + TEvTabletStatus(EStatus status, TEvTablet::TEvTabletDead::EReason reason, std::pair<ui64, ui32> tabletId, ui32 generation) { Record.SetStatus(status); Record.SetReason(reason); @@ -216,12 +216,12 @@ struct TEvLocal { } TEvTabletStatus(EStatus status, std::pair<ui64, ui32> tabletId, ui32 generation) { - Record.SetStatus(status); + Record.SetStatus(status); Record.SetTabletID(tabletId.first); Record.SetFollowerId(tabletId.second); - Record.SetGeneration(generation); - } - }; + Record.SetGeneration(generation); + } + }; struct TEvEnumerateTablets : public TEventPB<TEvEnumerateTablets, NKikimrLocal::TEvEnumerateTablets, EvEnumerateTablets> { @@ -261,23 +261,23 @@ struct TEvLocal { struct TEvTabletMetricsAck : public TEventPB<TEvTabletMetricsAck, NKikimrLocal::TEvTabletMetricsAck, EvTabletMetricsAck> { }; - + struct TEvAddTenant : public TEventLocal<TEvAddTenant, EvAddTenant> { TRegistrationInfo TenantInfo; - + TEvAddTenant(const TString &domainName) : TenantInfo(domainName) {} - + TEvAddTenant(const TString &domainName, NKikimrTabletBase::TMetrics resourceLimit) : TenantInfo(domainName, resourceLimit) - {} - + {} + TEvAddTenant(const TRegistrationInfo &info) : TenantInfo(info) - {} - }; - + {} + }; + struct TEvRemoveTenant : public TEventLocal<TEvRemoveTenant, EvRemoveTenant> { TString TenantName; @@ -365,10 +365,10 @@ struct TLocalConfig : public TThrRefBase { }; TMap<TTabletTypes::EType, TTabletClassInfo> TabletClassInfo; -}; - -IActor* CreateLocal(TLocalConfig *config); - +}; + +IActor* CreateLocal(TLocalConfig *config); + inline TActorId MakeLocalID(ui32 node) { char x[12] = { 'l', 'o', 'c', 'l'}; x[4] = (char)(node & 0xFF); @@ -380,8 +380,8 @@ inline TActorId MakeLocalID(ui32 node) { x[10] = 0; x[11] = 0; return TActorId(node, TStringBuf(x, 12)); -} - +} + inline TActorId MakeLocalRegistrarID(ui32 node, ui64 hiveId) { char x[12] = { 'l', 'o', 'c', 'l'}; x[4] = (char)(node & 0xFF); @@ -393,6 +393,6 @@ inline TActorId MakeLocalRegistrarID(ui32 node, ui64 hiveId) { x[10] = (char)(((hiveId >> 16) & 0xFF) ^ ((hiveId >> 48) & 0xFF)); x[11] = (char)(((hiveId >> 24) & 0xFF) ^ ((hiveId >> 56) & 0xFF)); return TActorId(node, TStringBuf(x, 12)); -} +} } diff --git a/ydb/core/mind/node_broker.cpp b/ydb/core/mind/node_broker.cpp index ef7d194f14..a2ef938369 100644 --- a/ydb/core/mind/node_broker.cpp +++ b/ydb/core/mind/node_broker.cpp @@ -832,10 +832,10 @@ void TNodeBroker::Handle(TEvNodeBroker::TEvRegistrationRequest::TPtr &ev, NActors::TScopeId ScopeId; public: - static constexpr NKikimrServices::TActivity::EType ActorActivityType() { - return NKikimrServices::TActivity::NODE_BROKER_ACTOR; - } - + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { + return NKikimrServices::TActivity::NODE_BROKER_ACTOR; + } + TRegisterNodeActor(TEvNodeBroker::TEvRegistrationRequest::TPtr& ev, TNodeBroker *self) : Ev(ev) , Self(self) diff --git a/ydb/core/mind/tenant_node_enumeration.cpp b/ydb/core/mind/tenant_node_enumeration.cpp index c19dcb715b..15ecddceb2 100644 --- a/ydb/core/mind/tenant_node_enumeration.cpp +++ b/ydb/core/mind/tenant_node_enumeration.cpp @@ -1,150 +1,150 @@ -#include "tenant_node_enumeration.h" -#include "tenant_pool.h" +#include "tenant_node_enumeration.h" +#include "tenant_pool.h" #include <ydb/core/base/appdata.h> #include <ydb/core/base/statestorage.h> #include <ydb/core/base/path.h> #include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/actors/core/hfunc.h> -#include <util/generic/algorithm.h> - -namespace NKikimr { - -TString MakeTenantNodeEnumerationPath(const TString &tenantName) { - return "node+" + tenantName; -} - -static ui32 ExtractDefaultGroupForPath(const TString &path) { - auto *domains = AppData()->DomainsInfo.Get(); - const TStringBuf domainName = ExtractDomain(path); - auto *domainInfo = domains->GetDomainByName(domainName); - if (domainInfo) - return domainInfo->DefaultStateStorageGroup; - else - return Max<ui32>(); -} - -class TTenantNodeEnumerationPublisher : public TActorBootstrapped<TTenantNodeEnumerationPublisher> { +#include <util/generic/algorithm.h> + +namespace NKikimr { + +TString MakeTenantNodeEnumerationPath(const TString &tenantName) { + return "node+" + tenantName; +} + +static ui32 ExtractDefaultGroupForPath(const TString &path) { + auto *domains = AppData()->DomainsInfo.Get(); + const TStringBuf domainName = ExtractDomain(path); + auto *domainInfo = domains->GetDomainByName(domainName); + if (domainInfo) + return domainInfo->DefaultStateStorageGroup; + else + return Max<ui32>(); +} + +class TTenantNodeEnumerationPublisher : public TActorBootstrapped<TTenantNodeEnumerationPublisher> { TMap<TString, TActorId> PublishActors; - - void Handle(TEvTenantPool::TEvTenantPoolStatus::TPtr &ev) { - const auto &record = ev->Get()->Record; - + + void Handle(TEvTenantPool::TEvTenantPoolStatus::TPtr &ev) { + const auto &record = ev->Get()->Record; + TMap<TString, TActorId> toRemove; - toRemove.swap(PublishActors); - - for (auto &x : record.GetSlots()) { - if (const TString &assigned = x.GetAssignedTenant()) { - auto it = toRemove.find(assigned); - if (it != toRemove.end()) { - PublishActors.emplace(*it); - toRemove.erase(it); - } else { - const TString assignedPath = MakeTenantNodeEnumerationPath(assigned); - const ui32 statestorageGroupId = ExtractDefaultGroupForPath(assigned); - if (statestorageGroupId == Max<ui32>()) - continue; - + toRemove.swap(PublishActors); + + for (auto &x : record.GetSlots()) { + if (const TString &assigned = x.GetAssignedTenant()) { + auto it = toRemove.find(assigned); + if (it != toRemove.end()) { + PublishActors.emplace(*it); + toRemove.erase(it); + } else { + const TString assignedPath = MakeTenantNodeEnumerationPath(assigned); + const ui32 statestorageGroupId = ExtractDefaultGroupForPath(assigned); + if (statestorageGroupId == Max<ui32>()) + continue; + const TActorId publishActor = Register(CreateBoardPublishActor(assignedPath, TString(), SelfId(), statestorageGroupId, 0, true)); - - PublishActors.emplace(assigned, publishActor); - } - } - } - - for (auto &xpair : toRemove) { - Send(xpair.second, new TEvents::TEvPoisonPill()); - } - } -public: - static constexpr NKikimrServices::TActivity::EType ActorActivityType() { - return NKikimrServices::TActivity::TENANT_NODES_ENUMERATION; - } - - TTenantNodeEnumerationPublisher() - {} - - void Bootstrap() { - Send(MakeTenantPoolRootID(), new TEvents::TEvSubscribe()); - Become(&TThis::StateWait); - } - - STATEFN(StateWait) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvTenantPool::TEvTenantPoolStatus, Handle); - } - } -}; - -class TTenantNodeEnumerationLookup : public TActorBootstrapped<TTenantNodeEnumerationLookup> { + + PublishActors.emplace(assigned, publishActor); + } + } + } + + for (auto &xpair : toRemove) { + Send(xpair.second, new TEvents::TEvPoisonPill()); + } + } +public: + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { + return NKikimrServices::TActivity::TENANT_NODES_ENUMERATION; + } + + TTenantNodeEnumerationPublisher() + {} + + void Bootstrap() { + Send(MakeTenantPoolRootID(), new TEvents::TEvSubscribe()); + Become(&TThis::StateWait); + } + + STATEFN(StateWait) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvTenantPool::TEvTenantPoolStatus, Handle); + } + } +}; + +class TTenantNodeEnumerationLookup : public TActorBootstrapped<TTenantNodeEnumerationLookup> { const TActorId ReplyTo; - const TString TenantName; + const TString TenantName; TActorId LookupActor; - - void PassAway() override { - if (LookupActor) { - Send(LookupActor, new TEvents::TEvPoisonPill()); + + void PassAway() override { + if (LookupActor) { + Send(LookupActor, new TEvents::TEvPoisonPill()); LookupActor = TActorId(); - } - - IActor::PassAway(); - } - - void ReportErrorAndDie() { - Send(ReplyTo, new TEvTenantNodeEnumerator::TEvLookupResult(TenantName, false)); - PassAway(); - } - - void Handle(TEvStateStorage::TEvBoardInfo::TPtr &ev) { + } + + IActor::PassAway(); + } + + void ReportErrorAndDie() { + Send(ReplyTo, new TEvTenantNodeEnumerator::TEvLookupResult(TenantName, false)); + PassAway(); + } + + void Handle(TEvStateStorage::TEvBoardInfo::TPtr &ev) { LookupActor = TActorId(); - - auto *msg = ev->Get(); - - if (msg->Status != TEvStateStorage::TEvBoardInfo::EStatus::Ok) - return ReportErrorAndDie(); - - TVector<ui32> nodes; - for (auto &xpair : msg->InfoEntries) { - nodes.push_back(xpair.first.NodeId()); - } - SortUnique(nodes); - - Send(ReplyTo, new TEvTenantNodeEnumerator::TEvLookupResult(TenantName, std::move(nodes))); - PassAway(); - } -public: - static constexpr NKikimrServices::TActivity::EType ActorActivityType() { - return NKikimrServices::TActivity::TENANT_NODES_ENUMERATION; - } - + + auto *msg = ev->Get(); + + if (msg->Status != TEvStateStorage::TEvBoardInfo::EStatus::Ok) + return ReportErrorAndDie(); + + TVector<ui32> nodes; + for (auto &xpair : msg->InfoEntries) { + nodes.push_back(xpair.first.NodeId()); + } + SortUnique(nodes); + + Send(ReplyTo, new TEvTenantNodeEnumerator::TEvLookupResult(TenantName, std::move(nodes))); + PassAway(); + } +public: + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { + return NKikimrServices::TActivity::TENANT_NODES_ENUMERATION; + } + TTenantNodeEnumerationLookup(TActorId replyTo, const TString &tenantName) - : ReplyTo(replyTo) - , TenantName(tenantName) - {} - - void Bootstrap() { - const ui32 statestorageGroupId = ExtractDefaultGroupForPath(TenantName); - if (statestorageGroupId == Max<ui32>()) - return ReportErrorAndDie(); - - const TString path = MakeTenantNodeEnumerationPath(TenantName); - LookupActor = Register(CreateBoardLookupActor(path, SelfId(), statestorageGroupId, EBoardLookupMode::Majority, false, false)); - - Become(&TThis::StateWait); - } - - STATEFN(StateWait) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvBoardInfo, Handle); - } - } -}; - -IActor* CreateTenantNodeEnumerationPublisher() { - return new TTenantNodeEnumerationPublisher(); -} - + : ReplyTo(replyTo) + , TenantName(tenantName) + {} + + void Bootstrap() { + const ui32 statestorageGroupId = ExtractDefaultGroupForPath(TenantName); + if (statestorageGroupId == Max<ui32>()) + return ReportErrorAndDie(); + + const TString path = MakeTenantNodeEnumerationPath(TenantName); + LookupActor = Register(CreateBoardLookupActor(path, SelfId(), statestorageGroupId, EBoardLookupMode::Majority, false, false)); + + Become(&TThis::StateWait); + } + + STATEFN(StateWait) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvBoardInfo, Handle); + } + } +}; + +IActor* CreateTenantNodeEnumerationPublisher() { + return new TTenantNodeEnumerationPublisher(); +} + IActor* CreateTenantNodeEnumerationLookup(TActorId replyTo, const TString &tenantName) { - return new TTenantNodeEnumerationLookup(replyTo, tenantName); -} - -} + return new TTenantNodeEnumerationLookup(replyTo, tenantName); +} + +} diff --git a/ydb/core/mind/tenant_node_enumeration.h b/ydb/core/mind/tenant_node_enumeration.h index a856418a68..f7ee7e937e 100644 --- a/ydb/core/mind/tenant_node_enumeration.h +++ b/ydb/core/mind/tenant_node_enumeration.h @@ -1,39 +1,39 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include <library/cpp/actors/core/event_local.h> - -#include <util/generic/vector.h> - -namespace NKikimr { - - struct TEvTenantNodeEnumerator { - enum EEv { - EvLookupResult = EventSpaceBegin(TKikimrEvents::ES_TENANT_NODE_ENUMERATOR), - - EvEnd - }; - - static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_TENANT_NODE_ENUMERATOR), - "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_TENANT_NODE_ENUMERATOR)"); - - struct TEvLookupResult : public TEventLocal<TEvLookupResult, EvLookupResult> { - const TString Tenant; - const bool Success; - TVector<ui32> AssignedNodes; - - TEvLookupResult(const TString &tenant, TVector<ui32> &&assignedNodes) - : Tenant(tenant) - , Success(true) - , AssignedNodes(std::move(assignedNodes)) - {} - - TEvLookupResult(const TString &tenant, bool success) - : Tenant(tenant) - , Success(success) - {} - }; - }; - - IActor* CreateTenantNodeEnumerationPublisher(); + +#include <util/generic/vector.h> + +namespace NKikimr { + + struct TEvTenantNodeEnumerator { + enum EEv { + EvLookupResult = EventSpaceBegin(TKikimrEvents::ES_TENANT_NODE_ENUMERATOR), + + EvEnd + }; + + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_TENANT_NODE_ENUMERATOR), + "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_TENANT_NODE_ENUMERATOR)"); + + struct TEvLookupResult : public TEventLocal<TEvLookupResult, EvLookupResult> { + const TString Tenant; + const bool Success; + TVector<ui32> AssignedNodes; + + TEvLookupResult(const TString &tenant, TVector<ui32> &&assignedNodes) + : Tenant(tenant) + , Success(true) + , AssignedNodes(std::move(assignedNodes)) + {} + + TEvLookupResult(const TString &tenant, bool success) + : Tenant(tenant) + , Success(success) + {} + }; + }; + + IActor* CreateTenantNodeEnumerationPublisher(); IActor* CreateTenantNodeEnumerationLookup(TActorId replyTo, const TString &tenantName); -} // namespace NKikimr +} // namespace NKikimr diff --git a/ydb/core/mind/tenant_node_enumeration_ut.cpp b/ydb/core/mind/tenant_node_enumeration_ut.cpp index ec834b19d4..f8c7a505c2 100644 --- a/ydb/core/mind/tenant_node_enumeration_ut.cpp +++ b/ydb/core/mind/tenant_node_enumeration_ut.cpp @@ -1,71 +1,71 @@ -#include "tenant_node_enumeration.h" +#include "tenant_node_enumeration.h" #include <ydb/core/testlib/tenant_runtime.h> - + #include <library/cpp/testing/unittest/registar.h> - -namespace NKikimr { - -namespace { - -void CheckAddTenant(TTenantTestRuntime &runtime, const TString &tenant, TEvLocal::TEvTenantStatus::EStatus status, ui64 cpu = 1, ui64 expectedCpu = 0, ui64 memory = 1, ui64 expectedMemory = 0, ui64 network = 1, ui64 expectedNetwork = 0) -{ - NKikimrTabletBase::TMetrics limit; - limit.SetCPU(cpu); - limit.SetMemory(memory); - limit.SetNetwork(network); - runtime.Send(new IEventHandle(MakeLocalID(runtime.GetNodeId(0)), - runtime.Sender, - new TEvLocal::TEvAddTenant(tenant, limit))); - TAutoPtr<IEventHandle> handle; - auto reply = runtime.GrabEdgeEventRethrow<TEvLocal::TEvTenantStatus>(handle); - UNIT_ASSERT_VALUES_EQUAL(reply->TenantName, tenant); - UNIT_ASSERT_VALUES_EQUAL((int)reply->Status, (int)status); - if (status == TEvLocal::TEvTenantStatus::STARTED) { - if (expectedCpu) - UNIT_ASSERT_VALUES_EQUAL(reply->ResourceLimit.GetCPU(), expectedCpu); - else - UNIT_ASSERT_VALUES_EQUAL(reply->ResourceLimit.GetCPU(), cpu); - if (expectedMemory) - UNIT_ASSERT_VALUES_EQUAL(reply->ResourceLimit.GetMemory(), expectedMemory); - else - UNIT_ASSERT_VALUES_EQUAL(reply->ResourceLimit.GetMemory(), memory); - if (expectedNetwork) - UNIT_ASSERT_VALUES_EQUAL(reply->ResourceLimit.GetNetwork(), expectedNetwork); - else - UNIT_ASSERT_VALUES_EQUAL(reply->ResourceLimit.GetNetwork(), network); - } -} - -} - -Y_UNIT_TEST_SUITE(TEnumerationTest) { - Y_UNIT_TEST(TestPublish) { + +namespace NKikimr { + +namespace { + +void CheckAddTenant(TTenantTestRuntime &runtime, const TString &tenant, TEvLocal::TEvTenantStatus::EStatus status, ui64 cpu = 1, ui64 expectedCpu = 0, ui64 memory = 1, ui64 expectedMemory = 0, ui64 network = 1, ui64 expectedNetwork = 0) +{ + NKikimrTabletBase::TMetrics limit; + limit.SetCPU(cpu); + limit.SetMemory(memory); + limit.SetNetwork(network); + runtime.Send(new IEventHandle(MakeLocalID(runtime.GetNodeId(0)), + runtime.Sender, + new TEvLocal::TEvAddTenant(tenant, limit))); + TAutoPtr<IEventHandle> handle; + auto reply = runtime.GrabEdgeEventRethrow<TEvLocal::TEvTenantStatus>(handle); + UNIT_ASSERT_VALUES_EQUAL(reply->TenantName, tenant); + UNIT_ASSERT_VALUES_EQUAL((int)reply->Status, (int)status); + if (status == TEvLocal::TEvTenantStatus::STARTED) { + if (expectedCpu) + UNIT_ASSERT_VALUES_EQUAL(reply->ResourceLimit.GetCPU(), expectedCpu); + else + UNIT_ASSERT_VALUES_EQUAL(reply->ResourceLimit.GetCPU(), cpu); + if (expectedMemory) + UNIT_ASSERT_VALUES_EQUAL(reply->ResourceLimit.GetMemory(), expectedMemory); + else + UNIT_ASSERT_VALUES_EQUAL(reply->ResourceLimit.GetMemory(), memory); + if (expectedNetwork) + UNIT_ASSERT_VALUES_EQUAL(reply->ResourceLimit.GetNetwork(), expectedNetwork); + else + UNIT_ASSERT_VALUES_EQUAL(reply->ResourceLimit.GetNetwork(), network); + } +} + +} + +Y_UNIT_TEST_SUITE(TEnumerationTest) { + Y_UNIT_TEST(TestPublish) { return; - TTenantTestRuntime runtime(DefaultTenantTestConfig); - - CheckAddTenant(runtime, TENANT1_1_NAME, TEvLocal::TEvTenantStatus::STARTED, 5); - CheckAddTenant(runtime, TENANT1_2_NAME, TEvLocal::TEvTenantStatus::STARTED); - CheckAddTenant(runtime, TENANT2_1_NAME, TEvLocal::TEvTenantStatus::STARTED); - CheckAddTenant(runtime, TENANT1_U_NAME, TEvLocal::TEvTenantStatus::UNKNOWN_TENANT); - CheckAddTenant(runtime, TENANTU_1_NAME, TEvLocal::TEvTenantStatus::UNKNOWN_TENANT); - CheckAddTenant(runtime, TENANT1_1_NAME, TEvLocal::TEvTenantStatus::STARTED, 3, 5); - - runtime.WaitForHiveState({{{DOMAIN1_NAME, 1, 1, 1}, - {TENANT1_1_NAME, 5, 1, 1}, + TTenantTestRuntime runtime(DefaultTenantTestConfig); + + CheckAddTenant(runtime, TENANT1_1_NAME, TEvLocal::TEvTenantStatus::STARTED, 5); + CheckAddTenant(runtime, TENANT1_2_NAME, TEvLocal::TEvTenantStatus::STARTED); + CheckAddTenant(runtime, TENANT2_1_NAME, TEvLocal::TEvTenantStatus::STARTED); + CheckAddTenant(runtime, TENANT1_U_NAME, TEvLocal::TEvTenantStatus::UNKNOWN_TENANT); + CheckAddTenant(runtime, TENANTU_1_NAME, TEvLocal::TEvTenantStatus::UNKNOWN_TENANT); + CheckAddTenant(runtime, TENANT1_1_NAME, TEvLocal::TEvTenantStatus::STARTED, 3, 5); + + runtime.WaitForHiveState({{{DOMAIN1_NAME, 1, 1, 1}, + {TENANT1_1_NAME, 5, 1, 1}, {TENANT1_2_NAME, 1, 1, 1}}}); - - runtime.Register(CreateTenantNodeEnumerationPublisher(), 0); - runtime.DispatchEvents(TDispatchOptions(), TDuration::MilliSeconds(1000)); - + + runtime.Register(CreateTenantNodeEnumerationPublisher(), 0); + runtime.DispatchEvents(TDispatchOptions(), TDuration::MilliSeconds(1000)); + TActorId sender = runtime.AllocateEdgeActor(); runtime.Register(CreateTenantNodeEnumerationLookup(sender, "/" + DOMAIN1_NAME)); - - TAutoPtr<IEventHandle> handle; - const auto event = runtime.GrabEdgeEvent<TEvTenantNodeEnumerator::TEvLookupResult>(handle); - UNIT_ASSERT(event->Success); - UNIT_ASSERT(event->AssignedNodes.size() == 1 && event->AssignedNodes[0] == 1); - } -} - -} //namespace NKikimr + + TAutoPtr<IEventHandle> handle; + const auto event = runtime.GrabEdgeEvent<TEvTenantNodeEnumerator::TEvLookupResult>(handle); + UNIT_ASSERT(event->Success); + UNIT_ASSERT(event->AssignedNodes.size() == 1 && event->AssignedNodes[0] == 1); + } +} + +} //namespace NKikimr diff --git a/ydb/core/mind/tenant_pool.cpp b/ydb/core/mind/tenant_pool.cpp index dff57a7f43..80236570b9 100644 --- a/ydb/core/mind/tenant_pool.cpp +++ b/ydb/core/mind/tenant_pool.cpp @@ -270,7 +270,7 @@ public: for (auto &subscriber : StatusSubscribers) { LOG_DEBUG_S(ctx, NKikimrServices::TENANT_POOL, LogPrefix << "send status update to " << subscriber); - ctx.Send(subscriber, BuildStatusEvent(true)); + ctx.Send(subscriber, BuildStatusEvent(true)); } } @@ -341,7 +341,7 @@ public: DetachSlot(*tenant->AssignedSlots.begin(), ctx); } - THolder<TEvTenantPool::TEvTenantPoolStatus> BuildStatusEvent(bool listStatic = false) + THolder<TEvTenantPool::TEvTenantPoolStatus> BuildStatusEvent(bool listStatic = false) { THolder<TEvTenantPool::TEvTenantPoolStatus> ev = MakeHolder<TEvTenantPool::TEvTenantPoolStatus>(); if (listStatic) { @@ -497,17 +497,17 @@ public: Die(ctx); } - void Handle(TEvents::TEvSubscribe::TPtr &ev, const TActorContext &ctx) { - Y_UNUSED(ctx); - StatusSubscribers.insert(ev->Sender); - Send(ev->Sender, BuildStatusEvent(true)); - } - - void Handle(TEvents::TEvUnsubscribe::TPtr &ev, const TActorContext &ctx) { - Y_UNUSED(ctx); - StatusSubscribers.erase(ev->Sender); - } - + void Handle(TEvents::TEvSubscribe::TPtr &ev, const TActorContext &ctx) { + Y_UNUSED(ctx); + StatusSubscribers.insert(ev->Sender); + Send(ev->Sender, BuildStatusEvent(true)); + } + + void Handle(TEvents::TEvUnsubscribe::TPtr &ev, const TActorContext &ctx) { + Y_UNUSED(ctx); + StatusSubscribers.erase(ev->Sender); + } + void Handle(TEvConsole::TEvConfigNotificationRequest::TPtr &ev, const TActorContext &ctx) { @@ -623,7 +623,7 @@ public: { auto& rec = ev->Get()->Record; auto event = BuildStatusEvent(rec.GetListStaticSlots()); - ctx.Send(ev->Sender, std::move(event), 0, ev->Cookie); + ctx.Send(ev->Sender, std::move(event), 0, ev->Cookie); } void Handle(TEvTenantPool::TEvConfigureSlot::TPtr &ev, const TActorContext &ctx) @@ -766,8 +766,8 @@ public: TRACE_EVENT(NKikimrServices::TENANT_POOL); switch (ev->GetTypeRewrite()) { CFunc(TEvents::TSystem::PoisonPill, HandlePoison); - HFuncTraced(TEvents::TEvSubscribe, Handle); - HFuncTraced(TEvents::TEvUnsubscribe, Handle); + HFuncTraced(TEvents::TEvSubscribe, Handle); + HFuncTraced(TEvents::TEvUnsubscribe, Handle); HFuncTraced(TEvConsole::TEvConfigNotificationRequest, Handle); HFuncTraced(TEvLocal::TEvTenantStatus, Handle); HFuncTraced(TEvTabletPipe::TEvClientConnected, Handle); @@ -855,16 +855,16 @@ public: return res; } - void Handle(TEvents::TEvSubscribe::TPtr &ev, const TActorContext &ctx) { - for (auto &pr : DomainTenantPools) - ctx.Send(new IEventHandle(pr.second, ev->Sender, new TEvents::TEvSubscribe())); - } - - void Handle(TEvents::TEvUnsubscribe::TPtr &ev, const TActorContext &ctx) { - for (auto &pr : DomainTenantPools) - ctx.Send(new IEventHandle(pr.second, ev->Sender, new TEvents::TEvUnsubscribe())); - } - + void Handle(TEvents::TEvSubscribe::TPtr &ev, const TActorContext &ctx) { + for (auto &pr : DomainTenantPools) + ctx.Send(new IEventHandle(pr.second, ev->Sender, new TEvents::TEvSubscribe())); + } + + void Handle(TEvents::TEvUnsubscribe::TPtr &ev, const TActorContext &ctx) { + for (auto &pr : DomainTenantPools) + ctx.Send(new IEventHandle(pr.second, ev->Sender, new TEvents::TEvUnsubscribe())); + } + void Handle(TEvLocal::TEvLocalDrainNode::TPtr &ev, const TActorContext &ctx) { LOG_NOTICE_S(ctx, NKikimrServices::TENANT_POOL, "Forward drain node to local."); ctx.Send(ev->Forward(LocalID)); @@ -923,8 +923,8 @@ public: STFUNC(StateWork) { switch (ev->GetTypeRewrite()) { CFunc(TEvents::TSystem::PoisonPill, HandlePoison); - HFunc(TEvents::TEvSubscribe, Handle); - HFunc(TEvents::TEvUnsubscribe, Handle); + HFunc(TEvents::TEvSubscribe, Handle); + HFunc(TEvents::TEvUnsubscribe, Handle); HFunc(NMon::TEvHttpInfo, Handle); HFunc(TEvLocal::TEvLocalDrainNode, Handle); default: diff --git a/ydb/core/mind/tenant_pool.h b/ydb/core/mind/tenant_pool.h index 3d36c90ddd..0202ba7863 100644 --- a/ydb/core/mind/tenant_pool.h +++ b/ydb/core/mind/tenant_pool.h @@ -96,8 +96,8 @@ inline TActorId MakeTenantPoolID(ui32 node = 0, ui32 domain = 0) { } inline TActorId MakeTenantPoolRootID() { - char x[12] = { 't', 'e', 'n', 'a', 'n', 't', 'p', 'o', 'o', 'l', 'r', 't' }; + char x[12] = { 't', 'e', 'n', 'a', 'n', 't', 'p', 'o', 'o', 'l', 'r', 't' }; return TActorId(0, TStringBuf(x, 12)); -} +} } // namespace NKikimr diff --git a/ydb/core/mind/ut/ya.make b/ydb/core/mind/ut/ya.make index cb309fdf44..26e6412fc7 100644 --- a/ydb/core/mind/ut/ya.make +++ b/ydb/core/mind/ut/ya.make @@ -39,7 +39,7 @@ SRCS( tenant_ut_broker.cpp tenant_ut_local.cpp tenant_ut_pool.cpp - tenant_node_enumeration_ut.cpp + tenant_node_enumeration_ut.cpp ) YQL_LAST_ABI_VERSION() diff --git a/ydb/core/mind/ya.make b/ydb/core/mind/ya.make index 2355f969be..b9248c9d91 100644 --- a/ydb/core/mind/ya.make +++ b/ydb/core/mind/ya.make @@ -1,14 +1,14 @@ -LIBRARY() - +LIBRARY() + OWNER( ddoarn xenoxeno g:kikimr ) -SRCS( - configured_tablet_bootstrapper.cpp - configured_tablet_bootstrapper.h +SRCS( + configured_tablet_bootstrapper.cpp + configured_tablet_bootstrapper.h defs.h dynamic_nameserver.cpp dynamic_nameserver.h @@ -18,8 +18,8 @@ SRCS( labels_maintainer.h lease_holder.cpp lease_holder.h - local.cpp - local.h + local.cpp + local.h node_broker.cpp node_broker.h node_broker_impl.h @@ -32,8 +32,8 @@ SRCS( node_broker__update_config_subscription.cpp node_broker__update_epoch.cpp table_adapter.h - tenant_node_enumeration.cpp - tenant_node_enumeration.h + tenant_node_enumeration.cpp + tenant_node_enumeration.h tenant_pool.h tenant_pool.cpp tenant_slot_broker.cpp @@ -49,9 +49,9 @@ SRCS( tenant_slot_broker__update_pool_status.cpp tenant_slot_broker__update_node_location.cpp tenant_slot_broker__update_slot_status.cpp -) - -PEERDIR( +) + +PEERDIR( library/cpp/actors/core ydb/core/actorlib_impl ydb/core/base @@ -75,9 +75,9 @@ PEERDIR( ydb/core/tx/scheme_board ydb/core/tx/scheme_cache ydb/core/tx/schemeshard -) - -END() +) + +END() RECURSE( address_classification diff --git a/ydb/core/mon/ya.make b/ydb/core/mon/ya.make index 134a386eb1..c717b0f5b9 100644 --- a/ydb/core/mon/ya.make +++ b/ydb/core/mon/ya.make @@ -1,24 +1,24 @@ -LIBRARY() - +LIBRARY() + OWNER( ddoarn xenoxeno g:kikimr ) -SRCS( - mon.cpp +SRCS( + mon.cpp mon.h crossref.cpp crossref.h -) - -PEERDIR( +) + +PEERDIR( library/cpp/actors/core library/cpp/lwtrace/mon library/cpp/string_utils/url ydb/core/base ydb/library/aclib -) - -END() +) + +END() diff --git a/ydb/core/persqueue/blob.cpp b/ydb/core/persqueue/blob.cpp index b542aa5384..7727f12a13 100644 --- a/ydb/core/persqueue/blob.cpp +++ b/ydb/core/persqueue/blob.cpp @@ -1,6 +1,6 @@ #include "blob.h" -#include "type_codecs.h" - +#include "type_codecs.h" + #include <util/string/builder.h> #include <util/string/escape.h> #include <util/system/unaligned_mem.h> diff --git a/ydb/core/persqueue/read_balancer.h b/ydb/core/persqueue/read_balancer.h index ae87ef98d9..6a07edcb78 100644 --- a/ydb/core/persqueue/read_balancer.h +++ b/ydb/core/persqueue/read_balancer.h @@ -102,7 +102,7 @@ class TPersQueueReadBalancer : public TActor<TPersQueueReadBalancer>, public TTa }; - struct TTxPreInit : public ITransaction { + struct TTxPreInit : public ITransaction { TPersQueueReadBalancer * const Self; TTxPreInit(TPersQueueReadBalancer *self) @@ -117,7 +117,7 @@ class TPersQueueReadBalancer : public TActor<TPersQueueReadBalancer>, public TTa friend struct TTxPreInit; - struct TTxInit : public ITransaction { + struct TTxInit : public ITransaction { TPersQueueReadBalancer * const Self; TTxInit(TPersQueueReadBalancer *self) @@ -145,7 +145,7 @@ class TPersQueueReadBalancer : public TActor<TPersQueueReadBalancer>, public TTa ui64 Idx; }; - struct TTxWrite : public ITransaction { + struct TTxWrite : public ITransaction { TPersQueueReadBalancer * const Self; TVector<ui32> DeletedPartitions; TVector<std::pair<ui32, TPartInfo>> NewPartitions; diff --git a/ydb/core/persqueue/ut/ya.make b/ydb/core/persqueue/ut/ya.make index d3a1770775..7cbb0b9496 100644 --- a/ydb/core/persqueue/ut/ya.make +++ b/ydb/core/persqueue/ut/ya.make @@ -30,10 +30,10 @@ PEERDIR( YQL_LAST_ABI_VERSION() SRCS( - internals_ut.cpp + internals_ut.cpp mirrorer_ut.cpp pq_ut.cpp - type_codecs_ut.cpp + type_codecs_ut.cpp pq_ut.h sourceid_ut.cpp user_info_ut.cpp diff --git a/ydb/core/persqueue/ya.make b/ydb/core/persqueue/ya.make index 9fafb4b70e..50e89676ef 100644 --- a/ydb/core/persqueue/ya.make +++ b/ydb/core/persqueue/ya.make @@ -24,7 +24,7 @@ SRCS( read_balancer.cpp read_speed_limiter.cpp subscriber.cpp - type_codecs_defs.cpp + type_codecs_defs.cpp user_info.cpp write_meta.cpp actor_persqueue_client_iface.h diff --git a/ydb/core/protos/config.proto b/ydb/core/protos/config.proto index d7a489bd6d..d64169d4fc 100644 --- a/ydb/core/protos/config.proto +++ b/ydb/core/protos/config.proto @@ -26,31 +26,31 @@ import "ydb/core/protos/key.proto"; import "ydb/core/protos/alloc.proto"; import "ydb/core/protos/node_limits.proto"; import "ydb/core/yq/libs/config/protos/yq_config.proto"; - -package NKikimrConfig; + +package NKikimrConfig; option java_package = "ru.yandex.kikimr.proto"; - -message TAffinity { + +message TAffinity { repeated uint32 X = 1; // DEPRECATED: Use `CpuList` instead // Numerical list of processors. The numbers are separated by commas and may include ranges. For example: 0,5,7,9-11 optional string CpuList = 2; // Processors to include. Use all processor if not set. optional string ExcludeCpuList = 3; // Exclude specified processors from `CpuList` (or all processors if not set) -} - -message TActorSystemConfig { - message TExecutor { - enum EType { - BASIC = 1; - IO = 2; +} + +message TActorSystemConfig { + message TExecutor { + enum EType { + BASIC = 1; + IO = 2; UNITED = 3; - }; + }; - optional EType Type = 1; + optional EType Type = 1; optional uint32 Threads = 2; - optional uint64 SpinThreshold = 3; - optional TAffinity Affinity = 4; - optional uint32 InjectMadSquirrels = 5; + optional uint64 SpinThreshold = 3; + optional TAffinity Affinity = 4; + optional uint32 InjectMadSquirrels = 5; optional string Name = 6; optional uint32 TimePerMailboxMicroSecs = 7; optional uint32 EventsPerMailbox = 8; @@ -65,23 +65,23 @@ message TActorSystemConfig { optional uint32 MaxThreads = 13; // Higher balancing bound, should be not lower than `Threads` optional uint32 BalancingPriority = 14; // Priority of pool to obtain cpu due to balancing (higher is better) optional uint64 ToleratedLatencyUs = 15; // p100-latency threshold indicating that more cpus are required by pool - } - - message TScheduler { - optional uint64 Resolution = 1; - optional uint64 SpinThreshold = 2; - optional uint64 ProgressThreshold = 3; - optional TAffinity Affinity = 4; + } + + message TScheduler { + optional uint64 Resolution = 1; + optional uint64 SpinThreshold = 2; + optional uint64 ProgressThreshold = 3; + optional TAffinity Affinity = 4; optional bool UseSchedulerActor = 5; - } - - repeated TExecutor Executor = 1; - optional TScheduler Scheduler = 2; - - optional uint32 SysExecutor = 3; - optional uint32 UserExecutor = 4; - optional uint32 IoExecutor = 5; - optional uint32 BatchExecutor = 6; + } + + repeated TExecutor Executor = 1; + optional TScheduler Scheduler = 2; + + optional uint32 SysExecutor = 3; + optional uint32 UserExecutor = 4; + optional uint32 IoExecutor = 5; + optional uint32 BatchExecutor = 6; message TServiceExecutor { required string ServiceName = 1; @@ -108,9 +108,9 @@ message TActorSystemConfig { } optional TUnitedWorkers UnitedWorkers = 11; -} - -message TStaticNameserviceConfig { +} + +message TStaticNameserviceConfig { enum ENameserviceType { NS_DEFAULT = 0; // default (nodebroker) @@ -124,11 +124,11 @@ message TStaticNameserviceConfig { optional string Address = 2; } - message TNode { // todo: multiple networks - optional uint32 NodeId = 1; - - optional string Address = 2; - optional uint32 Port = 3; + message TNode { // todo: multiple networks + optional uint32 NodeId = 1; + + optional string Address = 2; + optional uint32 Port = 3; optional string Host = 4; optional string InterconnectHost = 5; @@ -138,73 +138,73 @@ message TStaticNameserviceConfig { repeated TEndpoint Endpoint = 7; optional NActorsInterconnect.TNodeLocation WalleLocation = 8 [deprecated=true]; - } - - repeated TNode Node = 1; + } + + repeated TNode Node = 1; optional string ClusterUUID = 2; repeated string AcceptUUID = 3; optional bool SuppressVersionCheck = 4; optional ENameserviceType Type = 5; -} - +} + message TDynamicNameserviceConfig { optional uint32 MaxStaticNodeId = 1 [default = 1000]; optional uint32 MaxDynamicNodeId = 2 [default = 200000]; optional uint64 LeaseDuration = 3 [default = 3600000000]; // DEPRECATED } -message TDomainsConfig { - message TStateStorage { - message TRing { - optional uint32 NToSelect = 1; - repeated TRing Ring = 2; +message TDomainsConfig { + message TStateStorage { + message TRing { + optional uint32 NToSelect = 1; + repeated TRing Ring = 2; repeated uint32 Node = 3; optional bool UseSingleNodeActorId = 4; optional bool UseRingSpecificNodeSelection = 5; - } - - optional uint32 SSId = 1; - optional TRing Ring = 2; - } - + } + + optional uint32 SSId = 1; + optional TRing Ring = 2; + } + message TStoragePoolType { optional string Kind = 1; optional NKikimrBlobStorage.TDefineStoragePool PoolConfig = 2; } - message TDomain { + message TDomain { message TTxLimits { optional uint64 PerRequestDataSizeLimit = 1; optional uint64 PerShardReadSizeLimit = 2; optional uint64 PerShardIncomingReadSetSizeLimit = 3; } - optional uint32 DomainId = 1; - optional fixed64 SchemeRoot = 2; - repeated uint64 Coordinator = 3; - repeated uint64 Mediator = 4; - repeated uint64 Proxy = 5; + optional uint32 DomainId = 1; + optional fixed64 SchemeRoot = 2; + repeated uint64 Coordinator = 3; + repeated uint64 Mediator = 4; + repeated uint64 Proxy = 5; repeated uint32 SSId = 6; repeated uint32 HiveUid = 7; - optional uint64 PlanResolution = 8; - optional string Name = 9; + optional uint64 PlanResolution = 8; + optional string Name = 9; optional TTxLimits TxLimits = 10; // DEPRECATED repeated TStoragePoolType StoragePoolTypes = 11; repeated fixed64 ExplicitMediators = 12; repeated fixed64 ExplicitCoordinators = 13; repeated fixed64 ExplicitAllocators = 14; - optional uint32 SchemeBoardSSId = 15; - } - + optional uint32 SchemeBoardSSId = 15; + } + message THiveConfig { // look for another THiveConfig later in this file optional uint32 HiveUid = 1; optional fixed64 Hive = 2; } - message TExecLevel { - } - + message TExecLevel { + } + message TNamedCompactionPolicy { optional string Name = 1; optional NKikimrSchemeOp.TCompactionPolicy Policy = 2; @@ -219,23 +219,23 @@ message TDomainsConfig { repeated string ViewerAllowedSIDs = 6; } - repeated TDomain Domain = 1; - repeated TStateStorage StateStorage = 2; - repeated TExecLevel ExecLevel = 3; + repeated TDomain Domain = 1; + repeated TStateStorage StateStorage = 2; + repeated TExecLevel ExecLevel = 3; repeated THiveConfig HiveConfig = 4; repeated TNamedCompactionPolicy NamedCompactionPolicy = 5; optional TSecurityConfig SecurityConfig = 6; optional bool ForbidImplicitStoragePools = 7 [default = true]; -} - -message TBlobStorageConfig { +} + +message TBlobStorageConfig { optional NKikimrBlobStorage.TNodeWardenServiceSet ServiceSet = 1; optional bool EnableOverseerLsnReporting = 2 [default = false]; // deprecated optional string CacheFilePath = 3; optional bool CachePDisks = 4 [default = true]; optional bool CacheVDisks = 5 [default = true]; -} - +} + message TBlobStorageFormatConfig { message TDrive { optional uint64 RackId = 1; @@ -295,22 +295,22 @@ message TCompileServiceConfig { } message TBootstrap { - enum ETabletType { + enum ETabletType { TX_DUMMY = 0; HIVE = 1; - - TX_COORDINATOR = 10; - TX_MEDIATOR = 11; - TX_PROXY = 12; + + TX_COORDINATOR = 10; + TX_MEDIATOR = 11; + TX_PROXY = 12; FLAT_TX_COORDINATOR = 13; FLAT_HIVE = 14; FLAT_BS_CONTROLLER = 15; - FLAT_TX_PROXY = 17; + FLAT_TX_PROXY = 17; TX_ALLOCATOR = 18; - - BS_DOMAINCONTROLLER = 20; - + + BS_DOMAINCONTROLLER = 20; + SCHEMESHARD = 30; DATASHARD = 31; FLAT_SCHEMESHARD = 32; @@ -325,23 +325,23 @@ message TBootstrap { TENANT_SLOT_BROKER = 53; CONSOLE = 54; - FAKE_DATASHARD = 700; - } - - message TTablet { - optional ETabletType Type = 1; - repeated uint32 Node = 2; - optional NKikimrTabletBase.TTabletStorageInfo Info = 3; - optional bool StandBy = 4; - optional uint64 WatchThreshold = 5; + FAKE_DATASHARD = 700; + } + + message TTablet { + optional ETabletType Type = 1; + repeated uint32 Node = 2; + optional NKikimrTabletBase.TTabletStorageInfo Info = 3; + optional bool StandBy = 4; + optional uint64 WatchThreshold = 5; optional bool StartFollowers = 6; - optional bool AllowDynamicConfiguration = 7 [default = false]; - } - - repeated TTablet Tablet = 1; - - optional uint64 ProxySchemeCacheNodes = 2; - optional uint64 ProxySchemeCacheDistNodes = 3; + optional bool AllowDynamicConfiguration = 7 [default = false]; + } + + repeated TTablet Tablet = 1; + + optional uint64 ProxySchemeCacheNodes = 2; + optional uint64 ProxySchemeCacheDistNodes = 3; optional NKikimrTablet.TCompactionBroker CompactionBroker = 4; optional NKikimrNodeLimits.TNodeLimitsConfig NodeLimits = 5; optional NKikimrResourceBroker.TResourceBrokerConfig ResourceBroker = 6; @@ -582,19 +582,19 @@ message TGRpcConfig { repeated string PublicAddressesV6 = 17; optional string PublicTargetNameOverride = 18; - // empty service list is 'run most services "what means 'most' in unspecified"' - repeated string Services = 20; - optional bool ServeRootDomains = 21 [default = true]; + // empty service list is 'run most services "what means 'most' in unspecified"' + repeated string Services = 20; + optional bool ServeRootDomains = 21 [default = true]; repeated string ServicesEnabled = 22; repeated string ServicesDisabled = 23; - + // server socket options optional bool KeepAliveEnable = 100 [default = true]; // SO_KEEPALIVE optional uint32 KeepAliveIdleTimeoutTriggerSec = 101 [default = 90]; // TCP_KEEPIDLE optional uint32 KeepAliveMaxProbeCount = 102 [default = 3]; // TCP_KEEPCNT optional uint32 KeepAliveProbeIntervalSec = 103 [default = 10]; // TCP_KEEPINTVL - - repeated TGRpcConfig ExtEndpoints = 200; // run specific services on separate endpoints + + repeated TGRpcConfig ExtEndpoints = 200; // run specific services on separate endpoints } message TDynamicNodeConfig { diff --git a/ydb/core/protos/counters_bs_controller.proto b/ydb/core/protos/counters_bs_controller.proto index 5883f96c8e..c0bd88bea1 100644 --- a/ydb/core/protos/counters_bs_controller.proto +++ b/ydb/core/protos/counters_bs_controller.proto @@ -1,13 +1,13 @@ import "ydb/core/protos/counters.proto"; - -package NKikimr.NBlobStorageController; - -option java_package = "ru.yandex.kikimr.proto"; - -option (TabletTypeName) = "BSController"; // Used as prefix for all counters - -enum ESimpleCounters { - COUNTER_RESPONSE_TIME_USEC = 0 [(CounterOpts) = {Name: "ResponseTimeMicrosec"}]; + +package NKikimr.NBlobStorageController; + +option java_package = "ru.yandex.kikimr.proto"; + +option (TabletTypeName) = "BSController"; // Used as prefix for all counters + +enum ESimpleCounters { + COUNTER_RESPONSE_TIME_USEC = 0 [(CounterOpts) = {Name: "ResponseTimeMicrosec"}]; COUNTER_GROUPS_WITH_SLOTS_ON_FAULTY_DISKS = 1 [(CounterOpts) = {Name: "GroupsWithSlotsOnFaultyDisks"}]; COUNTER_SLOTS_ON_FAULTY_DISKS = 2 [(CounterOpts) = {Name: "SlotsOnFaultyDisks"}]; COUNTER_BYTES_ON_FAULTY_DISKS = 3 [(CounterOpts) = {Name: "BytesOnFaultyDisks"}]; @@ -28,9 +28,9 @@ enum ESimpleCounters { COUNTER_DISK_SCRUB_CUR_DISKS = 18 [(CounterOpts) = {Name: "CurrentlyScrubbedDisks"}]; COUNTER_DISK_SCRUB_CUR_GROUPS = 19 [(CounterOpts) = {Name: "CurrentlyScrubbedGroups"}]; COUNTER_SELF_HEAL_UNREASSIGNABLE_GROUPS = 20 [(CounterOpts) = {Name: "SelfHealUnreassignableGroups"}]; -} - -enum ECumulativeCounters { +} + +enum ECumulativeCounters { COUNTER_REGISTER_NODE_COUNT = 0 [(CounterOpts) = {Name: "RegisterNodeCount"}]; COUNTER_REGISTER_NODE_USEC = 1 [(CounterOpts) = {Name: "RegisterNodeMicrosec"}]; COUNTER_GET_GROUP_COUNT = 2 [(CounterOpts) = {Name: "GetGroupCount"}]; @@ -73,10 +73,10 @@ enum ECumulativeCounters { COUNTER_CONFIGCMD_REASSIGN_GROUP_DISK_USEC = 37 [(CounterOpts) = {Name: "ReassignGroupDisk"}]; COUNTER_DISK_SCRUB_QUANTUM_FINISHED = 38 [(CounterOpts) = {Name: "QuantumFinished"}]; -} - -enum EPercentileCounters { - option (GlobalCounterOpts) = { +} + +enum EPercentileCounters { + option (GlobalCounterOpts) = { Ranges { Value: 0 Name: "(1) < 500 us" } Ranges { Value: 500 Name: "(2) 0.5-1 ms" } Ranges { Value: 1000 Name: "(3) 1-2 ms" } @@ -95,8 +95,8 @@ enum EPercentileCounters { Ranges { Value: 8000000 Name: "(16) 8-16 s" } Ranges { Value: 16000000 Name: "(17) 16-32 s" } Ranges { Value: 32000000 Name: "(18) 32 < s" } - }; - + }; + COUNTER_PERCENTILE_SELECT_GROUPS = 0 [(CounterOpts) = {Name: "SelectGroups"}]; COUNTER_FAULTY_USETTLED_PDISKS = 1 [(CounterOpts) = { @@ -188,9 +188,9 @@ enum EPercentileCounters { Ranges { Value: 21600 Name: "21600" } Ranges { Value: 86400 Name: "inf" } }]; -} - -enum ETxTypes { +} + +enum ETxTypes { TXTYPE_INIT_SCHEME = 0 [(TxTypeOpts) = {Name: "TTxInitScheme"}]; TXTYPE_MIGRATE = 1 [(TxTypeOpts) = {Name: "TTxMigrate"}]; TXTYPE_LOAD_EVERYTHING = 2 [(TxTypeOpts) = {Name: "TTxLoadEverything"}]; @@ -214,4 +214,4 @@ enum ETxTypes { TXTYPE_SCRUB_QUANTUM_FINISHED = 20 [(TxTypeOpts) = {Name: "TTxScrubQuantumFinished"}]; TXTYPE_UPDATE_LAST_SEEN_READY = 21 [(TxTypeOpts) = {Name: "TTxUpdateLastSeenReady"}]; TXTYPE_UPDATE_NODE_DRIVES = 22 [(TxTypeOpts) = {Name: "TTxUpdateNodeDrives"}]; -} +} diff --git a/ydb/core/protos/counters_hive.proto b/ydb/core/protos/counters_hive.proto index 34bdadf1e8..952f4e99e3 100644 --- a/ydb/core/protos/counters_hive.proto +++ b/ydb/core/protos/counters_hive.proto @@ -7,10 +7,10 @@ option java_package = "ru.yandex.kikimr.proto"; option (TabletTypeName) = "Hive"; // Used as prefix for all counters enum ESimpleCounters { - COUNTER_TABLETS_TOTAL = 0 [(CounterOpts) = {Name: "TabletsTotal"}]; - COUNTER_TABLETS_ALIVE = 1 [(CounterOpts) = {Name: "TabletsAlive"}]; - COUNTER_BOOTQUEUE_SIZE = 2 [(CounterOpts) = {Name: "BootQueueSize"}]; - COUNTER_STATE_DONE = 3 [(CounterOpts) = {Name: "StateDone"}]; + COUNTER_TABLETS_TOTAL = 0 [(CounterOpts) = {Name: "TabletsTotal"}]; + COUNTER_TABLETS_ALIVE = 1 [(CounterOpts) = {Name: "TabletsAlive"}]; + COUNTER_BOOTQUEUE_SIZE = 2 [(CounterOpts) = {Name: "BootQueueSize"}]; + COUNTER_STATE_DONE = 3 [(CounterOpts) = {Name: "StateDone"}]; COUNTER_RESPONSE_TIME_USEC = 4 [(CounterOpts) = {Name: "ResponseTimeMicrosec"}]; COUNTER_METRICS_COUNTER = 5 [(CounterOpts) = {Name: "MetricsCounter"}]; COUNTER_METRICS_CPU = 6 [(CounterOpts) = {Name: "MetricsCPU"}]; diff --git a/ydb/core/protos/flat_scheme_op.proto b/ydb/core/protos/flat_scheme_op.proto index a95f044b1a..33e598c1c2 100644 --- a/ydb/core/protos/flat_scheme_op.proto +++ b/ydb/core/protos/flat_scheme_op.proto @@ -248,10 +248,10 @@ message TPipelineConfig { } message TPartitionConfig { - optional string NamedCompactionPolicy = 1; // One of the predefined policies - optional TCompactionPolicy CompactionPolicy = 2; // Customized policy + optional string NamedCompactionPolicy = 1; // One of the predefined policies + optional TCompactionPolicy CompactionPolicy = 2; // Customized policy optional uint64 FollowerCount = 3; - optional uint64 ExecutorCacheSize = 4; // Cache size for the whole tablet including all user and system tables + optional uint64 ExecutorCacheSize = 4; // Cache size for the whole tablet including all user and system tables optional bool AllowFollowerPromotion = 5 [default = true]; // if true followers can upgrade to leader, if false followers only handle reads optional uint64 TxReadSizeLimit = 6; // Maximum size in bytes that is allowed to be read by a single Tx //optional bool CrossDataCenterFollowers = 7; // deprecated -> CrossDataCenterFollowerCount diff --git a/ydb/core/protos/flat_tx_scheme.proto b/ydb/core/protos/flat_tx_scheme.proto index 4482ae7919..dc06523e5c 100644 --- a/ydb/core/protos/flat_tx_scheme.proto +++ b/ydb/core/protos/flat_tx_scheme.proto @@ -68,8 +68,8 @@ message TEvDescribeSchemeResult { optional string Reason = 2; optional string Path = 3; optional NKikimrSchemeOp.TPathDescription PathDescription = 4; - optional fixed64 PathOwner = 5; - optional fixed64 PathId = 6; + optional fixed64 PathOwner = 5; + optional fixed64 PathId = 6; optional string LastExistedPrefixPath = 7; optional fixed64 LastExistedPrefixPathId = 8; diff --git a/ydb/core/protos/grpc.proto b/ydb/core/protos/grpc.proto index 8bc3f9b240..797cc2de82 100644 --- a/ydb/core/protos/grpc.proto +++ b/ydb/core/protos/grpc.proto @@ -11,19 +11,19 @@ service TGRpcServer { // TODO // * Rename Request to MiniKQLRequest ??? - + ///////////////////////////////////////////////////////////////////////////////////////////////// // KIKIMR CLIENT INTERFACE ///////////////////////////////////////////////////////////////////////////////////////////////// - // MiniKQL request (DML) + // MiniKQL request (DML) rpc Request(TRequest) returns (TResponse); - // DML transactions + // DML transactions rpc SchemeOperation(TSchemeOperation) returns (TResponse); - // status polling for scheme transactions + // status polling for scheme transactions rpc SchemeOperationStatus(TSchemeOperationStatus) returns (TResponse); - // describe + // describe rpc SchemeDescribe(TSchemeDescribe) returns (TResponse); // whoami rpc WhoAmI(TWhoAmI) returns (TResponse); @@ -92,13 +92,13 @@ service TGRpcServer { rpc LocalSchemeTx(TLocalSchemeTx) returns (TResponse); rpc TabletKillRequest(TTabletKillRequest) returns (TResponse); rpc InterconnectDebug(TInterconnectDebug) returns (TResponse); - + // [DEPRECATED] //rpc Navigate(TSchemeNavigate) returns (TResponse); - ///////////////////////////////////////////////////////////////////////////////////////////////// - // MONITORING - ///////////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////////// + // MONITORING + ///////////////////////////////////////////////////////////////////////////////////////////////// rpc TabletStateRequest(TTabletStateRequest) returns (TResponse); ///////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/ydb/core/protos/issue_id.proto b/ydb/core/protos/issue_id.proto index f6d7a04a3d..1c82c0d95e 100644 --- a/ydb/core/protos/issue_id.proto +++ b/ydb/core/protos/issue_id.proto @@ -1,86 +1,86 @@ -syntax = "proto3"; - -package NKikimrIssues; -option java_package = "ru.yandex.kikimr.proto"; - +syntax = "proto3"; + +package NKikimrIssues; +option java_package = "ru.yandex.kikimr.proto"; + import "ydb/library/yql/public/issue/protos/issue_severity.proto"; - -message TIssuesIds { -// reserved range [200000, 399999] - enum EIssueCode { - DEFAULT_ERROR = 0; - UNEXPECTED = 1; - INFO = 2; - WARNING = 3; - SUCCESS = 4; - - ACCESS_DENIED = 200000; - - PATH_NOT_EXIST = 200200; - DATABASE_NOT_EXIST = 200202; - - GENERIC_DATASHARD_ERROR = 200300; - - GENERIC_RESOLVE_ERROR = 200400; + +message TIssuesIds { +// reserved range [200000, 399999] + enum EIssueCode { + DEFAULT_ERROR = 0; + UNEXPECTED = 1; + INFO = 2; + WARNING = 3; + SUCCESS = 4; + + ACCESS_DENIED = 200000; + + PATH_NOT_EXIST = 200200; + DATABASE_NOT_EXIST = 200202; + + GENERIC_DATASHARD_ERROR = 200300; + + GENERIC_RESOLVE_ERROR = 200400; RESOLVE_LOOKUP_ERROR = 200401; - - GENERIC_TXPROXY_ERROR = 200500; - KEY_PARSE_ERROR = 200501; - EMPTY_OP_RANGE = 200502; - ENGINE_ERROR = 200503; - DOMAIN_LOCALITY_ERROR = 200504; - SHARD_NOT_AVAILABLE = 200505; - TX_STATE_UNKNOWN = 200506; - TX_DECLINED_BY_COORDINATOR = 200507; + + GENERIC_TXPROXY_ERROR = 200500; + KEY_PARSE_ERROR = 200501; + EMPTY_OP_RANGE = 200502; + ENGINE_ERROR = 200503; + DOMAIN_LOCALITY_ERROR = 200504; + SHARD_NOT_AVAILABLE = 200505; + TX_STATE_UNKNOWN = 200506; + TX_DECLINED_BY_COORDINATOR = 200507; TX_DECLINED_IMPLICIT_COORDINATOR = 200508; SHARD_PROGRAM_SIZE_EXCEEDED = 200509; - - SCOPE_REQPROXY = 200600; - - SCOPE_TXPROXY_INTERPRET = 200700; - SCOPE_TXPROXY_RESOLVE = 200701; - SCOPE_TXPROXY_PREPARE = 200702; - SCOPE_TXPROXY_EXECUTE = 200703; + + SCOPE_REQPROXY = 200600; + + SCOPE_TXPROXY_INTERPRET = 200700; + SCOPE_TXPROXY_RESOLVE = 200701; + SCOPE_TXPROXY_PREPARE = 200702; + SCOPE_TXPROXY_EXECUTE = 200703; YDB_API_VALIDATION_ERROR = 200800; YDB_AUTH_UNAVAILABLE = 200801; YDB_DB_NOT_READY = 200802; YDB_RESOURCE_USAGE_LIMITED = 200803; - } - - message TIssueId { - EIssueCode code = 2; - NYql.TSeverityIds.ESeverityId severity = 1; - string format = 3; - } - - repeated TIssueId ids = 1; -} - -message TStatusIds { - enum EStatusCode { - UNKNOWN = 0; - SUCCESS = 1; - TRANSIENT = 2; - - ERROR = 128; - INPROGRESS = 129; - TIMEOUT = 130; - NOTREADY = 131; - INTERNAL_ERROR = 133; - REJECTED = 134; - NOTSUPPORTED = 135; - OVERLOADED = 136; - PATH_NOT_EXIST = 137; - ACCESS_DENIED = 138; - - BAD_REQUEST = 150; - QUERY_ERROR = 151; - PROCESS_ERROR = 152; - BAD_SESSION = 153; - - LOCKS_INVALIDATED = 170; - LOCKS_ACQUIRE_FAILURE = 171; - SCHEME_ERROR = 172; - } -} + } + + message TIssueId { + EIssueCode code = 2; + NYql.TSeverityIds.ESeverityId severity = 1; + string format = 3; + } + + repeated TIssueId ids = 1; +} + +message TStatusIds { + enum EStatusCode { + UNKNOWN = 0; + SUCCESS = 1; + TRANSIENT = 2; + + ERROR = 128; + INPROGRESS = 129; + TIMEOUT = 130; + NOTREADY = 131; + INTERNAL_ERROR = 133; + REJECTED = 134; + NOTSUPPORTED = 135; + OVERLOADED = 136; + PATH_NOT_EXIST = 137; + ACCESS_DENIED = 138; + + BAD_REQUEST = 150; + QUERY_ERROR = 151; + PROCESS_ERROR = 152; + BAD_SESSION = 153; + + LOCKS_INVALIDATED = 170; + LOCKS_ACQUIRE_FAILURE = 171; + SCHEME_ERROR = 172; + } +} diff --git a/ydb/core/protos/msgbus.proto b/ydb/core/protos/msgbus.proto index 51330712f9..df7cda5980 100644 --- a/ydb/core/protos/msgbus.proto +++ b/ydb/core/protos/msgbus.proto @@ -54,7 +54,7 @@ message TMsgBusRequestBase { message TRequest { optional NKikimrTxUserProxy.TTransaction Transaction = 1; optional uint64 ProxyFlags = 2; - optional uint64 ExecTimeoutPeriod = 4; + optional uint64 ExecTimeoutPeriod = 4; optional string SecurityToken = 5; } @@ -101,7 +101,7 @@ message TResponse { {Value: 3 Name: "NotImplemented" Man: "Not yet implemented feature requested" }, {Value: 4 Name: "ResolveError" Man: "Some keys not resolved, see UnresolvedKeys for details" }, {Value: 5 Name: "AccessDenied" Man: "Access denied for request" }, - {Value: 6 Name: "DomainLocalityError" Man: "Cross database transactions not allowed"}, + {Value: 6 Name: "DomainLocalityError" Man: "Cross database transactions not allowed"}, {Value: 16 Name: "ProxyNotReady" Man: "Transaction proxy not ready for handling requests, try later. Most known case is temporary lack of txid-s" }, {Value: 17 Name: "ProxyAccepted" Man: "Request accepted by proxy. Transitional status" }, {Value: 18 Name: "ProxyResolved" Man: "Request keys resolved to datashards. Transitional status" }, @@ -109,7 +109,7 @@ message TResponse { {Value: 20 Name: "ProxyShardNotAvailable" Man: "One or more of affected datashards not available, request execution cancelled" }, {Value: 21 Name: "ProxyShardTryLater" Man: "One or more of affected datashards are starting, try again" }, {Value: 22 Name: "ProxyShardOverloaded" Man: "One or more of affected datashards are overloaded, try again" }, - {Value: 23 Name: "ProxyShardUnknown" Man: "State of transaction on one or more datashards is unknown" }, + {Value: 23 Name: "ProxyShardUnknown" Man: "State of transaction on one or more datashards is unknown" }, {Value: 32 Name: "CoordinatorDeclined" Man: "Coordinator declines to plan transaction, try again" }, {Value: 33 Name: "CoordinatorOutdated" Man: "Coordinator was not able to plan transaction due to timing restrictions, try again" }, {Value: 34 Name: "CoordinatorAborted" Man: "Transaction aborted by coordinator" }, @@ -128,9 +128,9 @@ message TResponse { optional bytes ProxyErrors = 6; - optional NKikimrIssues.TStatusIds.EStatusCode StatusCode = 7; + optional NKikimrIssues.TStatusIds.EStatusCode StatusCode = 7; repeated Ydb.Issue.IssueMessage Issues = 8; - + optional uint32 ExecutionEngineStatus = 100 [ (CommonDescription) = "MiniKQL engine processing status, if OK - see ExecutionEngineResponseStatus", (EnumValueHint) = { Hints : [ @@ -260,27 +260,27 @@ message TTabletCountersRequest { optional uint64 Timeout = 11; } -message TLocalMKQL { - message TProgram { - optional bytes Bin = 1; - optional string Text = 2; - }; - - message TParams { - optional bytes Bin = 1; - optional string Text = 2; - } - - optional uint64 TabletID = 1; - optional NKikimrTxUserProxy.TMiniKQLTransaction Program = 2; +message TLocalMKQL { + message TProgram { + optional bytes Bin = 1; + optional string Text = 2; + }; + + message TParams { + optional bytes Bin = 1; + optional string Text = 2; + } + + optional uint64 TabletID = 1; + optional NKikimrTxUserProxy.TMiniKQLTransaction Program = 2; optional bool ConnectToFollower = 3; - + optional string SecurityToken = 5; - optional bool WithRetry = 10; - optional uint64 Timeout = 11; -} - + optional bool WithRetry = 10; + optional uint64 Timeout = 11; +} + message TLocalSchemeTx { optional uint64 TabletID = 1; optional bool ConnectToFollower = 2; @@ -451,8 +451,8 @@ message TFlatDescribeResponse { optional NKikimrSchemeOp.TPathDescription PathDescription = 2; optional string ErrorReason = 3; // When present contains human-readable error description optional int32 SchemeStatus = 4; - - optional NKikimrIssues.TStatusIds.EStatusCode StatusCode = 7; + + optional NKikimrIssues.TStatusIds.EStatusCode StatusCode = 7; repeated Ydb.Issue.IssueMessage Issues = 8; }; diff --git a/ydb/core/protos/scheme_log.proto b/ydb/core/protos/scheme_log.proto index e6b23804f5..fcf4ba52b9 100644 --- a/ydb/core/protos/scheme_log.proto +++ b/ydb/core/protos/scheme_log.proto @@ -12,21 +12,21 @@ message TAlterRecord { AddColumnToKey = 5; AddColumnToFamily = 6; AddFamily = 7; - UpdateExecutorInfo = 8; + UpdateExecutorInfo = 8; SetCompactionPolicy = 9; SetRoom = 10; SetFamily = 11; SetRedo = 12; SetTable = 13; }; - + required EDeltaType DeltaType = 1; optional uint32 TableId = 2; optional string TableName = 3; optional uint32 ColumnId = 4; optional uint32 FamilyId = 7; optional uint32 RoomId = 8; - + //_ Global: DB redo log tweaks settings optional uint32 Annex = 16; // Same as Large, but for redo log @@ -60,13 +60,13 @@ message TAlterRecord { optional bytes Default = 10; // Serialized default value for cell optional bool NotNull = 24 [default = false]; - optional uint64 ExecutorCacheSize = 100; + optional uint64 ExecutorCacheSize = 100; optional NKikimrSchemeOp.TCompactionPolicy CompactionPolicy = 101; - optional bool ExecutorAllowLogBatching = 102; - optional uint64 ExecutorLogFlushPeriod = 103; - optional uint32 ExecutorLimitInFlyTx = 104; + optional bool ExecutorAllowLogBatching = 102; + optional uint64 ExecutorLogFlushPeriod = 103; + optional uint32 ExecutorLimitInFlyTx = 104; optional string ExecutorResourceProfile = 105; - optional bool ExecutorLogFastCommitTactic = 106; + optional bool ExecutorLogFastCommitTactic = 106; }; message TSchemeChanges { diff --git a/ydb/core/protos/services.proto b/ydb/core/protos/services.proto index 45dde9723a..c17c8a7dc3 100644 --- a/ydb/core/protos/services.proto +++ b/ydb/core/protos/services.proto @@ -10,7 +10,7 @@ enum EServiceKikimr { BLOBSTORAGE = 257; STATESTORAGE = 258; - RESOURCE_BROKER = 259; + RESOURCE_BROKER = 259; // BLOBSTORAGE section BS_SKELETON = 260; @@ -49,7 +49,7 @@ enum EServiceKikimr { BS_PROXY_PATCH = 343; BS_VDISK_SCRUB = 344; BS_VDISK_PATCH = 345; - + // DATASHARD section // TX_DATASHARD = 290; // /////////////////////// @@ -71,9 +71,9 @@ enum EServiceKikimr { BLOB_CACHE = 333; TX_COLUMNSHARD_SCAN = 334; - // BLOBSTORAGE again - BS_HANDOFF = 298; - + // BLOBSTORAGE again + BS_HANDOFF = 298; + // HIVE section HIVE = 300; LOCAL = 301; @@ -86,9 +86,9 @@ enum EServiceKikimr { TABLET_MAIN = 311; TABLET_DATABASE = 312; TABLET_RESOLVER = 313; - TABLET_SAUSAGECACHE = 314; - TABLET_FLATEX = 315; - TABLET_FLATBOOT = 316; + TABLET_SAUSAGECACHE = 314; + TABLET_FLATEX = 315; + TABLET_FLATBOOT = 316; TABLET_AGGREGATOR = 317; TABLET_OPS_HOST = 666; OPS_COMPACT = 667; @@ -180,13 +180,13 @@ enum EServiceKikimr { // SQS section SQS = 470; - BOARD_REPLICA = 480; - BOARD_LOOKUP = 481; - BOARD_PUBLISH = 482; + BOARD_REPLICA = 480; + BOARD_LOOKUP = 481; + BOARD_PUBLISH = 482; + + QUOTER_SERVICE = 490; + QUOTER_PROXY = 491; - QUOTER_SERVICE = 490; - QUOTER_PROXY = 491; - // HEALTH section HEALTH = 500; @@ -195,7 +195,7 @@ enum EServiceKikimr { DATASHARD_BACKUP = 522; CMS = 523; - + HTTP = 524; NODE_BROKER = 525; @@ -220,7 +220,7 @@ enum EServiceKikimr { KQP_LOAD_TEST = 544; KQP_SESSION = 545; - TABLET_RESOURCE_BROKER = 540; + TABLET_RESOURCE_BROKER = 540; // KESUS section KESUS_PROXY = 550; @@ -671,12 +671,12 @@ message TActivity { TX_PROXY_EXPORT = 356; KQP_SCAN_COMPUTE_ACTOR = 357; KQP_TABLE_SCAN = 358; - CONFIGURED_BOOTSTRAPPER = 359; - TX_ALLOCATOR_CLIENT_ACTOR = 360; + CONFIGURED_BOOTSTRAPPER = 359; + TX_ALLOCATOR_CLIENT_ACTOR = 360; BLOCKSTORE_AUTH = 361; - INTERCONNECT_MONACTOR = 362; - BS_MONSTREAM_ACTOR = 363; - NODE_WARDEN_STATAGGR_ACTOR = 364; + INTERCONNECT_MONACTOR = 362; + BS_MONSTREAM_ACTOR = 363; + NODE_WARDEN_STATAGGR_ACTOR = 364; UPLOAD_ROWS_INTERNAL = 365; PERSQUEUE_CLUSTER_TRACKER = 366; NET_CLASSIFIER_ACTOR = 367; @@ -698,7 +698,7 @@ message TActivity { CMS_SENTINEL_CONFIG_UPDATER_ACTOR = 383; CMS_SENTINEL_STATE_UPDATER_ACTOR = 384; CMS_SENTINEL_STATUS_CHANGER_ACTOR = 385; - TENANT_NODES_ENUMERATION = 386; + TENANT_NODES_ENUMERATION = 386; SCHEME_BOARD_SYNCHRONIZER_ACTOR = 387; SCHEME_BOARD_REPLICA_SYNCHRONIZER_ACTOR = 388; SYSTEM_VIEW_PART_STATS_COLLECTOR = 389; diff --git a/ydb/core/protos/statestorage.proto b/ydb/core/protos/statestorage.proto index 5b655c3243..4165af89ba 100644 --- a/ydb/core/protos/statestorage.proto +++ b/ydb/core/protos/statestorage.proto @@ -25,12 +25,12 @@ message TEvInfo { repeated NActorsProto.TActorId Follower = 11; repeated NActorsProto.TActorId FollowerTablet = 12; repeated NActorsProto.TActorId FollowerCandidates = 13; - optional fixed32 ConfigContentHash = 14; + optional fixed32 ConfigContentHash = 14; +}; + +message TEvReplicaShutdown { }; -message TEvReplicaShutdown { -}; - message TEvDumpRequest { }; @@ -46,30 +46,30 @@ message TEvUpdate { optional uint32 ProposedGeneration = 5; optional uint32 ProposedStep = 6; optional uint64 Signature = 7; - optional bool IsGuardian = 8; + optional bool IsGuardian = 8; }; message TEvDelete { optional fixed64 TabletID = 1; }; -message TEvCleanup { - optional fixed64 TabletID = 1; +message TEvCleanup { + optional fixed64 TabletID = 1; optional NActorsProto.TActorId ProposedLeader = 2; -} - +} + message TEvRegisterFollower { - optional fixed64 TabletID = 1; + optional fixed64 TabletID = 1; optional NActorsProto.TActorId Follower = 2; optional NActorsProto.TActorId FollowerTablet = 3; - optional bool Candidate = 4; -} - + optional bool Candidate = 4; +} + message TEvUnregisterFollower { - optional fixed64 TabletID = 1; + optional fixed64 TabletID = 1; optional NActorsProto.TActorId Follower = 2; -} - +} + message TEvLock { optional fixed64 TabletID = 1; optional uint64 Cookie = 2; @@ -77,56 +77,56 @@ message TEvLock { optional uint32 ProposedGeneration = 4; optional uint64 Signature = 5; }; - + message TEvReplicaLeaderDemoted { - optional fixed64 TabletID = 1; - optional uint64 Signature = 2; -}; - -message TEvReplicaBoardPublish { - optional string Path = 1; + optional fixed64 TabletID = 1; + optional uint64 Signature = 2; +}; + +message TEvReplicaBoardPublish { + optional string Path = 1; optional bytes Payload = 2; - optional uint64 TtlMs = 3; - optional bool Register = 4; + optional uint64 TtlMs = 3; + optional bool Register = 4; optional NActorsProto.TActorId Owner = 5; -}; - -message TEvReplicaBoardPublishAck { -}; - -message TEvReplicaBoardLookup { - optional string Path = 1; +}; + +message TEvReplicaBoardPublishAck { +}; + +message TEvReplicaBoardLookup { + optional string Path = 1; optional NActorsProto.TActorId Owner = 2; - optional bool Subscribe = 3; -}; - -message TEvReplicaBoardCleanup { -}; - -message TBoardEntryInfo { + optional bool Subscribe = 3; +}; + +message TEvReplicaBoardCleanup { +}; + +message TBoardEntryInfo { optional NActorsProto.TActorId Owner = 1; optional bytes Payload = 2; -}; - -message TEvReplicaBoardInfo { - optional string Path = 1; - optional bool Dropped = 2; - repeated TBoardEntryInfo Info = 3; -} - -message TEndpointBoardEntry { - optional string Address = 1; - optional uint32 Port = 2; - optional float Load = 3; - - optional bool Ssl = 4; - repeated string Services = 5; - - optional string DataCenter = 6; +}; + +message TEvReplicaBoardInfo { + optional string Path = 1; + optional bool Dropped = 2; + repeated TBoardEntryInfo Info = 3; +} + +message TEndpointBoardEntry { + optional string Address = 1; + optional uint32 Port = 2; + optional float Load = 3; + + optional bool Ssl = 4; + repeated string Services = 5; + + optional string DataCenter = 6; optional uint32 NodeId = 7; repeated string AddressesV4 = 8; repeated string AddressesV6 = 9; optional string TargetNameOverride = 10; -}; - +}; + diff --git a/ydb/core/protos/tablet.proto b/ydb/core/protos/tablet.proto index 3fad551919..f0bec238e7 100644 --- a/ydb/core/protos/tablet.proto +++ b/ydb/core/protos/tablet.proto @@ -68,17 +68,17 @@ message TTabletLogEntry { optional uint32 Confirmed = 4; optional bool IsSnapshot = 5; - repeated NKikimrProto.TLogoBlobID GcDiscovered = 6; - repeated NKikimrProto.TLogoBlobID GcLeft = 7; - - optional bool IsTotalSnapshot = 8; - + repeated NKikimrProto.TLogoBlobID GcDiscovered = 6; + repeated NKikimrProto.TLogoBlobID GcLeft = 7; + + optional bool IsTotalSnapshot = 8; + // zero log entry optional fixed64 ZeroConfirmed = 10; optional uint32 ZeroTailSz = 11; repeated fixed64 ZeroTailBitmask = 12; - - optional bytes EmbeddedLogBody = 13; + + optional bytes EmbeddedLogBody = 13; } message TTabletChannelInfo { @@ -99,8 +99,8 @@ message TTabletStorageInfo { repeated TTabletChannelInfo Channels = 2; optional TTabletTypes.EType TabletType = 3; optional uint32 Version = 4; - optional uint64 TenantIdOwner = 5; - optional uint64 TenantIdLocalId = 6; + optional uint64 TenantIdOwner = 5; + optional uint64 TenantIdLocalId = 6; } message TEvPing { @@ -127,61 +127,61 @@ message TEvReadLocalBaseResult { } message TEvFollowerAttach { - optional fixed64 TabletId = 1; + optional fixed64 TabletId = 1; optional uint32 FollowerAttempt = 2; -} - +} + message TEvFollowerUpdate { - optional fixed64 TabletId = 1; + optional fixed64 TabletId = 1; optional uint32 FollowerAttempt = 2; - optional uint64 StreamCounter = 3; - - optional uint32 Generation = 10; - optional uint32 Step = 11; - - repeated NKikimrProto.TLogoBlobID ReferencesIds = 12; - repeated bytes References = 13; - optional bool IsSnapshot = 14; - optional bytes Body = 15; - optional bytes AuxPayload = 16; - optional TTabletStorageInfo TabletStorageInfo = 17; // set only for initial log snapshot - - repeated NKikimrProto.TLogoBlobID GcDiscovered = 20; - repeated NKikimrProto.TLogoBlobID GcLeft = 21; - optional bool NeedGCApplyAck = 22; -} - + optional uint64 StreamCounter = 3; + + optional uint32 Generation = 10; + optional uint32 Step = 11; + + repeated NKikimrProto.TLogoBlobID ReferencesIds = 12; + repeated bytes References = 13; + optional bool IsSnapshot = 14; + optional bytes Body = 15; + optional bytes AuxPayload = 16; + optional TTabletStorageInfo TabletStorageInfo = 17; // set only for initial log snapshot + + repeated NKikimrProto.TLogoBlobID GcDiscovered = 20; + repeated NKikimrProto.TLogoBlobID GcLeft = 21; + optional bool NeedGCApplyAck = 22; +} + message TEvFollowerGcAck { - optional fixed64 TabletId = 1; + optional fixed64 TabletId = 1; optional uint32 FollowerAttempt = 2; - optional uint32 Generation = 3; - optional uint32 Step = 4; -} - + optional uint32 Generation = 3; + optional uint32 Step = 4; +} + message TEvFollowerAuxUpdate { - optional fixed64 TabletId = 1; + optional fixed64 TabletId = 1; optional uint32 FollowerAttempt = 2; - optional uint64 StreamCounter = 3; - - optional bytes AuxPayload = 10; -} - + optional uint64 StreamCounter = 3; + + optional bytes AuxPayload = 10; +} + message TEvFollowerDetach { - optional fixed64 TabletId = 1; + optional fixed64 TabletId = 1; optional uint32 FollowerAttempt = 2; -} - +} + message TEvFollowerDisconnect { - optional fixed64 TabletId = 1; + optional fixed64 TabletId = 1; optional uint32 FollowerAttempt = 2; - optional uint32 Reason = 3; // todo: enum -} - + optional uint32 Reason = 3; // todo: enum +} + message TEvFollowerRefresh { - optional fixed64 TabletId = 1; - optional uint32 Generation = 2; - optional bool OfflineProtocol = 3; -} + optional fixed64 TabletId = 1; + optional uint32 Generation = 2; + optional bool OfflineProtocol = 3; +} message TEvGetCounters { } diff --git a/ydb/core/protos/tablet_database.proto b/ydb/core/protos/tablet_database.proto index 2a75a813cc..a6658688a6 100644 --- a/ydb/core/protos/tablet_database.proto +++ b/ydb/core/protos/tablet_database.proto @@ -13,35 +13,35 @@ message TExecutorSettings { optional bool KeepInMemory = 5; } - message TCompactionPolicy { - message TGenerationPolicy { - optional uint32 GenerationId = 1; - optional uint64 SizeToCompact = 2; // - optional uint32 CountToCompact = 3; // - optional uint64 TimeFromCompaction = 4; // AND ^^ - optional uint32 ForceCountToCompact = 10; // OR one of force limits happend - optional uint64 ForceSizeToCompact = 11; // - optional uint64 ForceTimeFromCompaction = 12; // - optional uint32 CompactionQueue = 20; // what broker queue to use for compaction (by default: generationid + 1) - } - - optional uint64 InMemSizeToSnapshot = 1; // - optional uint32 InMemStepsToSnapshot = 2; // snapshot inmem state when size AND steps from last snapshot passed - optional uint32 InMemForceStepsToSnapshot = 3; // OR steps passed - optional uint64 InMemForceSizeToSnapshot = 4; // OR size reached - optional uint64 InMemForceTimeToSnapshot = 5; // OR time from last snapshot passed - optional uint32 InMemCompactionQueue = 6; // default: 0 - - repeated TGenerationPolicy Generation = 10; - } - - message TDatabasePolicy { - optional uint64 MainCacheSize = 1; - optional uint32 ExecutorTxInFly = 2; - optional uint32 TabletMetaInfoChannelIndex = 3; - - optional TCompactionPolicy CompactionPolicy = 10; - repeated TLocalityGroupPolicy LocalityGroupPolicy = 11; + message TCompactionPolicy { + message TGenerationPolicy { + optional uint32 GenerationId = 1; + optional uint64 SizeToCompact = 2; // + optional uint32 CountToCompact = 3; // + optional uint64 TimeFromCompaction = 4; // AND ^^ + optional uint32 ForceCountToCompact = 10; // OR one of force limits happend + optional uint64 ForceSizeToCompact = 11; // + optional uint64 ForceTimeFromCompaction = 12; // + optional uint32 CompactionQueue = 20; // what broker queue to use for compaction (by default: generationid + 1) + } + + optional uint64 InMemSizeToSnapshot = 1; // + optional uint32 InMemStepsToSnapshot = 2; // snapshot inmem state when size AND steps from last snapshot passed + optional uint32 InMemForceStepsToSnapshot = 3; // OR steps passed + optional uint64 InMemForceSizeToSnapshot = 4; // OR size reached + optional uint64 InMemForceTimeToSnapshot = 5; // OR time from last snapshot passed + optional uint32 InMemCompactionQueue = 6; // default: 0 + + repeated TGenerationPolicy Generation = 10; + } + + message TDatabasePolicy { + optional uint64 MainCacheSize = 1; + optional uint32 ExecutorTxInFly = 2; + optional uint32 TabletMetaInfoChannelIndex = 3; + + optional TCompactionPolicy CompactionPolicy = 10; + repeated TLocalityGroupPolicy LocalityGroupPolicy = 11; reserved 100; //optional bool ExposeCounters = 100; } diff --git a/ydb/core/protos/tx_datashard.proto b/ydb/core/protos/tx_datashard.proto index bbce9aca1e..89863b2540 100644 --- a/ydb/core/protos/tx_datashard.proto +++ b/ydb/core/protos/tx_datashard.proto @@ -482,10 +482,10 @@ message TEvProposeTransaction { optional TMvccSnapshot MvccSnapshot = 10; } -message TEvCancelTransactionProposal { - optional uint64 TxId = 1; -} - +message TEvCancelTransactionProposal { + optional uint64 TxId = 1; +} + message TError { enum EKind { OK = 0; diff --git a/ydb/core/protos/tx_proxy.proto b/ydb/core/protos/tx_proxy.proto index da1c723c44..dedd2f9cbb 100644 --- a/ydb/core/protos/tx_proxy.proto +++ b/ydb/core/protos/tx_proxy.proto @@ -5,7 +5,7 @@ import "ydb/core/protos/query_stats.proto"; import "ydb/library/mkql_proto/protos/minikql.proto"; import "ydb/public/api/protos/ydb_issue_message.proto"; - + package NKikimrTxUserProxy; option java_package = "ru.yandex.kikimr.proto"; @@ -188,7 +188,7 @@ message TTransaction { message TEvProposeTransaction { optional TTransaction Transaction = 1; optional uint64 ProxyFlags = 2; - optional uint64 ExecTimeoutPeriod = 3; + optional uint64 ExecTimeoutPeriod = 3; optional string UserToken = 4; // already built and serialized user's token optional bool StreamResponse = 5; optional uint64 CancelAfterMs = 6; @@ -213,9 +213,9 @@ message TEvProposeTransactionStatus { optional fixed64 TxId = 2; optional fixed64 Step = 3; - optional NKikimrIssues.TStatusIds.EStatusCode StatusCode = 7; + optional NKikimrIssues.TStatusIds.EStatusCode StatusCode = 7; repeated Ydb.Issue.IssueMessage Issues = 8; - + optional uint32 ExecutionEngineStatus = 10; optional uint32 ExecutionEngineResponseStatus = 11; optional bytes ExecutionEngineResponse = 12; // Native document. @@ -225,7 +225,7 @@ message TEvProposeTransactionStatus { repeated bytes UnresolvedKeys = 16; // text optional TMiniKQLCompileResults MiniKQLCompileResults = 17; - optional NKikimrMiniKQL.TResult ExecutionEngineEvaluatedResponse = 18; + optional NKikimrMiniKQL.TResult ExecutionEngineEvaluatedResponse = 18; optional NKikimrQueryStats.TTxStats TxStats = 19; optional TTxProxyTimings Timings = 20; diff --git a/ydb/core/protos/ya.make b/ydb/core/protos/ya.make index 8b2e705dc9..70bb65514c 100644 --- a/ydb/core/protos/ya.make +++ b/ydb/core/protos/ya.make @@ -37,7 +37,7 @@ SRCS( console_config.proto console_tenant.proto counters_tx_allocator.proto - counters_bs_controller.proto + counters_bs_controller.proto counters_coordinator.proto counters_columnshard.proto counters_datashard.proto @@ -64,7 +64,7 @@ SRCS( http_config.proto import.proto index_builder.proto - issue_id.proto + issue_id.proto kesus.proto kqp_query_settings.proto kqp_physical.proto @@ -133,7 +133,7 @@ SRCS( GENERATE_ENUM_SERIALIZATION(blobstorage_pdisk_config.pb.h) -PEERDIR( +PEERDIR( library/cpp/actors/protos ydb/core/yq/libs/config/protos ydb/library/login/protos @@ -144,8 +144,8 @@ PEERDIR( ydb/library/yql/dq/proto ydb/library/yql/public/issue/protos ydb/library/yql/public/types -) - +) + EXCLUDE_TAGS(GO_PROTO) END() diff --git a/ydb/core/quoter/defs.h b/ydb/core/quoter/defs.h index 65d6274870..7361613831 100644 --- a/ydb/core/quoter/defs.h +++ b/ydb/core/quoter/defs.h @@ -1,8 +1,8 @@ -#pragma once +#pragma once // unique tag to fix pragma once gcc glueing: ./ydb/core/quoter/defs.h #include <ydb/core/base/defs.h> #include <ydb/core/base/events.h> - -namespace NKikimr { - -} + +namespace NKikimr { + +} diff --git a/ydb/core/quoter/kesus_quoter_proxy.cpp b/ydb/core/quoter/kesus_quoter_proxy.cpp index e051e63eb3..4d2d20691e 100644 --- a/ydb/core/quoter/kesus_quoter_proxy.cpp +++ b/ydb/core/quoter/kesus_quoter_proxy.cpp @@ -1,5 +1,5 @@ #include "kesus_quoter_proxy.h" -#include "quoter_service_impl.h" +#include "quoter_service_impl.h" #include "debug_info.h" #include <ydb/core/base/counters.h> @@ -13,10 +13,10 @@ #include <library/cpp/actors/core/log.h> #include <library/cpp/actors/core/actor_bootstrapped.h> -#include <util/generic/map.h> -#include <util/generic/hash.h> +#include <util/generic/map.h> +#include <util/generic/hash.h> #include <util/system/types.h> - + #include <limits> #include <cmath> @@ -37,20 +37,20 @@ #define KESUS_PROXY_LOG_WARN(stream) PLOG_WARN(LogPrefix << stream) #define KESUS_PROXY_LOG_ERROR(stream) PLOG_ERROR(LogPrefix << stream) -namespace NKikimr { -namespace NQuoter { - +namespace NKikimr { +namespace NQuoter { + static constexpr double FADING_ALLOCATION_COEFFICIENT = 0.999; static constexpr double PREFETCH_COEFFICIENT_DEFAULT = 0.20; static constexpr double PREFETCH_WATERMARK_DEFAULT = 0.75; using NKesus::TEvKesus; -class TKesusQuoterProxy : public TActorBootstrapped<TKesusQuoterProxy> { - struct TResourceState { - const TString Resource; +class TKesusQuoterProxy : public TActorBootstrapped<TKesusQuoterProxy> { + struct TResourceState { + const TString Resource; ui64 ResId = Max<ui64>(); - + double Available = 0; double QueueWeight = 0; double ResourceBucketMaxSize = 0; @@ -59,7 +59,7 @@ class TKesusQuoterProxy : public TActorBootstrapped<TKesusQuoterProxy> { bool ProxySessionWasSent = false; TInstant LastAllocated = TInstant::Zero(); std::pair<TDuration, double> AverageAllocationParams = {TDuration::Zero(), 0.0}; - + NKikimrKesus::TStreamingQuoterResource Props; bool InitedProps = false; @@ -144,7 +144,7 @@ class TKesusQuoterProxy : public TActorBootstrapped<TKesusQuoterProxy> { explicit TResourceState(const TString& resource, const NMonitoring::TDynamicCounterPtr& quoterCounters) : Resource(resource) , Counters(resource, quoterCounters) - {} + {} void AddUpdate(TEvQuota::TEvProxyUpdate& ev) const { TVector<TEvQuota::TUpdateTick> update; @@ -211,8 +211,8 @@ class TKesusQuoterProxy : public TActorBootstrapped<TKesusQuoterProxy> { *Counters.Accumulated = static_cast<i64>(available); } } - }; - + }; + struct TEvPrivate { enum EEv { EvOfflineResourceAllocation = EventSpaceBegin(TEvents::ES_PRIVATE), @@ -242,28 +242,28 @@ class TKesusQuoterProxy : public TActorBootstrapped<TKesusQuoterProxy> { }; const TActorId QuoterServiceId; - const ui64 QuoterId; - const TVector<TString> Path; + const ui64 QuoterId; + const TVector<TString> Path; const TString LogPrefix; - TIntrusiveConstPtr<NSchemeCache::TSchemeCacheNavigate::TKesusInfo> KesusInfo; + TIntrusiveConstPtr<NSchemeCache::TSchemeCacheNavigate::TKesusInfo> KesusInfo; THolder<ITabletPipeFactory> TabletPipeFactory; TActorId KesusPipeClient; - + bool Connected = false; TInstant DisconnectTime; ui64 OfflineAllocationCookie = 0; - + TMap<TString, THolder<TResourceState>> Resources; // Map because iterators are needed to remain valid during insertions. - THashMap<ui64, decltype(Resources)::iterator> ResIndex; - + THashMap<ui64, decltype(Resources)::iterator> ResIndex; + THashMap<ui64, std::vector<TString>> CookieToResourcePath; ui64 NextCookie = 1; - + THolder<NKesus::TEvKesus::TEvUpdateConsumptionState> UpdateEv; THolder<NKesus::TEvKesus::TEvAccountResources> AccountEv; THolder<TEvQuota::TEvProxyUpdate> ProxyUpdateEv; THashMap<TDuration, THolder<TEvPrivate::TEvOfflineResourceAllocation>> OfflineAllocationEvSchedule; - + struct TCounters { NMonitoring::TDynamicCounterPtr QuoterCounters; @@ -286,14 +286,14 @@ private: std::vector<TString> paths = {std::move(resourcePath)}; return NewCookieForRequest(std::move(paths)); } - + ui64 NewCookieForRequest(std::vector<TString> resourcePaths) { Y_VERIFY(!resourcePaths.empty()); const ui64 cookie = NextCookie++; Y_VERIFY(CookieToResourcePath.emplace(cookie, std::move(resourcePaths)).second); return cookie; } - + std::vector<TString> PopResourcePathsForRequest(ui64 cookie) { auto resPathIt = CookieToResourcePath.find(cookie); if (resPathIt != CookieToResourcePath.end()) { @@ -304,13 +304,13 @@ private: return {}; } } - + static TString KesusErrorToString(const NKikimrKesus::TKesusError& err) { NYql::TIssues issues; NYql::IssuesFromMessage(err.GetIssues(), issues); return issues.ToString(); } - + void SendProxySessionError(TEvQuota::TEvProxySession::EResult code, const TString& resourcePath) { KESUS_PROXY_LOG_TRACE("ProxySession(\"" << resourcePath << "\", Error: " << code << ")"); Send(QuoterServiceId, @@ -322,8 +322,8 @@ private: TDuration::Zero(), TEvQuota::EStatUpdatePolicy::Never )); - } - + } + void ProcessSubscribeResourceError(Ydb::StatusIds::StatusCode code, TResourceState* resState) { if (!resState->ProxySessionWasSent) { resState->ProxySessionWasSent = true; @@ -349,13 +349,13 @@ private: TEvQuota::EStatUpdatePolicy::EveryActiveTick )); } - } - + } + TResourceState* FindResource(ui64 id) { const auto indexIt = ResIndex.find(id); return indexIt != ResIndex.end() ? indexIt->second->second.Get() : nullptr; } - + const TResourceState* FindResource(ui64 id) const { const auto indexIt = ResIndex.find(id); return indexIt != ResIndex.end() ? indexIt->second->second.Get() : nullptr; @@ -598,7 +598,7 @@ private: void DeleteResourceInfo(const TString& resource, const ui64 resourceId) { auto indexIt = ResIndex.find(resourceId); - if (indexIt != ResIndex.end()) { + if (indexIt != ResIndex.end()) { auto resIt = indexIt->second; if (resIt != Resources.end()) { // else it is already new resource with same path. TResourceState& res = *resIt->second; @@ -607,12 +607,12 @@ private: } Resources.erase(resIt); } - ResIndex.erase(indexIt); - return; - } - + ResIndex.erase(indexIt); + return; + } + auto resIt = Resources.find(resource); - if (resIt != Resources.end()) { + if (resIt != Resources.end()) { TResourceState& res = *resIt->second; if (res.SessionIsActive) { ActivateSession(res, false); @@ -620,9 +620,9 @@ private: if (res.ResId != Max<ui64>()) { ResIndex.erase(res.ResId); } - Resources.erase(resIt); - } - } + Resources.erase(resIt); + } + } void Handle(TEvQuota::TEvProxyCloseSession::TPtr& ev) { TEvQuota::TEvProxyCloseSession* msg = ev->Get(); @@ -855,45 +855,45 @@ private: return TStringBuilder() << "[" << CanonizePath(path) << "]: "; } -public: +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::QUOTER_PROXY_ACTOR; - } - + } + TKesusQuoterProxy(ui64 quoterId, const NSchemeCache::TSchemeCacheNavigate::TEntry& navEntry, const TActorId& quoterServiceId, THolder<ITabletPipeFactory> tabletPipeFactory) : QuoterServiceId(quoterServiceId) , QuoterId(quoterId) - , Path(navEntry.Path) + , Path(navEntry.Path) , LogPrefix(GetLogPrefix(Path)) - , KesusInfo(navEntry.KesusInfo) + , KesusInfo(navEntry.KesusInfo) , TabletPipeFactory(std::move(tabletPipeFactory)) - { + { Y_VERIFY(KesusInfo); Y_VERIFY(GetKesusTabletId()); Y_VERIFY(TabletPipeFactory); - Y_UNUSED(QuoterId); + Y_UNUSED(QuoterId); QUOTER_SYSTEM_DEBUG(DebugInfo->KesusQuoterProxies.emplace(CanonizePath(Path), this)); - } - + } + ~TKesusQuoterProxy() { QUOTER_SYSTEM_DEBUG(DebugInfo->KesusQuoterProxies.erase(CanonizePath(Path))); } - void Bootstrap() { + void Bootstrap() { KESUS_PROXY_LOG_INFO("Created kesus quoter proxy. Tablet id: " << GetKesusTabletId()); Counters.Init(CanonizePath(Path)); - Become(&TThis::StateFunc); + Become(&TThis::StateFunc); ConnectToKesus(false); - } - - STFUNC(StateFunc) { - Y_UNUSED(ctx); - switch (ev->GetTypeRewrite()) { - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); - hFunc(TEvQuota::TEvProxyRequest, Handle); - hFunc(TEvQuota::TEvProxyStats, Handle); - hFunc(TEvQuota::TEvProxyCloseSession, Handle); + } + + STFUNC(StateFunc) { + Y_UNUSED(ctx); + switch (ev->GetTypeRewrite()) { + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + hFunc(TEvQuota::TEvProxyRequest, Handle); + hFunc(TEvQuota::TEvProxyStats, Handle); + hFunc(TEvQuota::TEvProxyCloseSession, Handle); hFunc(TEvTabletPipe::TEvClientConnected, Handle); hFunc(TEvTabletPipe::TEvClientDestroyed, Handle); hFunc(NKesus::TEvKesus::TEvSubscribeOnResourcesResult, Handle); @@ -901,18 +901,18 @@ public: hFunc(NKesus::TEvKesus::TEvUpdateConsumptionStateAck, Handle); hFunc(NKesus::TEvKesus::TEvAccountResourcesAck, Handle); hFunc(TEvPrivate::TEvOfflineResourceAllocation, Handle); - default: + default: KESUS_PROXY_LOG_WARN("TKesusQuoterProxy::StateFunc unexpected event type# " - << ev->GetTypeRewrite() - << " event: " - << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?")); + << ev->GetTypeRewrite() + << " event: " + << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?")); Y_VERIFY_DEBUG(false, "Unknown event"); - break; - } + break; + } ScheduleOfflineAllocation(); SendDeferredEvents(); - } + } ui64 GetKesusTabletId() const { return KesusInfo->Description.GetKesusTabletId(); @@ -958,8 +958,8 @@ public: } TActorBootstrapped::PassAway(); } -}; - +}; + struct TDefaultTabletPipeFactory : public ITabletPipeFactory { IActor* CreateTabletPipe(const NActors::TActorId& owner, ui64 tabletId, const NKikimr::NTabletPipe::TClientConfig& config) override { return NTabletPipe::CreateClient(owner, tabletId, config); @@ -968,18 +968,18 @@ struct TDefaultTabletPipeFactory : public ITabletPipeFactory { THolder<ITabletPipeFactory> ITabletPipeFactory::GetDefaultFactory() { return MakeHolder<TDefaultTabletPipeFactory>(); -} - +} + IActor* CreateKesusQuoterProxy(ui64 quoterId, const NSchemeCache::TSchemeCacheNavigate::TEntry& navEntry, const TActorId& quoterServiceId, THolder<ITabletPipeFactory> tabletPipeFactory) { return new TKesusQuoterProxy(quoterId, navEntry, quoterServiceId, std::move(tabletPipeFactory)); -} +} TKesusResourceAllocationStatistics::TKesusResourceAllocationStatistics(size_t windowSize) : BestPrevStat(windowSize) , Stat(windowSize) { Y_ASSERT(windowSize >= 2); -} +} void TKesusResourceAllocationStatistics::SetProps(const NKikimrKesus::TStreamingQuoterResource& props) { DefaultAllocationDelta = TDuration::MilliSeconds(100); diff --git a/ydb/core/quoter/quoter_service.cpp b/ydb/core/quoter/quoter_service.cpp index c4aa98281a..b9a1b629f5 100644 --- a/ydb/core/quoter/quoter_service.cpp +++ b/ydb/core/quoter/quoter_service.cpp @@ -1,29 +1,29 @@ -#include "quoter_service_impl.h" +#include "quoter_service_impl.h" #include "debug_info.h" #include "kesus_quoter_proxy.h" #include "probes.h" #include <ydb/core/base/counters.h> #include <library/cpp/lwtrace/mon/mon_lwtrace.h> - + #include <cmath> -#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR -#error log macro definition clash -#endif - +#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR +#error log macro definition clash +#endif + #define BLOG_T(stream) LOG_TRACE_S((TlsActivationContext->AsActorContext()), NKikimrServices::QUOTER_SERVICE, stream) -#define BLOG_D(stream) LOG_DEBUG_S((TlsActivationContext->AsActorContext()), NKikimrServices::QUOTER_SERVICE, stream) -#define BLOG_I(stream) LOG_INFO_S((TlsActivationContext->AsActorContext()), NKikimrServices::QUOTER_SERVICE, stream) +#define BLOG_D(stream) LOG_DEBUG_S((TlsActivationContext->AsActorContext()), NKikimrServices::QUOTER_SERVICE, stream) +#define BLOG_I(stream) LOG_INFO_S((TlsActivationContext->AsActorContext()), NKikimrServices::QUOTER_SERVICE, stream) #define BLOG_WARN(stream) LOG_WARN_S((TlsActivationContext->AsActorContext()), NKikimrServices::QUOTER_SERVICE, stream) -#define BLOG_ERROR(stream) LOG_ERROR_S((TlsActivationContext->AsActorContext()), NKikimrServices::QUOTER_SERVICE, stream) - +#define BLOG_ERROR(stream) LOG_ERROR_S((TlsActivationContext->AsActorContext()), NKikimrServices::QUOTER_SERVICE, stream) + LWTRACE_USING(QUOTER_SERVICE_PROVIDER); - -namespace NKikimr { -namespace NQuoter { - + +namespace NKikimr { +namespace NQuoter { + extern const TString CONSUMED_COUNTER_NAME = "QuotaConsumed"; extern const TString REQUESTED_COUNTER_NAME = "QuotaRequested"; extern const TString RESOURCE_COUNTER_SENSOR_NAME = "resource"; @@ -47,71 +47,71 @@ NMonitoring::IHistogramCollectorPtr GetLatencyHistogramBuckets() { return NMonitoring::ExplicitHistogram({0, 1, 2, 5, 10, 20, 50, 100, 500, 1000, 2000, 5000, 10000, 30000, 50000}); } -TRequest& TReqState::Get(ui32 idx) { - Y_VERIFY(idx < Requests.size()); - auto &x = Requests[idx]; - Y_VERIFY(x.Source); - return Requests[idx]; -} - -ui32 TReqState::Idx(TRequest &request) { - const ui32 idx = static_cast<ui32>(&request - &*Requests.begin()); - Y_VERIFY(idx < Requests.size()); - return idx; -} - +TRequest& TReqState::Get(ui32 idx) { + Y_VERIFY(idx < Requests.size()); + auto &x = Requests[idx]; + Y_VERIFY(x.Source); + return Requests[idx]; +} + +ui32 TReqState::Idx(TRequest &request) { + const ui32 idx = static_cast<ui32>(&request - &*Requests.begin()); + Y_VERIFY(idx < Requests.size()); + return idx; +} + ui32 TReqState::HeadByOwner(TActorId ownerId) { - if (ui32 *x = ByOwner.FindPtr(ownerId)) - return *x; - else - return Max<ui32>(); -} - + if (ui32 *x = ByOwner.FindPtr(ownerId)) + return *x; + else + return Max<ui32>(); +} + ui32 TReqState::Allocate(TActorId source, ui64 eventCookie) { - ui32 idx; - if (Unused) { - idx = Unused.back(); - Unused.pop_back(); - } else { - idx = Requests.size(); - Requests.emplace_back(); - } - - auto &x = Requests[idx]; - x.Source = source; - x.EventCookie = eventCookie; + ui32 idx; + if (Unused) { + idx = Unused.back(); + Unused.pop_back(); + } else { + idx = Requests.size(); + Requests.emplace_back(); + } + + auto &x = Requests[idx]; + x.Source = source; + x.EventCookie = eventCookie; x.StartTime = TActivationContext::Now(); - - Y_VERIFY_DEBUG(x.PrevByOwner == Max<ui32>()); - Y_VERIFY_DEBUG(x.NextByOwner == Max<ui32>()); - Y_VERIFY_DEBUG(x.PrevDeadlineRequest == Max<ui32>()); - Y_VERIFY_DEBUG(x.NextDeadlineRequest == Max<ui32>()); - - auto itpair = ByOwner.emplace(source, idx); - if (!itpair.second) { - ui32 &other = itpair.first->second; - x.NextByOwner = other; - Requests[other].PrevByOwner = idx; - other = idx; - } - - return idx; -} - -void TReqState::Free(ui32 idx) { - auto &x = Get(idx); - - bool lastEntry = true; - if (x.NextByOwner != Max<ui32>()) { - lastEntry = false; - Requests[x.NextByOwner].PrevByOwner = x.PrevByOwner; - } - - if (x.PrevByOwner != Max<ui32>()) { - lastEntry = false; - Requests[x.PrevByOwner].NextByOwner = x.NextByOwner; - } - + + Y_VERIFY_DEBUG(x.PrevByOwner == Max<ui32>()); + Y_VERIFY_DEBUG(x.NextByOwner == Max<ui32>()); + Y_VERIFY_DEBUG(x.PrevDeadlineRequest == Max<ui32>()); + Y_VERIFY_DEBUG(x.NextDeadlineRequest == Max<ui32>()); + + auto itpair = ByOwner.emplace(source, idx); + if (!itpair.second) { + ui32 &other = itpair.first->second; + x.NextByOwner = other; + Requests[other].PrevByOwner = idx; + other = idx; + } + + return idx; +} + +void TReqState::Free(ui32 idx) { + auto &x = Get(idx); + + bool lastEntry = true; + if (x.NextByOwner != Max<ui32>()) { + lastEntry = false; + Requests[x.NextByOwner].PrevByOwner = x.PrevByOwner; + } + + if (x.PrevByOwner != Max<ui32>()) { + lastEntry = false; + Requests[x.PrevByOwner].NextByOwner = x.NextByOwner; + } + if (lastEntry) { ByOwner.erase(x.Source); } else { @@ -122,89 +122,89 @@ void TReqState::Free(ui32 idx) { } } - x.NextByOwner = Max<ui32>(); - x.PrevByOwner = Max<ui32>(); - - if (x.NextDeadlineRequest != Max<ui32>()) { - Requests[x.NextDeadlineRequest].PrevDeadlineRequest = x.PrevDeadlineRequest; - } - - if (x.PrevDeadlineRequest != Max<ui32>()) { - Requests[x.PrevDeadlineRequest].NextDeadlineRequest = x.NextDeadlineRequest; - } - - x.PrevDeadlineRequest = Max<ui32>(); - x.NextDeadlineRequest = Max<ui32>(); - + x.NextByOwner = Max<ui32>(); + x.PrevByOwner = Max<ui32>(); + + if (x.NextDeadlineRequest != Max<ui32>()) { + Requests[x.NextDeadlineRequest].PrevDeadlineRequest = x.PrevDeadlineRequest; + } + + if (x.PrevDeadlineRequest != Max<ui32>()) { + Requests[x.PrevDeadlineRequest].NextDeadlineRequest = x.NextDeadlineRequest; + } + + x.PrevDeadlineRequest = Max<ui32>(); + x.NextDeadlineRequest = Max<ui32>(); + x.Source = TActorId(); x.Orbit.Reset(); - Unused.push_back(idx); -} - -TResourceLeaf& TResState::Get(ui32 idx) { - Y_VERIFY(idx < Leafs.size()); - return Leafs[idx]; -} - + Unused.push_back(idx); +} + +TResourceLeaf& TResState::Get(ui32 idx) { + Y_VERIFY(idx < Leafs.size()); + return Leafs[idx]; +} + ui32 TResState::Allocate(TResource *resource, ui64 amount, bool isUsedAmount, ui32 requestIdx) { - ui32 idx; - if (Unused) { - idx = Unused.back(); - Unused.pop_back(); - } else { - idx = Leafs.size(); - Leafs.emplace_back(); - } - - auto &x = Leafs[idx]; - x.Resource = resource; - x.Amount = amount; + ui32 idx; + if (Unused) { + idx = Unused.back(); + Unused.pop_back(); + } else { + idx = Leafs.size(); + Leafs.emplace_back(); + } + + auto &x = Leafs[idx]; + x.Resource = resource; + x.Amount = amount; x.IsUsedAmount = isUsedAmount; - x.RequestIdx = requestIdx; - - Y_VERIFY_DEBUG(x.NextInWaitQueue == Max<ui32>()); - Y_VERIFY_DEBUG(x.PrevInWaitQueue == Max<ui32>()); - Y_VERIFY_DEBUG(x.NextResourceLeaf == Max<ui32>()); - - Y_VERIFY_DEBUG(x.State == EResourceState::Unknown); - Y_VERIFY_DEBUG(x.QuoterId == 0); - Y_VERIFY_DEBUG(x.ResourceId == 0); - Y_VERIFY_DEBUG(x.QuoterName.empty()); - Y_VERIFY_DEBUG(x.ResourceName.empty()); - - return idx; -} - -void TResState::FreeChain(ui32 headIdx) { - while (headIdx != Max<ui32>()) { - auto &x = Get(headIdx); - Y_VERIFY_DEBUG(x.Resource == nullptr); - Y_VERIFY_DEBUG(x.NextInWaitQueue == Max<ui32>()); - Y_VERIFY_DEBUG(x.PrevInWaitQueue == Max<ui32>()); - - Unused.push_back(headIdx); - headIdx = x.NextResourceLeaf; - x.NextResourceLeaf = Max<ui32>(); - - x.Amount = Max<ui64>(); - x.RequestIdx = Max<ui32>(); - x.State = EResourceState::Unknown; - x.QuoterId = 0; - x.ResourceId = 0; - TString().swap(x.ResourceName); - TString().swap(x.QuoterName); + x.RequestIdx = requestIdx; + + Y_VERIFY_DEBUG(x.NextInWaitQueue == Max<ui32>()); + Y_VERIFY_DEBUG(x.PrevInWaitQueue == Max<ui32>()); + Y_VERIFY_DEBUG(x.NextResourceLeaf == Max<ui32>()); + + Y_VERIFY_DEBUG(x.State == EResourceState::Unknown); + Y_VERIFY_DEBUG(x.QuoterId == 0); + Y_VERIFY_DEBUG(x.ResourceId == 0); + Y_VERIFY_DEBUG(x.QuoterName.empty()); + Y_VERIFY_DEBUG(x.ResourceName.empty()); + + return idx; +} + +void TResState::FreeChain(ui32 headIdx) { + while (headIdx != Max<ui32>()) { + auto &x = Get(headIdx); + Y_VERIFY_DEBUG(x.Resource == nullptr); + Y_VERIFY_DEBUG(x.NextInWaitQueue == Max<ui32>()); + Y_VERIFY_DEBUG(x.PrevInWaitQueue == Max<ui32>()); + + Unused.push_back(headIdx); + headIdx = x.NextResourceLeaf; + x.NextResourceLeaf = Max<ui32>(); + + x.Amount = Max<ui64>(); + x.RequestIdx = Max<ui32>(); + x.State = EResourceState::Unknown; + x.QuoterId = 0; + x.ResourceId = 0; + TString().swap(x.ResourceName); + TString().swap(x.QuoterName); x.StartQueueing = TInstant::Zero(); x.StartCharging = TInstant::Zero(); - } -} - -void TResource::ApplyQuotaChannel(const TEvQuota::TUpdateTick &tick) { - // full rewrite - // todo: incremental update (?) as-is would be applied on next tick - QuotaChannels[tick.Channel] = tick; -} - + } +} + +void TResource::ApplyQuotaChannel(const TEvQuota::TUpdateTick &tick) { + // full rewrite + // todo: incremental update (?) as-is would be applied on next tick + QuotaChannels[tick.Channel] = tick; +} + void TResource::MarkStartedCharging(TRequest& request, TResourceLeaf& leaf, TInstant now) { if (leaf.StartCharging == TInstant::Zero()) { leaf.StartCharging = now; @@ -264,14 +264,14 @@ void TResource::ChargeUsedAmount(double amount, TInstant now) { } TDuration TResource::Charge(double amount, TInstant now) { -// Zero - charged -// Max - not in current tick (or resource already queued) -// smth b/w - delayed by pace limit +// Zero - charged +// Max - not in current tick (or resource already queued) +// smth b/w - delayed by pace limit if (TickRate < TICK_RATE_EPSILON) { // zero return TDuration::Max(); } - - // could be fullfilled right now? + + // could be fullfilled right now? const double ticksToFullfill = amount / TickRate; const double durationToFullfillInUs = ticksToFullfill * static_cast<double>(TickSize.MicroSeconds()); // TODO: calculate time for many requests (not for one). Now errors can be accumulated when big rates are used. @@ -287,50 +287,50 @@ TDuration TResource::Charge(double amount, TInstant now) { << ". LastAllocated: " << LastAllocated); if (Balance >= 0.0) { - if (timeToFullfill <= now) { - LastAllocated = Max(now - QuoterServiceConfig.ScheduleTickSize * 2, timeToFullfill); - Balance -= amount; - AmountConsumed += amount; + if (timeToFullfill <= now) { + LastAllocated = Max(now - QuoterServiceConfig.ScheduleTickSize * 2, timeToFullfill); + Balance -= amount; + AmountConsumed += amount; History.Add(now, amount); - - if (FreeBalance > Balance) - FreeBalance = Balance; - + + if (FreeBalance > Balance) + FreeBalance = Balance; + Counters.Consumed->Add(static_cast<i64>(amount)); StopStarvation(now); - return TDuration::Zero(); - } - - if (amount <= FreeBalance) { - LastAllocated = now; - FreeBalance -= amount; - Balance -= amount; - AmountConsumed += amount; + return TDuration::Zero(); + } + + if (amount <= FreeBalance) { + LastAllocated = now; + FreeBalance -= amount; + Balance -= amount; + AmountConsumed += amount; History.Add(now, amount); - + Counters.Consumed->Add(static_cast<i64>(amount)); StopStarvation(now); - return TDuration::Zero(); - } - } - + return TDuration::Zero(); + } + } + StartStarvation(now); - const TDuration delay = timeToFullfill - now; - return (delay > TDuration::Zero()) ? delay : TDuration::Max(); -} - + const TDuration delay = timeToFullfill - now; + return (delay > TDuration::Zero()) ? delay : TDuration::Max(); +} + TResource& TQuoterState::GetOrCreate(ui64 quoterId, ui64 resId, const TString& quoter, const TString& resource, const TQuoterServiceConfig "erServiceConfig) { - auto xpair = Resources.emplace(resId, nullptr); - if (xpair.second) + auto xpair = Resources.emplace(resId, nullptr); + if (xpair.second) xpair.first->second.Reset(new TResource(quoterId, resId, quoter, resource, quoterServiceConfig, Counters.QuoterCounters)); - - return *xpair.first->second; -} - -bool TQuoterState::Empty() { - return Resources.empty() && WaitingResource.empty() && WaitingQueueResolve.empty(); -} - + + return *xpair.first->second; +} + +bool TQuoterState::Empty() { + return Resources.empty() && WaitingResource.empty() && WaitingQueueResolve.empty(); +} + TQuoterService::TQuoterService(const TQuoterServiceConfig &config) : Config(config) , LastProcessed(TInstant::Zero()) @@ -344,349 +344,349 @@ TQuoterService::~TQuoterService() { QUOTER_SYSTEM_DEBUG(DebugInfo->QuoterService = nullptr); } -void TQuoterService::ScheduleNextTick(TInstant requested, TResource &quores) { +void TQuoterService::ScheduleNextTick(TInstant requested, TResource &quores) { TryTickSchedule(); - const TInstant next = TimeToGranularity(requested); - const TInstant last = TimeToGranularity(quores.LastTick + quores.TickSize); + const TInstant next = TimeToGranularity(requested); + const TInstant last = TimeToGranularity(quores.LastTick + quores.TickSize); const TInstant selected = Max(next, last, LastProcessed); - quores.NextTick = selected; - quores.LastTick = selected; + quores.NextTick = selected; + quores.LastTick = selected; BLOG_T("Schedule next tick for \"" << quores.Resource << "\". Tick size: " << quores.TickSize << ". Time: " << quores.NextTick); - ScheduleFeed[quores.NextTick].emplace(&quores); -} - -TInstant TQuoterService::TimeToGranularity(TInstant rawTime) { - // up to next schedule tick - const ui64 rawUs = rawTime.MicroSeconds(); - const ui64 schedUs = Config.ScheduleTickSize.MicroSeconds(); - const ui64 x = (rawUs + (schedUs - 1)) / schedUs * schedUs; - return TInstant::MicroSeconds(x); -} - -void TQuoterService::Bootstrap() { + ScheduleFeed[quores.NextTick].emplace(&quores); +} + +TInstant TQuoterService::TimeToGranularity(TInstant rawTime) { + // up to next schedule tick + const ui64 rawUs = rawTime.MicroSeconds(); + const ui64 schedUs = Config.ScheduleTickSize.MicroSeconds(); + const ui64 x = (rawUs + (schedUs - 1)) / schedUs * schedUs; + return TInstant::MicroSeconds(x); +} + +void TQuoterService::Bootstrap() { TIntrusivePtr<NMonitoring::TDynamicCounters> counters = GetServiceCounters(AppData()->Counters, QUOTER_SERVICE_COUNTER_SENSOR_NAME); - - Counters.ActiveQuoterProxies = counters->GetCounter("ActiveQuoterProxies", false); - Counters.ActiveProxyResources = counters->GetCounter("ActiveProxyResources", false); - Counters.KnownLocalResources = counters->GetCounter("KnownLocalResources", false); - Counters.RequestsInFly = counters->GetCounter("RequestsInFly", false); - Counters.Requests = counters->GetCounter("Requests", true); - Counters.ResultOk = counters->GetCounter("ResultOk", true); - Counters.ResultDeadline = counters->GetCounter("ResultDeadline", true); - Counters.ResultError = counters->GetCounter("ResultError", true); + + Counters.ActiveQuoterProxies = counters->GetCounter("ActiveQuoterProxies", false); + Counters.ActiveProxyResources = counters->GetCounter("ActiveProxyResources", false); + Counters.KnownLocalResources = counters->GetCounter("KnownLocalResources", false); + Counters.RequestsInFly = counters->GetCounter("RequestsInFly", false); + Counters.Requests = counters->GetCounter("Requests", true); + Counters.ResultOk = counters->GetCounter("ResultOk", true); + Counters.ResultDeadline = counters->GetCounter("ResultDeadline", true); + Counters.ResultError = counters->GetCounter("ResultError", true); Counters.RequestLatency = counters->GetHistogram("RequestLatencyMs", GetLatencyHistogramBuckets()); - + Counters.ServiceCounters = std::move(counters); StaticRatedQuoter.InitCounters(Counters.ServiceCounters); NLwTraceMonPage::ProbeRegistry().AddProbesList(LWTRACE_GET_PROBES(QUOTER_SERVICE_PROVIDER)); - Become(&TThis::StateFunc); -} - + Become(&TThis::StateFunc); +} + void TQuoterService::TryTickSchedule(TInstant now) { - if (!TickScheduled) { - TickScheduled = true; + if (!TickScheduled) { + TickScheduled = true; LastProcessed = TimeToGranularity(now != TInstant::Zero() ? now : TActivationContext::Now()); - Schedule(Config.ScheduleTickSize, new TEvents::TEvWakeup()); - } -} - -void TQuoterService::ReplyRequest(TRequest &request, ui32 reqIdx, TEvQuota::TEvClearance::EResult resultCode) { + Schedule(Config.ScheduleTickSize, new TEvents::TEvWakeup()); + } +} + +void TQuoterService::ReplyRequest(TRequest &request, ui32 reqIdx, TEvQuota::TEvClearance::EResult resultCode) { LWTRACK(RequestDone, request.Orbit, resultCode, request.EventCookie); - Send(request.Source, new TEvQuota::TEvClearance(resultCode), 0, request.EventCookie); - - ForgetRequest(request, reqIdx); -} - -void TQuoterService::ForgetRequest(TRequest &request, ui32 reqIdx) { - // request must be replied - // we must not stop track request while not replied or explicitly canceled + Send(request.Source, new TEvQuota::TEvClearance(resultCode), 0, request.EventCookie); + + ForgetRequest(request, reqIdx); +} + +void TQuoterService::ForgetRequest(TRequest &request, ui32 reqIdx) { + // request must be replied + // we must not stop track request while not replied or explicitly canceled // so only correct entry points are from ReplyRequest or from CancelRequest - - // cleanup from resource wait queue - for (ui32 leafIdx = request.ResourceLeaf; leafIdx != Max<ui32>(); ) { - TResourceLeaf &leaf = ResState.Get(leafIdx); - - switch (leaf.State) { - case EResourceState::Unknown: - case EResourceState::Cleared: - break; - case EResourceState::Wait: - if (leaf.Resource) { - if (leaf.NextInWaitQueue != Max<ui32>()) { - ResState.Get(leaf.NextInWaitQueue).PrevInWaitQueue = leaf.PrevInWaitQueue; - } else { - Y_VERIFY(leaf.Resource->QueueTail == leafIdx); - leaf.Resource->QueueTail = leaf.PrevInWaitQueue; - } - - if (leaf.PrevInWaitQueue != Max<ui32>()) { - ResState.Get(leaf.PrevInWaitQueue).NextInWaitQueue = leaf.NextInWaitQueue; - } else { - Y_VERIFY(leaf.Resource->QueueHead == leafIdx); - leaf.Resource->QueueHead = leaf.NextInWaitQueue; - } - - if (leaf.Resource->QueueHead == Max<ui32>()) { - leaf.Resource->QueueSize = 0; + + // cleanup from resource wait queue + for (ui32 leafIdx = request.ResourceLeaf; leafIdx != Max<ui32>(); ) { + TResourceLeaf &leaf = ResState.Get(leafIdx); + + switch (leaf.State) { + case EResourceState::Unknown: + case EResourceState::Cleared: + break; + case EResourceState::Wait: + if (leaf.Resource) { + if (leaf.NextInWaitQueue != Max<ui32>()) { + ResState.Get(leaf.NextInWaitQueue).PrevInWaitQueue = leaf.PrevInWaitQueue; + } else { + Y_VERIFY(leaf.Resource->QueueTail == leafIdx); + leaf.Resource->QueueTail = leaf.PrevInWaitQueue; + } + + if (leaf.PrevInWaitQueue != Max<ui32>()) { + ResState.Get(leaf.PrevInWaitQueue).NextInWaitQueue = leaf.NextInWaitQueue; + } else { + Y_VERIFY(leaf.Resource->QueueHead == leafIdx); + leaf.Resource->QueueHead = leaf.NextInWaitQueue; + } + + if (leaf.Resource->QueueHead == Max<ui32>()) { + leaf.Resource->QueueSize = 0; leaf.Resource->QueueWeight = 0.0; - } else { - leaf.Resource->QueueSize -= 1; - leaf.Resource->QueueWeight -= leaf.Amount; - } - - // TODO: resource schedule update over new active entry - - leaf.Resource = nullptr; - leaf.PrevInWaitQueue = Max<ui32>(); - leaf.NextInWaitQueue = Max<ui32>(); - } - break; - case EResourceState::ResolveQuoter: - if (TQuoterState *quoter = Quoters.FindPtr(leaf.QuoterId)) - quoter->WaitingQueueResolve.erase(reqIdx); - break; - case EResourceState::ResolveResource: - if (TQuoterState *quoter = Quoters.FindPtr(leaf.QuoterId)) - if (TSet<ui32> *resWaitMap = quoter->WaitingResource.FindPtr(leaf.ResourceName)) - resWaitMap->erase(reqIdx); - break; - } - - leaf.State = EResourceState::Unknown; - leafIdx = leaf.NextResourceLeaf; - } - - ResState.FreeChain(request.ResourceLeaf); - request.ResourceLeaf = Max<ui32>(); - - // cleanup from deadline queue is inside of generic ReqState::Free - ReqState.Free(reqIdx); - - Counters.RequestsInFly->Dec(); -} - -void TQuoterService::DeclineRequest(TRequest &request, ui32 reqIdx) { + } else { + leaf.Resource->QueueSize -= 1; + leaf.Resource->QueueWeight -= leaf.Amount; + } + + // TODO: resource schedule update over new active entry + + leaf.Resource = nullptr; + leaf.PrevInWaitQueue = Max<ui32>(); + leaf.NextInWaitQueue = Max<ui32>(); + } + break; + case EResourceState::ResolveQuoter: + if (TQuoterState *quoter = Quoters.FindPtr(leaf.QuoterId)) + quoter->WaitingQueueResolve.erase(reqIdx); + break; + case EResourceState::ResolveResource: + if (TQuoterState *quoter = Quoters.FindPtr(leaf.QuoterId)) + if (TSet<ui32> *resWaitMap = quoter->WaitingResource.FindPtr(leaf.ResourceName)) + resWaitMap->erase(reqIdx); + break; + } + + leaf.State = EResourceState::Unknown; + leafIdx = leaf.NextResourceLeaf; + } + + ResState.FreeChain(request.ResourceLeaf); + request.ResourceLeaf = Max<ui32>(); + + // cleanup from deadline queue is inside of generic ReqState::Free + ReqState.Free(reqIdx); + + Counters.RequestsInFly->Dec(); +} + +void TQuoterService::DeclineRequest(TRequest &request, ui32 reqIdx) { Counters.ResultError->Inc(); - - return ReplyRequest(request, reqIdx, TEvQuota::TEvClearance::EResult::UnknownResource); -} - + + return ReplyRequest(request, reqIdx, TEvQuota::TEvClearance::EResult::UnknownResource); +} + void TQuoterService::FailRequest(TRequest &request, ui32 reqIdx) { Counters.ResultError->Inc(); return ReplyRequest(request, reqIdx, TEvQuota::TEvClearance::EResult::GenericError); } -void TQuoterService::AllowRequest(TRequest &request, ui32 reqIdx) { - Counters.ResultOk->Inc(); +void TQuoterService::AllowRequest(TRequest &request, ui32 reqIdx) { + Counters.ResultOk->Inc(); Counters.RequestLatency->Collect((TActivationContext::Now() - request.StartTime).MilliSeconds()); - - return ReplyRequest(request, reqIdx, TEvQuota::TEvClearance::EResult::Success); -} - -void TQuoterService::DeadlineRequest(TRequest &request, ui32 reqIdx) { + + return ReplyRequest(request, reqIdx, TEvQuota::TEvClearance::EResult::Success); +} + +void TQuoterService::DeadlineRequest(TRequest &request, ui32 reqIdx) { Counters.ResultDeadline->Inc(); - - return ReplyRequest(request, reqIdx, TEvQuota::TEvClearance::EResult::Deadline); -} - -TQuoterService::EInitLeafStatus TQuoterService::InitSystemLeaf(const TEvQuota::TResourceLeaf &leaf, TRequest &request, ui32 reqIdx) { - if (leaf.ResourceId == TEvQuota::TResourceLeaf::ResourceForbid) { - return EInitLeafStatus::Forbid; - } - - if (leaf.ResourceId == TEvQuota::TResourceLeaf::ResourceNocheck) { - // do nothing, always allow - return EInitLeafStatus::Charged; - } - - if ((leaf.ResourceId & (0x3ULL << 62)) == (1ULL << 62)) { - // static rated resource - const ui32 rate = (leaf.ResourceId & 0x3FFFFFFF); + + return ReplyRequest(request, reqIdx, TEvQuota::TEvClearance::EResult::Deadline); +} + +TQuoterService::EInitLeafStatus TQuoterService::InitSystemLeaf(const TEvQuota::TResourceLeaf &leaf, TRequest &request, ui32 reqIdx) { + if (leaf.ResourceId == TEvQuota::TResourceLeaf::ResourceForbid) { + return EInitLeafStatus::Forbid; + } + + if (leaf.ResourceId == TEvQuota::TResourceLeaf::ResourceNocheck) { + // do nothing, always allow + return EInitLeafStatus::Charged; + } + + if ((leaf.ResourceId & (0x3ULL << 62)) == (1ULL << 62)) { + // static rated resource + const ui32 rate = (leaf.ResourceId & 0x3FFFFFFF); auto &quores = StaticRatedQuoter.GetOrCreate(leaf.QuoterId, leaf.ResourceId, TString(), TString(), Config); - if (quores.LastAllocated == TInstant::Max()) { - Counters.KnownLocalResources->Inc(); - - quores.NextTick = TInstant::Zero(); - quores.LastTick = TInstant::Zero(); - - quores.QueueHead = Max<ui32>(); - quores.QueueTail = Max<ui32>(); - - quores.LastAllocated = TInstant::Zero(); + if (quores.LastAllocated == TInstant::Max()) { + Counters.KnownLocalResources->Inc(); + + quores.NextTick = TInstant::Zero(); + quores.LastTick = TInstant::Zero(); + + quores.QueueHead = Max<ui32>(); + quores.QueueTail = Max<ui32>(); + + quores.LastAllocated = TInstant::Zero(); quores.AmountConsumed = 0.0; // NOTE: do not change `History`: we dont need it for static rate - + quores.FreeBalance = 0.0; quores.TickRate = static_cast<double>(rate); - quores.Balance = quores.TickRate; - - quores.TickSize = TDuration::Seconds(1); - quores.StatUpdatePolicy = EStatUpdatePolicy::Never; - - quores.ApplyQuotaChannel(TEvQuota::TUpdateTick(0, Max<ui32>(), rate, TEvQuota::ETickPolicy::Ahead)); - FeedResource(quores); - } - - if (quores.NextTick == TInstant::Zero()) { - ScheduleNextTick(TActivationContext::Now(), quores); - } - - return TryCharge(quores, TEvQuota::TResourceLeaf::QuoterSystem, QuoterIdCounter, leaf, request, reqIdx); - } - - return EInitLeafStatus::Unknown; -} - -TQuoterService::EInitLeafStatus TQuoterService::InitResourceLeaf(const TEvQuota::TResourceLeaf &leaf, TRequest &request, ui32 reqIdx) { - // resolve quoter - ui64 quoterId = leaf.QuoterId; - TQuoterState *quoter = quoterId ? Quoters.FindPtr(quoterId) : nullptr; - if (quoter == nullptr) { - if (!leaf.Quoter) + quores.Balance = quores.TickRate; + + quores.TickSize = TDuration::Seconds(1); + quores.StatUpdatePolicy = EStatUpdatePolicy::Never; + + quores.ApplyQuotaChannel(TEvQuota::TUpdateTick(0, Max<ui32>(), rate, TEvQuota::ETickPolicy::Ahead)); + FeedResource(quores); + } + + if (quores.NextTick == TInstant::Zero()) { + ScheduleNextTick(TActivationContext::Now(), quores); + } + + return TryCharge(quores, TEvQuota::TResourceLeaf::QuoterSystem, QuoterIdCounter, leaf, request, reqIdx); + } + + return EInitLeafStatus::Unknown; +} + +TQuoterService::EInitLeafStatus TQuoterService::InitResourceLeaf(const TEvQuota::TResourceLeaf &leaf, TRequest &request, ui32 reqIdx) { + // resolve quoter + ui64 quoterId = leaf.QuoterId; + TQuoterState *quoter = quoterId ? Quoters.FindPtr(quoterId) : nullptr; + if (quoter == nullptr) { + if (!leaf.Quoter) return EInitLeafStatus::GenericError; - - auto qIndxIt = QuotersIndex.find(leaf.Quoter); - if (qIndxIt == QuotersIndex.end()) { - TVector<TString> path = NKikimr::SplitPath(leaf.Quoter); + + auto qIndxIt = QuotersIndex.find(leaf.Quoter); + if (qIndxIt == QuotersIndex.end()) { + TVector<TString> path = NKikimr::SplitPath(leaf.Quoter); if (path.empty()) { BLOG_WARN("Empty path to quoter is provided: \"" << leaf.Quoter << "\""); return EInitLeafStatus::GenericError; } - + if (CanonizePath(path) != leaf.Quoter) { BLOG_WARN("Not canonized path to quoter is provided. Provided: \"" << leaf.Quoter << "\", but canonized is \"" << CanonizePath(path) << "\""); return EInitLeafStatus::GenericError; } - - quoterId = ++QuoterIdCounter; - QuotersIndex.emplace(leaf.Quoter, quoterId); - + + quoterId = ++QuoterIdCounter; + QuotersIndex.emplace(leaf.Quoter, quoterId); + quoter = &Quoters.emplace(quoterId, TQuoterState(leaf.Quoter, Counters.ServiceCounters)).first->second; - Counters.ActiveQuoterProxies->Inc(); - - THolder<NSchemeCache::TSchemeCacheNavigate> req(new NSchemeCache::TSchemeCacheNavigate()); - req->ResultSet.emplace_back(); - req->ResultSet.back().Path.swap(path); - req->ResultSet.back().Operation = NSchemeCache::TSchemeCacheNavigate::OpPath; - Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(req), IEventHandle::FlagTrackDelivery, 0); - - BLOG_I("resolve new quoter " << leaf.Quoter); - } else { - // ok, got quoterId, proceed - quoterId = qIndxIt->second; - quoter = Quoters.FindPtr(quoterId); - Y_VERIFY(quoter != nullptr); - } - } - - if (!quoter->ProxyId) { - quoter->WaitingQueueResolve.emplace(reqIdx); - - // todo: make generic 'leaf for resolve' helper + Counters.ActiveQuoterProxies->Inc(); + + THolder<NSchemeCache::TSchemeCacheNavigate> req(new NSchemeCache::TSchemeCacheNavigate()); + req->ResultSet.emplace_back(); + req->ResultSet.back().Path.swap(path); + req->ResultSet.back().Operation = NSchemeCache::TSchemeCacheNavigate::OpPath; + Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(req), IEventHandle::FlagTrackDelivery, 0); + + BLOG_I("resolve new quoter " << leaf.Quoter); + } else { + // ok, got quoterId, proceed + quoterId = qIndxIt->second; + quoter = Quoters.FindPtr(quoterId); + Y_VERIFY(quoter != nullptr); + } + } + + if (!quoter->ProxyId) { + quoter->WaitingQueueResolve.emplace(reqIdx); + + // todo: make generic 'leaf for resolve' helper const ui32 resLeafIdx = ResState.Allocate(nullptr, leaf.Amount, leaf.IsUsedAmount, reqIdx); - TResourceLeaf& resLeaf = ResState.Get(resLeafIdx); - - resLeaf.QuoterId = quoterId; - resLeaf.QuoterName = leaf.Quoter; - resLeaf.ResourceId = leaf.ResourceId; - resLeaf.ResourceName = leaf.Resource; - - resLeaf.NextResourceLeaf = request.ResourceLeaf; - request.ResourceLeaf = resLeafIdx; - - resLeaf.State = EResourceState::ResolveQuoter; - - return EInitLeafStatus::Wait; - } - - ui64 resourceId = leaf.ResourceId; - THolder<TResource> *resHolder = leaf.ResourceId ? quoter->Resources.FindPtr(resourceId) : nullptr; - if (resHolder == nullptr) { - if (!leaf.Resource) + TResourceLeaf& resLeaf = ResState.Get(resLeafIdx); + + resLeaf.QuoterId = quoterId; + resLeaf.QuoterName = leaf.Quoter; + resLeaf.ResourceId = leaf.ResourceId; + resLeaf.ResourceName = leaf.Resource; + + resLeaf.NextResourceLeaf = request.ResourceLeaf; + request.ResourceLeaf = resLeafIdx; + + resLeaf.State = EResourceState::ResolveQuoter; + + return EInitLeafStatus::Wait; + } + + ui64 resourceId = leaf.ResourceId; + THolder<TResource> *resHolder = leaf.ResourceId ? quoter->Resources.FindPtr(resourceId) : nullptr; + if (resHolder == nullptr) { + if (!leaf.Resource) return EInitLeafStatus::GenericError; - - if (const ui64 *rsId = quoter->ResourcesIndex.FindPtr(leaf.Resource)) { - resourceId = *rsId; - resHolder = quoter->Resources.FindPtr(resourceId); - } - - if (resHolder == nullptr) { - auto rIndxIt = quoter->WaitingResource.emplace(leaf.Resource, TSet<ui32>()); - rIndxIt.first->second.emplace(reqIdx); - + + if (const ui64 *rsId = quoter->ResourcesIndex.FindPtr(leaf.Resource)) { + resourceId = *rsId; + resHolder = quoter->Resources.FindPtr(resourceId); + } + + if (resHolder == nullptr) { + auto rIndxIt = quoter->WaitingResource.emplace(leaf.Resource, TSet<ui32>()); + rIndxIt.first->second.emplace(reqIdx); + const ui32 resLeafIdx = ResState.Allocate(nullptr, leaf.Amount, leaf.IsUsedAmount, reqIdx); - TResourceLeaf& resLeaf = ResState.Get(resLeafIdx); - - resLeaf.QuoterId = quoterId; - resLeaf.QuoterName = leaf.Quoter; - resLeaf.ResourceId = leaf.ResourceId; - resLeaf.ResourceName = leaf.Resource; - - resLeaf.NextResourceLeaf = request.ResourceLeaf; - request.ResourceLeaf = resLeafIdx; - - resLeaf.State = EResourceState::ResolveResource; - - if (rIndxIt.second) { // new resource, create resource session - BLOG_I("resolve resource " << resLeaf.ResourceName << " on quoter " << quoter->QuoterName); - Send(quoter->ProxyId, new TEvQuota::TEvProxyRequest(resLeaf.ResourceName)); - } - - return EInitLeafStatus::Wait; - } - } - + TResourceLeaf& resLeaf = ResState.Get(resLeafIdx); + + resLeaf.QuoterId = quoterId; + resLeaf.QuoterName = leaf.Quoter; + resLeaf.ResourceId = leaf.ResourceId; + resLeaf.ResourceName = leaf.Resource; + + resLeaf.NextResourceLeaf = request.ResourceLeaf; + request.ResourceLeaf = resLeafIdx; + + resLeaf.State = EResourceState::ResolveResource; + + if (rIndxIt.second) { // new resource, create resource session + BLOG_I("resolve resource " << resLeaf.ResourceName << " on quoter " << quoter->QuoterName); + Send(quoter->ProxyId, new TEvQuota::TEvProxyRequest(resLeaf.ResourceName)); + } + + return EInitLeafStatus::Wait; + } + } + if ((*resHolder)->NextTick == TInstant::Zero()) { ScheduleNextTick(TActivationContext::Now(), **resHolder); } - // ok, got resource - const EInitLeafStatus chargeResult = TryCharge(**resHolder, quoterId, resourceId, leaf, request, reqIdx); - - switch (resHolder->Get()->StatUpdatePolicy) { + // ok, got resource + const EInitLeafStatus chargeResult = TryCharge(**resHolder, quoterId, resourceId, leaf, request, reqIdx); + + switch (resHolder->Get()->StatUpdatePolicy) { case EStatUpdatePolicy::EveryTick: case EStatUpdatePolicy::EveryActiveTick: - case EStatUpdatePolicy::OnActivity: - FillStats(**resHolder); - break; - default: - break; - } - - return chargeResult; -} - -void TQuoterService::MarkScheduleAllocation(TResource& quores, TDuration delay, TInstant now) { + case EStatUpdatePolicy::OnActivity: + FillStats(**resHolder); + break; + default: + break; + } + + return chargeResult; +} + +void TQuoterService::MarkScheduleAllocation(TResource& quores, TDuration delay, TInstant now) { TryTickSchedule(now); - Y_VERIFY(quores.NextTick != TInstant::Zero() && quores.NextTick != TInstant::Max()); - Y_VERIFY(delay > TDuration::Zero()); - - if (delay == TDuration::Max()) { - if (quores.Activation) { - ScheduleAllocation[quores.Activation].erase(&quores); - quores.Activation = TInstant::Zero(); - } - - return; - } - - const TInstant newActivation = TimeToGranularity(now + delay); - if (quores.Activation && quores.Activation != newActivation) { - ScheduleAllocation[quores.Activation].erase(&quores); - quores.Activation = TInstant::Zero(); - } - - if (newActivation < quores.NextTick) { - ScheduleAllocation[newActivation].emplace(&quores); - quores.Activation = newActivation; - } -} - -TQuoterService::EInitLeafStatus TQuoterService::TryCharge(TResource& quores, ui64 quoterId, ui64 resourceId, const TEvQuota::TResourceLeaf &leaf, TRequest &request, ui32 reqIdx) { + Y_VERIFY(quores.NextTick != TInstant::Zero() && quores.NextTick != TInstant::Max()); + Y_VERIFY(delay > TDuration::Zero()); + + if (delay == TDuration::Max()) { + if (quores.Activation) { + ScheduleAllocation[quores.Activation].erase(&quores); + quores.Activation = TInstant::Zero(); + } + + return; + } + + const TInstant newActivation = TimeToGranularity(now + delay); + if (quores.Activation && quores.Activation != newActivation) { + ScheduleAllocation[quores.Activation].erase(&quores); + quores.Activation = TInstant::Zero(); + } + + if (newActivation < quores.NextTick) { + ScheduleAllocation[newActivation].emplace(&quores); + quores.Activation = newActivation; + } +} + +TQuoterService::EInitLeafStatus TQuoterService::TryCharge(TResource& quores, ui64 quoterId, ui64 resourceId, const TEvQuota::TResourceLeaf &leaf, TRequest &request, ui32 reqIdx) { *quores.Counters.Requested += leaf.Amount; ++*quores.Counters.RequestsCount; @@ -703,207 +703,207 @@ TQuoterService::EInitLeafStatus TQuoterService::TryCharge(TResource& quores, ui6 if (quores.QueueSize == 0) { startedCharge = true; const TDuration delay = quores.Charge(leaf.Amount, now); - + if (delay == TDuration::Zero()) { LWTRACK(StartCharging, request.Orbit, leaf.Quoter, leaf.Resource, leaf.QuoterId, leaf.ResourceId); quores.Counters.RequestTime->Collect((now - request.StartTime).MilliSeconds()); return EInitLeafStatus::Charged; } - MarkScheduleAllocation(quores, delay, now); - } - - // need wait entry for resource + MarkScheduleAllocation(quores, delay, now); + } + + // need wait entry for resource const ui32 resLeafIdx = ResState.Allocate(&quores, leaf.Amount, leaf.IsUsedAmount, reqIdx); - TResourceLeaf& resLeaf = ResState.Get(resLeafIdx); - - resLeaf.State = EResourceState::Wait; + TResourceLeaf& resLeaf = ResState.Get(resLeafIdx); + + resLeaf.State = EResourceState::Wait; if (startedCharge) { quores.MarkStartedCharging(request, resLeaf, now); } else { resLeaf.StartQueueing = now; } - - quores.QueueSize += 1; - quores.QueueWeight += leaf.Amount; - - resLeaf.QuoterId = quoterId; - resLeaf.QuoterName = leaf.Quoter; - resLeaf.ResourceId = resourceId; - resLeaf.ResourceName = leaf.Resource; - - if (quores.QueueTail == Max<ui32>()) { - quores.QueueTail = resLeafIdx; - quores.QueueHead = resLeafIdx; - } else { + + quores.QueueSize += 1; + quores.QueueWeight += leaf.Amount; + + resLeaf.QuoterId = quoterId; + resLeaf.QuoterName = leaf.Quoter; + resLeaf.ResourceId = resourceId; + resLeaf.ResourceName = leaf.Resource; + + if (quores.QueueTail == Max<ui32>()) { + quores.QueueTail = resLeafIdx; + quores.QueueHead = resLeafIdx; + } else { Y_VERIFY_DEBUG(ResState.Get(quores.QueueTail).NextInWaitQueue == Max<ui32>()); - resLeaf.PrevInWaitQueue = quores.QueueTail; - ResState.Get(quores.QueueTail).NextInWaitQueue = resLeafIdx; + resLeaf.PrevInWaitQueue = quores.QueueTail; + ResState.Get(quores.QueueTail).NextInWaitQueue = resLeafIdx; quores.QueueTail = resLeafIdx; - } - - resLeaf.NextResourceLeaf = request.ResourceLeaf; - request.ResourceLeaf = resLeafIdx; - - return EInitLeafStatus::Wait; -} - -void TQuoterService::InitialRequestProcessing(TEvQuota::TEvRequest::TPtr &ev, const ui32 reqIdx) { - TryTickSchedule(); - - TEvQuota::TEvRequest *msg = ev->Get(); - TRequest &request = ReqState.Get(reqIdx); - - request.Operator = msg->Operator; - request.Deadline = TInstant::Max(); - Y_VERIFY(request.Operator == EResourceOperator::And); // todo: support other modes - - Y_VERIFY(msg->Reqs.size() >= 1); - bool canAllow = true; - for (const auto &leaf : msg->Reqs) { + } + + resLeaf.NextResourceLeaf = request.ResourceLeaf; + request.ResourceLeaf = resLeafIdx; + + return EInitLeafStatus::Wait; +} + +void TQuoterService::InitialRequestProcessing(TEvQuota::TEvRequest::TPtr &ev, const ui32 reqIdx) { + TryTickSchedule(); + + TEvQuota::TEvRequest *msg = ev->Get(); + TRequest &request = ReqState.Get(reqIdx); + + request.Operator = msg->Operator; + request.Deadline = TInstant::Max(); + Y_VERIFY(request.Operator == EResourceOperator::And); // todo: support other modes + + Y_VERIFY(msg->Reqs.size() >= 1); + bool canAllow = true; + for (const auto &leaf : msg->Reqs) { LWTRACK(RequestResource, request.Orbit, leaf.Amount, leaf.Quoter, leaf.Resource, leaf.QuoterId, leaf.ResourceId); - const EInitLeafStatus initLeafStatus = - (leaf.QuoterId == TEvQuota::TResourceLeaf::QuoterSystem) ? - InitSystemLeaf(leaf, request, reqIdx) : - InitResourceLeaf(leaf, request, reqIdx); - - switch (initLeafStatus) { - case EInitLeafStatus::Unknown: - return DeclineRequest(request, reqIdx); + const EInitLeafStatus initLeafStatus = + (leaf.QuoterId == TEvQuota::TResourceLeaf::QuoterSystem) ? + InitSystemLeaf(leaf, request, reqIdx) : + InitResourceLeaf(leaf, request, reqIdx); + + switch (initLeafStatus) { + case EInitLeafStatus::Unknown: + return DeclineRequest(request, reqIdx); case EInitLeafStatus::GenericError: return FailRequest(request, reqIdx); - case EInitLeafStatus::Forbid: - return DeadlineRequest(request, reqIdx); - case EInitLeafStatus::Charged: - break; - case EInitLeafStatus::Wait: - canAllow = false; - break; - default: - Y_FAIL("unkown initLeafStatus"); - } - } - - if (canAllow) { - Y_VERIFY(request.ResourceLeaf == Max<ui32>()); - return AllowRequest(request, reqIdx); - } - - if (msg->Deadline != TDuration::Max()) { - const TDuration delay = Min(TDuration::Days(1), msg->Deadline); + case EInitLeafStatus::Forbid: + return DeadlineRequest(request, reqIdx); + case EInitLeafStatus::Charged: + break; + case EInitLeafStatus::Wait: + canAllow = false; + break; + default: + Y_FAIL("unkown initLeafStatus"); + } + } + + if (canAllow) { + Y_VERIFY(request.ResourceLeaf == Max<ui32>()); + return AllowRequest(request, reqIdx); + } + + if (msg->Deadline != TDuration::Max()) { + const TDuration delay = Min(TDuration::Days(1), msg->Deadline); const TInstant now = TActivationContext::Now(); TryTickSchedule(now); request.Deadline = TimeToGranularity(now + delay); - - auto deadlineIt = ScheduleDeadline.find(request.Deadline); - if (deadlineIt == ScheduleDeadline.end()) { - TInstant deadline = request.Deadline; // allocate could invalidate request& + + auto deadlineIt = ScheduleDeadline.find(request.Deadline); + if (deadlineIt == ScheduleDeadline.end()) { + TInstant deadline = request.Deadline; // allocate could invalidate request& deadlineIt = ScheduleDeadline.emplace(deadline, ReqState.Allocate(TActorId(0, "placeholder"), 0)).first; - } - - const ui32 placeholderIdx = deadlineIt->second; - TRequest &placeholder = ReqState.Get(placeholderIdx); - TRequest &reqq = ReqState.Get(reqIdx); - - if (placeholder.NextDeadlineRequest != Max<ui32>()) { - reqq.NextDeadlineRequest = placeholder.NextDeadlineRequest; - ReqState.Get(placeholder.NextDeadlineRequest).PrevDeadlineRequest = reqIdx; - } - reqq.PrevDeadlineRequest = placeholderIdx; - placeholder.NextDeadlineRequest = reqIdx; - } -} - -void TQuoterService::Handle(TEvQuota::TEvRequest::TPtr &ev) { + } + + const ui32 placeholderIdx = deadlineIt->second; + TRequest &placeholder = ReqState.Get(placeholderIdx); + TRequest &reqq = ReqState.Get(reqIdx); + + if (placeholder.NextDeadlineRequest != Max<ui32>()) { + reqq.NextDeadlineRequest = placeholder.NextDeadlineRequest; + ReqState.Get(placeholder.NextDeadlineRequest).PrevDeadlineRequest = reqIdx; + } + reqq.PrevDeadlineRequest = placeholderIdx; + placeholder.NextDeadlineRequest = reqIdx; + } +} + +void TQuoterService::Handle(TEvQuota::TEvRequest::TPtr &ev) { BLOG_T("Request(" << PrintEvent(ev) << ")"); - Counters.RequestsInFly->Inc(); - Counters.Requests->Inc(); - - TEvQuota::TEvRequest *msg = ev->Get(); - const ui32 reqIdx = ReqState.Allocate(ev->Sender, ev->Cookie); - TRequest &request = ReqState.Get(reqIdx); + Counters.RequestsInFly->Inc(); + Counters.Requests->Inc(); + + TEvQuota::TEvRequest *msg = ev->Get(); + const ui32 reqIdx = ReqState.Allocate(ev->Sender, ev->Cookie); + TRequest &request = ReqState.Get(reqIdx); LWTRACK(StartRequest, request.Orbit, msg->Operator, msg->Deadline, ev->Cookie); - - if (msg->Reqs.empty()) // request nothing? most probably is error so decline - return DeclineRequest(request, reqIdx); - - // dirty processing of simple embedded resources - if (msg->Reqs.size() == 1) { + + if (msg->Reqs.empty()) // request nothing? most probably is error so decline + return DeclineRequest(request, reqIdx); + + // dirty processing of simple embedded resources + if (msg->Reqs.size() == 1) { const TEvQuota::TResourceLeaf &leaf = msg->Reqs[0]; - switch (msg->Operator) { - case EResourceOperator::And: - // only one case supported right now - { - if (leaf.QuoterId == TEvQuota::TResourceLeaf::QuoterSystem) { - switch (leaf.ResourceId) { - case TEvQuota::TResourceLeaf::ResourceForbid: + switch (msg->Operator) { + case EResourceOperator::And: + // only one case supported right now + { + if (leaf.QuoterId == TEvQuota::TResourceLeaf::QuoterSystem) { + switch (leaf.ResourceId) { + case TEvQuota::TResourceLeaf::ResourceForbid: LWTRACK(RequestResource, request.Orbit, leaf.Amount, leaf.Quoter, leaf.Resource, leaf.QuoterId, leaf.ResourceId); - return DeadlineRequest(request, reqIdx); - case TEvQuota::TResourceLeaf::ResourceNocheck: + return DeadlineRequest(request, reqIdx); + case TEvQuota::TResourceLeaf::ResourceNocheck: LWTRACK(RequestResource, request.Orbit, leaf.Amount, leaf.Quoter, leaf.Resource, leaf.QuoterId, leaf.ResourceId); - return AllowRequest(request, reqIdx); - } - } - } - break; - // not supported yet modes - default: + return AllowRequest(request, reqIdx); + } + } + } + break; + // not supported yet modes + default: LWTRACK(RequestResource, request.Orbit, leaf.Amount, leaf.Quoter, leaf.Resource, leaf.QuoterId, leaf.ResourceId); - return DeclineRequest(request, reqIdx); - } - } - // ok, simple processing failed, make full processing - InitialRequestProcessing(ev, reqIdx); -} - -void TQuoterService::Handle(TEvQuota::TEvCancelRequest::TPtr &ev) { - const ui64 cookie = ev->Cookie; - - const ui32 headByOwner = ReqState.HeadByOwner(ev->Sender); - if (headByOwner == Max<ui32>()) - return; - - TRequest &headRequest = ReqState.Get(headByOwner); - - ui32 nextReqIdx = headRequest.NextByOwner; - while (nextReqIdx != Max<ui32>()) { - const ui32 reqIdx = nextReqIdx; - TRequest &req = ReqState.Get(nextReqIdx); - nextReqIdx = req.NextByOwner; - - if (cookie == 0 || req.EventCookie == cookie) - ForgetRequest(req, reqIdx); - } - - if (cookie == 0 || headRequest.EventCookie == cookie) - ForgetRequest(headRequest, headByOwner); -} - -void TQuoterService::Handle(TEvQuota::TEvProxySession::TPtr &ev) { - TEvQuota::TEvProxySession *msg = ev->Get(); - - const ui64 quoterId = msg->QuoterId; - const TString &resourceName = msg->Resource; - - auto quoterIt = Quoters.find(quoterId); - if (quoterIt == Quoters.end()) - return; - - TQuoterState "er = quoterIt->second; - if (quoter.ProxyId != ev->Sender) - return; - - auto resIt = quoter.WaitingResource.find(resourceName); - Y_VERIFY(resIt != quoter.WaitingResource.end()); - - TSet<ui32> waitingRequests = std::move(resIt->second); - quoter.WaitingResource.erase(resIt); - - const bool isError = msg->Result != msg->Success; - if (isError) { - BLOG_I("resource sesson failed: " << quoter.QuoterName << ":" << resourceName); - + return DeclineRequest(request, reqIdx); + } + } + // ok, simple processing failed, make full processing + InitialRequestProcessing(ev, reqIdx); +} + +void TQuoterService::Handle(TEvQuota::TEvCancelRequest::TPtr &ev) { + const ui64 cookie = ev->Cookie; + + const ui32 headByOwner = ReqState.HeadByOwner(ev->Sender); + if (headByOwner == Max<ui32>()) + return; + + TRequest &headRequest = ReqState.Get(headByOwner); + + ui32 nextReqIdx = headRequest.NextByOwner; + while (nextReqIdx != Max<ui32>()) { + const ui32 reqIdx = nextReqIdx; + TRequest &req = ReqState.Get(nextReqIdx); + nextReqIdx = req.NextByOwner; + + if (cookie == 0 || req.EventCookie == cookie) + ForgetRequest(req, reqIdx); + } + + if (cookie == 0 || headRequest.EventCookie == cookie) + ForgetRequest(headRequest, headByOwner); +} + +void TQuoterService::Handle(TEvQuota::TEvProxySession::TPtr &ev) { + TEvQuota::TEvProxySession *msg = ev->Get(); + + const ui64 quoterId = msg->QuoterId; + const TString &resourceName = msg->Resource; + + auto quoterIt = Quoters.find(quoterId); + if (quoterIt == Quoters.end()) + return; + + TQuoterState "er = quoterIt->second; + if (quoter.ProxyId != ev->Sender) + return; + + auto resIt = quoter.WaitingResource.find(resourceName); + Y_VERIFY(resIt != quoter.WaitingResource.end()); + + TSet<ui32> waitingRequests = std::move(resIt->second); + quoter.WaitingResource.erase(resIt); + + const bool isError = msg->Result != msg->Success; + if (isError) { + BLOG_I("resource sesson failed: " << quoter.QuoterName << ":" << resourceName); + for (ui32 reqIdx : waitingRequests) { if (msg->Result == TEvQuota::TEvProxySession::UnknownResource) { DeclineRequest(ReqState.Get(reqIdx), reqIdx); @@ -911,301 +911,301 @@ void TQuoterService::Handle(TEvQuota::TEvProxySession::TPtr &ev) { FailRequest(ReqState.Get(reqIdx), reqIdx); } } - - return; - } - - const ui64 resourceId = msg->ResourceId; - - BLOG_I("resource session established: " << quoter.QuoterName << ":" << resourceName << " as " << resourceId); - - // success, create resource + + return; + } + + const ui64 resourceId = msg->ResourceId; + + BLOG_I("resource session established: " << quoter.QuoterName << ":" << resourceName << " as " << resourceId); + + // success, create resource auto resPairIt = quoter.Resources.emplace(resourceId, new TResource(quoterId, resourceId, quoter.QuoterName, resourceName, Config, quoter.Counters.QuoterCounters)); - Y_VERIFY(resPairIt.second, "must be no duplicating resources"); - quoter.ResourcesIndex.emplace(resourceName, resourceId); - - Counters.ActiveProxyResources->Inc(); - - TResource &quores = *resPairIt.first->second; - quores.TickSize = msg->TickSize; - quores.StatUpdatePolicy = msg->StatUpdatePolicy; + Y_VERIFY(resPairIt.second, "must be no duplicating resources"); + quoter.ResourcesIndex.emplace(resourceName, resourceId); + + Counters.ActiveProxyResources->Inc(); + + TResource &quores = *resPairIt.first->second; + quores.TickSize = msg->TickSize; + quores.StatUpdatePolicy = msg->StatUpdatePolicy; quores.LastAllocated = TInstant::Zero(); - - // move requests to 'wait resource' state - for (ui32 reqId : waitingRequests) { - TRequest &req = ReqState.Get(reqId); - ui32 resIdx = req.ResourceLeaf; - while (resIdx != Max<ui32>()) { - TResourceLeaf &leaf = ResState.Get(resIdx); - Y_VERIFY(leaf.RequestIdx == reqId); - if (leaf.State == EResourceState::ResolveResource - && leaf.QuoterId == quoterId - && leaf.ResourceName == resourceName) - { - leaf.Resource = &quores; - leaf.State = EResourceState::Wait; - leaf.ResourceId = resourceId; - - quores.QueueSize += 1; - quores.QueueWeight += leaf.Amount; + + // move requests to 'wait resource' state + for (ui32 reqId : waitingRequests) { + TRequest &req = ReqState.Get(reqId); + ui32 resIdx = req.ResourceLeaf; + while (resIdx != Max<ui32>()) { + TResourceLeaf &leaf = ResState.Get(resIdx); + Y_VERIFY(leaf.RequestIdx == reqId); + if (leaf.State == EResourceState::ResolveResource + && leaf.QuoterId == quoterId + && leaf.ResourceName == resourceName) + { + leaf.Resource = &quores; + leaf.State = EResourceState::Wait; + leaf.ResourceId = resourceId; + + quores.QueueSize += 1; + quores.QueueWeight += leaf.Amount; quores.Counters.Requested->Add(leaf.Amount); - - if (quores.QueueTail == Max<ui32>()) { - quores.QueueTail = resIdx; - quores.QueueHead = resIdx; - } else { + + if (quores.QueueTail == Max<ui32>()) { + quores.QueueTail = resIdx; + quores.QueueHead = resIdx; + } else { Y_VERIFY_DEBUG(ResState.Get(quores.QueueTail).NextInWaitQueue == Max<ui32>()); - leaf.PrevInWaitQueue = quores.QueueTail; - ResState.Get(quores.QueueTail).NextInWaitQueue = resIdx; + leaf.PrevInWaitQueue = quores.QueueTail; + ResState.Get(quores.QueueTail).NextInWaitQueue = resIdx; quores.QueueTail = resIdx; - } - } - // initial charge would be in first session update - resIdx = leaf.NextResourceLeaf; - } - } - - switch (quores.StatUpdatePolicy) { - case EStatUpdatePolicy::OnActivity: - if (quores.QueueSize > 0) - FillStats(quores); - break; - case EStatUpdatePolicy::Never: - case EStatUpdatePolicy::EveryTick: - case EStatUpdatePolicy::EveryActiveTick: - break; - default: - Y_FAIL("not implemented"); - } -} - -void TQuoterService::Handle(TEvQuota::TEvProxyUpdate::TPtr &ev) { - TEvQuota::TEvProxyUpdate *msg = ev->Get(); - const ui64 quoterId = msg->QuoterId; - auto quoterIt = Quoters.find(quoterId); - if (quoterIt == Quoters.end()) - return; - - TQuoterState "er = quoterIt->second; - if (quoter.ProxyId != ev->Sender) - return; - - if (msg->QuoterState == EUpdateState::Broken || (msg->QuoterState == EUpdateState::Evict && quoter.Empty())) { - BLOG_I("closing quoter on ProxyUpdate " << quoter.QuoterName); - return BreakQuoter(quoterIt); - } - - BLOG_D("ProxyUpdate for quoter " << quoter.QuoterName); - - for (auto &resUpdate : msg->Resources) { - auto resourceIt = quoter.Resources.find(resUpdate.ResourceId); - if (resourceIt == quoter.Resources.end()) - continue; - - TResource &quores = *resourceIt->second; - - if (resUpdate.ResourceState == EUpdateState::Broken - || (resUpdate.ResourceState == EUpdateState::Evict && quores.QueueHead == Max<ui32>())) - { + } + } + // initial charge would be in first session update + resIdx = leaf.NextResourceLeaf; + } + } + + switch (quores.StatUpdatePolicy) { + case EStatUpdatePolicy::OnActivity: + if (quores.QueueSize > 0) + FillStats(quores); + break; + case EStatUpdatePolicy::Never: + case EStatUpdatePolicy::EveryTick: + case EStatUpdatePolicy::EveryActiveTick: + break; + default: + Y_FAIL("not implemented"); + } +} + +void TQuoterService::Handle(TEvQuota::TEvProxyUpdate::TPtr &ev) { + TEvQuota::TEvProxyUpdate *msg = ev->Get(); + const ui64 quoterId = msg->QuoterId; + auto quoterIt = Quoters.find(quoterId); + if (quoterIt == Quoters.end()) + return; + + TQuoterState "er = quoterIt->second; + if (quoter.ProxyId != ev->Sender) + return; + + if (msg->QuoterState == EUpdateState::Broken || (msg->QuoterState == EUpdateState::Evict && quoter.Empty())) { + BLOG_I("closing quoter on ProxyUpdate " << quoter.QuoterName); + return BreakQuoter(quoterIt); + } + + BLOG_D("ProxyUpdate for quoter " << quoter.QuoterName); + + for (auto &resUpdate : msg->Resources) { + auto resourceIt = quoter.Resources.find(resUpdate.ResourceId); + if (resourceIt == quoter.Resources.end()) + continue; + + TResource &quores = *resourceIt->second; + + if (resUpdate.ResourceState == EUpdateState::Broken + || (resUpdate.ResourceState == EUpdateState::Evict && quores.QueueHead == Max<ui32>())) + { BLOG_I("closing resource on ProxyUpdate " << quoter.QuoterName << ":" << quores.Resource); - Send(quoter.ProxyId, new TEvQuota::TEvProxyCloseSession(quores.Resource, quores.ResourceId)); - - ForbidResource(quores); - quoter.ResourcesIndex.erase(quores.Resource); - quoter.Resources.erase(resourceIt); - continue; - } - - for (auto &update : resUpdate.Update) { + Send(quoter.ProxyId, new TEvQuota::TEvProxyCloseSession(quores.Resource, quores.ResourceId)); + + ForbidResource(quores); + quoter.ResourcesIndex.erase(quores.Resource); + quoter.Resources.erase(resourceIt); + continue; + } + + for (auto &update : resUpdate.Update) { if (update.Ticks == 0) { - quores.QuotaChannels.erase(update.Channel); + quores.QuotaChannels.erase(update.Channel); } else { Y_VERIFY(update.Rate >= 0.0); - quores.QuotaChannels[update.Channel] = update; + quores.QuotaChannels[update.Channel] = update; } - } - + } + if (quores.NextTick == TInstant::Zero()) { - FeedResource(quores); + FeedResource(quores); TryTickSchedule(); } - } - - if (quoter.Empty()) { + } + + if (quoter.Empty()) { BLOG_I("closing quoter on ProxyUpdate as no activity left " << quoter.QuoterName); - return BreakQuoter(quoterIt); - } -} - -void TQuoterService::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev) { + return BreakQuoter(quoterIt); + } +} + +void TQuoterService::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev) { THolder<NSchemeCache::TSchemeCacheNavigate> navigate(ev->Get()->Request.Release()); - Y_VERIFY(navigate->ResultSet.size() == 1); - - auto &navEntry = navigate->ResultSet.front(); - const TString &path = CanonizePath(navEntry.Path); - - auto quotersIndexIt = QuotersIndex.find(path); - if (quotersIndexIt == QuotersIndex.end()) - return; - - auto quoterIt = Quoters.find(quotersIndexIt->second); - Y_VERIFY(quoterIt != Quoters.end()); - if (quoterIt->second.ProxyId) - return; - - switch (navEntry.Kind) { - case NSchemeCache::TSchemeCacheNavigate::KindKesus: - BLOG_I("path resolved as Kesus " << path); - return CreateKesusQuoter(navEntry, quotersIndexIt, quoterIt); - default: - BLOG_I("path not resolved as known entity " << path); - return BreakQuoter(quotersIndexIt, quoterIt); - } -} - -void TQuoterService::CreateKesusQuoter(NSchemeCache::TSchemeCacheNavigate::TEntry &navigate, decltype(QuotersIndex)::iterator indexIt, decltype(Quoters)::iterator quoterIt) { - // todo: create quoter - TQuoterState "er = quoterIt->second; - const ui64 quoterId = quoterIt->first; - - if (quoter.ProxyId) { - return BreakQuoter(indexIt, quoterIt); - } - + Y_VERIFY(navigate->ResultSet.size() == 1); + + auto &navEntry = navigate->ResultSet.front(); + const TString &path = CanonizePath(navEntry.Path); + + auto quotersIndexIt = QuotersIndex.find(path); + if (quotersIndexIt == QuotersIndex.end()) + return; + + auto quoterIt = Quoters.find(quotersIndexIt->second); + Y_VERIFY(quoterIt != Quoters.end()); + if (quoterIt->second.ProxyId) + return; + + switch (navEntry.Kind) { + case NSchemeCache::TSchemeCacheNavigate::KindKesus: + BLOG_I("path resolved as Kesus " << path); + return CreateKesusQuoter(navEntry, quotersIndexIt, quoterIt); + default: + BLOG_I("path not resolved as known entity " << path); + return BreakQuoter(quotersIndexIt, quoterIt); + } +} + +void TQuoterService::CreateKesusQuoter(NSchemeCache::TSchemeCacheNavigate::TEntry &navigate, decltype(QuotersIndex)::iterator indexIt, decltype(Quoters)::iterator quoterIt) { + // todo: create quoter + TQuoterState "er = quoterIt->second; + const ui64 quoterId = quoterIt->first; + + if (quoter.ProxyId) { + return BreakQuoter(indexIt, quoterIt); + } + quoter.ProxyId = Register(CreateKesusQuoterProxy(quoterId, navigate, SelfId()), TMailboxType::HTSwap, AppData()->UserPoolId); - - TSet<ui32> waitingQueueResolve(std::move(quoter.WaitingQueueResolve)); - for (ui32 reqIdx : waitingQueueResolve) { - TRequest &req = ReqState.Get(reqIdx); - for (ui32 resLeafIdx = req.ResourceLeaf; resLeafIdx != Max<ui32>(); ) { - TResourceLeaf &leaf = ResState.Get(resLeafIdx); - if (leaf.QuoterId == quoterId) { - Y_VERIFY(leaf.State == EResourceState::ResolveQuoter); - Y_VERIFY(leaf.ResourceName); - - auto itpair = quoter.WaitingResource.emplace(leaf.ResourceName, TSet<ui32>()); - itpair.first->second.emplace(reqIdx); - - if (itpair.second) { // new resolve entry, request - BLOG_I("resolve resource " << leaf.ResourceName << " on quoter " << quoter.QuoterName); - Send(quoter.ProxyId, new TEvQuota::TEvProxyRequest(leaf.ResourceName)); - } - - leaf.State = EResourceState::ResolveResource; - } - resLeafIdx = leaf.NextResourceLeaf; - } - } -} - -void TQuoterService::BreakQuoter(decltype(Quoters)::iterator quoterIt) { - return BreakQuoter(QuotersIndex.find(quoterIt->second.QuoterName), quoterIt); -} - -void TQuoterService::BreakQuoter(decltype(QuotersIndex)::iterator indexIt, decltype(Quoters)::iterator quoterIt) { - // quoter is broken, fail everything and cleanup - TQuoterState "er = quoterIt->second; - - if (quoter.ProxyId) { - Send(quoter.ProxyId, new TEvents::TEvPoisonPill()); + + TSet<ui32> waitingQueueResolve(std::move(quoter.WaitingQueueResolve)); + for (ui32 reqIdx : waitingQueueResolve) { + TRequest &req = ReqState.Get(reqIdx); + for (ui32 resLeafIdx = req.ResourceLeaf; resLeafIdx != Max<ui32>(); ) { + TResourceLeaf &leaf = ResState.Get(resLeafIdx); + if (leaf.QuoterId == quoterId) { + Y_VERIFY(leaf.State == EResourceState::ResolveQuoter); + Y_VERIFY(leaf.ResourceName); + + auto itpair = quoter.WaitingResource.emplace(leaf.ResourceName, TSet<ui32>()); + itpair.first->second.emplace(reqIdx); + + if (itpair.second) { // new resolve entry, request + BLOG_I("resolve resource " << leaf.ResourceName << " on quoter " << quoter.QuoterName); + Send(quoter.ProxyId, new TEvQuota::TEvProxyRequest(leaf.ResourceName)); + } + + leaf.State = EResourceState::ResolveResource; + } + resLeafIdx = leaf.NextResourceLeaf; + } + } +} + +void TQuoterService::BreakQuoter(decltype(Quoters)::iterator quoterIt) { + return BreakQuoter(QuotersIndex.find(quoterIt->second.QuoterName), quoterIt); +} + +void TQuoterService::BreakQuoter(decltype(QuotersIndex)::iterator indexIt, decltype(Quoters)::iterator quoterIt) { + // quoter is broken, fail everything and cleanup + TQuoterState "er = quoterIt->second; + + if (quoter.ProxyId) { + Send(quoter.ProxyId, new TEvents::TEvPoisonPill()); quoter.ProxyId = TActorId(); - } - - TSet<ui32> waitingQueueResolve(std::move(quoter.WaitingQueueResolve)); - for (ui32 reqIdx : waitingQueueResolve) { - DeclineRequest(ReqState.Get(reqIdx), reqIdx); - } - - TMap<TString, TSet<ui32>> waitingResource(std::move(quoter.WaitingResource)); - for (auto &xpair : waitingResource) { - for (ui32 reqIdx : xpair.second) - DeclineRequest(ReqState.Get(reqIdx), reqIdx); - } - - for (auto &xpair : quoter.Resources) { - ForbidResource(*xpair.second); - } - - Quoters.erase(quoterIt); - QuotersIndex.erase(indexIt); - - Counters.ActiveQuoterProxies->Dec(); -} - -void TQuoterService::ForbidResource(TResource &quores) { - while (quores.QueueHead != Max<ui32>()) { - const ui32 reqIdx = ResState.Get(quores.QueueHead).RequestIdx; - DeclineRequest(ReqState.Get(reqIdx), reqIdx); - } - - if (quores.Activation != TInstant::Zero()) { - ScheduleAllocation[quores.Activation].erase(&quores); - quores.Activation = TInstant::Zero(); - } - - if (quores.NextTick != TInstant::Zero()) { - ScheduleFeed[quores.NextTick].erase(&quores); - quores.NextTick = TInstant::Zero(); - } - - Counters.ActiveProxyResources->Dec(); - - // cleanup is outside -} - -void TQuoterService::CheckRequest(ui32 reqIdx) { - TRequest &request = ReqState.Get(reqIdx); - - for (ui32 nextLeaf = request.ResourceLeaf; nextLeaf != Max<ui32>(); ) { - auto &leaf = ResState.Get(nextLeaf); - if (leaf.State != EResourceState::Cleared) - return; - nextLeaf = leaf.NextResourceLeaf; - } - - // ok, no uncleared resources, process request - AllowRequest(request, reqIdx); -} - -void TQuoterService::FillStats(TResource &quores) { - auto &dq = StatsToPublish[quores.QuoterId]; + } + + TSet<ui32> waitingQueueResolve(std::move(quoter.WaitingQueueResolve)); + for (ui32 reqIdx : waitingQueueResolve) { + DeclineRequest(ReqState.Get(reqIdx), reqIdx); + } + + TMap<TString, TSet<ui32>> waitingResource(std::move(quoter.WaitingResource)); + for (auto &xpair : waitingResource) { + for (ui32 reqIdx : xpair.second) + DeclineRequest(ReqState.Get(reqIdx), reqIdx); + } + + for (auto &xpair : quoter.Resources) { + ForbidResource(*xpair.second); + } + + Quoters.erase(quoterIt); + QuotersIndex.erase(indexIt); + + Counters.ActiveQuoterProxies->Dec(); +} + +void TQuoterService::ForbidResource(TResource &quores) { + while (quores.QueueHead != Max<ui32>()) { + const ui32 reqIdx = ResState.Get(quores.QueueHead).RequestIdx; + DeclineRequest(ReqState.Get(reqIdx), reqIdx); + } + + if (quores.Activation != TInstant::Zero()) { + ScheduleAllocation[quores.Activation].erase(&quores); + quores.Activation = TInstant::Zero(); + } + + if (quores.NextTick != TInstant::Zero()) { + ScheduleFeed[quores.NextTick].erase(&quores); + quores.NextTick = TInstant::Zero(); + } + + Counters.ActiveProxyResources->Dec(); + + // cleanup is outside +} + +void TQuoterService::CheckRequest(ui32 reqIdx) { + TRequest &request = ReqState.Get(reqIdx); + + for (ui32 nextLeaf = request.ResourceLeaf; nextLeaf != Max<ui32>(); ) { + auto &leaf = ResState.Get(nextLeaf); + if (leaf.State != EResourceState::Cleared) + return; + nextLeaf = leaf.NextResourceLeaf; + } + + // ok, no uncleared resources, process request + AllowRequest(request, reqIdx); +} + +void TQuoterService::FillStats(TResource &quores) { + auto &dq = StatsToPublish[quores.QuoterId]; const double expectedRate = -1.0; const double cap = -1.0; dq.emplace_back(quores.ResourceId, 0, quores.AmountConsumed, quores.History, quores.QueueSize, quores.QueueWeight, expectedRate, cap); quores.AmountConsumed = 0.0; quores.History.Clear(); -} - -void TQuoterService::FeedResource(TResource &quores) { +} + +void TQuoterService::FeedResource(TResource &quores) { quores.Balance = 0.0; quores.FreeBalance = 0.0; quores.TickRate = 0.0; - - for (auto it = quores.QuotaChannels.begin(), end = quores.QuotaChannels.end(); it != end;) { - auto "a = it->second; - - switch (quota.Policy) { - case TEvQuota::ETickPolicy::Front: - quores.Balance += quota.Rate; - quores.FreeBalance += quota.Rate; - break; - case TEvQuota::ETickPolicy::Sustained: - case TEvQuota::ETickPolicy::Ahead: - quores.Balance += quota.Rate; - break; - } - - quores.TickRate += quota.Rate; - - if (quota.Ticks == 1) { - it = quores.QuotaChannels.erase(it); - } else { - if (quota.Ticks != Max<ui32>()) // Max<ui32> means forever - --quota.Ticks; - ++it; - } - } - + + for (auto it = quores.QuotaChannels.begin(), end = quores.QuotaChannels.end(); it != end;) { + auto "a = it->second; + + switch (quota.Policy) { + case TEvQuota::ETickPolicy::Front: + quores.Balance += quota.Rate; + quores.FreeBalance += quota.Rate; + break; + case TEvQuota::ETickPolicy::Sustained: + case TEvQuota::ETickPolicy::Ahead: + quores.Balance += quota.Rate; + break; + } + + quores.TickRate += quota.Rate; + + if (quota.Ticks == 1) { + it = quores.QuotaChannels.erase(it); + } else { + if (quota.Ticks != Max<ui32>()) // Max<ui32> means forever + --quota.Ticks; + ++it; + } + } + BLOG_T("Feed resource \"" << quores.Resource << "\". Balance: " << quores.Balance << ". FreeBalance: " << quores.FreeBalance); LWPROBE(FeedResource, quores.Quoter, @@ -1215,72 +1215,72 @@ void TQuoterService::FeedResource(TResource &quores) { quores.Balance, quores.FreeBalance); - if (quores.QueueTail == Max<ui32>()) { - quores.NextTick = TInstant::Zero(); - } else { - // must recheck resource allocation + if (quores.QueueTail == Max<ui32>()) { + quores.NextTick = TInstant::Zero(); + } else { + // must recheck resource allocation ScheduleNextTick(quores.NextTick ? quores.NextTick + quores.TickSize : TActivationContext::Now(), quores); - AllocateResource(quores); - } - - switch (quores.StatUpdatePolicy) { - case EStatUpdatePolicy::EveryTick: - FillStats(quores); - break; - case EStatUpdatePolicy::EveryActiveTick: - if (quores.QueueSize || quores.AmountConsumed > 0) - FillStats(quores); - break; - case EStatUpdatePolicy::OnActivity: - if (quores.AmountConsumed > 0) - FillStats(quores); - break; - default: - break; - } -} - -void TQuoterService::AllocateResource(TResource &quores) { + AllocateResource(quores); + } + + switch (quores.StatUpdatePolicy) { + case EStatUpdatePolicy::EveryTick: + FillStats(quores); + break; + case EStatUpdatePolicy::EveryActiveTick: + if (quores.QueueSize || quores.AmountConsumed > 0) + FillStats(quores); + break; + case EStatUpdatePolicy::OnActivity: + if (quores.AmountConsumed > 0) + FillStats(quores); + break; + default: + break; + } +} + +void TQuoterService::AllocateResource(TResource &quores) { BLOG_T("Allocate resource \"" << quores.Resource << "\""); - const TInstant now = TActivationContext::Now(); + const TInstant now = TActivationContext::Now(); ui64 requestsProcessed = 0; const double prevAmountConsumed = quores.AmountConsumed; - while (quores.QueueHead != Max<ui32>()) { - TResourceLeaf &leaf = ResState.Get(quores.QueueHead); + while (quores.QueueHead != Max<ui32>()) { + TResourceLeaf &leaf = ResState.Get(quores.QueueHead); TDuration delay = quores.Charge(ReqState.Get(leaf.RequestIdx), leaf, now); - - if (delay == TDuration::Zero()) { - // resource available and charged - // detach from Resource request queue - Y_VERIFY(leaf.PrevInWaitQueue == Max<ui32>()); - quores.QueueHead = leaf.NextInWaitQueue; - - if (quores.QueueHead != Max<ui32>()) { - TResourceLeaf &nextLeaf = ResState.Get(quores.QueueHead); - nextLeaf.PrevInWaitQueue = Max<ui32>(); - - quores.QueueSize -= 1; - quores.QueueWeight -= leaf.Amount; - } else { - // last entry in queue - quores.QueueTail = Max<ui32>(); - - quores.QueueSize = 0; + + if (delay == TDuration::Zero()) { + // resource available and charged + // detach from Resource request queue + Y_VERIFY(leaf.PrevInWaitQueue == Max<ui32>()); + quores.QueueHead = leaf.NextInWaitQueue; + + if (quores.QueueHead != Max<ui32>()) { + TResourceLeaf &nextLeaf = ResState.Get(quores.QueueHead); + nextLeaf.PrevInWaitQueue = Max<ui32>(); + + quores.QueueSize -= 1; + quores.QueueWeight -= leaf.Amount; + } else { + // last entry in queue + quores.QueueTail = Max<ui32>(); + + quores.QueueSize = 0; quores.QueueWeight = 0.0; - } - - leaf.NextInWaitQueue = Max<ui32>(); - leaf.PrevInWaitQueue = Max<ui32>(); - leaf.Resource = nullptr; - leaf.State = EResourceState::Cleared; - - CheckRequest(leaf.RequestIdx); + } + + leaf.NextInWaitQueue = Max<ui32>(); + leaf.PrevInWaitQueue = Max<ui32>(); + leaf.Resource = nullptr; + leaf.State = EResourceState::Cleared; + + CheckRequest(leaf.RequestIdx); ++requestsProcessed; - } else { - MarkScheduleAllocation(quores, delay, now); + } else { + MarkScheduleAllocation(quores, delay, now); break; - } - } + } + } LWPROBE(AllocateResource, quores.Quoter, quores.Resource, @@ -1292,70 +1292,70 @@ void TQuoterService::AllocateResource(TResource &quores) { quores.QueueWeight, quores.Balance, quores.FreeBalance); -} - -void TQuoterService::HandleTick() { +} + +void TQuoterService::HandleTick() { const TInstant until = TimeToGranularity(TActivationContext::Now()); while (LastProcessed < until) { - // process resource allocation - auto allocIt = ScheduleAllocation.find(LastProcessed); - if (allocIt != ScheduleAllocation.end()) { - while (allocIt->second) { - auto xset = std::move(allocIt->second); - for (TResource* quores : xset) { - quores->Activation = TInstant::Zero(); - AllocateResource(*quores); - } - } - ScheduleAllocation.erase(allocIt); - } - - // process resource feeding - auto feedIt = ScheduleFeed.find(LastProcessed); - if (feedIt != ScheduleFeed.end()) { - while (feedIt->second) { - auto xset = std::move(feedIt->second); - for (TResource* quores : xset) - FeedResource(*quores); - } - - ScheduleFeed.erase(feedIt); - } - - // process deadlines - auto deadlineIt = ScheduleDeadline.find(LastProcessed); - if (deadlineIt != ScheduleDeadline.end()) { - TRequest &placeholder = ReqState.Get(deadlineIt->second); - Y_VERIFY(placeholder.Source.NodeId() == 0); - while (placeholder.NextDeadlineRequest != Max<ui32>()) { - TRequest &reqToCancel = ReqState.Get(placeholder.NextDeadlineRequest); - DeadlineRequest(reqToCancel, placeholder.NextDeadlineRequest); - } - - // TODO: return placeholder request - ReqState.Free(deadlineIt->second); - ScheduleDeadline.erase(deadlineIt); - } - - LastProcessed += Config.ScheduleTickSize; - } - - if (ScheduleAllocation || ScheduleFeed || ScheduleDeadline) { - Schedule(Config.ScheduleTickSize, new TEvents::TEvWakeup()); + // process resource allocation + auto allocIt = ScheduleAllocation.find(LastProcessed); + if (allocIt != ScheduleAllocation.end()) { + while (allocIt->second) { + auto xset = std::move(allocIt->second); + for (TResource* quores : xset) { + quores->Activation = TInstant::Zero(); + AllocateResource(*quores); + } + } + ScheduleAllocation.erase(allocIt); + } + + // process resource feeding + auto feedIt = ScheduleFeed.find(LastProcessed); + if (feedIt != ScheduleFeed.end()) { + while (feedIt->second) { + auto xset = std::move(feedIt->second); + for (TResource* quores : xset) + FeedResource(*quores); + } + + ScheduleFeed.erase(feedIt); + } + + // process deadlines + auto deadlineIt = ScheduleDeadline.find(LastProcessed); + if (deadlineIt != ScheduleDeadline.end()) { + TRequest &placeholder = ReqState.Get(deadlineIt->second); + Y_VERIFY(placeholder.Source.NodeId() == 0); + while (placeholder.NextDeadlineRequest != Max<ui32>()) { + TRequest &reqToCancel = ReqState.Get(placeholder.NextDeadlineRequest); + DeadlineRequest(reqToCancel, placeholder.NextDeadlineRequest); + } + + // TODO: return placeholder request + ReqState.Free(deadlineIt->second); + ScheduleDeadline.erase(deadlineIt); + } + + LastProcessed += Config.ScheduleTickSize; + } + + if (ScheduleAllocation || ScheduleFeed || ScheduleDeadline) { + Schedule(Config.ScheduleTickSize, new TEvents::TEvWakeup()); } else { TickScheduled = false; - } -} - -void TQuoterService::PublishStats() { - for (auto &xpair : StatsToPublish) { - if (TQuoterState *qs = Quoters.FindPtr(xpair.first)) { - Send(qs->ProxyId, new TEvQuota::TEvProxyStats(std::move(xpair.second))); - } - } - StatsToPublish.clear(); -} - + } +} + +void TQuoterService::PublishStats() { + for (auto &xpair : StatsToPublish) { + if (TQuoterState *qs = Quoters.FindPtr(xpair.first)) { + Send(qs->ProxyId, new TEvQuota::TEvProxyStats(std::move(xpair.second))); + } + } + StatsToPublish.clear(); +} + TString TQuoterService::PrintEvent(const TEvQuota::TEvRequest::TPtr& ev) { const auto& req = *ev->Get(); TStringBuilder ret; @@ -1387,10 +1387,10 @@ TString TQuoterService::PrintEvent(const TEvQuota::TEvRequest::TPtr& ev) { return std::move(ret); } -} // namespace NQuoter - -IActor* CreateQuoterService(const TQuoterServiceConfig &config) { - return new NQuoter::TQuoterService(config); -} - -} // namespace NKikimr +} // namespace NQuoter + +IActor* CreateQuoterService(const TQuoterServiceConfig &config) { + return new NQuoter::TQuoterService(config); +} + +} // namespace NKikimr diff --git a/ydb/core/quoter/quoter_service.h b/ydb/core/quoter/quoter_service.h index 0b95dae8ca..982f6552b9 100644 --- a/ydb/core/quoter/quoter_service.h +++ b/ydb/core/quoter/quoter_service.h @@ -1,13 +1,13 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include <ydb/core/base/quoter.h> - -namespace NKikimr { - -struct TQuoterServiceConfig { - TDuration ScheduleTickSize = TDuration::MilliSeconds(1); - }; - -IActor* CreateQuoterService(const TQuoterServiceConfig &config = TQuoterServiceConfig()); - -} + +namespace NKikimr { + +struct TQuoterServiceConfig { + TDuration ScheduleTickSize = TDuration::MilliSeconds(1); + }; + +IActor* CreateQuoterService(const TQuoterServiceConfig &config = TQuoterServiceConfig()); + +} diff --git a/ydb/core/quoter/quoter_service_impl.h b/ydb/core/quoter/quoter_service_impl.h index c3b1a0a5db..d27ea134e1 100644 --- a/ydb/core/quoter/quoter_service_impl.h +++ b/ydb/core/quoter/quoter_service_impl.h @@ -1,6 +1,6 @@ -#pragma once -#include "defs.h" -#include "quoter_service.h" +#pragma once +#include "defs.h" +#include "quoter_service.h" #include <ydb/core/base/tablet_pipe.h> #include <ydb/core/base/appdata.h> @@ -12,12 +12,12 @@ #include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/lwtrace/shuttle.h> -#include <util/generic/set.h> -#include <util/generic/deque.h> - -namespace NKikimr { -namespace NQuoter { - +#include <util/generic/set.h> +#include <util/generic/deque.h> + +namespace NKikimr { +namespace NQuoter { + extern const TString CONSUMED_COUNTER_NAME; extern const TString REQUESTED_COUNTER_NAME; extern const TString RESOURCE_COUNTER_SENSOR_NAME; @@ -35,120 +35,120 @@ extern const TString REQUESTS_COUNT_SENSOR_NAME; extern const TString ELAPSED_MICROSEC_IN_STARVATION_SENSOR_NAME; extern const TString DISCONNECTS_COUNTER_SENSOR_NAME; -using EResourceOperator = TEvQuota::EResourceOperator; -using EStatUpdatePolicy = TEvQuota::EStatUpdatePolicy; -using EUpdateState = TEvQuota::EUpdateState; - -struct TResource; - +using EResourceOperator = TEvQuota::EResourceOperator; +using EStatUpdatePolicy = TEvQuota::EStatUpdatePolicy; +using EUpdateState = TEvQuota::EUpdateState; + +struct TResource; + NMonitoring::IHistogramCollectorPtr GetLatencyHistogramBuckets(); -struct TRequest { +struct TRequest { TActorId Source = TActorId(); - ui64 EventCookie = 0; - + ui64 EventCookie = 0; + TInstant StartTime; - EResourceOperator Operator = EResourceOperator::Unknown; - TInstant Deadline = TInstant::Max(); - ui32 ResourceLeaf = Max<ui32>(); - - ui32 PrevDeadlineRequest = Max<ui32>(); - ui32 NextDeadlineRequest = Max<ui32>(); - - ui32 PrevByOwner = Max<ui32>(); - ui32 NextByOwner = Max<ui32>(); + EResourceOperator Operator = EResourceOperator::Unknown; + TInstant Deadline = TInstant::Max(); + ui32 ResourceLeaf = Max<ui32>(); + + ui32 PrevDeadlineRequest = Max<ui32>(); + ui32 NextDeadlineRequest = Max<ui32>(); + + ui32 PrevByOwner = Max<ui32>(); + ui32 NextByOwner = Max<ui32>(); // tracing mutable NLWTrace::TOrbit Orbit; -}; - -class TReqState { -private: - TVector<TRequest> Requests; +}; + +class TReqState { +private: + TVector<TRequest> Requests; THashMap<TActorId, ui32> ByOwner; - TVector<ui32> Unused; -public: - ui32 Idx(TRequest &request); - TRequest& Get(ui32 idx); + TVector<ui32> Unused; +public: + ui32 Idx(TRequest &request); + TRequest& Get(ui32 idx); ui32 HeadByOwner(TActorId ownerId); ui32 Allocate(TActorId source, ui64 eventCookie); - void Free(ui32 idx); -}; - -enum class EResourceState { - Unknown, - ResolveQuoter, - ResolveResource, - Wait, - Cleared, -}; - -struct TResourceLeaf { - TResource *Resource = nullptr; - ui64 Amount = Max<ui64>(); + void Free(ui32 idx); +}; + +enum class EResourceState { + Unknown, + ResolveQuoter, + ResolveResource, + Wait, + Cleared, +}; + +struct TResourceLeaf { + TResource *Resource = nullptr; + ui64 Amount = Max<ui64>(); bool IsUsedAmount = false; - - ui32 RequestIdx = Max<ui32>(); - - ui32 NextInWaitQueue = Max<ui32>(); - ui32 PrevInWaitQueue = Max<ui32>(); - - ui32 NextResourceLeaf = Max<ui32>(); - - EResourceState State = EResourceState::Unknown; - - ui64 QuoterId = 0; - ui64 ResourceId = 0; - - TString QuoterName; // optional - TString ResourceName; + + ui32 RequestIdx = Max<ui32>(); + + ui32 NextInWaitQueue = Max<ui32>(); + ui32 PrevInWaitQueue = Max<ui32>(); + + ui32 NextResourceLeaf = Max<ui32>(); + + EResourceState State = EResourceState::Unknown; + + ui64 QuoterId = 0; + ui64 ResourceId = 0; + + TString QuoterName; // optional + TString ResourceName; TInstant StartQueueing = TInstant::Zero(); // optional phase TInstant StartCharging = TInstant::Zero(); // when resource is processed -}; - -class TResState { -private: - TVector<TResourceLeaf> Leafs; - TVector<ui32> Unused; -public: - TResourceLeaf& Get(ui32 idx); +}; + +class TResState { +private: + TVector<TResourceLeaf> Leafs; + TVector<ui32> Unused; +public: + TResourceLeaf& Get(ui32 idx); ui32 Allocate(TResource *resource, ui64 amount, bool isUsedAmount, ui32 requestIdx); - void FreeChain(ui32 headIdx); -}; - -struct TResource { - const ui64 QuoterId; - const ui64 ResourceId; + void FreeChain(ui32 headIdx); +}; + +struct TResource { + const ui64 QuoterId; + const ui64 ResourceId; const TString Quoter; - const TString Resource; + const TString Resource; const TQuoterServiceConfig& QuoterServiceConfig; - - TInstant Activation = TInstant::Zero(); - TInstant NextTick = TInstant::Zero(); - TInstant LastTick = TInstant::Zero(); - - ui32 QueueHead = Max<ui32>(); // to resource leaf - ui32 QueueTail = Max<ui32>(); - - ui32 QueueSize = 0; + + TInstant Activation = TInstant::Zero(); + TInstant NextTick = TInstant::Zero(); + TInstant LastTick = TInstant::Zero(); + + ui32 QueueHead = Max<ui32>(); // to resource leaf + ui32 QueueTail = Max<ui32>(); + + ui32 QueueSize = 0; double QueueWeight = 0; - - TInstant LastAllocated = TInstant::Max(); - + + TInstant LastAllocated = TInstant::Max(); + double FreeBalance = 0.0; // could be used w/o pace limit double Balance = 0.0; // total balance, but under pace limit double TickRate = 0.0; - - TDuration TickSize = TDuration::Seconds(1); - TMap<ui32, TEvQuota::TUpdateTick> QuotaChannels; - - // stats block - TEvQuota::EStatUpdatePolicy StatUpdatePolicy = TEvQuota::EStatUpdatePolicy::Never; + + TDuration TickSize = TDuration::Seconds(1); + TMap<ui32, TEvQuota::TUpdateTick> QuotaChannels; + + // stats block + TEvQuota::EStatUpdatePolicy StatUpdatePolicy = TEvQuota::EStatUpdatePolicy::Never; double AmountConsumed = 0.0; // consumed from last stats notification TTimeSeriesMap<double> History; // consumption history from last stats notification TInstant StartStarvationTime = TInstant::Zero(); - + struct { NMonitoring::TDynamicCounters::TCounterPtr Consumed; NMonitoring::TDynamicCounters::TCounterPtr Requested; @@ -159,10 +159,10 @@ struct TResource { } Counters; TResource(ui64 quoterId, ui64 resourceId, const TString& quoter, const TString& resource, const TQuoterServiceConfig "erServiceConfig, const NMonitoring::TDynamicCounterPtr& quoterCounters) - : QuoterId(quoterId) - , ResourceId(resourceId) + : QuoterId(quoterId) + , ResourceId(resourceId) , Quoter(quoter) - , Resource(resource) + , Resource(resource) , QuoterServiceConfig(quoterServiceConfig) { auto counters = quoterCounters->GetSubgroup(RESOURCE_COUNTER_SENSOR_NAME, resource ? resource : "__StaticRatedResource"); @@ -173,8 +173,8 @@ struct TResource { Counters.RequestsCount = counters->GetCounter(REQUESTS_COUNT_SENSOR_NAME, true); Counters.ElapsedMicrosecInStarvation = counters->GetCounter(ELAPSED_MICROSEC_IN_STARVATION_SENSOR_NAME, true); } - - void ApplyQuotaChannel(const TEvQuota::TUpdateTick &tick); + + void ApplyQuotaChannel(const TEvQuota::TUpdateTick &tick); TDuration Charge(double amount, TInstant now); // Zero - fullfiled, Max - not in current tick, Duration - in current tick, but not right now due to pace limit TDuration Charge(TRequest& request, TResourceLeaf& leaf, TInstant now); void ChargeUsedAmount(double amount, TInstant now); @@ -182,153 +182,153 @@ struct TResource { void MarkStartedCharging(TRequest& request, TResourceLeaf& leaf, TInstant now); void StartStarvation(TInstant now); void StopStarvation(TInstant now); -}; - -struct TScheduleTick { - ui32 ActivationHead = Max<ui32>(); -}; - -struct TQuoterState { - const TString QuoterName; +}; + +struct TScheduleTick { + ui32 ActivationHead = Max<ui32>(); +}; + +struct TQuoterState { + const TString QuoterName; TActorId ProxyId; - - THashMap<ui64, THolder<TResource>> Resources; - THashMap<TString, ui64> ResourcesIndex; - - TSet<ui32> WaitingQueueResolve; // => requests - TMap<TString, TSet<ui32>> WaitingResource; // => requests - + + THashMap<ui64, THolder<TResource>> Resources; + THashMap<TString, ui64> ResourcesIndex; + + TSet<ui32> WaitingQueueResolve; // => requests + TMap<TString, TSet<ui32>> WaitingResource; // => requests + struct { NMonitoring::TDynamicCounterPtr QuoterCounters; } Counters; TResource& GetOrCreate(ui64 quoterId, ui64 resId, const TString& quoter, const TString& resource, const TQuoterServiceConfig "erServiceConfig); - bool Empty(); - + bool Empty(); + void InitCounters(const NMonitoring::TDynamicCounterPtr& serviceCounters) { Counters.QuoterCounters = serviceCounters->GetSubgroup(QUOTER_COUNTER_SENSOR_NAME, QuoterName); } TQuoterState(const TString& quoterName, const NMonitoring::TDynamicCounterPtr& serviceCounters) - : QuoterName(quoterName) + : QuoterName(quoterName) { if (serviceCounters) { InitCounters(serviceCounters); } } -}; - -class TQuoterService : public TActorBootstrapped<TQuoterService> { - TQuoterServiceConfig Config; - TInstant LastProcessed; - - THashMap<TInstant, TSet<TResource*>> ScheduleAllocation; // some sort of linked list instead of TSet? - THashMap<TInstant, TSet<TResource*>> ScheduleFeed; - THashMap<TInstant, ui32> ScheduleDeadline; - - THashMap<ui64, ui32> Deadlines; // ticknum => req-idx - TResState ResState; - TReqState ReqState; - - THashMap<ui64, TQuoterState> Quoters; - THashMap<TString, ui64> QuotersIndex; - ui64 QuoterIdCounter = 1; - - TQuoterState StaticRatedQuoter; // ??? could be just static rated quoters, w/o all fancy quoter stuff - - bool TickScheduled; - - TMap<ui64, TDeque<TEvQuota::TProxyStat>> StatsToPublish; // quoterId -> stats - - struct { +}; + +class TQuoterService : public TActorBootstrapped<TQuoterService> { + TQuoterServiceConfig Config; + TInstant LastProcessed; + + THashMap<TInstant, TSet<TResource*>> ScheduleAllocation; // some sort of linked list instead of TSet? + THashMap<TInstant, TSet<TResource*>> ScheduleFeed; + THashMap<TInstant, ui32> ScheduleDeadline; + + THashMap<ui64, ui32> Deadlines; // ticknum => req-idx + TResState ResState; + TReqState ReqState; + + THashMap<ui64, TQuoterState> Quoters; + THashMap<TString, ui64> QuotersIndex; + ui64 QuoterIdCounter = 1; + + TQuoterState StaticRatedQuoter; // ??? could be just static rated quoters, w/o all fancy quoter stuff + + bool TickScheduled; + + TMap<ui64, TDeque<TEvQuota::TProxyStat>> StatsToPublish; // quoterId -> stats + + struct { NMonitoring::TDynamicCounterPtr ServiceCounters; - NMonitoring::TDynamicCounters::TCounterPtr ActiveQuoterProxies; - NMonitoring::TDynamicCounters::TCounterPtr ActiveProxyResources; - NMonitoring::TDynamicCounters::TCounterPtr KnownLocalResources; - NMonitoring::TDynamicCounters::TCounterPtr RequestsInFly; - NMonitoring::TDynamicCounters::TCounterPtr Requests; - NMonitoring::TDynamicCounters::TCounterPtr ResultOk; - NMonitoring::TDynamicCounters::TCounterPtr ResultDeadline; - NMonitoring::TDynamicCounters::TCounterPtr ResultError; + NMonitoring::TDynamicCounters::TCounterPtr ActiveQuoterProxies; + NMonitoring::TDynamicCounters::TCounterPtr ActiveProxyResources; + NMonitoring::TDynamicCounters::TCounterPtr KnownLocalResources; + NMonitoring::TDynamicCounters::TCounterPtr RequestsInFly; + NMonitoring::TDynamicCounters::TCounterPtr Requests; + NMonitoring::TDynamicCounters::TCounterPtr ResultOk; + NMonitoring::TDynamicCounters::TCounterPtr ResultDeadline; + NMonitoring::TDynamicCounters::TCounterPtr ResultError; NMonitoring::THistogramPtr RequestLatency; - } Counters; - - enum class EInitLeafStatus { - Unknown, - Forbid, - Charged, - Wait, + } Counters; + + enum class EInitLeafStatus { + Unknown, + Forbid, + Charged, + Wait, GenericError, - }; - - void ScheduleNextTick(TInstant requested, TResource &quores); - TInstant TimeToGranularity(TInstant rawTime); + }; + + void ScheduleNextTick(TInstant requested, TResource &quores); + TInstant TimeToGranularity(TInstant rawTime); void TryTickSchedule(TInstant now = TInstant::Zero()); - - void ReplyRequest(TRequest &request, ui32 reqIdx, TEvQuota::TEvClearance::EResult resultCode); - void ForgetRequest(TRequest &request, ui32 reqIdx); - void DeclineRequest(TRequest &request, ui32 reqIdx); + + void ReplyRequest(TRequest &request, ui32 reqIdx, TEvQuota::TEvClearance::EResult resultCode); + void ForgetRequest(TRequest &request, ui32 reqIdx); + void DeclineRequest(TRequest &request, ui32 reqIdx); void FailRequest(TRequest &request, ui32 reqIdx); - void AllowRequest(TRequest &request, ui32 reqIdx); - void DeadlineRequest(TRequest &request, ui32 reqIdx); - - EInitLeafStatus InitSystemLeaf(const TEvQuota::TResourceLeaf &leaf, TRequest &request, ui32 reqIdx); - EInitLeafStatus InitResourceLeaf(const TEvQuota::TResourceLeaf &leaf, TRequest &request, ui32 reqIdx); - EInitLeafStatus TryCharge(TResource& quores, ui64 quoterId, ui64 resourceId, const TEvQuota::TResourceLeaf &leaf, TRequest &request, ui32 reqIdx); + void AllowRequest(TRequest &request, ui32 reqIdx); + void DeadlineRequest(TRequest &request, ui32 reqIdx); + + EInitLeafStatus InitSystemLeaf(const TEvQuota::TResourceLeaf &leaf, TRequest &request, ui32 reqIdx); + EInitLeafStatus InitResourceLeaf(const TEvQuota::TResourceLeaf &leaf, TRequest &request, ui32 reqIdx); + EInitLeafStatus TryCharge(TResource& quores, ui64 quoterId, ui64 resourceId, const TEvQuota::TResourceLeaf &leaf, TRequest &request, ui32 reqIdx); EInitLeafStatus NotifyUsed(TResource& quores, ui64 quoterId, ui64 resourceId, const TEvQuota::TResourceLeaf &leaf, TRequest &request); - void MarkScheduleAllocation(TResource& quores, TDuration delay, TInstant now); - - void InitialRequestProcessing(TEvQuota::TEvRequest::TPtr &ev, const ui32 reqIdx); - - void ForbidResource(TResource &quores); - void CheckRequest(ui32 reqIdx); - void FillStats(TResource &quores); - void FeedResource(TResource &quores); - void AllocateResource(TResource &quores); - void PublishStats(); - - void Handle(TEvQuota::TEvRequest::TPtr &ev); - void Handle(TEvQuota::TEvCancelRequest::TPtr &ev); - void Handle(TEvQuota::TEvProxySession::TPtr &ev); - void Handle(TEvQuota::TEvProxyUpdate::TPtr &ev); - void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev); - void HandleTick(); - - void CreateKesusQuoter(NSchemeCache::TSchemeCacheNavigate::TEntry &navigate, decltype(QuotersIndex)::iterator indexIt, decltype(Quoters)::iterator quoterIt); - void BreakQuoter(decltype(QuotersIndex)::iterator indexIt, decltype(Quoters)::iterator quoterIt); - void BreakQuoter(decltype(Quoters)::iterator quoterIt); + void MarkScheduleAllocation(TResource& quores, TDuration delay, TInstant now); + + void InitialRequestProcessing(TEvQuota::TEvRequest::TPtr &ev, const ui32 reqIdx); + + void ForbidResource(TResource &quores); + void CheckRequest(ui32 reqIdx); + void FillStats(TResource &quores); + void FeedResource(TResource &quores); + void AllocateResource(TResource &quores); + void PublishStats(); + + void Handle(TEvQuota::TEvRequest::TPtr &ev); + void Handle(TEvQuota::TEvCancelRequest::TPtr &ev); + void Handle(TEvQuota::TEvProxySession::TPtr &ev); + void Handle(TEvQuota::TEvProxyUpdate::TPtr &ev); + void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev); + void HandleTick(); + + void CreateKesusQuoter(NSchemeCache::TSchemeCacheNavigate::TEntry &navigate, decltype(QuotersIndex)::iterator indexIt, decltype(Quoters)::iterator quoterIt); + void BreakQuoter(decltype(QuotersIndex)::iterator indexIt, decltype(Quoters)::iterator quoterIt); + void BreakQuoter(decltype(Quoters)::iterator quoterIt); TString PrintEvent(const TEvQuota::TEvRequest::TPtr& ev); -public: +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::QUOTER_SERVICE_ACTOR; - } - + } + TQuoterService(const TQuoterServiceConfig &config); ~TQuoterService(); - + void Bootstrap(); - STFUNC(StateFunc) { - Y_UNUSED(ctx); - switch (ev->GetTypeRewrite()) { - hFunc(TEvQuota::TEvRequest, Handle); - hFunc(TEvQuota::TEvCancelRequest, Handle); - hFunc(TEvQuota::TEvProxySession, Handle); - hFunc(TEvQuota::TEvProxyUpdate, Handle); - cFunc(TEvents::TEvWakeup::EventType, HandleTick); - hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle); - default: - LOG_WARN_S(ctx, NKikimrServices::QUOTER_SERVICE, "TQuoterService::StateFunc unexpected event type# " - << ev->GetTypeRewrite() - << " event: " - << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?")); - break; - } - - PublishStats(); - } -}; - -} -} + STFUNC(StateFunc) { + Y_UNUSED(ctx); + switch (ev->GetTypeRewrite()) { + hFunc(TEvQuota::TEvRequest, Handle); + hFunc(TEvQuota::TEvCancelRequest, Handle); + hFunc(TEvQuota::TEvProxySession, Handle); + hFunc(TEvQuota::TEvProxyUpdate, Handle); + cFunc(TEvents::TEvWakeup::EventType, HandleTick); + hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle); + default: + LOG_WARN_S(ctx, NKikimrServices::QUOTER_SERVICE, "TQuoterService::StateFunc unexpected event type# " + << ev->GetTypeRewrite() + << " event: " + << TString(ev->HasEvent() ? ev->GetBase()->ToString() : "serialized?")); + break; + } + + PublishStats(); + } +}; + +} +} diff --git a/ydb/core/quoter/quoter_service_ut.cpp b/ydb/core/quoter/quoter_service_ut.cpp index 440208dd2f..88c74ca3fb 100644 --- a/ydb/core/quoter/quoter_service_ut.cpp +++ b/ydb/core/quoter/quoter_service_ut.cpp @@ -1,58 +1,58 @@ -#include "quoter_service.h" - +#include "quoter_service.h" + #include <ydb/core/kesus/tablet/events.h> #include <ydb/core/testlib/basics/appdata.h> #include <ydb/core/testlib/basics/helpers.h> #include <ydb/core/testlib/tablet_helpers.h> #include <ydb/core/testlib/test_client.h> - + #include <library/cpp/testing/unittest/registar.h> - + #include <util/system/compiler.h> #include <util/system/valgrind.h> -namespace NKikimr { -using namespace Tests; - -Y_UNIT_TEST_SUITE(TQuoterServiceTest) { - Y_UNIT_TEST(StaticRateLimiter) { - TServerSettings serverSettings(0); - TServer server = TServer(serverSettings, true); - TTestActorRuntime *runtime = server.GetRuntime(); - +namespace NKikimr { +using namespace Tests; + +Y_UNIT_TEST_SUITE(TQuoterServiceTest) { + Y_UNIT_TEST(StaticRateLimiter) { + TServerSettings serverSettings(0); + TServer server = TServer(serverSettings, true); + TTestActorRuntime *runtime = server.GetRuntime(); + const TActorId serviceId = MakeQuoterServiceID(); const TActorId serviceActorId = runtime->Register(CreateQuoterService()); - runtime->RegisterService(serviceId, serviceActorId); - + runtime->RegisterService(serviceId, serviceActorId); + TActorId sender = runtime->AllocateEdgeActor(); - { - runtime->Send(new IEventHandle(MakeQuoterServiceID(), sender, - new TEvQuota::TEvRequest(TEvQuota::EResourceOperator::And, { - TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::ResourceForbid, 1) - }, TDuration::Max()))); - - THolder<TEvQuota::TEvClearance> reply = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); - UNIT_ASSERT(reply->Result == TEvQuota::TEvClearance::EResult::Deadline); - } - { - runtime->Send(new IEventHandle(MakeQuoterServiceID(), sender, - new TEvQuota::TEvRequest(TEvQuota::EResourceOperator::And, { - TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::ResourceNocheck, 1) - }, TDuration::Max()))); - - THolder<TEvQuota::TEvClearance> reply = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); - UNIT_ASSERT(reply->Result == TEvQuota::TEvClearance::EResult::Success); - } - - { - runtime->Send(new IEventHandle(MakeQuoterServiceID(), sender, - new TEvQuota::TEvRequest(TEvQuota::EResourceOperator::And, { - TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::MakeTaggedRateRes(1, 1000), 1) - }, TDuration::Max()))); - - THolder<TEvQuota::TEvClearance> reply = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); - UNIT_ASSERT(reply->Result == TEvQuota::TEvClearance::EResult::Success); - } + { + runtime->Send(new IEventHandle(MakeQuoterServiceID(), sender, + new TEvQuota::TEvRequest(TEvQuota::EResourceOperator::And, { + TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::ResourceForbid, 1) + }, TDuration::Max()))); + + THolder<TEvQuota::TEvClearance> reply = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); + UNIT_ASSERT(reply->Result == TEvQuota::TEvClearance::EResult::Deadline); + } + { + runtime->Send(new IEventHandle(MakeQuoterServiceID(), sender, + new TEvQuota::TEvRequest(TEvQuota::EResourceOperator::And, { + TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::ResourceNocheck, 1) + }, TDuration::Max()))); + + THolder<TEvQuota::TEvClearance> reply = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); + UNIT_ASSERT(reply->Result == TEvQuota::TEvClearance::EResult::Success); + } + + { + runtime->Send(new IEventHandle(MakeQuoterServiceID(), sender, + new TEvQuota::TEvRequest(TEvQuota::EResourceOperator::And, { + TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::MakeTaggedRateRes(1, 1000), 1) + }, TDuration::Max()))); + + THolder<TEvQuota::TEvClearance> reply = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); + UNIT_ASSERT(reply->Result == TEvQuota::TEvClearance::EResult::Success); + } { // test static quter queues processing @@ -107,8 +107,8 @@ Y_UNIT_TEST_SUITE(TQuoterServiceTest) { reply = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); UNIT_ASSERT(reply->Result == TEvQuota::TEvClearance::EResult::Success); } - } - + } + #if defined(OPTIMIZED) #error "Macro conflict." #endif @@ -256,86 +256,86 @@ Y_UNIT_TEST_SUITE(TQuoterServiceTest) { } #endif - Y_UNIT_TEST(StaticMultipleAndResources) { - TServerSettings serverSettings(0); - TServer server = TServer(serverSettings, true); - TTestActorRuntime *runtime = server.GetRuntime(); - + Y_UNIT_TEST(StaticMultipleAndResources) { + TServerSettings serverSettings(0); + TServer server = TServer(serverSettings, true); + TTestActorRuntime *runtime = server.GetRuntime(); + const TActorId serviceId = MakeQuoterServiceID(); const TActorId serviceActorId = runtime->Register(CreateQuoterService()); - runtime->RegisterService(serviceId, serviceActorId); - + runtime->RegisterService(serviceId, serviceActorId); + TActorId sender = runtime->AllocateEdgeActor(); - { - runtime->Send(new IEventHandle(MakeQuoterServiceID(), sender, - new TEvQuota::TEvRequest(TEvQuota::EResourceOperator::And, { - TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::ResourceForbid, 1), - TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::ResourceNocheck, 1), - }, TDuration::Max()))); - - THolder<TEvQuota::TEvClearance> reply = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); - UNIT_ASSERT(reply->Result == TEvQuota::TEvClearance::EResult::Deadline); - } - { - runtime->Send(new IEventHandle(MakeQuoterServiceID(), sender, - new TEvQuota::TEvRequest(TEvQuota::EResourceOperator::And, { - TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::ResourceNocheck, 1), - TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::ResourceNocheck, 1), - }, TDuration::Max()))); - - THolder<TEvQuota::TEvClearance> reply = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); - UNIT_ASSERT(reply->Result == TEvQuota::TEvClearance::EResult::Success); - } - - { - runtime->Send(new IEventHandle(MakeQuoterServiceID(), sender, - new TEvQuota::TEvRequest(TEvQuota::EResourceOperator::And, { - TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::MakeTaggedRateRes(1, 1000), 1), - TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::ResourceNocheck, 1), - }, TDuration::Max()))); - - THolder<TEvQuota::TEvClearance> reply = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); - UNIT_ASSERT(reply->Result == TEvQuota::TEvClearance::EResult::Success); - } - } - - Y_UNIT_TEST(StaticDeadlines) { - TServerSettings serverSettings(0); - TServer server = TServer(serverSettings, true); - TTestActorRuntime *runtime = server.GetRuntime(); - + { + runtime->Send(new IEventHandle(MakeQuoterServiceID(), sender, + new TEvQuota::TEvRequest(TEvQuota::EResourceOperator::And, { + TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::ResourceForbid, 1), + TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::ResourceNocheck, 1), + }, TDuration::Max()))); + + THolder<TEvQuota::TEvClearance> reply = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); + UNIT_ASSERT(reply->Result == TEvQuota::TEvClearance::EResult::Deadline); + } + { + runtime->Send(new IEventHandle(MakeQuoterServiceID(), sender, + new TEvQuota::TEvRequest(TEvQuota::EResourceOperator::And, { + TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::ResourceNocheck, 1), + TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::ResourceNocheck, 1), + }, TDuration::Max()))); + + THolder<TEvQuota::TEvClearance> reply = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); + UNIT_ASSERT(reply->Result == TEvQuota::TEvClearance::EResult::Success); + } + + { + runtime->Send(new IEventHandle(MakeQuoterServiceID(), sender, + new TEvQuota::TEvRequest(TEvQuota::EResourceOperator::And, { + TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::MakeTaggedRateRes(1, 1000), 1), + TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::ResourceNocheck, 1), + }, TDuration::Max()))); + + THolder<TEvQuota::TEvClearance> reply = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); + UNIT_ASSERT(reply->Result == TEvQuota::TEvClearance::EResult::Success); + } + } + + Y_UNIT_TEST(StaticDeadlines) { + TServerSettings serverSettings(0); + TServer server = TServer(serverSettings, true); + TTestActorRuntime *runtime = server.GetRuntime(); + const TActorId serviceId = MakeQuoterServiceID(); const TActorId serviceActorId = runtime->Register(CreateQuoterService()); - runtime->RegisterService(serviceId, serviceActorId); - + runtime->RegisterService(serviceId, serviceActorId); + TActorId sender = runtime->AllocateEdgeActor(); - { - runtime->Send(new IEventHandle(MakeQuoterServiceID(), sender, - new TEvQuota::TEvRequest(TEvQuota::EResourceOperator::And, { - TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::MakeTaggedRateRes(1, 10), 20) - }, TDuration::Seconds(3)))); - - runtime->Send(new IEventHandle(MakeQuoterServiceID(), sender, - new TEvQuota::TEvRequest(TEvQuota::EResourceOperator::And, { - TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::MakeTaggedRateRes(1, 10), 20) - }, TDuration::Seconds(3)))); - - runtime->Send(new IEventHandle(MakeQuoterServiceID(), sender, - new TEvQuota::TEvRequest(TEvQuota::EResourceOperator::And, { - TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::MakeTaggedRateRes(1, 10), 20) - }, TDuration::Seconds(3)))); - - THolder<TEvQuota::TEvClearance> reply1 = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); + { + runtime->Send(new IEventHandle(MakeQuoterServiceID(), sender, + new TEvQuota::TEvRequest(TEvQuota::EResourceOperator::And, { + TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::MakeTaggedRateRes(1, 10), 20) + }, TDuration::Seconds(3)))); + + runtime->Send(new IEventHandle(MakeQuoterServiceID(), sender, + new TEvQuota::TEvRequest(TEvQuota::EResourceOperator::And, { + TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::MakeTaggedRateRes(1, 10), 20) + }, TDuration::Seconds(3)))); + + runtime->Send(new IEventHandle(MakeQuoterServiceID(), sender, + new TEvQuota::TEvRequest(TEvQuota::EResourceOperator::And, { + TEvQuota::TResourceLeaf(TEvQuota::TResourceLeaf::QuoterSystem, TEvQuota::TResourceLeaf::MakeTaggedRateRes(1, 10), 20) + }, TDuration::Seconds(3)))); + + THolder<TEvQuota::TEvClearance> reply1 = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); UNIT_ASSERT_C(reply1->Result == TEvQuota::TEvClearance::EResult::Success, "Result: " << static_cast<int>(reply1->Result)); - - THolder<TEvQuota::TEvClearance> reply2 = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); + + THolder<TEvQuota::TEvClearance> reply2 = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); UNIT_ASSERT_C(reply2->Result == TEvQuota::TEvClearance::EResult::Success, "Result: " << static_cast<int>(reply2->Result)); - - THolder<TEvQuota::TEvClearance> reply3 = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); + + THolder<TEvQuota::TEvClearance> reply3 = runtime->GrabEdgeEvent<TEvQuota::TEvClearance>(); UNIT_ASSERT_C(reply3->Result == TEvQuota::TEvClearance::EResult::Deadline, "Result: " << static_cast<int>(reply3->Result)); - } - } - -} - -} + } + } + +} + +} diff --git a/ydb/core/quoter/ut/ya.make b/ydb/core/quoter/ut/ya.make index f507192a06..eca5ac0e40 100644 --- a/ydb/core/quoter/ut/ya.make +++ b/ydb/core/quoter/ut/ya.make @@ -3,14 +3,14 @@ IF (NOT OS_WINDOWS) UNITTEST_FOR(ydb/core/quoter) OWNER(g:kikimr) - + PEERDIR( library/cpp/testing/gmock_in_unittest ydb/core/testlib ) - + YQL_LAST_ABI_VERSION() - + SRCS( kesus_quoter_ut.cpp quoter_service_ut.cpp @@ -30,6 +30,6 @@ IF (NOT OS_WINDOWS) SIZE(MEDIUM) TIMEOUT(600) ENDIF() - + END() ENDIF() diff --git a/ydb/core/quoter/ya.make b/ydb/core/quoter/ya.make index 3f3368d468..937aae960d 100644 --- a/ydb/core/quoter/ya.make +++ b/ydb/core/quoter/ya.make @@ -1,21 +1,21 @@ -LIBRARY() - -OWNER( - ddoarn - g:kikimr -) - -SRCS( +LIBRARY() + +OWNER( + ddoarn + g:kikimr +) + +SRCS( debug_info.cpp - defs.h - kesus_quoter_proxy.cpp + defs.h + kesus_quoter_proxy.cpp probes.cpp - quoter_service.cpp - quoter_service.h - quoter_service_impl.h -) - -PEERDIR( + quoter_service.cpp + quoter_service.h + quoter_service_impl.h +) + +PEERDIR( library/cpp/actors/core library/cpp/containers/ring_buffer ydb/core/base @@ -23,9 +23,9 @@ PEERDIR( ydb/core/tx/scheme_cache ydb/core/util ydb/library/yql/public/issue -) - -END() +) + +END() RECURSE( quoter_service_bandwidth_test diff --git a/ydb/core/scheme/scheme_tablecell.h b/ydb/core/scheme/scheme_tablecell.h index a2d8406451..bccfdca97d 100644 --- a/ydb/core/scheme/scheme_tablecell.h +++ b/ydb/core/scheme/scheme_tablecell.h @@ -162,7 +162,7 @@ inline int CompareTypedCells(const TCell& a, const TCell& b, NScheme::TTypeIdOrd case NKikimr::NScheme::NTypeIds::String2m: case NKikimr::NScheme::NTypeIds::Utf8: case NKikimr::NScheme::NTypeIds::Json: - case NKikimr::NScheme::NTypeIds::Yson: + case NKikimr::NScheme::NTypeIds::Yson: // XXX: using memcmp is meaningless for both JsonDocument and Json case NKikimr::NScheme::NTypeIds::JsonDocument: case NKikimr::NScheme::NTypeIds::DyNumber: @@ -224,57 +224,57 @@ inline int CompareTypedCellVectors(const TCell* a, const TCell* b, const TTypeCl return 0; } -// TODO: use NYql ops when TCell and TUnboxedValuePod had merged +// TODO: use NYql ops when TCell and TUnboxedValuePod had merged inline ui64 GetValueHash(NScheme::TTypeId type, const TCell& cell) { if (cell.IsNull()) return 0; - const NYql::NProto::TypeIds yqlType = static_cast<NYql::NProto::TypeIds>(type); - switch (yqlType) { - case NYql::NProto::TypeIds::Bool: - return ((*(const ui8 *)cell.Data()) == 0) ? THash<ui8>()((ui8)0) : THash<ui8>()((ui8)1); - case NYql::NProto::TypeIds::Int8: - return THash<i8>()(*(const i8*)cell.Data()); - case NYql::NProto::TypeIds::Uint8: + const NYql::NProto::TypeIds yqlType = static_cast<NYql::NProto::TypeIds>(type); + switch (yqlType) { + case NYql::NProto::TypeIds::Bool: + return ((*(const ui8 *)cell.Data()) == 0) ? THash<ui8>()((ui8)0) : THash<ui8>()((ui8)1); + case NYql::NProto::TypeIds::Int8: + return THash<i8>()(*(const i8*)cell.Data()); + case NYql::NProto::TypeIds::Uint8: return THash<ui8>()(*(const ui8*)cell.Data()); - case NYql::NProto::TypeIds::Int16: - return THash<i16>()(*(const i16*)cell.Data()); - case NYql::NProto::TypeIds::Uint16: - return THash<ui16>()(*(const ui16*)cell.Data()); - case NYql::NProto::TypeIds::Int32: + case NYql::NProto::TypeIds::Int16: + return THash<i16>()(*(const i16*)cell.Data()); + case NYql::NProto::TypeIds::Uint16: + return THash<ui16>()(*(const ui16*)cell.Data()); + case NYql::NProto::TypeIds::Int32: return THash<i32>()(ReadUnaligned<i32>((const i32*)cell.Data())); - case NYql::NProto::TypeIds::Uint32: + case NYql::NProto::TypeIds::Uint32: return THash<ui32>()(ReadUnaligned<ui32>((const ui32*)cell.Data())); - case NYql::NProto::TypeIds::Int64: + case NYql::NProto::TypeIds::Int64: return THash<i64>()(ReadUnaligned<i64>((const i64*)cell.Data())); - case NYql::NProto::TypeIds::Uint64: + case NYql::NProto::TypeIds::Uint64: return THash<ui64>()(ReadUnaligned<ui64>((const ui64*)cell.Data())); - case NYql::NProto::TypeIds::Float: + case NYql::NProto::TypeIds::Float: return THash<float>()(ReadUnaligned<float>((const float*)cell.Data())); - case NYql::NProto::TypeIds::Double: + case NYql::NProto::TypeIds::Double: return THash<double>()(ReadUnaligned<double>((const double*)cell.Data())); - case NYql::NProto::TypeIds::Date: + case NYql::NProto::TypeIds::Date: return THash<ui16>()(ReadUnaligned<ui16>((const ui16*)cell.Data())); - case NYql::NProto::TypeIds::Datetime: - return THash<ui32>()(ReadUnaligned<ui32>((const ui32*)cell.Data())); - case NYql::NProto::TypeIds::Timestamp: - return THash<ui32>()(ReadUnaligned<ui64>((const ui64*)cell.Data())); - case NYql::NProto::TypeIds::Interval: - return THash<ui32>()(ReadUnaligned<ui64>((const ui64*)cell.Data())); - - case NYql::NProto::TypeIds::String: - case NYql::NProto::TypeIds::Utf8: - case NYql::NProto::TypeIds::Yson: - case NYql::NProto::TypeIds::Json: - case NYql::NProto::TypeIds::Decimal: + case NYql::NProto::TypeIds::Datetime: + return THash<ui32>()(ReadUnaligned<ui32>((const ui32*)cell.Data())); + case NYql::NProto::TypeIds::Timestamp: + return THash<ui32>()(ReadUnaligned<ui64>((const ui64*)cell.Data())); + case NYql::NProto::TypeIds::Interval: + return THash<ui32>()(ReadUnaligned<ui64>((const ui64*)cell.Data())); + + case NYql::NProto::TypeIds::String: + case NYql::NProto::TypeIds::Utf8: + case NYql::NProto::TypeIds::Yson: + case NYql::NProto::TypeIds::Json: + case NYql::NProto::TypeIds::Decimal: case NYql::NProto::TypeIds::JsonDocument: case NYql::NProto::TypeIds::DyNumber: return ComputeHash(TStringBuf{cell.Data(), cell.Size()}); - default: - Y_VERIFY_DEBUG(false, "Type not supported for user columns: %d", type); - break; + default: + Y_VERIFY_DEBUG(false, "Type not supported for user columns: %d", type); + break; } return 0; @@ -527,4 +527,4 @@ void DbgPrintValue(TString&, const TCell&, ui32 type); TString DbgPrintCell(const TCell& r, NScheme::TTypeId typeId, const NScheme::TTypeRegistry& typeRegistry); TString DbgPrintTuple(const TDbTupleRef& row, const NScheme::TTypeRegistry& typeRegistry); -} +} diff --git a/ydb/core/scheme/scheme_tablecell_ut.cpp b/ydb/core/scheme/scheme_tablecell_ut.cpp index 36c2d07f1a..5bd4a27ab9 100644 --- a/ydb/core/scheme/scheme_tablecell_ut.cpp +++ b/ydb/core/scheme/scheme_tablecell_ut.cpp @@ -281,76 +281,76 @@ Y_UNIT_TEST_SUITE(Scheme) { NScheme::NTypeIds::Decimal); } - Y_UNIT_TEST(YqlTypesMustBeDefined) { - const char charArr[64] = { 0 }; - - TArrayRef<const NScheme::TTypeId> yqlIds(NScheme::NTypeIds::YqlIds); - for (NScheme::TTypeId typeId : yqlIds) { - switch (typeId) { - case NScheme::NTypeIds::Int32: - GetValueHash(typeId, TCell(charArr, sizeof(i32))); - CompareTypedCells(TCell(charArr, sizeof(i32)), TCell(charArr, sizeof(i32)), typeId); - break; - case NScheme::NTypeIds::Uint32: - GetValueHash(typeId, TCell(charArr, sizeof(ui32))); - CompareTypedCells(TCell(charArr, sizeof(ui32)), TCell(charArr, sizeof(ui32)), typeId); - break; - case NScheme::NTypeIds::Int64: - GetValueHash(typeId, TCell(charArr, sizeof(i64))); - CompareTypedCells(TCell(charArr, sizeof(i64)), TCell(charArr, sizeof(i64)), typeId); - break; - case NScheme::NTypeIds::Uint64: - GetValueHash(typeId, TCell(charArr, sizeof(ui64))); - CompareTypedCells(TCell(charArr, sizeof(ui64)), TCell(charArr, sizeof(ui64)), typeId); - break; - case NScheme::NTypeIds::Byte: - GetValueHash(typeId, TCell(charArr, sizeof(ui8))); - CompareTypedCells(TCell(charArr, sizeof(ui8)), TCell(charArr, sizeof(ui8)), typeId); - break; - case NScheme::NTypeIds::Bool: - GetValueHash(typeId, TCell(charArr, sizeof(ui8))); - CompareTypedCells(TCell(charArr, sizeof(ui8)), TCell(charArr, sizeof(ui8)), typeId); - break; - case NScheme::NTypeIds::Double: - GetValueHash(typeId, TCell(charArr, sizeof(double))); - CompareTypedCells(TCell(charArr, sizeof(double)), TCell(charArr, sizeof(double)), typeId); - break; - case NScheme::NTypeIds::Float: - GetValueHash(typeId, TCell(charArr, sizeof(float))); - CompareTypedCells(TCell(charArr, sizeof(float)), TCell(charArr, sizeof(float)), typeId); - break; - case NScheme::NTypeIds::String: - case NScheme::NTypeIds::Utf8: - case NScheme::NTypeIds::Yson: - case NScheme::NTypeIds::Json: + Y_UNIT_TEST(YqlTypesMustBeDefined) { + const char charArr[64] = { 0 }; + + TArrayRef<const NScheme::TTypeId> yqlIds(NScheme::NTypeIds::YqlIds); + for (NScheme::TTypeId typeId : yqlIds) { + switch (typeId) { + case NScheme::NTypeIds::Int32: + GetValueHash(typeId, TCell(charArr, sizeof(i32))); + CompareTypedCells(TCell(charArr, sizeof(i32)), TCell(charArr, sizeof(i32)), typeId); + break; + case NScheme::NTypeIds::Uint32: + GetValueHash(typeId, TCell(charArr, sizeof(ui32))); + CompareTypedCells(TCell(charArr, sizeof(ui32)), TCell(charArr, sizeof(ui32)), typeId); + break; + case NScheme::NTypeIds::Int64: + GetValueHash(typeId, TCell(charArr, sizeof(i64))); + CompareTypedCells(TCell(charArr, sizeof(i64)), TCell(charArr, sizeof(i64)), typeId); + break; + case NScheme::NTypeIds::Uint64: + GetValueHash(typeId, TCell(charArr, sizeof(ui64))); + CompareTypedCells(TCell(charArr, sizeof(ui64)), TCell(charArr, sizeof(ui64)), typeId); + break; + case NScheme::NTypeIds::Byte: + GetValueHash(typeId, TCell(charArr, sizeof(ui8))); + CompareTypedCells(TCell(charArr, sizeof(ui8)), TCell(charArr, sizeof(ui8)), typeId); + break; + case NScheme::NTypeIds::Bool: + GetValueHash(typeId, TCell(charArr, sizeof(ui8))); + CompareTypedCells(TCell(charArr, sizeof(ui8)), TCell(charArr, sizeof(ui8)), typeId); + break; + case NScheme::NTypeIds::Double: + GetValueHash(typeId, TCell(charArr, sizeof(double))); + CompareTypedCells(TCell(charArr, sizeof(double)), TCell(charArr, sizeof(double)), typeId); + break; + case NScheme::NTypeIds::Float: + GetValueHash(typeId, TCell(charArr, sizeof(float))); + CompareTypedCells(TCell(charArr, sizeof(float)), TCell(charArr, sizeof(float)), typeId); + break; + case NScheme::NTypeIds::String: + case NScheme::NTypeIds::Utf8: + case NScheme::NTypeIds::Yson: + case NScheme::NTypeIds::Json: case NScheme::NTypeIds::JsonDocument: case NScheme::NTypeIds::DyNumber: - GetValueHash(typeId, TCell(charArr, 30)); - CompareTypedCells(TCell(charArr, 30), TCell(charArr, 30), typeId); - break; - case NScheme::NTypeIds::Decimal: - GetValueHash(typeId, TCell(charArr, sizeof(ui64) * 2)); - CompareTypedCells(TCell(charArr, sizeof(ui64) * 2), TCell(charArr, sizeof(ui64) * 2), typeId); - break; - case NScheme::NTypeIds::Date: - GetValueHash(typeId, TCell(charArr, sizeof(ui16))); - CompareTypedCells(TCell(charArr, sizeof(ui16)), TCell(charArr, sizeof(ui16)), typeId); - break; - case NScheme::NTypeIds::Datetime: - GetValueHash(typeId, TCell(charArr, sizeof(ui32))); - CompareTypedCells(TCell(charArr, sizeof(ui32)), TCell(charArr, sizeof(ui32)), typeId); - break; - case NScheme::NTypeIds::Timestamp: - GetValueHash(typeId, TCell(charArr, sizeof(ui64))); - CompareTypedCells(TCell(charArr, sizeof(ui64)), TCell(charArr, sizeof(ui64)), typeId); - break; - case NScheme::NTypeIds::Interval: - GetValueHash(typeId, TCell(charArr, sizeof(i64))); - CompareTypedCells(TCell(charArr, sizeof(i64)), TCell(charArr, sizeof(i64)), typeId); - break; - default: - UNIT_FAIL("undefined YQL type"); - } - } - } + GetValueHash(typeId, TCell(charArr, 30)); + CompareTypedCells(TCell(charArr, 30), TCell(charArr, 30), typeId); + break; + case NScheme::NTypeIds::Decimal: + GetValueHash(typeId, TCell(charArr, sizeof(ui64) * 2)); + CompareTypedCells(TCell(charArr, sizeof(ui64) * 2), TCell(charArr, sizeof(ui64) * 2), typeId); + break; + case NScheme::NTypeIds::Date: + GetValueHash(typeId, TCell(charArr, sizeof(ui16))); + CompareTypedCells(TCell(charArr, sizeof(ui16)), TCell(charArr, sizeof(ui16)), typeId); + break; + case NScheme::NTypeIds::Datetime: + GetValueHash(typeId, TCell(charArr, sizeof(ui32))); + CompareTypedCells(TCell(charArr, sizeof(ui32)), TCell(charArr, sizeof(ui32)), typeId); + break; + case NScheme::NTypeIds::Timestamp: + GetValueHash(typeId, TCell(charArr, sizeof(ui64))); + CompareTypedCells(TCell(charArr, sizeof(ui64)), TCell(charArr, sizeof(ui64)), typeId); + break; + case NScheme::NTypeIds::Interval: + GetValueHash(typeId, TCell(charArr, sizeof(i64))); + CompareTypedCells(TCell(charArr, sizeof(i64)), TCell(charArr, sizeof(i64)), typeId); + break; + default: + UNIT_FAIL("undefined YQL type"); + } + } + } } diff --git a/ydb/core/scheme/scheme_tabledefs.cpp b/ydb/core/scheme/scheme_tabledefs.cpp index 3e2a4391b4..8c91e03d0e 100644 --- a/ydb/core/scheme/scheme_tabledefs.cpp +++ b/ydb/core/scheme/scheme_tabledefs.cpp @@ -1,15 +1,15 @@ -#include "scheme_tabledefs.h" - -namespace NKikimr { - +#include "scheme_tabledefs.h" + +namespace NKikimr { + bool TTableRange::IsEmptyRange(TConstArrayRef<const NScheme::TTypeId> cellTypeIds) const { - if (Point) - return false; - + if (Point) + return false; + const int compares = CompareBorders<true, false>(To, From, InclusiveTo, InclusiveFrom, cellTypeIds); - return (compares < 0); -} - + return (compares < 0); +} + bool TSerializedTableRange::IsEmpty(TConstArrayRef<NScheme::TTypeId> type) const { auto cmp = CompareBorders<true, false>(To.GetCells(), From.GetCells(), ToInclusive, FromInclusive, type); @@ -17,19 +17,19 @@ bool TSerializedTableRange::IsEmpty(TConstArrayRef<NScheme::TTypeId> type) const } void TKeyDesc::Out(IOutputStream& o, TKeyDesc::EStatus x) { -#define KEYDESCRIPTION_STATUS_TO_STRING_IMPL(name, ...) \ - case EStatus::name: \ - o << #name; \ - return; - - switch (x) { - SCHEME_KEY_DESCRIPTION_STATUS_MAP(KEYDESCRIPTION_STATUS_TO_STRING_IMPL) - default: - o << static_cast<int>(x); - return; - } -} - +#define KEYDESCRIPTION_STATUS_TO_STRING_IMPL(name, ...) \ + case EStatus::name: \ + o << #name; \ + return; + + switch (x) { + SCHEME_KEY_DESCRIPTION_STATUS_MAP(KEYDESCRIPTION_STATUS_TO_STRING_IMPL) + default: + o << static_cast<int>(x); + return; + } +} + struct TSystemColumnsData { const TString PartitionColumnName = "_yql_partition_id"; @@ -45,7 +45,7 @@ bool IsSystemColumn(ui32 columnId) { default: return false; } -} +} bool IsSystemColumn(const TStringBuf columnName) { return GetSystemColumns().FindPtr(columnName); diff --git a/ydb/core/scheme/scheme_tabledefs.h b/ydb/core/scheme/scheme_tabledefs.h index 5bbe0ae2cb..190233fdee 100644 --- a/ydb/core/scheme/scheme_tabledefs.h +++ b/ydb/core/scheme/scheme_tabledefs.h @@ -1,7 +1,7 @@ -#pragma once - -#include "defs.h" -#include "scheme_tablecell.h" +#pragma once + +#include "defs.h" +#include "scheme_tablecell.h" #include <ydb/core/base/pathid.h> #include <ydb/core/protos/tx.pb.h> @@ -9,23 +9,23 @@ #include <ydb/library/aclib/aclib.h> #include <library/cpp/deprecated/enum_codegen/enum_codegen.h> - + #include <util/generic/maybe.h> #include <util/generic/map.h> -namespace NKikimr { - +namespace NKikimr { + using TSchemaVersion = ui64; -// ident for table, must be unique in selected scope -// for global transactions ownerid is tabletid of owning schemeshard and tableid is counter designated by schemeshard +// ident for table, must be unique in selected scope +// for global transactions ownerid is tabletid of owning schemeshard and tableid is counter designated by schemeshard // SysViewInfo is not empty for system views attached to corresponding table -struct TTableId { +struct TTableId { TPathId PathId; TString SysViewInfo; TSchemaVersion SchemaVersion = 0; - + TTableId() = default; // raw ctors @@ -33,8 +33,8 @@ struct TTableId { : PathId(ownerId, tableId) , SysViewInfo(sysViewInfo) , SchemaVersion(schemaVersion) - {} - + {} + TTableId(ui64 ownerId, ui64 tableId, const TString& sysViewInfo) : TTableId(ownerId, tableId, sysViewInfo, 0) {} @@ -45,8 +45,8 @@ struct TTableId { TTableId(ui64 ownerId, ui64 tableId) : TTableId(ownerId, tableId, TString(), 0) - {} - + {} + // ctors from TPathId TTableId(const TPathId& pathId, const TString& sysViewInfo, ui64 schemaVersion) : TTableId(pathId.OwnerId, pathId.LocalPathId, sysViewInfo, schemaVersion) @@ -64,14 +64,14 @@ struct TTableId { : TTableId(pathId, TString(), 0) {} - explicit operator bool() const noexcept { + explicit operator bool() const noexcept { return bool(PathId); - } - + } + bool HasSamePath(const TTableId &x) const noexcept { return PathId == x.PathId && SysViewInfo == x.SysViewInfo; - } - + } + bool IsSystemView() const noexcept { return !SysViewInfo.empty(); } @@ -103,9 +103,9 @@ struct TTableId { } return hash; - } -}; - + } +}; + struct TIndexId { TPathId PathId; TSchemaVersion SchemaVersion = 0; @@ -138,45 +138,45 @@ using TTablePathHashMap = THashMap<TTableId, T, TTablePathHashFn, TTablePathEqua using TTablePathHashSet = THashSet<TTableId, TTablePathHashFn, TTablePathEqualFn>; -// defines key range as low and high borders (possibly partial - w/o defined key values on tail) -// missing values interpreted as infinity and mean "greater then any key with set prefix" -// column order must match table key order -// [{a, null}, {b, null}) => { (a, null), (b, null), inclusive = true, inclusive = false ) } -// ({a, inf}, {b, inf}) => { (a), (b), false, false) } ('inclusive' does not matter for infinity) -// [{a, 1}, {inf}) => { (a, 1), (), inclusive = true, inclusive = false) } -// (-inf, +inf) => { (null, null), (), inclusive = true, false) } ((null, null) is smallest defined key greater then -infinity, so we must include it in range -// [{a, 1}, {b, 3}] => { (a, 1), (b, 3), inclusive = true, inclusive = true) } (probably most used case w/o any corner cases -class TTableRange { -public: +// defines key range as low and high borders (possibly partial - w/o defined key values on tail) +// missing values interpreted as infinity and mean "greater then any key with set prefix" +// column order must match table key order +// [{a, null}, {b, null}) => { (a, null), (b, null), inclusive = true, inclusive = false ) } +// ({a, inf}, {b, inf}) => { (a), (b), false, false) } ('inclusive' does not matter for infinity) +// [{a, 1}, {inf}) => { (a, 1), (), inclusive = true, inclusive = false) } +// (-inf, +inf) => { (null, null), (), inclusive = true, false) } ((null, null) is smallest defined key greater then -infinity, so we must include it in range +// [{a, 1}, {b, 3}] => { (a, 1), (b, 3), inclusive = true, inclusive = true) } (probably most used case w/o any corner cases +class TTableRange { +public: TConstArrayRef<TCell> From; TConstArrayRef<TCell> To; bool InclusiveFrom; bool InclusiveTo; bool Point; - + explicit TTableRange(TConstArrayRef<TCell> point) - : From(point) - , To() - , InclusiveFrom(true) - , InclusiveTo(true) + : From(point) + , To() + , InclusiveFrom(true) + , InclusiveTo(true) , Point(true) {} - + TTableRange(TConstArrayRef<TCell> fromValues, bool inclusiveFrom, TConstArrayRef<TCell> toValues, bool inclusiveTo, bool point = false) - : From(fromValues) - , To(toValues) - , InclusiveFrom(inclusiveFrom || point) - , InclusiveTo(inclusiveTo || point) + : From(fromValues) + , To(toValues) + , InclusiveFrom(inclusiveFrom || point) + , InclusiveTo(inclusiveTo || point) , Point(point) { if (Point) { Y_VERIFY_DEBUG(toValues.empty() || fromValues.size() == toValues.size()); } } - + bool IsEmptyRange(TConstArrayRef<const NScheme::TTypeId> cellTypeIds) const; -}; - +}; + class TSerializedTableRange { public: TSerializedCellVec From; @@ -283,55 +283,55 @@ int ComparePointAndRange(const TConstArrayRef<TCell>& point, const TTableRange& // Template args determine where range lies regarding compared border. // E.g. CompareBorders<true, true>(...) compares borders of ranges lying on the left // of compared borders (or in other words upper range borders are compared). -template<bool FirstLeft, bool SecondLeft> +template<bool FirstLeft, bool SecondLeft> int CompareBorders(TConstArrayRef<TCell> first, TConstArrayRef<TCell> second, bool inclusiveFirst, bool inclusiveSecond, TConstArrayRef<NScheme::TTypeId> cellTypes) { - const ui32 firstSize = first.size(); - const ui32 secondSize = second.size(); - - for (ui32 idx = 0, keyColumns = cellTypes.size(); idx < keyColumns; ++idx) { - const bool firstComplete = (firstSize == idx); - const bool secondComplete = (secondSize == idx); - - if (firstComplete) { - if (secondComplete) - return 0; - return 1; - } - - if (secondComplete) - return -1; - - if (first[idx].IsNull()) { - if (!second[idx].IsNull()) - return -1; - } else if (second[idx].IsNull()) { - return 1; + const ui32 firstSize = first.size(); + const ui32 secondSize = second.size(); + + for (ui32 idx = 0, keyColumns = cellTypes.size(); idx < keyColumns; ++idx) { + const bool firstComplete = (firstSize == idx); + const bool secondComplete = (secondSize == idx); + + if (firstComplete) { + if (secondComplete) + return 0; + return 1; + } + + if (secondComplete) + return -1; + + if (first[idx].IsNull()) { + if (!second[idx].IsNull()) + return -1; + } else if (second[idx].IsNull()) { + return 1; } else if (const int compares = CompareTypedCells(first[idx], second[idx], cellTypes[idx])) { - return compares; - } - } - - if (FirstLeft && SecondLeft) { - if (inclusiveFirst == inclusiveSecond) - return 0; - return (inclusiveFirst ? 1 : -1); - } else if (FirstLeft && !SecondLeft) { - if (inclusiveFirst && inclusiveSecond) - return 0; - return -1; - } else if (!FirstLeft && SecondLeft) { - if (inclusiveFirst && inclusiveSecond) - return 0; - return 1; - } else { // !FirstLeft && !SecondLeft - if (inclusiveFirst == inclusiveSecond) - return 0; - return (inclusiveFirst ? -1 : 1); - } -} - + return compares; + } + } + + if (FirstLeft && SecondLeft) { + if (inclusiveFirst == inclusiveSecond) + return 0; + return (inclusiveFirst ? 1 : -1); + } else if (FirstLeft && !SecondLeft) { + if (inclusiveFirst && inclusiveSecond) + return 0; + return -1; + } else if (!FirstLeft && SecondLeft) { + if (inclusiveFirst && inclusiveSecond) + return 0; + return 1; + } else { // !FirstLeft && !SecondLeft + if (inclusiveFirst == inclusiveSecond) + return 0; + return (inclusiveFirst ? -1 : 1); + } +} + /// @note returns 0 on any overlap inline int CompareRanges(const TTableRange& rangeX, const TTableRange& rangeY, const TConstArrayRef<NScheme::TTypeId> types) @@ -385,13 +385,13 @@ private: TOwnedCellVec FromKey; TOwnedCellVec ToKey; }; - + TOwnedTableRange(TInit init) : TTableRange(std::move(init.Range)) , FromKey_(std::move(init.FromKey)) , ToKey_(std::move(init.ToKey)) { } - + static TInit Allocate(TOwnedCellVec fromKey, bool inclusiveFrom, TOwnedCellVec toKey, bool inclusiveTo, bool point) @@ -422,11 +422,11 @@ private: Point = false; } -public: +public: TOwnedTableRange() : TTableRange({ }, false, { }, false, false) { } - + explicit TOwnedTableRange(TOwnedCellVec point) : TOwnedTableRange(Allocate(std::move(point), true, TOwnedCellVec(), true, true)) { } @@ -434,7 +434,7 @@ public: explicit TOwnedTableRange(TConstArrayRef<TCell> point) : TOwnedTableRange(Allocate(TOwnedCellVec(point), true, TOwnedCellVec(), true, true)) { } - + TOwnedTableRange(TOwnedCellVec fromKey, bool inclusiveFrom, TOwnedCellVec toKey, bool inclusiveTo, bool point = false) : TOwnedTableRange(Allocate(std::move(fromKey), inclusiveFrom, std::move(toKey), inclusiveTo, point)) { } @@ -494,8 +494,8 @@ public: private: TOwnedCellVec FromKey_; TOwnedCellVec ToKey_; -}; - +}; + struct TReadTarget { enum class EMode { Online, @@ -579,63 +579,63 @@ struct TSecurityObject : TAtomicRefCount<TSecurityObject>, NACLib::TSecurityObje {} }; -// key description of one minikql operation +// key description of one minikql operation class TKeyDesc : TNonCopyable { -public: - - // what we do on row? - enum struct ERowOperation { - Unknown = 1, - Read = 2, - Update = 3, - Erase = 4, - }; - - // what we do on column? - enum struct EColumnOperation { - Read = 1, - Set = 2, // == erase - InplaceUpdate = 3, - }; - +public: + + // what we do on row? + enum struct ERowOperation { + Unknown = 1, + Read = 2, + Update = 3, + Erase = 4, + }; + + // what we do on column? + enum struct EColumnOperation { + Read = 1, + Set = 2, // == erase + InplaceUpdate = 3, + }; + enum ESystemColumnIds : ui32 { EColumnIdInvalid = Max<ui32>(), EColumnIdSystemStart = EColumnIdInvalid - 1000, EColumnIdDataShard = EColumnIdSystemStart + 1 }; -#define SCHEME_KEY_DESCRIPTION_STATUS_MAP(XX) \ - XX(Unknown, 0) \ - XX(Ok, 1) \ - XX(TypeCheckFailed, 2) \ - XX(OperationNotSupported, 3) \ +#define SCHEME_KEY_DESCRIPTION_STATUS_MAP(XX) \ + XX(Unknown, 0) \ + XX(Ok, 1) \ + XX(TypeCheckFailed, 2) \ + XX(OperationNotSupported, 3) \ XX(NotExists, 4) \ XX(SnapshotNotExist, 5) \ XX(SnapshotNotReady, 6) - - enum class EStatus { - SCHEME_KEY_DESCRIPTION_STATUS_MAP(ENUM_VALUE_GEN) - }; - + + enum class EStatus { + SCHEME_KEY_DESCRIPTION_STATUS_MAP(ENUM_VALUE_GEN) + }; + static void Out(IOutputStream& out, EStatus x); - - // one column operation (in) - struct TColumnOp { - ui32 Column; - EColumnOperation Operation; - ui32 ExpectedType; + + // one column operation (in) + struct TColumnOp { + ui32 Column; + EColumnOperation Operation; + ui32 ExpectedType; ui32 InplaceUpdateMode; ui32 ImmediateUpdateSize; - }; - - // one column info (out) - struct TColumnInfo { - ui32 Column; - ui32 Type; - ui32 AllowInplaceMode; - EStatus Status; - }; - + }; + + // one column info (out) + struct TColumnInfo { + ui32 Column; + ui32 Type; + ui32 AllowInplaceMode; + EStatus Status; + }; + struct TRangeLimits { ui64 ItemsLimit; ui64 BytesLimit; @@ -662,8 +662,8 @@ public: TMaybe<TPartitionRangeInfo> Range; }; - // in - const TTableId TableId; + // in + const TTableId TableId; const TOwnedTableRange Range; const TRangeLimits RangeLimits; const ERowOperation RowOperation; @@ -671,30 +671,30 @@ public: const TVector<TColumnOp> Columns; const bool Reverse; TReadTarget ReadTarget; // Set for Read row operation - - // out - EStatus Status; + + // out + EStatus Status; TVector<TColumnInfo> ColumnInfos; TVector<TPartitionInfo> Partitions; TIntrusivePtr<TSecurityObject> SecurityObject; - + bool IsSystemView() const { return Partitions.empty(); } - template<typename TKeyColumnTypes, typename TColumns> + template<typename TKeyColumnTypes, typename TColumns> TKeyDesc(const TTableId& tableId, const TTableRange& range, ERowOperation rowOperation, const TKeyColumnTypes &keyColumnTypes, const TColumns &columns, ui64 itemsLimit = 0, ui64 bytesLimit = 0, bool reverse = false) - : TableId(tableId) + : TableId(tableId) , Range(range.From, range.InclusiveFrom, range.To, range.InclusiveTo, range.Point) , RangeLimits(itemsLimit, bytesLimit) , RowOperation(rowOperation) - , KeyColumnTypes(keyColumnTypes.begin(), keyColumnTypes.end()) - , Columns(columns.begin(), columns.end()) + , KeyColumnTypes(keyColumnTypes.begin(), keyColumnTypes.end()) + , Columns(columns.begin(), columns.end()) , Reverse(reverse) - , Status(EStatus::Unknown) - {} -}; - + , Status(EStatus::Unknown) + {} +}; + struct TSystemColumnInfo { TKeyDesc::ESystemColumnIds ColumnId; NKikimr::NScheme::TTypeId TypeId; @@ -710,8 +710,8 @@ inline int ComparePointKeys(const TKeyDesc& point1, const TKeyDesc& point2) { Y_VERIFY(point2.Range.Point); return CompareTypedCellVectors( point1.Range.From.data(), point2.Range.From.data(), point1.KeyColumnTypes.data(), point1.KeyColumnTypes.size()); -} - +} + inline int ComparePointAndRangeKeys(const TKeyDesc& point, const TKeyDesc& range) { Y_VERIFY(point.Range.Point); return ComparePointAndRange(point.Range.From, range.Range, point.KeyColumnTypes, range.KeyColumnTypes); diff --git a/ydb/core/scheme/tablet_scheme.h b/ydb/core/scheme/tablet_scheme.h index 089f6f5597..4373b3576a 100644 --- a/ydb/core/scheme/tablet_scheme.h +++ b/ydb/core/scheme/tablet_scheme.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include <ydb/public/lib/scheme_types/scheme_type_id.h> #include <ydb/core/scheme_types/scheme_raw_type_value.h> diff --git a/ydb/core/scheme/ya.make b/ydb/core/scheme/ya.make index aa330c3e15..128ef015bf 100644 --- a/ydb/core/scheme/ya.make +++ b/ydb/core/scheme/ya.make @@ -8,8 +8,8 @@ OWNER( SRCS( scheme_borders.cpp - scheme_tablecell.cpp - scheme_tabledefs.cpp + scheme_tablecell.cpp + scheme_tabledefs.cpp scheme_types_defs.cpp ) diff --git a/ydb/core/scheme_types/scheme_type_registry.cpp b/ydb/core/scheme_types/scheme_type_registry.cpp index 1a7343d2a4..d737254361 100644 --- a/ydb/core/scheme_types/scheme_type_registry.cpp +++ b/ydb/core/scheme_types/scheme_type_registry.cpp @@ -1,6 +1,6 @@ #include "scheme_type_registry.h" #include "scheme_types.h" -#include "scheme_types_defs.h" +#include "scheme_types_defs.h" #include <util/digest/murmur.h> #include <util/generic/algorithm.h> @@ -13,13 +13,13 @@ namespace NScheme { TTypeRegistry::TTypeRegistry() { - // move to 'init defaults?' + // move to 'init defaults?' RegisterType<TInt32>(); RegisterType<TUint32>(); RegisterType<TInt64>(); RegisterType<TUint64>(); - RegisterType<TDouble>(); - RegisterType<TFloat>(); + RegisterType<TDouble>(); + RegisterType<TFloat>(); RegisterType<TUint8>(); RegisterType<TBool>(); RegisterType<TPairUi64Ui64>(); diff --git a/ydb/core/scheme_types/scheme_type_registry.h b/ydb/core/scheme_types/scheme_type_registry.h index bb3f24a061..a82af19267 100644 --- a/ydb/core/scheme_types/scheme_type_registry.h +++ b/ydb/core/scheme_types/scheme_type_registry.h @@ -25,7 +25,7 @@ public: // template <typename T> void RegisterType() { - RegisterType(Singleton<T>()); + RegisterType(Singleton<T>()); } void RegisterType(const IType *type) { @@ -36,8 +36,8 @@ public: Y_VERIFY(TypeByNameMap.insert({ type->GetName(), type }).second); TypeMetadataRegistry.Register(type); - } - + } + // ITypeSP GetType(TTypeId typeId) const { if (typeId) { diff --git a/ydb/core/scheme_types/scheme_types.h b/ydb/core/scheme_types/scheme_types.h index 88231e8c5a..3034843a24 100644 --- a/ydb/core/scheme_types/scheme_types.h +++ b/ydb/core/scheme_types/scheme_types.h @@ -1,19 +1,19 @@ -#pragma once +#pragma once #include <ydb/public/lib/scheme_types/scheme_type_id.h> #include <util/string/hex.h> -#include <util/string/cast.h> +#include <util/string/cast.h> -#include <typeinfo> - +#include <typeinfo> -namespace NKikimr { + +namespace NKikimr { namespace NScheme { - + //////////////////////////////////////////////////////// class ITypeMetadata { -public: +public: enum class EFlags { CanBeValueInKey = 0x01, CanCompare = 0x02, @@ -27,30 +27,30 @@ public: }; virtual ~ITypeMetadata() {} - + virtual TTypeId GetTypeId() const = 0; virtual const char* GetName() const = 0; }; - + class IType : public ITypeMetadata { friend class ITypeSP; friend class TTypeRegistry; -}; - +}; + //////////////////////////////////////////////////////// class ITypeSP { public: // ITypeSP(const IType* t = nullptr) : Type(t) - , TypeId(t ? t->GetTypeId() : 0) - {} - + , TypeId(t ? t->GetTypeId() : 0) + {} + ITypeSP(TTypeId typeId) : Type(nullptr) , TypeId(typeId) - {} - + {} + // const IType* operator->() const noexcept { return Type; } explicit operator bool() const noexcept { return TypeId != 0; } diff --git a/ydb/core/scheme_types/scheme_types_defs.cpp b/ydb/core/scheme_types/scheme_types_defs.cpp index b925a986d1..eeaba2e9af 100644 --- a/ydb/core/scheme_types/scheme_types_defs.cpp +++ b/ydb/core/scheme_types/scheme_types_defs.cpp @@ -13,8 +13,8 @@ namespace NNames { DECLARE_TYPED_TYPE_NAME(Uint64); DECLARE_TYPED_TYPE_NAME(Uint8); DECLARE_TYPED_TYPE_NAME(Bool); - DECLARE_TYPED_TYPE_NAME(Double); - DECLARE_TYPED_TYPE_NAME(Float); + DECLARE_TYPED_TYPE_NAME(Double); + DECLARE_TYPED_TYPE_NAME(Float); DECLARE_TYPED_TYPE_NAME(PairUi64Ui64); DECLARE_TYPED_TYPE_NAME(String); DECLARE_TYPED_TYPE_NAME(SmallBoundedString); diff --git a/ydb/core/scheme_types/scheme_types_defs.h b/ydb/core/scheme_types/scheme_types_defs.h index 1dc3ff04ab..bb06b09702 100644 --- a/ydb/core/scheme_types/scheme_types_defs.h +++ b/ydb/core/scheme_types/scheme_types_defs.h @@ -23,7 +23,7 @@ public: // typedef T TValueType; static constexpr TTypeId TypeId = TypeId_; - + // class TInstance { public: @@ -49,7 +49,7 @@ public: } TTypeId GetTypeId() const override { return TypeId; } static TRawTypeValue ToRawTypeValue(const T& value) { - return TRawTypeValue((void*)&value, sizeof(T), TypeId); + return TRawTypeValue((void*)&value, sizeof(T), TypeId); } static const char* TypeName() { @@ -58,11 +58,11 @@ public: }; //////////////////////////////////////////////////////// - + template<typename T, ui32 TypeId, const char* Name> class IIntegerTypeWithKeyString : public TTypedType<T, IIntegerTypeWithKeyString<T, TypeId, Name>, TypeId, Name> { static_assert(std::is_integral<T>::value, "expect std::is_integral<T>::value"); -public: +public: }; //////////////////////////////////////////////////////// @@ -75,43 +75,43 @@ namespace NNames { extern const char Int64[6]; extern const char Uint64[7]; } - + class TInt32 : public IIntegerTypeWithKeyString<i32, NTypeIds::Int32, NNames::Int32> {}; class TUint32 : public IIntegerTypeWithKeyString<ui32, NTypeIds::Uint32, NNames::Uint32> {}; class TInt64 : public IIntegerTypeWithKeyString<i64, NTypeIds::Int64, NNames::Int64> {}; class TUint64 : public IIntegerTypeWithKeyString<ui64, NTypeIds::Uint64, NNames::Uint64> {}; -// upyachka to get around undefined tryfromstring for chars +// upyachka to get around undefined tryfromstring for chars namespace NNames { extern const char Uint8[6]; } class TUint8 : public TTypedType<ui8, TUint8, NTypeIds::Uint8, NNames::Uint8> { -public: -}; - +public: +}; + namespace NNames { extern const char Bool[5]; } class TBool : public TTypedType<bool, TBool, NTypeIds::Bool, NNames::Bool> { -public: -}; - -namespace NNames { +public: +}; + +namespace NNames { extern const char Float[6]; extern const char Double[7]; -} - -template<typename T, typename TDerived, ui32 TypeId, const char *Name> -class TRealBase : public TTypedType<T, TDerived, TypeId, Name> { -public: -}; - +} + +template<typename T, typename TDerived, ui32 TypeId, const char *Name> +class TRealBase : public TTypedType<T, TDerived, TypeId, Name> { +public: +}; + class TDouble : public TRealBase<double, TDouble, NTypeIds::Double, NNames::Double> {}; class TFloat : public TRealBase<float, TFloat, NTypeIds::Float, NNames::Float> {}; - + //////////////////////////////////////////////////////// template<typename TFirst, typename TSecond, ui32 TypeId, const char* Name> class IIntegerPair : public TTypedType< @@ -131,7 +131,7 @@ namespace NNames { } class TPairUi64Ui64 : public IIntegerPair<ui64, ui64, NTypeIds::PairUi64Ui64, NNames::PairUi64Ui64> {}; - + //////////////////////////////////////////////////////// /// Byte strings diff --git a/ydb/core/security/secure_request.h b/ydb/core/security/secure_request.h index d4a33cde9d..04e276a897 100644 --- a/ydb/core/security/secure_request.h +++ b/ydb/core/security/secure_request.h @@ -61,10 +61,10 @@ private: } public: - static constexpr NKikimrServices::TActivity::EType ActorActivityType() { - return NKikimrServices::TActivity::GRPC_REQ_AUTH; - } - + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { + return NKikimrServices::TActivity::GRPC_REQ_AUTH; + } + template <typename... Args> TSecureRequestActor(Args&&... args) : TBase(std::forward<Args>(args)...) diff --git a/ydb/core/security/ya.make b/ydb/core/security/ya.make index 2592ef53d2..514b0c3474 100644 --- a/ydb/core/security/ya.make +++ b/ydb/core/security/ya.make @@ -1,19 +1,19 @@ -LIBRARY() - +LIBRARY() + OWNER( xenoxeno g:kikimr ) -SRCS( +SRCS( login_page.cpp login_page.h secure_request.h ticket_parser.cpp ticket_parser.h -) - -PEERDIR( +) + +PEERDIR( library/cpp/actors/core library/cpp/actors/http library/cpp/monlib/service/pages @@ -24,9 +24,9 @@ PEERDIR( ydb/library/aclib/protos ydb/library/login ydb/library/security -) - -END() +) + +END() RECURSE_FOR_TESTS( ut diff --git a/ydb/core/tablet/bootstrapper.cpp b/ydb/core/tablet/bootstrapper.cpp index 0a19021edd..d2e5dd8b7f 100644 --- a/ydb/core/tablet/bootstrapper.cpp +++ b/ydb/core/tablet/bootstrapper.cpp @@ -1,178 +1,178 @@ -#include "bootstrapper.h" - +#include "bootstrapper.h" + #include <ydb/core/base/tablet.h> #include <ydb/core/base/statestorage.h> #include <ydb/core/base/appdata.h> - + #include <library/cpp/actors/core/interconnect.h> #include <library/cpp/actors/core/hfunc.h> - + #include <ydb/core/protos/bootstrapper.pb.h> - -namespace NKikimr { - -struct TEvBootstrapper::TEvWatch : public TEventPB<TEvWatch, NKikimrBootstrapper::TEvWatch, EvWatch> { - TEvWatch() - {} - - TEvWatch(ui64 tabletId, ui64 selfSeed, ui64 round) - { - Record.SetTabletID(tabletId); - Record.SetSelfSeed(selfSeed); - Record.SetRound(round); - } -}; - -struct TEvBootstrapper::TEvWatchResult : public TEventPB<TEvWatchResult, NKikimrBootstrapper::TEvWatchResult, EvWatchResult> { - TEvWatchResult() - {} - - TEvWatchResult(ui64 tabletId, NKikimrBootstrapper::TEvWatchResult::EState state, ui64 seed, ui64 round) - { - Record.SetTabletID(tabletId); - Record.SetState(state); - Record.SetSeed(seed); - Record.SetRound(round); - } -}; - -struct TEvBootstrapper::TEvNotify : public TEventPB<TEvNotify, NKikimrBootstrapper::TEvNotify, EvNotify> { - TEvNotify() - {} - - TEvNotify(ui64 tabletId, NKikimrBootstrapper::TEvNotify::EOp op, ui64 round) - { - Record.SetTabletID(tabletId); - Record.SetOp(op); - Record.SetRound(round); - } -}; - - -class TBootstrapper : public TActor<TBootstrapper> { - TIntrusivePtr<TTabletStorageInfo> TabletInfo; - TIntrusivePtr<TBootstrapperInfo> BootstrapperInfo; - + +namespace NKikimr { + +struct TEvBootstrapper::TEvWatch : public TEventPB<TEvWatch, NKikimrBootstrapper::TEvWatch, EvWatch> { + TEvWatch() + {} + + TEvWatch(ui64 tabletId, ui64 selfSeed, ui64 round) + { + Record.SetTabletID(tabletId); + Record.SetSelfSeed(selfSeed); + Record.SetRound(round); + } +}; + +struct TEvBootstrapper::TEvWatchResult : public TEventPB<TEvWatchResult, NKikimrBootstrapper::TEvWatchResult, EvWatchResult> { + TEvWatchResult() + {} + + TEvWatchResult(ui64 tabletId, NKikimrBootstrapper::TEvWatchResult::EState state, ui64 seed, ui64 round) + { + Record.SetTabletID(tabletId); + Record.SetState(state); + Record.SetSeed(seed); + Record.SetRound(round); + } +}; + +struct TEvBootstrapper::TEvNotify : public TEventPB<TEvNotify, NKikimrBootstrapper::TEvNotify, EvNotify> { + TEvNotify() + {} + + TEvNotify(ui64 tabletId, NKikimrBootstrapper::TEvNotify::EOp op, ui64 round) + { + Record.SetTabletID(tabletId); + Record.SetOp(op); + Record.SetRound(round); + } +}; + + +class TBootstrapper : public TActor<TBootstrapper> { + TIntrusivePtr<TTabletStorageInfo> TabletInfo; + TIntrusivePtr<TBootstrapperInfo> BootstrapperInfo; + TActorId LookOnActorID; TActorId FollowerActorID; - - ui64 RoundCounter; - ui64 SelfSeed; - + + ui64 RoundCounter; + ui64 SelfSeed; + TInstant BootDelayedUntil; - // we watch someone and do not act w/o shutdown - struct TWatch { - struct TWatched { + // we watch someone and do not act w/o shutdown + struct TWatch { + struct TWatched { TActorId ActorID; - bool Owner; - - TWatched() - : Owner(false) - {} + bool Owner; + + TWatched() + : Owner(false) + {} TWatched(const TActorId &actorID, bool owner) - : ActorID(actorID) - , Owner(owner) - {} - }; - - bool CheckWatch(ui32 fromNode) { - bool seenOwner = false; - for (TWatched &x : Watched) { - seenOwner |= x.Owner; - if (x.ActorID.NodeId() == fromNode) - return (x.Owner == false); - } - return !seenOwner; - } - - bool RemoveAlienEntry(ui32 idx) { - Watched[idx] = Watched.back(); - Watched.pop_back(); - if (!AnyOf(Watched, [](const TWatch::TWatched &x) { return x.Owner; })) - Watched.clear(); - return Watched.empty(); - } - + : ActorID(actorID) + , Owner(owner) + {} + }; + + bool CheckWatch(ui32 fromNode) { + bool seenOwner = false; + for (TWatched &x : Watched) { + seenOwner |= x.Owner; + if (x.ActorID.NodeId() == fromNode) + return (x.Owner == false); + } + return !seenOwner; + } + + bool RemoveAlienEntry(ui32 idx) { + Watched[idx] = Watched.back(); + Watched.pop_back(); + if (!AnyOf(Watched, [](const TWatch::TWatched &x) { return x.Owner; })) + Watched.clear(); + return Watched.empty(); + } + bool RemoveAlien(const TActorId &alien) { - for (ui32 i = 0, e = Watched.size(); i != e; ++i) { - if (Watched[i].ActorID == alien) - return RemoveAlienEntry(i); - } - return false; - } - - bool RemoveAlienNode(ui32 node) { - for (ui32 i = 0, e = Watched.size(); i != e; ++i) { - if (Watched[i].ActorID.NodeId() == node) - return RemoveAlienEntry(i); - } - return false; - } - + for (ui32 i = 0, e = Watched.size(); i != e; ++i) { + if (Watched[i].ActorID == alien) + return RemoveAlienEntry(i); + } + return false; + } + + bool RemoveAlienNode(ui32 node) { + for (ui32 i = 0, e = Watched.size(); i != e; ++i) { + if (Watched[i].ActorID.NodeId() == node) + return RemoveAlienEntry(i); + } + return false; + } + TVector<TWatched> Watched; - }; - - // we are under watch, must notify on error - struct TWatched { - struct TWatcher { + }; + + // we are under watch, must notify on error + struct TWatched { + struct TWatcher { TActorId ActorID; - ui64 Round; - - TWatcher() - : ActorID() - , Round() - {} + ui64 Round; + + TWatcher() + : ActorID() + , Round() + {} TWatcher(const TActorId &actorID, ui64 round) - : ActorID(actorID) - , Round(round) - {} - }; - + : ActorID(actorID) + , Round(round) + {} + }; + void AddWatcher(const TActorId &actorId, ui64 round) { - for (TWatcher &x : Watchers) { - if (actorId.NodeId() == x.ActorID.NodeId()) { - x.ActorID = actorId; - x.Round = round; - return; - } - } - Watchers.push_back(TWatcher(actorId, round)); - } - + for (TWatcher &x : Watchers) { + if (actorId.NodeId() == x.ActorID.NodeId()) { + x.ActorID = actorId; + x.Round = round; + return; + } + } + Watchers.push_back(TWatcher(actorId, round)); + } + TVector<TWatcher> Watchers; - }; - - struct TRound { - enum class EAlienState { - Wait, - Unknown, - Free, + }; + + struct TRound { + enum class EAlienState { + Wait, + Unknown, + Free, Undelivered, Disconnected, - }; - - struct TAlien { - EAlienState State; - ui64 Seed; - - TAlien() - : State(EAlienState::Wait) - , Seed() - {} - TAlien(EAlienState state, ui64 seed) - : State(state) - , Seed(seed) - {} - }; - + }; + + struct TAlien { + EAlienState State; + ui64 Seed; + + TAlien() + : State(EAlienState::Wait) + , Seed() + {} + TAlien(EAlienState state, ui64 seed) + : State(state) + , Seed(seed) + {} + }; + TVector<TAlien> Aliens; - }; - - TAutoPtr<TWatch> Watches; // we watch them - TAutoPtr<TWatched> Watched; // we are under watch - TAutoPtr<TRound> Round; - + }; + + TAutoPtr<TWatch> Watches; // we watch them + TAutoPtr<TWatched> Watched; // we are under watch + TAutoPtr<TRound> Round; + const char* GetTabletTypeName() { return TTabletTypes::TypeToStr((TTabletTypes::EType)TabletInfo->TabletType); } @@ -181,154 +181,154 @@ class TBootstrapper : public TActor<TBootstrapper> { return NKikimrBootstrapper::TEvWatchResult::EState_Name(state).c_str(); } - ui32 AlienIndex(ui32 alienNodeId) { - for (ui32 i = 0, e = BootstrapperInfo->OtherNodes.size(); i != e; ++i) - if (BootstrapperInfo->OtherNodes[i] == alienNodeId) - return i; - return Max<ui32>(); - } - - void BeginNewRound(const TActorContext &ctx) { - if (BootstrapperInfo->OtherNodes.empty()) - return Boot(ctx); - + ui32 AlienIndex(ui32 alienNodeId) { + for (ui32 i = 0, e = BootstrapperInfo->OtherNodes.size(); i != e; ++i) + if (BootstrapperInfo->OtherNodes[i] == alienNodeId) + return i; + return Max<ui32>(); + } + + void BeginNewRound(const TActorContext &ctx) { + if (BootstrapperInfo->OtherNodes.empty()) + return Boot(ctx); + SelfSeed = AppData(ctx)->RandomProvider->GenRand64(); LOG_INFO(ctx, NKikimrServices::BOOTSTRAPPER, "tablet: %" PRIu64 ", type: %s, begin new round, seed: %" PRIu64, TabletInfo->TabletID, GetTabletTypeName(), SelfSeed); - - const ui64 tabletId = TabletInfo->TabletID; - ++RoundCounter; - - Round.Reset(new TRound()); - Round->Aliens.resize(BootstrapperInfo->OtherNodes.size()); - - for (ui32 alienNode : BootstrapperInfo->OtherNodes) { - ctx.Send(MakeBootstrapperID(tabletId, alienNode), new TEvBootstrapper::TEvWatch(tabletId, SelfSeed, RoundCounter), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, RoundCounter); - } - - Become(&TThis::StateFree); // todo: global timeout? - } - - void Boot(const TActorContext &ctx) { + + const ui64 tabletId = TabletInfo->TabletID; + ++RoundCounter; + + Round.Reset(new TRound()); + Round->Aliens.resize(BootstrapperInfo->OtherNodes.size()); + + for (ui32 alienNode : BootstrapperInfo->OtherNodes) { + ctx.Send(MakeBootstrapperID(tabletId, alienNode), new TEvBootstrapper::TEvWatch(tabletId, SelfSeed, RoundCounter), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, RoundCounter); + } + + Become(&TThis::StateFree); // todo: global timeout? + } + + void Boot(const TActorContext &ctx) { Y_VERIFY(!LookOnActorID); - + LOG_NOTICE(ctx, NKikimrServices::BOOTSTRAPPER, "tablet: %" PRIu64 ", type: %s, boot", TabletInfo->TabletID, GetTabletTypeName()); - + if (FollowerActorID) { LookOnActorID = FollowerActorID; FollowerActorID = TActorId(); ctx.Send(LookOnActorID, new TEvTablet::TEvPromoteToLeader(0, TabletInfo)); - } else { - TTabletSetupInfo *x = BootstrapperInfo->SetupInfo.Get(); + } else { + TTabletSetupInfo *x = BootstrapperInfo->SetupInfo.Get(); LookOnActorID = x->Tablet(TabletInfo.Get(), ctx.SelfID, ctx, 0, AppData(ctx)->ResourceProfiles); - } - + } + Y_VERIFY(LookOnActorID); - - Watched.Reset(new TWatched()); - - Become(&TThis::StateOwner); - } - - void Handle(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext &ctx) { - if (ev->Sender == LookOnActorID) { + + Watched.Reset(new TWatched()); + + Become(&TThis::StateOwner); + } + + void Handle(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext &ctx) { + if (ev->Sender == LookOnActorID) { LOG_INFO(ctx, NKikimrServices::BOOTSTRAPPER, "tablet: %" PRIu64 ", type: %s, tablet dead", TabletInfo->TabletID, GetTabletTypeName()); - + LookOnActorID = TActorId(); - NotifyAndRound(ctx); - } - } - - void Stop() { - if (LookOnActorID) { - Send(LookOnActorID, new TEvents::TEvPoisonPill()); + NotifyAndRound(ctx); + } + } + + void Stop() { + if (LookOnActorID) { + Send(LookOnActorID, new TEvents::TEvPoisonPill()); LookOnActorID = TActorId(); - } - + } + if (FollowerActorID) { Send(FollowerActorID, new TEvents::TEvPoisonPill()); FollowerActorID = TActorId(); - } - - NotifyWatchers(); - + } + + NotifyWatchers(); + BootDelayedUntil = { }; - Round.Destroy(); - } - - void HandlePoison() { - Stop(); - PassAway(); - } - - void Standby() { - Stop(); - Become(&TThis::StateStandBy); - } - + Round.Destroy(); + } + + void HandlePoison() { + Stop(); + PassAway(); + } + + void Standby() { + Stop(); + Become(&TThis::StateStandBy); + } + void BecomeWatch(const TActorId &watchOn, bool owner, const TActorContext &ctx) { Y_UNUSED(ctx); - + BootDelayedUntil = { }; - Round.Destroy(); - + Round.Destroy(); + LOG_INFO(ctx, NKikimrServices::BOOTSTRAPPER, "tablet: %" PRIu64 ", type: %s, become watch", TabletInfo->TabletID, GetTabletTypeName()); - - Watches.Reset(new TWatch()); - Watched.Reset(new TWatched()); - + + Watches.Reset(new TWatch()); + Watched.Reset(new TWatched()); + LOG_DEBUG(ctx, NKikimrServices::BOOTSTRAPPER, "tablet: %" PRIu64 ", type: %s, add watched node: %" PRIu32, TabletInfo->TabletID, GetTabletTypeName(), watchOn.NodeId()); - Watches->Watched.push_back(TWatch::TWatched(watchOn, owner)); - + Watches->Watched.push_back(TWatch::TWatched(watchOn, owner)); + if (BootstrapperInfo->StartFollowers && !FollowerActorID) { LOG_NOTICE(ctx, NKikimrServices::BOOTSTRAPPER, "tablet: %" PRIu64 ", type: %s, boot follower", TabletInfo->TabletID, GetTabletTypeName()); - TTabletSetupInfo *x = BootstrapperInfo->SetupInfo.Get(); + TTabletSetupInfo *x = BootstrapperInfo->SetupInfo.Get(); FollowerActorID = x->Follower(TabletInfo.Get(), ctx.SelfID, ctx, 0, AppData(ctx)->ResourceProfiles); - } - - Become(&TThis::StateWatch); - } - + } + + Become(&TThis::StateWatch); + } + bool ApplyAlienState(const TActorId &alien, NKikimrBootstrapper::TEvWatchResult::EState state, ui64 seed, const TActorContext &ctx) { - const ui32 alienNodeIdx = AlienIndex(alien.NodeId()); - if (alienNodeIdx == Max<ui32>()) - return true; - - if (Round->Aliens[alienNodeIdx].State != TRound::EAlienState::Wait) - return false; - + const ui32 alienNodeIdx = AlienIndex(alien.NodeId()); + if (alienNodeIdx == Max<ui32>()) + return true; + + if (Round->Aliens[alienNodeIdx].State != TRound::EAlienState::Wait) + return false; + LOG_DEBUG(ctx, NKikimrServices::BOOTSTRAPPER, "tablet: %" PRIu64 ", type: %s, apply alien %" PRIu32 " state: %s", TabletInfo->TabletID, GetTabletTypeName(), alien.NodeId(), GetStateName(state)); - - switch (state) { - case NKikimrBootstrapper::TEvWatchResult::UNKNOWN: - Round->Aliens[alienNodeIdx] = TRound::TAlien(TRound::EAlienState::Unknown, Max<ui64>()); - return false; - case NKikimrBootstrapper::TEvWatchResult::FREE: - Round->Aliens[alienNodeIdx] = TRound::TAlien(TRound::EAlienState::Free, seed); - return false; - case NKikimrBootstrapper::TEvWatchResult::OWNER: - BecomeWatch(alien, true, ctx); - return true; - case NKikimrBootstrapper::TEvWatchResult::WAITFOR: - BecomeWatch(alien, false, ctx); - return true; + + switch (state) { + case NKikimrBootstrapper::TEvWatchResult::UNKNOWN: + Round->Aliens[alienNodeIdx] = TRound::TAlien(TRound::EAlienState::Unknown, Max<ui64>()); + return false; + case NKikimrBootstrapper::TEvWatchResult::FREE: + Round->Aliens[alienNodeIdx] = TRound::TAlien(TRound::EAlienState::Free, seed); + return false; + case NKikimrBootstrapper::TEvWatchResult::OWNER: + BecomeWatch(alien, true, ctx); + return true; + case NKikimrBootstrapper::TEvWatchResult::WAITFOR: + BecomeWatch(alien, false, ctx); + return true; case NKikimrBootstrapper::TEvWatchResult::UNDELIVERED: Round->Aliens[alienNodeIdx] = TRound::TAlien(TRound::EAlienState::Undelivered, Max<ui64>()); return false; case NKikimrBootstrapper::TEvWatchResult::DISCONNECTED: Round->Aliens[alienNodeIdx] = TRound::TAlien(TRound::EAlienState::Disconnected, Max<ui64>()); return false; - default: + default: Y_FAIL("unhandled case"); - } - } - + } + } + bool CheckBootPermitted(size_t undelivered, size_t disconnected, const TActorContext &ctx) { // Total number of nodes that participate in tablet booting size_t total = 1 + BootstrapperInfo->OtherNodes.size(); @@ -375,23 +375,23 @@ class TBootstrapper : public TActor<TBootstrapper> { return false; } - void CheckRoundCompletion(const TActorContext &ctx) { - ui64 minAlienSeed = Max<ui64>(); - ui32 minAlien = Max<ui32>(); + void CheckRoundCompletion(const TActorContext &ctx) { + ui64 minAlienSeed = Max<ui64>(); + ui32 minAlien = Max<ui32>(); size_t undelivered = 0; size_t disconnected = 0; - for (ui32 i = 0, e = Round->Aliens.size(); i != e; ++i) { - const TRound::TAlien &alien = Round->Aliens[i]; + for (ui32 i = 0, e = Round->Aliens.size(); i != e; ++i) { + const TRound::TAlien &alien = Round->Aliens[i]; switch (alien.State) { case TRound::EAlienState::Wait: - return; + return; case TRound::EAlienState::Unknown: break; case TRound::EAlienState::Free: - if (minAlienSeed > alien.Seed) { - minAlienSeed = alien.Seed; - minAlien = BootstrapperInfo->OtherNodes[i]; - } + if (minAlienSeed > alien.Seed) { + minAlienSeed = alien.Seed; + minAlien = BootstrapperInfo->OtherNodes[i]; + } break; case TRound::EAlienState::Undelivered: ++undelivered; @@ -399,240 +399,240 @@ class TBootstrapper : public TActor<TBootstrapper> { case TRound::EAlienState::Disconnected: ++disconnected; break; - } - } - - Round.Destroy(); - - // ok, we got all reactions, now boot tablet or sleep for threshold - if (minAlienSeed < SelfSeed || minAlienSeed == SelfSeed && ctx.SelfID.NodeId() > minAlien) { + } + } + + Round.Destroy(); + + // ok, we got all reactions, now boot tablet or sleep for threshold + if (minAlienSeed < SelfSeed || minAlienSeed == SelfSeed && ctx.SelfID.NodeId() > minAlien) { LOG_DEBUG(ctx, NKikimrServices::BOOTSTRAPPER, "tablet: %" PRIu64 ", type: %s, lost round, wait for threshold", TabletInfo->TabletID, GetTabletTypeName()); - - const ui64 wx = BootstrapperInfo->WatchThreshold.MicroSeconds(); + + const ui64 wx = BootstrapperInfo->WatchThreshold.MicroSeconds(); const auto sleepDuration = TDuration::MicroSeconds(wx / 2 + wx * (SelfSeed % 0x10000) / 0x20000); - - Become(&TThis::StateSleep); - ctx.ExecutorThread.ActorSystem->Schedule(sleepDuration, new IEventHandle(ctx.SelfID, ctx.SelfID, new TEvents::TEvWakeup(), 0, RoundCounter)); - return; + + Become(&TThis::StateSleep); + ctx.ExecutorThread.ActorSystem->Schedule(sleepDuration, new IEventHandle(ctx.SelfID, ctx.SelfID, new TEvents::TEvWakeup(), 0, RoundCounter)); + return; } else if (!CheckBootPermitted(undelivered, disconnected, ctx)) { return; - } else { - Boot(ctx); - return; - } - } - - void NotifyWatchers() { - if (Watched) { - for (const TWatched::TWatcher &xw : Watched->Watchers) - Send(xw.ActorID, new TEvBootstrapper::TEvNotify(TabletInfo->TabletID, NKikimrBootstrapper::TEvNotify::DROP, xw.Round)); - Watched.Destroy(); - Watches.Destroy(); - } - } - - void NotifyAndRound(const TActorContext &ctx) { - NotifyWatchers(); - BeginNewRound(ctx); - } - - void HandleFree(TEvBootstrapper::TEvWatchResult::TPtr &ev, const TActorContext &ctx) { - const NKikimrBootstrapper::TEvWatchResult &record = ev->Get()->Record; + } else { + Boot(ctx); + return; + } + } + + void NotifyWatchers() { + if (Watched) { + for (const TWatched::TWatcher &xw : Watched->Watchers) + Send(xw.ActorID, new TEvBootstrapper::TEvNotify(TabletInfo->TabletID, NKikimrBootstrapper::TEvNotify::DROP, xw.Round)); + Watched.Destroy(); + Watches.Destroy(); + } + } + + void NotifyAndRound(const TActorContext &ctx) { + NotifyWatchers(); + BeginNewRound(ctx); + } + + void HandleFree(TEvBootstrapper::TEvWatchResult::TPtr &ev, const TActorContext &ctx) { + const NKikimrBootstrapper::TEvWatchResult &record = ev->Get()->Record; Y_VERIFY(record.GetTabletID() == TabletInfo->TabletID); - - if (record.GetRound() != RoundCounter) - return; - - if (ApplyAlienState(ev->Sender, record.GetState(), record.GetSeed(), ctx)) - return; - - CheckRoundCompletion(ctx); - } - - void HandleFree(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) { - const ui64 round = ev->Cookie; + + if (record.GetRound() != RoundCounter) + return; + + if (ApplyAlienState(ev->Sender, record.GetState(), record.GetSeed(), ctx)) + return; + + CheckRoundCompletion(ctx); + } + + void HandleFree(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) { + const ui64 round = ev->Cookie; LOG_DEBUG(ctx, NKikimrServices::BOOTSTRAPPER, "tablet: %" PRIu64 ", type: %s, undelivered from %s, round %" PRIu64, TabletInfo->TabletID, GetTabletTypeName(), ev->Sender.ToString().c_str(), round); - if (round != RoundCounter) - return; + if (round != RoundCounter) + return; if (ApplyAlienState(ev->Sender, NKikimrBootstrapper::TEvWatchResult::UNDELIVERED, Max<ui64>(), ctx)) - return; + return; + + CheckRoundCompletion(ctx); + } - CheckRoundCompletion(ctx); - } - - void HandleFree(TEvInterconnect::TEvNodeDisconnected::TPtr &ev, const TActorContext &ctx) { - const ui32 node = ev->Get()->NodeId; + void HandleFree(TEvInterconnect::TEvNodeDisconnected::TPtr &ev, const TActorContext &ctx) { + const ui32 node = ev->Get()->NodeId; LOG_DEBUG(ctx, NKikimrServices::BOOTSTRAPPER, "tablet: %" PRIu64 ", type: %s, disconnected from %" PRIu32, TabletInfo->TabletID, GetTabletTypeName(), node); if (ApplyAlienState(TActorId(node, 0, 0, 0), NKikimrBootstrapper::TEvWatchResult::DISCONNECTED, Max<ui64>(), ctx)) - return; + return; + + CheckRoundCompletion(ctx); + } - CheckRoundCompletion(ctx); - } - - void HandleFree(TEvBootstrapper::TEvWatch::TPtr &ev, const TActorContext &ctx) { - const NKikimrBootstrapper::TEvWatch &record = ev->Get()->Record; + void HandleFree(TEvBootstrapper::TEvWatch::TPtr &ev, const TActorContext &ctx) { + const NKikimrBootstrapper::TEvWatch &record = ev->Get()->Record; Y_VERIFY(record.GetTabletID() == TabletInfo->TabletID); - - ctx.Send(ev->Sender, new TEvBootstrapper::TEvWatchResult(record.GetTabletID(), NKikimrBootstrapper::TEvWatchResult::FREE, SelfSeed, record.GetRound())); - } - - void HandleWatch(TEvBootstrapper::TEvNotify::TPtr &ev, const TActorContext &ctx) { + + ctx.Send(ev->Sender, new TEvBootstrapper::TEvWatchResult(record.GetTabletID(), NKikimrBootstrapper::TEvWatchResult::FREE, SelfSeed, record.GetRound())); + } + + void HandleWatch(TEvBootstrapper::TEvNotify::TPtr &ev, const TActorContext &ctx) { const TActorId alien = ev->Sender; - if (Watches->RemoveAlien(alien)) { - NotifyAndRound(ctx); - } - } - - void HandleWatch(TEvInterconnect::TEvNodeDisconnected::TPtr &ev, const TActorContext &ctx) { - const ui32 node = ev->Get()->NodeId; + if (Watches->RemoveAlien(alien)) { + NotifyAndRound(ctx); + } + } + + void HandleWatch(TEvInterconnect::TEvNodeDisconnected::TPtr &ev, const TActorContext &ctx) { + const ui32 node = ev->Get()->NodeId; LOG_DEBUG(ctx, NKikimrServices::BOOTSTRAPPER, "tablet: %" PRIu64 ", type: %s, disconnected from %" PRIu32, TabletInfo->TabletID, GetTabletTypeName(), node); - - if (Watches->RemoveAlienNode(node)) { - NotifyAndRound(ctx); - } - } - - void HandleOwner(TEvBootstrapper::TEvWatch::TPtr &ev, const TActorContext &ctx) { - const NKikimrBootstrapper::TEvWatch &record = ev->Get()->Record; + + if (Watches->RemoveAlienNode(node)) { + NotifyAndRound(ctx); + } + } + + void HandleOwner(TEvBootstrapper::TEvWatch::TPtr &ev, const TActorContext &ctx) { + const NKikimrBootstrapper::TEvWatch &record = ev->Get()->Record; Y_VERIFY(record.GetTabletID() == TabletInfo->TabletID); - - // add to watchers list (if node not already there) - Watched->AddWatcher(ev->Sender, record.GetRound()); - ctx.Send(ev->Sender, new TEvBootstrapper::TEvWatchResult(record.GetTabletID(), NKikimrBootstrapper::TEvWatchResult::OWNER, 0, record.GetRound())); - } - - void HandleWatch(TEvBootstrapper::TEvWatch::TPtr &ev, const TActorContext &ctx) { - const NKikimrBootstrapper::TEvWatch &record = ev->Get()->Record; + + // add to watchers list (if node not already there) + Watched->AddWatcher(ev->Sender, record.GetRound()); + ctx.Send(ev->Sender, new TEvBootstrapper::TEvWatchResult(record.GetTabletID(), NKikimrBootstrapper::TEvWatchResult::OWNER, 0, record.GetRound())); + } + + void HandleWatch(TEvBootstrapper::TEvWatch::TPtr &ev, const TActorContext &ctx) { + const NKikimrBootstrapper::TEvWatch &record = ev->Get()->Record; Y_VERIFY(record.GetTabletID() == TabletInfo->TabletID); - - if (Watches->CheckWatch(ev->Sender.NodeId())) { - ctx.Send(ev->Sender, new TEvBootstrapper::TEvWatchResult(record.GetTabletID(), NKikimrBootstrapper::TEvWatchResult::UNKNOWN, 0, record.GetRound())); - } else { - Watched->AddWatcher(ev->Sender, record.GetRound()); - ctx.Send(ev->Sender, new TEvBootstrapper::TEvWatchResult(record.GetTabletID(), NKikimrBootstrapper::TEvWatchResult::WAITFOR, 0, record.GetRound())); - } - } - - void HandleSleep(TEvBootstrapper::TEvWatch::TPtr &ev, const TActorContext &ctx) { - HandleFree(ev, ctx); - } - - void HandleSleep(TEvents::TEvWakeup::TPtr &ev, const TActorContext &ctx) { - const ui64 roundCookie = ev->Cookie; - if (roundCookie != RoundCounter) - return; - - BeginNewRound(ctx); - } - - void HandleStandBy(TEvBootstrapper::TEvWatch::TPtr &ev, const TActorContext &ctx) { - const NKikimrBootstrapper::TEvWatch &record = ev->Get()->Record; + + if (Watches->CheckWatch(ev->Sender.NodeId())) { + ctx.Send(ev->Sender, new TEvBootstrapper::TEvWatchResult(record.GetTabletID(), NKikimrBootstrapper::TEvWatchResult::UNKNOWN, 0, record.GetRound())); + } else { + Watched->AddWatcher(ev->Sender, record.GetRound()); + ctx.Send(ev->Sender, new TEvBootstrapper::TEvWatchResult(record.GetTabletID(), NKikimrBootstrapper::TEvWatchResult::WAITFOR, 0, record.GetRound())); + } + } + + void HandleSleep(TEvBootstrapper::TEvWatch::TPtr &ev, const TActorContext &ctx) { + HandleFree(ev, ctx); + } + + void HandleSleep(TEvents::TEvWakeup::TPtr &ev, const TActorContext &ctx) { + const ui64 roundCookie = ev->Cookie; + if (roundCookie != RoundCounter) + return; + + BeginNewRound(ctx); + } + + void HandleStandBy(TEvBootstrapper::TEvWatch::TPtr &ev, const TActorContext &ctx) { + const NKikimrBootstrapper::TEvWatch &record = ev->Get()->Record; Y_VERIFY(record.GetTabletID() == TabletInfo->TabletID); - - ctx.Send(ev->Sender, new TEvBootstrapper::TEvWatchResult(record.GetTabletID(), NKikimrBootstrapper::TEvWatchResult::UNKNOWN, Max<ui64>(), record.GetRound())); - } - - void HandlePoisonStandBy() { - PassAway(); - } - - void PassAway() override { + + ctx.Send(ev->Sender, new TEvBootstrapper::TEvWatchResult(record.GetTabletID(), NKikimrBootstrapper::TEvWatchResult::UNKNOWN, Max<ui64>(), record.GetRound())); + } + + void HandlePoisonStandBy() { + PassAway(); + } + + void PassAway() override { for (ui32 nodeId : BootstrapperInfo->OtherNodes) { Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe); } - NotifyWatchers(); - TActor::PassAway(); - } - -public: + NotifyWatchers(); + TActor::PassAway(); + } + +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TABLET_BOOTSTRAPPER; } - TBootstrapper(TTabletStorageInfo *tabletInfo, TBootstrapperInfo *bootstrapperInfo, bool standby) - : TActor(standby ? &TThis::StateStandBy : &TThis::StateBoot) - , TabletInfo(tabletInfo) - , BootstrapperInfo(bootstrapperInfo) - , RoundCounter(0xdeadbeefdeadbeefull) - , SelfSeed(0xdeadbeefdeadbeefull) + TBootstrapper(TTabletStorageInfo *tabletInfo, TBootstrapperInfo *bootstrapperInfo, bool standby) + : TActor(standby ? &TThis::StateStandBy : &TThis::StateBoot) + , TabletInfo(tabletInfo) + , BootstrapperInfo(bootstrapperInfo) + , RoundCounter(0xdeadbeefdeadbeefull) + , SelfSeed(0xdeadbeefdeadbeefull) { Y_VERIFY(TTabletTypes::TYPE_INVALID != TabletInfo->TabletType); } - + TAutoPtr<IEventHandle> AfterRegister(const TActorId &selfId, const TActorId &parentId) override { Y_UNUSED(parentId); - return new IEventHandle(selfId, selfId, new TEvents::TEvBootstrap()); - } - - STFUNC(StateBoot) { - switch (ev->GetTypeRewrite()) { - CFunc(TEvents::TSystem::Bootstrap, BeginNewRound); - } - } - - STFUNC(StateFree) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvBootstrapper::TEvWatchResult, HandleFree); // => noop|sleep|owner|watch - HFunc(TEvBootstrapper::TEvWatch, HandleFree); // => reply - HFunc(TEvents::TEvUndelivered, HandleFree); // => watchresult with unknown - cFunc(TEvents::TSystem::PoisonPill, HandlePoison); // => die - HFunc(TEvInterconnect::TEvNodeDisconnected, HandleFree); // => watchresult with unknown - cFunc(TEvBootstrapper::EvStandBy, Standby); - } - } - - STFUNC(StateSleep) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvBootstrapper::TEvWatch, HandleSleep); - HFunc(TEvents::TEvWakeup, HandleSleep); - cFunc(TEvents::TSystem::PoisonPill, HandlePoison); - cFunc(TEvBootstrapper::EvStandBy, Standby); - } - } - - STFUNC(StateWatch) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvBootstrapper::TEvWatch, HandleWatch); - HFunc(TEvBootstrapper::TEvNotify, HandleWatch); - HFunc(TEvInterconnect::TEvNodeDisconnected, HandleWatch); - cFunc(TEvents::TSystem::PoisonPill, HandlePoison); - cFunc(TEvBootstrapper::EvStandBy, Standby); - } - } - - STFUNC(StateOwner) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvBootstrapper::TEvWatch, HandleOwner); - HFunc(TEvTablet::TEvTabletDead, Handle); - cFunc(TEvents::TSystem::PoisonPill, HandlePoison); - cFunc(TEvBootstrapper::EvStandBy, Standby); - } - } - - STFUNC(StateStandBy) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvBootstrapper::TEvWatch, HandleStandBy); - CFunc(TEvBootstrapper::EvActivate, BeginNewRound); - cFunc(TEvents::TSystem::PoisonPill, HandlePoisonStandBy); - } - } -}; - -IActor* CreateBootstrapper(TTabletStorageInfo *tabletInfo, TBootstrapperInfo *bootstrapperInfo, bool standby) { - return new TBootstrapper(tabletInfo, bootstrapperInfo, standby); -} - + return new IEventHandle(selfId, selfId, new TEvents::TEvBootstrap()); + } + + STFUNC(StateBoot) { + switch (ev->GetTypeRewrite()) { + CFunc(TEvents::TSystem::Bootstrap, BeginNewRound); + } + } + + STFUNC(StateFree) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvBootstrapper::TEvWatchResult, HandleFree); // => noop|sleep|owner|watch + HFunc(TEvBootstrapper::TEvWatch, HandleFree); // => reply + HFunc(TEvents::TEvUndelivered, HandleFree); // => watchresult with unknown + cFunc(TEvents::TSystem::PoisonPill, HandlePoison); // => die + HFunc(TEvInterconnect::TEvNodeDisconnected, HandleFree); // => watchresult with unknown + cFunc(TEvBootstrapper::EvStandBy, Standby); + } + } + + STFUNC(StateSleep) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvBootstrapper::TEvWatch, HandleSleep); + HFunc(TEvents::TEvWakeup, HandleSleep); + cFunc(TEvents::TSystem::PoisonPill, HandlePoison); + cFunc(TEvBootstrapper::EvStandBy, Standby); + } + } + + STFUNC(StateWatch) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvBootstrapper::TEvWatch, HandleWatch); + HFunc(TEvBootstrapper::TEvNotify, HandleWatch); + HFunc(TEvInterconnect::TEvNodeDisconnected, HandleWatch); + cFunc(TEvents::TSystem::PoisonPill, HandlePoison); + cFunc(TEvBootstrapper::EvStandBy, Standby); + } + } + + STFUNC(StateOwner) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvBootstrapper::TEvWatch, HandleOwner); + HFunc(TEvTablet::TEvTabletDead, Handle); + cFunc(TEvents::TSystem::PoisonPill, HandlePoison); + cFunc(TEvBootstrapper::EvStandBy, Standby); + } + } + + STFUNC(StateStandBy) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvBootstrapper::TEvWatch, HandleStandBy); + CFunc(TEvBootstrapper::EvActivate, BeginNewRound); + cFunc(TEvents::TSystem::PoisonPill, HandlePoisonStandBy); + } + } +}; + +IActor* CreateBootstrapper(TTabletStorageInfo *tabletInfo, TBootstrapperInfo *bootstrapperInfo, bool standby) { + return new TBootstrapper(tabletInfo, bootstrapperInfo, standby); +} + TActorId MakeBootstrapperID(ui64 tablet, ui32 node) { - char x[12] ={'b', 'o', 'o', 't'}; - memcpy(x + 4, &tablet, sizeof(ui64)); + char x[12] ={'b', 'o', 'o', 't'}; + memcpy(x + 4, &tablet, sizeof(ui64)); return TActorId(node, TStringBuf(x, x + 12)); -} - -} +} + +} diff --git a/ydb/core/tablet/bootstrapper.h b/ydb/core/tablet/bootstrapper.h index 6ebeb5e8a9..2e246ea2b0 100644 --- a/ydb/core/tablet/bootstrapper.h +++ b/ydb/core/tablet/bootstrapper.h @@ -1,53 +1,53 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include <ydb/core/tablet/tablet_setup.h> #include <ydb/core/base/tablet.h> #include <ydb/core/base/blobstorage.h> - -namespace NKikimr { - -struct TEvBootstrapper { - enum EEv { - EvActivate = EventSpaceBegin(TKikimrEvents::ES_BOOTSTRAPPER), - EvStandBy, - EvWatch, - EvWatchResult, - EvNotify, - - EvEnd, - }; - - static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_BOOTSTRAPPER), "event space overrun"); - - struct TEvActivate : public TEventBase<TEvActivate, EvActivate> { - DEFINE_SIMPLE_NONLOCAL_EVENT(TEvActivate, "TEvBootstrapper::Activate"); - }; - + +namespace NKikimr { + +struct TEvBootstrapper { + enum EEv { + EvActivate = EventSpaceBegin(TKikimrEvents::ES_BOOTSTRAPPER), + EvStandBy, + EvWatch, + EvWatchResult, + EvNotify, + + EvEnd, + }; + + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_BOOTSTRAPPER), "event space overrun"); + + struct TEvActivate : public TEventBase<TEvActivate, EvActivate> { + DEFINE_SIMPLE_NONLOCAL_EVENT(TEvActivate, "TEvBootstrapper::Activate"); + }; + struct TEvStandBy : public TEventBase<TEvStandBy, EvStandBy> { - DEFINE_SIMPLE_NONLOCAL_EVENT(TEvStandBy, "TEvBootstrapper::StandBy"); - }; - - struct TEvWatch; - struct TEvWatchResult; - struct TEvNotify; -}; - -struct TBootstrapperInfo : public TThrRefBase { - TIntrusivePtr<TTabletSetupInfo> SetupInfo; + DEFINE_SIMPLE_NONLOCAL_EVENT(TEvStandBy, "TEvBootstrapper::StandBy"); + }; + + struct TEvWatch; + struct TEvWatchResult; + struct TEvNotify; +}; + +struct TBootstrapperInfo : public TThrRefBase { + TIntrusivePtr<TTabletSetupInfo> SetupInfo; TVector<ui32> OtherNodes; - TDuration WatchThreshold; + TDuration WatchThreshold; TDuration OfflineDelay; bool StartFollowers; - - TBootstrapperInfo(TTabletSetupInfo *setupInfo) - : SetupInfo(setupInfo) - , WatchThreshold(TDuration::MilliSeconds(200)) + + TBootstrapperInfo(TTabletSetupInfo *setupInfo) + : SetupInfo(setupInfo) + , WatchThreshold(TDuration::MilliSeconds(200)) , OfflineDelay(TDuration::Seconds(3)) , StartFollowers(false) - {} -}; - -IActor* CreateBootstrapper(TTabletStorageInfo *tabletInfo, TBootstrapperInfo *bootstrapperInfo, bool standby = false); + {} +}; + +IActor* CreateBootstrapper(TTabletStorageInfo *tabletInfo, TBootstrapperInfo *bootstrapperInfo, bool standby = false); TActorId MakeBootstrapperID(ui64 tablet, ui32 node); - -} + +} diff --git a/ydb/core/tablet/defs.h b/ydb/core/tablet/defs.h index 987be720e5..b982be8e2c 100644 --- a/ydb/core/tablet/defs.h +++ b/ydb/core/tablet/defs.h @@ -1,11 +1,11 @@ -#pragma once +#pragma once // unique tag to fix pragma once gcc glueing: ./ydb/core/tablet/defs.h #include <ydb/core/base/defs.h> #include <ydb/core/base/events.h> #include <ydb/core/base/logoblob.h> - + namespace NKikimr { - + class TFlatBlobDataOutputStream; } diff --git a/ydb/core/tablet/node_tablet_monitor.cpp b/ydb/core/tablet/node_tablet_monitor.cpp index 47f567010e..8bb34e7ea0 100644 --- a/ydb/core/tablet/node_tablet_monitor.cpp +++ b/ydb/core/tablet/node_tablet_monitor.cpp @@ -454,7 +454,7 @@ private: } else if (actionParam == "kill_tablet") { if (cgi.Has("tablet_id")) { ui64 tabletId = FromStringWithDefault<ui64>(cgi.Get("tablet_id")); - ctx.Register(CreateTabletKiller(tabletId)); + ctx.Register(CreateTabletKiller(tabletId)); if (cgi.Has("filter_node_id")) ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes("<meta http-equiv=\"refresh\" content=\"0; nodetabmon?action=browse_tablets&node_id=" + cgi.Get("filter_node_id") + "\" />")); else diff --git a/ydb/core/tablet/node_whiteboard.cpp b/ydb/core/tablet/node_whiteboard.cpp index 4564d4da97..783758e99d 100644 --- a/ydb/core/tablet/node_whiteboard.cpp +++ b/ydb/core/tablet/node_whiteboard.cpp @@ -8,7 +8,7 @@ #include <library/cpp/actors/core/hfunc.h> #include <library/cpp/actors/core/process_stats.h> #include <ydb/core/node_whiteboard/node_whiteboard.h> -#include "tablet_counters.h" +#include "tablet_counters.h" #include <ydb/core/base/counters.h> #include <ydb/core/util/tuples.h> diff --git a/ydb/core/tablet/resource_broker.cpp b/ydb/core/tablet/resource_broker.cpp index f21796d4bf..fff30b2601 100644 --- a/ydb/core/tablet/resource_broker.cpp +++ b/ydb/core/tablet/resource_broker.cpp @@ -74,7 +74,7 @@ void TTask::OutputState(IOutputStream &os, const TString &prefix) const << prefix << " ID: " << TaskId << Endl << prefix << " Client: " << Client.ToString() << Endl << prefix << " Type: " << ToString(Type) << Endl - << prefix << " Required resources: {" << JoinSeq(", ", RequiredResources) << "}" << Endl + << prefix << " Required resources: {" << JoinSeq(", ", RequiredResources) << "}" << Endl << prefix << " Priority: " << Priority << Endl << prefix << " InFly: " << InFly << Endl << prefix << " Queue: " << Queue->Name << Endl diff --git a/ydb/core/tablet/tablet_counters.cpp b/ydb/core/tablet/tablet_counters.cpp index b9a72c626b..b2ef0d4ad7 100644 --- a/ydb/core/tablet/tablet_counters.cpp +++ b/ydb/core/tablet/tablet_counters.cpp @@ -1,118 +1,118 @@ -#include "tablet_counters.h" - -//////////////////////////////////////////// -namespace NKikimr { - -//////////////////////////////////////////// -/// The TTabletCountersBase class -//////////////////////////////////////////// -TAutoPtr<TTabletCountersBase> -TTabletCountersBase::MakeDiffForAggr(const TTabletCountersBase& baseLine) const { - TAutoPtr<TTabletCountersBase> retVal = new TTabletCountersBase(*this); - if (baseLine.HasCounters()) { +#include "tablet_counters.h" + +//////////////////////////////////////////// +namespace NKikimr { + +//////////////////////////////////////////// +/// The TTabletCountersBase class +//////////////////////////////////////////// +TAutoPtr<TTabletCountersBase> +TTabletCountersBase::MakeDiffForAggr(const TTabletCountersBase& baseLine) const { + TAutoPtr<TTabletCountersBase> retVal = new TTabletCountersBase(*this); + if (baseLine.HasCounters()) { Y_VERIFY_DEBUG(baseLine.SimpleCounters.Size() == SimpleCounters.Size()); Y_VERIFY_DEBUG(baseLine.CumulativeCounters.Size() == CumulativeCounters.Size()); Y_VERIFY_DEBUG(baseLine.PercentileCounters.Size() == PercentileCounters.Size()); - + Y_VERIFY_DEBUG(baseLine.SimpleCountersMetaInfo == SimpleCountersMetaInfo); Y_VERIFY_DEBUG(baseLine.CumulativeCountersMetaInfo == CumulativeCountersMetaInfo); Y_VERIFY_DEBUG(baseLine.PercentileCountersMetaInfo == PercentileCountersMetaInfo); - - retVal->SimpleCounters.AdjustToBaseLine(baseLine.SimpleCounters); - retVal->CumulativeCounters.AdjustToBaseLine(baseLine.CumulativeCounters); - retVal->PercentileCounters.AdjustToBaseLine(baseLine.PercentileCounters); - } - return retVal; -} - -//////////////////////////////////////////// -void TTabletCountersBase::RememberCurrentStateAsBaseline(/*out*/ TTabletCountersBase& baseLine) const { - baseLine = *this; -} - -//////////////////////////////////////////// -// private -//////////////////////////////////////////// -TTabletCountersBase::TTabletCountersBase(const TTabletCountersBase& rp) - : TTabletCountersBase() -{ - *this = rp; -} - -//////////////////////////////////////////// -TTabletCountersBase& -TTabletCountersBase::operator = (const TTabletCountersBase& rp) { - if (&rp == this) - return *this; - - if (!HasCounters()) { - SimpleCounters.Reset(rp.SimpleCounters); - SimpleCountersMetaInfo = rp.SimpleCountersMetaInfo; - - CumulativeCounters.Reset(rp.CumulativeCounters); - CumulativeCountersMetaInfo = rp.CumulativeCountersMetaInfo; - - PercentileCounters.Reset(rp.PercentileCounters); - PercentileCountersMetaInfo = rp.PercentileCountersMetaInfo; - } else { - SimpleCounters.SetTo(rp.SimpleCounters); - CumulativeCounters.SetTo(rp.CumulativeCounters); - PercentileCounters.SetTo(rp.PercentileCounters); - } - - return *this; -} - + + retVal->SimpleCounters.AdjustToBaseLine(baseLine.SimpleCounters); + retVal->CumulativeCounters.AdjustToBaseLine(baseLine.CumulativeCounters); + retVal->PercentileCounters.AdjustToBaseLine(baseLine.PercentileCounters); + } + return retVal; +} + +//////////////////////////////////////////// +void TTabletCountersBase::RememberCurrentStateAsBaseline(/*out*/ TTabletCountersBase& baseLine) const { + baseLine = *this; +} + +//////////////////////////////////////////// +// private +//////////////////////////////////////////// +TTabletCountersBase::TTabletCountersBase(const TTabletCountersBase& rp) + : TTabletCountersBase() +{ + *this = rp; +} + +//////////////////////////////////////////// +TTabletCountersBase& +TTabletCountersBase::operator = (const TTabletCountersBase& rp) { + if (&rp == this) + return *this; + + if (!HasCounters()) { + SimpleCounters.Reset(rp.SimpleCounters); + SimpleCountersMetaInfo = rp.SimpleCountersMetaInfo; + + CumulativeCounters.Reset(rp.CumulativeCounters); + CumulativeCountersMetaInfo = rp.CumulativeCountersMetaInfo; + + PercentileCounters.Reset(rp.PercentileCounters); + PercentileCountersMetaInfo = rp.PercentileCountersMetaInfo; + } else { + SimpleCounters.SetTo(rp.SimpleCounters); + CumulativeCounters.SetTo(rp.CumulativeCounters); + PercentileCounters.SetTo(rp.PercentileCounters); + } + + return *this; +} + void TTabletSimpleCounterBase::OutputHtml(IOutputStream &os, const char* name) const { HTML(os) {PRE() {os << name << ": " << Value;}} -} - +} + void TTabletPercentileCounter::OutputHtml(IOutputStream &os, const char* name) const { HTML(os) { DIV_CLASS("row") { DIV_CLASS("col-md-12") {H4() {os << name;}} } - + DIV_CLASS("row") { - for (ui32 i = 0; i < RangeCount; ++i) { + for (ui32 i = 0; i < RangeCount; ++i) { DIV_CLASS("col-md-3") { PRE() { - os << Ranges[i].RangeName << ": " << Values[i]; + os << Ranges[i].RangeName << ": " << Values[i]; } } - } + } } } -} - +} + void TTabletCountersBase::OutputHtml(IOutputStream &os) const { HTML(os) { DIV_CLASS("row") { DIV_CLASS("col-md-12") {OutputHtml(os, "Simple", SimpleCountersMetaInfo, "col-md-3", SimpleCounters);} DIV_CLASS("col-md-12") {OutputHtml(os, "Cumulative", CumulativeCountersMetaInfo, "col-md-3", CumulativeCounters);} DIV_CLASS("col-md-12") {OutputHtml(os, "Percentile", PercentileCountersMetaInfo, "col-md-12", PercentileCounters);} - + } } -} - -//////////////////////////////////////////// -template<typename T> +} + +//////////////////////////////////////////// +template<typename T> void TTabletCountersBase::OutputHtml(IOutputStream &os, const char* sectionName, const char* const* counterNames, const char* counterClass, const TCountersArray<T>& counters) const { HTML(os) { DIV_CLASS("row") { DIV_CLASS("col-md-12") {H3() {os << sectionName; }} } DIV_CLASS("row") { - for (ui32 i = 0, e = counters.Size(); i < e; ++i) { + for (ui32 i = 0, e = counters.Size(); i < e; ++i) { if (counterNames[i]) { DIV_CLASS(counterClass) {counters[i].OutputHtml(os, counterNames[i]);} } - } + } } } -} - +} + void TTabletCountersBase::OutputProto(NKikimrTabletBase::TTabletCountersBase& op) const { if (HasCounters()) { for (ui32 idx = 0; idx < SimpleCounters.Size(); ++idx) { @@ -247,5 +247,5 @@ IOutputStream& operator <<(IOutputStream& out, const TTabletLabeledCountersBase: } -} // end of NKikimr namespace - +} // end of NKikimr namespace + diff --git a/ydb/core/tablet/tablet_counters.h b/ydb/core/tablet/tablet_counters.h index ff6af770ea..a8cc27e9ed 100644 --- a/ydb/core/tablet/tablet_counters.h +++ b/ydb/core/tablet/tablet_counters.h @@ -1,5 +1,5 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include <util/generic/singleton.h> #include <util/generic/vector.h> #include <library/cpp/deprecated/enum_codegen/enum_codegen.h> @@ -7,62 +7,62 @@ #include <google/protobuf/descriptor.pb.h> #include <ydb/core/protos/counters.pb.h> #include <ydb/core/protos/tablet_counters.pb.h> - -//////////////////////////////////////////// -namespace NKikimr { - -#define COUNTER_TEXT_ARRAY(name, value, ...) value, - -#define COUNTER_PERCENTILE_CONFIG_ARRAY(rangeVal, rangeText, ...) { rangeVal, rangeText }, - -template <typename T> -class TCountersArray; - -//////////////////////////////////////////// -/// The TTabletSimpleCounterBase class -//////////////////////////////////////////// -class TTabletSimpleCounterBase { -public: - // - TTabletSimpleCounterBase() - : Value(0) - {} - ~TTabletSimpleCounterBase() {} - - // - ui64 Get() const { - return Value; - } - + +//////////////////////////////////////////// +namespace NKikimr { + +#define COUNTER_TEXT_ARRAY(name, value, ...) value, + +#define COUNTER_PERCENTILE_CONFIG_ARRAY(rangeVal, rangeText, ...) { rangeVal, rangeText }, + +template <typename T> +class TCountersArray; + +//////////////////////////////////////////// +/// The TTabletSimpleCounterBase class +//////////////////////////////////////////// +class TTabletSimpleCounterBase { +public: + // + TTabletSimpleCounterBase() + : Value(0) + {} + ~TTabletSimpleCounterBase() {} + + // + ui64 Get() const { + return Value; + } + void OutputHtml(IOutputStream &os, const char* name) const; - -protected: - // - ui64 Value; -}; - -//////////////////////////////////////////// -/// The TTabletSimpleCounter class -//////////////////////////////////////////// -class TTabletSimpleCounter : public TTabletSimpleCounterBase { - friend class TCountersArray<TTabletSimpleCounter>; -public: - // - TTabletSimpleCounter() - {} - ~TTabletSimpleCounter() - {} - - // + +protected: + // + ui64 Value; +}; + +//////////////////////////////////////////// +/// The TTabletSimpleCounter class +//////////////////////////////////////////// +class TTabletSimpleCounter : public TTabletSimpleCounterBase { + friend class TCountersArray<TTabletSimpleCounter>; +public: + // + TTabletSimpleCounter() + {} + ~TTabletSimpleCounter() + {} + + // TTabletSimpleCounter& Set(ui64 value) { Value = value; - return *this; - } + return *this; + } TTabletSimpleCounter& Add(ui64 delta) { Value += delta; return *this; - } + } TTabletSimpleCounter& Sub(ui64 delta) { Value -= delta; @@ -72,7 +72,7 @@ public: TTabletSimpleCounter& operator = (ui64 value) { return Set(value); } - + TTabletSimpleCounter& operator += (ui64 delta) { return Add(delta); } @@ -81,86 +81,86 @@ public: return Sub(delta); } -private: - // - void Initialize(const TTabletSimpleCounter& rp) { - SetTo(rp); - } - void AdjustToBaseLine(const TTabletSimpleCounter&) { /* no-op */ } - void SetTo(const TTabletSimpleCounter& rp) { - Value = rp.Value; - } +private: + // + void Initialize(const TTabletSimpleCounter& rp) { + SetTo(rp); + } + void AdjustToBaseLine(const TTabletSimpleCounter&) { /* no-op */ } + void SetTo(const TTabletSimpleCounter& rp) { + Value = rp.Value; + } void Populate(const TTabletSimpleCounter& rp) { SetTo(rp); } -}; - -//////////////////////////////////////////// -/// The TTabletCumulativeCounter class -//////////////////////////////////////////// -class TTabletCumulativeCounter : public TTabletSimpleCounterBase{ - friend class TCountersArray<TTabletCumulativeCounter>; -public: - // - TTabletCumulativeCounter() - {} - ~TTabletCumulativeCounter() - {} - - // - TTabletCumulativeCounter& Increment(ui64 delta) { - Value += delta; - return *this; - } - TTabletCumulativeCounter& operator += (ui64 delta) { - return Increment(delta); - } - -private: - // - void Initialize(const TTabletCumulativeCounter& rp) { - SetTo(rp); - } - void AdjustToBaseLine(const TTabletCumulativeCounter& baseLine) { +}; + +//////////////////////////////////////////// +/// The TTabletCumulativeCounter class +//////////////////////////////////////////// +class TTabletCumulativeCounter : public TTabletSimpleCounterBase{ + friend class TCountersArray<TTabletCumulativeCounter>; +public: + // + TTabletCumulativeCounter() + {} + ~TTabletCumulativeCounter() + {} + + // + TTabletCumulativeCounter& Increment(ui64 delta) { + Value += delta; + return *this; + } + TTabletCumulativeCounter& operator += (ui64 delta) { + return Increment(delta); + } + +private: + // + void Initialize(const TTabletCumulativeCounter& rp) { + SetTo(rp); + } + void AdjustToBaseLine(const TTabletCumulativeCounter& baseLine) { Y_VERIFY_DEBUG(Value >= baseLine.Value); - Value -= baseLine.Value; - } - void SetTo(const TTabletCumulativeCounter& rp) { - Value = rp.Value; - } + Value -= baseLine.Value; + } + void SetTo(const TTabletCumulativeCounter& rp) { + Value = rp.Value; + } void Populate(const TTabletCumulativeCounter& rp) { Value += rp.Value; } -}; - -//////////////////////////////////////////// -/// The TTabletPercentileCounter class -//////////////////////////////////////////// -class TTabletPercentileCounter : TNonCopyable { - friend class TCountersArray<TTabletPercentileCounter>; -public: - // +}; + +//////////////////////////////////////////// +/// The TTabletPercentileCounter class +//////////////////////////////////////////// +class TTabletPercentileCounter : TNonCopyable { + friend class TCountersArray<TTabletPercentileCounter>; +public: + // struct TRangeDef { - ui64 RangeVal; - const char* RangeName; + ui64 RangeVal; + const char* RangeName; friend bool operator <(const TRangeDef& x, const TRangeDef& y) { return x.RangeVal < y.RangeVal; } friend bool operator <(const ui64 x, const TRangeDef& y) { return x < y.RangeVal; } - }; - - template <ui32 rangeCount> + }; + + template <ui32 rangeCount> void Initialize(const TRangeDef(&ranges)[rangeCount], bool integral) { Initialize(rangeCount, ranges, integral); - } - - TTabletPercentileCounter& IncrementFor(ui64 what) { - ui32 index = FindSlot(what); - Values[index] += 1; - return *this; - } - + } + + TTabletPercentileCounter& IncrementFor(ui64 what) { + ui32 index = FindSlot(what); + Values[index] += 1; + return *this; + } + TTabletPercentileCounter& IncrementForRange(ui64 idx) { Values[idx] += 1; return *this; @@ -174,18 +174,18 @@ public: return *this; } - ui32 GetRangeCount() const { - return RangeCount; - } - - const char* GetRangeName(ui32 index) const { - return Ranges[index].RangeName; - } - - ui64 GetRangeValue(ui32 index) const { - return Values[index]; - } - + ui32 GetRangeCount() const { + return RangeCount; + } + + const char* GetRangeName(ui32 index) const { + return Ranges[index].RangeName; + } + + ui64 GetRangeValue(ui32 index) const { + return Values[index]; + } + ui64 GetRangeBound(ui32 index) const { return Ranges[index].RangeVal; } @@ -203,54 +203,54 @@ public: } void OutputHtml(IOutputStream &os, const char* name) const; - -private: - // - void AdjustToBaseLine(const TTabletPercentileCounter& baseLine) { - // + +private: + // + void AdjustToBaseLine(const TTabletPercentileCounter& baseLine) { + // Y_VERIFY_DEBUG(RangeCount == baseLine.RangeCount); if (Integral) { return; } - - for (ui32 i = 0; i < RangeCount; ++i) { + + for (ui32 i = 0; i < RangeCount; ++i) { Y_VERIFY_DEBUG(Values[i] >= baseLine.Values[i]); - Values[i] -= baseLine.Values[i]; - } - } - - void Initialize(const TTabletPercentileCounter& rp) { - // + Values[i] -= baseLine.Values[i]; + } + } + + void Initialize(const TTabletPercentileCounter& rp) { + // if (rp.IsInitialized()) { Initialize(rp.RangeCount, rp.Ranges, rp.Integral); SetTo(rp); } - } - - // - void SetTo(const TTabletPercentileCounter& rp) { - // + } + + // + void SetTo(const TTabletPercentileCounter& rp) { + // Y_VERIFY_DEBUG(RangeCount == rp.RangeCount); - for (ui32 i = 0; i < RangeCount; ++i) { - Values[i] = rp.Values[i]; - } - } - + for (ui32 i = 0; i < RangeCount; ++i) { + Values[i] = rp.Values[i]; + } + } + public: void Initialize(ui32 rangeCount, const TRangeDef* ranges, bool integral) { Y_VERIFY_DEBUG(!Ranges); Y_VERIFY_DEBUG(!Values); Y_VERIFY_DEBUG(rangeCount > 0); Y_VERIFY_DEBUG(ranges[0].RangeVal == 0); - - RangeCount = rangeCount; - Ranges = ranges; + + RangeCount = rangeCount; + Ranges = ranges; Integral = integral; - + Y_VERIFY_DEBUG(IsSorted()); - + Values = TArrayHolder<ui64>(new ui64[RangeCount]()); - } + } void Clear() { if (IsInitialized()) { @@ -259,15 +259,15 @@ public: } private: - // + // ui32 FindSlot(ui64 what) const { return Max<ssize_t>(0, std::upper_bound(Ranges, Ranges + RangeCount, what) - Ranges - 1); - } + } bool IsSorted() const { return std::is_sorted(Ranges, Ranges + RangeCount); - } - + } + bool IsInitialized() const { return RangeCount != 0; } @@ -283,32 +283,32 @@ private: } } - // + // ui32 RangeCount = 0; const TRangeDef* Ranges = nullptr; bool Integral = false; - - TArrayHolder<ui64> Values; -}; - -//////////////////////////////////////////// -template <typename T> -class TCountersArray : TNonCopyable { - friend class TTabletCountersBase; + + TArrayHolder<ui64> Values; +}; + +//////////////////////////////////////////// +template <typename T> +class TCountersArray : TNonCopyable { + friend class TTabletCountersBase; friend class TTabletLabeledCountersBase; -public: +public: typedef std::shared_ptr<T> TCountersHolder; - // - TCountersArray(ui32 countersQnt) - : CountersQnt(countersQnt) + // + TCountersArray(ui32 countersQnt) + : CountersQnt(countersQnt) , CountersHolder(nullptr) - , Counters(nullptr) - { + , Counters(nullptr) + { if (CountersQnt) { CountersHolder.reset(new T[CountersQnt](), &CheckedArrayDelete<T>); Counters = CountersHolder.get(); } - } + } //not owning constructor - can refer to part of other counters TCountersArray(TCountersHolder& countersHolder, T* counters, const ui32 countersQnt) @@ -318,65 +318,65 @@ public: { } - ~TCountersArray() - { - Counters = nullptr; - CountersQnt = 0; - } - - // - explicit operator bool() const { - return Counters; - } - - // - T& operator[] (ui32 index) { + ~TCountersArray() + { + Counters = nullptr; + CountersQnt = 0; + } + + // + explicit operator bool() const { + return Counters; + } + + // + T& operator[] (ui32 index) { Y_ASSERT(index < CountersQnt); - return Counters[index]; - } - - const T& operator[] (ui32 index) const { + return Counters[index]; + } + + const T& operator[] (ui32 index) const { Y_ASSERT(index < CountersQnt); - return Counters[index]; - } - - ui32 Size() const { - return CountersQnt; - } - -private: - // - void Reset(const TCountersArray<T>& rp) { + return Counters[index]; + } + + ui32 Size() const { + return CountersQnt; + } + +private: + // + void Reset(const TCountersArray<T>& rp) { Y_VERIFY(!CountersQnt); CountersHolder.reset(); - Counters = nullptr; - - CountersQnt = rp.CountersQnt; + Counters = nullptr; + + CountersQnt = rp.CountersQnt; if (CountersQnt) { CountersHolder.reset(new T[CountersQnt](), &CheckedArrayDelete<T>); Counters = CountersHolder.get(); } - - for (ui32 i = 0, e = CountersQnt; i < e; ++i) { - Counters[i].Initialize(rp.Counters[i]); - } - } - - // - void AdjustToBaseLine(const TCountersArray<T>& baseLine) { + + for (ui32 i = 0, e = CountersQnt; i < e; ++i) { + Counters[i].Initialize(rp.Counters[i]); + } + } + + // + void AdjustToBaseLine(const TCountersArray<T>& baseLine) { Y_VERIFY_DEBUG(baseLine.CountersQnt == CountersQnt); - for (ui32 i = 0, e = CountersQnt; i < e; ++i) { - Counters[i].AdjustToBaseLine(baseLine.Counters[i]); - } - } - - void SetTo(const TCountersArray<T>& rp) { + for (ui32 i = 0, e = CountersQnt; i < e; ++i) { + Counters[i].AdjustToBaseLine(baseLine.Counters[i]); + } + } + + void SetTo(const TCountersArray<T>& rp) { Y_VERIFY_DEBUG(rp.CountersQnt == CountersQnt); - for (ui32 i = 0, e = CountersQnt; i < e; ++i) { - Counters[i].SetTo(rp.Counters[i]); - } - } - + for (ui32 i = 0, e = CountersQnt; i < e; ++i) { + Counters[i].SetTo(rp.Counters[i]); + } + } + void Populate(const TCountersArray<T>& rp) { if (CountersQnt != rp.CountersQnt) { Reset(rp); @@ -387,41 +387,41 @@ private: } } - // - ui32 CountersQnt; + // + ui32 CountersQnt; TCountersHolder CountersHolder; - T* Counters; -}; - -//////////////////////////////////////////// -/// The TTabletCountersBase class -//////////////////////////////////////////// -class TTabletCountersBase { -public: - // - TTabletCountersBase() - : SimpleCounters(0) - , CumulativeCounters(0) - , PercentileCounters(0) - , SimpleCountersMetaInfo(nullptr) - , CumulativeCountersMetaInfo(nullptr) - , PercentileCountersMetaInfo(nullptr) - {} - - TTabletCountersBase(ui32 simpleCountersQnt, - ui32 cumulativeCountersQnt, - ui32 percentileCountersQnt, - const char* const * simpleCountersMetaInfo, - const char* const * cumulativeCountersMetaInfo, - const char* const * percentileCountersMetaInfo) - : SimpleCounters(simpleCountersQnt) - , CumulativeCounters(cumulativeCountersQnt) - , PercentileCounters(percentileCountersQnt) - , SimpleCountersMetaInfo(simpleCountersMetaInfo) - , CumulativeCountersMetaInfo(cumulativeCountersMetaInfo) - , PercentileCountersMetaInfo(percentileCountersMetaInfo) - {} - + T* Counters; +}; + +//////////////////////////////////////////// +/// The TTabletCountersBase class +//////////////////////////////////////////// +class TTabletCountersBase { +public: + // + TTabletCountersBase() + : SimpleCounters(0) + , CumulativeCounters(0) + , PercentileCounters(0) + , SimpleCountersMetaInfo(nullptr) + , CumulativeCountersMetaInfo(nullptr) + , PercentileCountersMetaInfo(nullptr) + {} + + TTabletCountersBase(ui32 simpleCountersQnt, + ui32 cumulativeCountersQnt, + ui32 percentileCountersQnt, + const char* const * simpleCountersMetaInfo, + const char* const * cumulativeCountersMetaInfo, + const char* const * percentileCountersMetaInfo) + : SimpleCounters(simpleCountersQnt) + , CumulativeCounters(cumulativeCountersQnt) + , PercentileCounters(percentileCountersQnt) + , SimpleCountersMetaInfo(simpleCountersMetaInfo) + , CumulativeCountersMetaInfo(cumulativeCountersMetaInfo) + , PercentileCountersMetaInfo(percentileCountersMetaInfo) + {} + //Constructor only for access of other counters. Lifetime of class constructed this way must not exceed lifetime of existed one. TTabletCountersBase(const ui32 simpleOffset, const ui32 cumulativeOffset, const ui32 percentileOffset, TTabletCountersBase* counters) : SimpleCounters(counters->Simple().CountersHolder, counters->Simple().Counters + simpleOffset, @@ -440,56 +440,56 @@ public: Y_VERIFY_DEBUG(counters->Percentile().Size() > percentileOffset); } - virtual ~TTabletCountersBase() - {} - - bool HasCounters() const { - return SimpleCounters || CumulativeCounters || PercentileCounters; - } - - // counters - TCountersArray<TTabletSimpleCounter>& Simple() { - return SimpleCounters; - } - const TCountersArray<TTabletSimpleCounter>& Simple() const { - return SimpleCounters; - } - - TCountersArray<TTabletCumulativeCounter>& Cumulative() { - return CumulativeCounters; - } - const TCountersArray<TTabletCumulativeCounter>& Cumulative() const { - return CumulativeCounters; - } - - TCountersArray<TTabletPercentileCounter>& Percentile() { - return PercentileCounters; - } - const TCountersArray<TTabletPercentileCounter>& Percentile() const { - return PercentileCounters; - } - - // - TAutoPtr<TTabletCountersBase> MakeDiffForAggr(const TTabletCountersBase&) const; - void RememberCurrentStateAsBaseline(/*out*/ TTabletCountersBase& baseLine) const; - - // + virtual ~TTabletCountersBase() + {} + + bool HasCounters() const { + return SimpleCounters || CumulativeCounters || PercentileCounters; + } + + // counters + TCountersArray<TTabletSimpleCounter>& Simple() { + return SimpleCounters; + } + const TCountersArray<TTabletSimpleCounter>& Simple() const { + return SimpleCounters; + } + + TCountersArray<TTabletCumulativeCounter>& Cumulative() { + return CumulativeCounters; + } + const TCountersArray<TTabletCumulativeCounter>& Cumulative() const { + return CumulativeCounters; + } + + TCountersArray<TTabletPercentileCounter>& Percentile() { + return PercentileCounters; + } + const TCountersArray<TTabletPercentileCounter>& Percentile() const { + return PercentileCounters; + } + + // + TAutoPtr<TTabletCountersBase> MakeDiffForAggr(const TTabletCountersBase&) const; + void RememberCurrentStateAsBaseline(/*out*/ TTabletCountersBase& baseLine) const; + + // void OutputHtml(IOutputStream &os) const; void OutputProto(NKikimrTabletBase::TTabletCountersBase& op) const; - - // - const char* SimpleCounterName(ui32 index) const { - return SimpleCountersMetaInfo[index]; - } - - const char* CumulativeCounterName(ui32 index) const { - return CumulativeCountersMetaInfo[index]; - } - - const char* PercentileCounterName(ui32 index) const { - return PercentileCountersMetaInfo[index]; - } - + + // + const char* SimpleCounterName(ui32 index) const { + return SimpleCountersMetaInfo[index]; + } + + const char* CumulativeCounterName(ui32 index) const { + return CumulativeCountersMetaInfo[index]; + } + + const char* PercentileCounterName(ui32 index) const { + return PercentileCountersMetaInfo[index]; + } + void Populate(const TTabletCountersBase& rp) { if (!HasCounters()) { SimpleCounters.Reset(rp.SimpleCounters); @@ -507,24 +507,24 @@ public: } } -private: - // - TTabletCountersBase(const TTabletCountersBase&); - TTabletCountersBase& operator = (const TTabletCountersBase&); - - // - template<typename T> +private: + // + TTabletCountersBase(const TTabletCountersBase&); + TTabletCountersBase& operator = (const TTabletCountersBase&); + + // + template<typename T> void OutputHtml(IOutputStream &os, const char* sectionName, const char* const* counterNames, const char* counterClass, const TCountersArray<T>& counters) const; - - // - TCountersArray<TTabletSimpleCounter> SimpleCounters; - TCountersArray<TTabletCumulativeCounter> CumulativeCounters; - TCountersArray<TTabletPercentileCounter> PercentileCounters; - const char* const * SimpleCountersMetaInfo; - const char* const * CumulativeCountersMetaInfo; - const char* const * PercentileCountersMetaInfo; -}; - + + // + TCountersArray<TTabletSimpleCounter> SimpleCounters; + TCountersArray<TTabletCumulativeCounter> CumulativeCounters; + TCountersArray<TTabletPercentileCounter> PercentileCounters; + const char* const * SimpleCountersMetaInfo; + const char* const * CumulativeCountersMetaInfo; + const char* const * PercentileCountersMetaInfo; +}; + //////////////////////////////////////////// /// The TTabletLabeledCountersBase class @@ -668,5 +668,5 @@ private: IOutputStream& operator <<(IOutputStream& out, const TTabletLabeledCountersBase::EAggregateFunc& func); -} // end of NKikimr - +} // end of NKikimr + diff --git a/ydb/core/tablet/tablet_counters_aggregator.cpp b/ydb/core/tablet/tablet_counters_aggregator.cpp index 5bdcce4d06..1885b26e09 100644 --- a/ydb/core/tablet/tablet_counters_aggregator.cpp +++ b/ydb/core/tablet/tablet_counters_aggregator.cpp @@ -19,7 +19,7 @@ #include <library/cpp/monlib/service/pages/templates.h> #include <library/cpp/monlib/dynamic_counters/encode.h> -#include <util/generic/xrange.h> +#include <util/generic/xrange.h> #include <util/string/vector.h> #include <util/string/split.h> @@ -32,12 +32,12 @@ namespace NKikimr { TActorId MakeTabletCountersAggregatorID(ui32 node, bool follower) { if (!follower) { - char x[12] = {'t','a','b','l','c','o','u','n','t','a','g','g'}; + char x[12] = {'t','a','b','l','c','o','u','n','t','a','g','g'}; return TActorId(node, TStringBuf(x, 12)); - } else { - char x[12] ={'s','l','a','v','c','o','u','n','t','a','g','g'}; + } else { + char x[12] ={'s','l','a','v','c','o','u','n','t','a','g','g'}; return TActorId(node, TStringBuf(x, 12)); - } + } } TStringBuf GetHistogramAggregateSimpleName(TStringBuf name) { @@ -118,7 +118,7 @@ public: HistSimpleCounters.emplace_back(std::move(percentileAggregate)); } - + ui64 GetSum(ui32 counterIndex) const { Y_VERIFY(counterIndex < SumSimpleCounters.size(), "inconsistent sum simple counters, %u >= %lu", counterIndex, SumSimpleCounters.size()); @@ -143,7 +143,7 @@ public: *MaxSimpleCounters[counterIndex] = value; } - void SetValue(ui64 tabletID, ui32 counterIndex, ui64 value, TTabletTypes::EType tabletType) { + void SetValue(ui64 tabletID, ui32 counterIndex, ui64 value, TTabletTypes::EType tabletType) { Y_VERIFY(counterIndex < CountersByTabletID.size(), "inconsistent counters for tablet type %s", TTabletTypes::TypeToStr(tabletType)); auto it = CountersByTabletID[counterIndex].find(tabletID); @@ -156,15 +156,15 @@ public: CountersByTabletID[counterIndex].insert(std::make_pair(tabletID, value)); ChangedCounters[counterIndex] = true; } - } + } - void ForgetTablet(ui64 tabletId) { - for (ui32 idx : xrange(CountersByTabletID.size())) { - auto &counters = CountersByTabletID[idx]; - counters.erase(tabletId); + void ForgetTablet(ui64 tabletId) { + for (ui32 idx : xrange(CountersByTabletID.size())) { + auto &counters = CountersByTabletID[idx]; + counters.erase(tabletId); ChangedCounters[idx] = true; - } - } + } + } void RecalcAll() { for (ui32 idx : xrange(CountersByTabletID.size())) { @@ -174,23 +174,23 @@ public: } } -private: - // - NMonitoring::TDynamicCounterPtr CounterGroup; +private: + // + NMonitoring::TDynamicCounterPtr CounterGroup; - TCountersVector MaxSimpleCounters; - TCountersVector SumSimpleCounters; + TCountersVector MaxSimpleCounters; + TCountersVector SumSimpleCounters; THistogramVector HistSimpleCounters; using TCountersByTabletIDMap = THashMap<ui64, ui64>; - + TVector<TCountersByTabletIDMap> CountersByTabletID; TVector<bool> ChangedCounters; - -private: - void Recalc(ui32 idx) { - auto &counters = CountersByTabletID[idx]; + +private: + void Recalc(ui32 idx) { + auto &counters = CountersByTabletID[idx]; THistogramCounter* histCounter = HistSimpleCounters[idx].Get(); - + ui64 maxVal = 0; ui64 sumVal = 0; @@ -198,7 +198,7 @@ private: histCounter->Clear(); } - for (auto&& t : counters) { + for (auto&& t : counters) { ui64 tValue = t.second; maxVal = Max(tValue, maxVal); sumVal += tValue; @@ -207,8 +207,8 @@ private: } } - *MaxSimpleCounters[idx].Get() = maxVal; - *SumSimpleCounters[idx].Get() = sumVal; + *MaxSimpleCounters[idx].Get() = maxVal; + *SumSimpleCounters[idx].Get() = sumVal; } }; @@ -346,7 +346,7 @@ public: } void SetValue(ui64 tabletID, ui32 counterIndex, ui64 value, ui64 id) { - + CountersByTabletID[counterIndex][tabletID] = std::make_pair(value, id); Changed = true; } @@ -502,13 +502,13 @@ public: // auto& quietStats = QuietTabletCounters[tabletID]; - + if (executorCounters) { if (quietStats.first == nullptr) quietStats.first = new TTabletCountersBase(); quietStats.first->Populate(*executorCounters); } - + if (appCounters) { if (quietStats.second == nullptr) quietStats.second = new TTabletCountersBase(); @@ -554,12 +554,12 @@ public: } void ForgetTablet(ui64 tabletID, TTabletTypes::EType tabletType, TPathId tenantPathId) { - AllTypes.Forget(tabletID); - // and now erase from every other path - auto iterTabletType = CountersByTabletType.find(tabletType); - if (iterTabletType != CountersByTabletType.end()) { - iterTabletType->second->Forget(tabletID); - } + AllTypes.Forget(tabletID); + // and now erase from every other path + auto iterTabletType = CountersByTabletType.find(tabletType); + if (iterTabletType != CountersByTabletType.end()) { + iterTabletType->second->Forget(tabletID); + } // from db counters if (auto itPath = CountersByPathId.find(tenantPathId); itPath != CountersByPathId.end()) { itPath->second->Forget(tabletID, tabletType); @@ -723,26 +723,26 @@ private: if (!TabletExecutorCounters.IsInitialized) { TabletExecutorCounters.Initialize(executorCounters); } - TabletExecutorCounters.Apply(tabletID, executorCounters, tabletType); + TabletExecutorCounters.Apply(tabletID, executorCounters, tabletType); } if (appCounters) { if (!TabletAppCounters.IsInitialized) { TabletAppCounters.Initialize(limitedAppCounters ? limitedAppCounters : appCounters); } - TabletAppCounters.Apply(tabletID, appCounters, tabletType); + TabletAppCounters.Apply(tabletID, appCounters, tabletType); } } - void Forget(ui64 tabletId) { + void Forget(ui64 tabletId) { if (TabletExecutorCounters.IsInitialized) { TabletExecutorCounters.Forget(tabletId); } if (TabletAppCounters.IsInitialized) { TabletAppCounters.Forget(tabletId); } - } - + } + void RecalcAll() { if (TabletExecutorCounters.IsInitialized) { TabletExecutorCounters.RecalcAll(); @@ -905,7 +905,7 @@ private: IsInitialized = true; } - void Apply(ui64 tabletID, const TTabletCountersBase* counters, TTabletTypes::EType tabletType) { + void Apply(ui64 tabletID, const TTabletCountersBase* counters, TTabletTypes::EType tabletType) { Y_VERIFY(counters); TInstant now = TInstant::Now(); @@ -999,9 +999,9 @@ private: } } - void Forget(ui64 tabletId) { - Y_VERIFY(IsInitialized); - + void Forget(ui64 tabletId) { + Y_VERIFY(IsInitialized); + if (DoAggregateSimpleCounters || DoAggregateCumulativeCounters) { if (DoAggregateSimpleCounters) { AggregatedSimpleCounters.ForgetTablet(tabletId); @@ -1010,11 +1010,11 @@ private: AggregatedCumulativeCounters.ForgetTablet(tabletId); LastAggregateUpdateTime.erase(tabletId); } - } else { - for (auto &x : SimpleCounters) - x = 0; - } - } + } else { + for (auto &x : SimpleCounters) + x = 0; + } + } void RecalcAll() { if (DoAggregateSimpleCounters) { @@ -1618,12 +1618,12 @@ TTabletCountersAggregatorActor::Bootstrap(const TActorContext &ctx) { TabletMon = new TTabletMon(appData->Counters, Follower, DbWatcherActorId); auto mon = appData->Mon; - if (mon) { + if (mon) { if (!Follower) mon->RegisterActorPage(nullptr, "labeledcounters", "Labeled Counters", false, TlsActivationContext->ExecutorThread.ActorSystem, SelfId(), false); - else + else mon->RegisterActorPage(nullptr, "followercounters", "Follower Counters", false, TlsActivationContext->ExecutorThread.ActorSystem, SelfId(), false); - } + } ctx.Schedule(TDuration::Seconds(WAKEUP_TIMEOUT_SECONDS), new TEvents::TEvWakeup()); } @@ -1859,7 +1859,7 @@ CreateTabletCountersAggregator(bool follower) { void TabletCountersForgetTablet(ui64 tabletId, TTabletTypes::EType tabletType, TPathId tenantPathId, bool follower, TActorIdentity identity) { const TActorId countersAggregator = MakeTabletCountersAggregatorID(identity.NodeId(), follower); identity.Send(countersAggregator, new TEvTabletCounters::TEvTabletCountersForgetTablet(tabletId, tabletType, tenantPathId)); -} +} /////////////////////////////////////////// @@ -1933,7 +1933,7 @@ public: void Die(const TActorContext& ctx) override { for (const ui32 node : Nodes) { - ctx.Send(TActivationContext::InterconnectProxy(node), new TEvents::TEvUnsubscribe()); + ctx.Send(TActivationContext::InterconnectProxy(node), new TEvents::TEvUnsubscribe()); } TBase::Die(ctx); } @@ -2297,7 +2297,7 @@ public: void Die(const TActorContext& ctx) override { for (const ui32 node : Nodes) { - ctx.Send(TActivationContext::InterconnectProxy(node), new TEvents::TEvUnsubscribe()); + ctx.Send(TActivationContext::InterconnectProxy(node), new TEvents::TEvUnsubscribe()); } TBase::Die(ctx); } diff --git a/ydb/core/tablet/tablet_counters_aggregator.h b/ydb/core/tablet/tablet_counters_aggregator.h index 451338033e..db350d41cb 100644 --- a/ydb/core/tablet/tablet_counters_aggregator.h +++ b/ydb/core/tablet/tablet_counters_aggregator.h @@ -2,7 +2,7 @@ //////////////////////////////////////////// #include "defs.h" -#include "tablet_counters.h" +#include "tablet_counters.h" #include <library/cpp/actors/core/defs.h> #include <library/cpp/actors/core/actor.h> @@ -44,7 +44,7 @@ struct TEvTabletCounters { struct TEvTabletAddCounters : public TEventLocal<TEvTabletAddCounters, EvTabletAddCounters> { // - const ui64 TabletID; + const ui64 TabletID; const TTabletTypes::EType TabletType; const TPathId TenantPathId; TAutoPtr<TTabletCountersBase> ExecutorCounters; @@ -79,13 +79,13 @@ struct TEvTabletCounters { // struct TEvTabletCountersForgetTablet : public TEventLocal<TEvTabletCountersForgetTablet, EvTabletCountersForgetTablet> { // - const ui64 TabletID; + const ui64 TabletID; const TTabletTypes::EType TabletType; const TPathId TenantPathId; TEvTabletCountersForgetTablet(ui64 tabletID, TTabletTypes::EType tabletType, TPathId tenantPathId) : TabletID(tabletID) - , TabletType(tabletType) + , TabletType(tabletType) , TenantPathId(tenantPathId) {} }; diff --git a/ydb/core/tablet/tablet_impl.h b/ydb/core/tablet/tablet_impl.h index 00e8aba9d9..b47b1f1097 100644 --- a/ydb/core/tablet/tablet_impl.h +++ b/ydb/core/tablet/tablet_impl.h @@ -1,122 +1,122 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include <ydb/core/base/tablet.h> #include <ydb/core/base/statestorage.h> - + #include <ydb/core/protos/tablet.pb.h> #include <ydb/core/base/blobstorage.h> #include <ydb/core/tablet/tablet_metrics.h> - + #include <library/cpp/actors/core/scheduler_cookie.h> -#include <util/generic/deque.h> +#include <util/generic/deque.h> #include <ydb/core/base/tracing.h> - -namespace NKikimr { - + +namespace NKikimr { + IActor* CreateTabletReqRebuildHistoryGraph(const TActorId &owner, TTabletStorageInfo *info, ui32 blockedGen, NTracing::ITrace *trace, ui64 followerCookie); IActor* CreateTabletFindLastEntry(const TActorId &owner, bool readBody, TTabletStorageInfo *info, ui32 blockedGen); IActor* CreateTabletReqWriteLog(const TActorId &owner, const TLogoBlobID &entryId, NKikimrTabletBase::TTabletLogEntry *entry, TVector<TEvTablet::TLogEntryReference> &refs, TEvBlobStorage::TEvPut::ETactic commitTactic, TTabletStorageInfo *info); IActor* CreateTabletReqBlockBlobStorage(const TActorId &owner, TTabletStorageInfo *info, ui32 generation, bool blockPrevEntry); IActor* CreateTabletReqDelete(const TActorId &owner, const TIntrusivePtr<TTabletStorageInfo> &tabletStorageInfo, ui32 generation = std::numeric_limits<ui32>::max()); - -struct TEvTabletBase { - enum EEv { - EvBlockBlobStorageResult = EventSpaceBegin(TKikimrEvents::ES_TABLETBASE), - EvRebuildGraphResult, - EvFindLatestLogEntryResult, - EvWriteLogResult, + +struct TEvTabletBase { + enum EEv { + EvBlockBlobStorageResult = EventSpaceBegin(TKikimrEvents::ES_TABLETBASE), + EvRebuildGraphResult, + EvFindLatestLogEntryResult, + EvWriteLogResult, EvDeleteTabletResult, - + EvFollowerRetry = EvBlockBlobStorageResult + 512, EvTrySyncFollower, EvTryBuildFollowerGraph, - - EvEnd - }; - + + EvEnd + }; + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_TABLETBASE), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_TABLETBASE)"); - - struct TEvBlockBlobStorageResult : public TEventLocal<TEvBlockBlobStorageResult, EvBlockBlobStorageResult> { - const NKikimrProto::EReplyStatus Status; + + struct TEvBlockBlobStorageResult : public TEventLocal<TEvBlockBlobStorageResult, EvBlockBlobStorageResult> { + const NKikimrProto::EReplyStatus Status; const ui64 TabletId; const TString ErrorReason; - + TEvBlockBlobStorageResult(NKikimrProto::EReplyStatus status, ui64 tabletId, const TString &reason = TString()) - : Status(status) + : Status(status) , TabletId(tabletId) , ErrorReason(reason) - {} - }; - - struct TEvRebuildGraphResult : public TEventLocal<TEvRebuildGraphResult, EvRebuildGraphResult> { - const NKikimrProto::EReplyStatus Status; + {} + }; + + struct TEvRebuildGraphResult : public TEventLocal<TEvRebuildGraphResult, EvRebuildGraphResult> { + const NKikimrProto::EReplyStatus Status; const TString ErrorReason; - - TIntrusivePtr<TEvTablet::TDependencyGraph> DependencyGraph; + + TIntrusivePtr<TEvTablet::TDependencyGraph> DependencyGraph; NMetrics::TTabletThroughputRawValue GroupReadBytes; NMetrics::TTabletIopsRawValue GroupReadOps; THolder<NTracing::ITrace> Trace; - + TEvRebuildGraphResult( NKikimrProto::EReplyStatus status, NTracing::ITrace *trace, const TString &reason = TString() ) - : Status(status) + : Status(status) , ErrorReason(reason) , Trace(trace) - {} - + {} + TEvRebuildGraphResult( const TIntrusivePtr<TEvTablet::TDependencyGraph> &graph, NMetrics::TTabletThroughputRawValue &&read, NMetrics::TTabletIopsRawValue &&readOps, NTracing::ITrace *trace ) - : Status(NKikimrProto::OK) - , DependencyGraph(graph) + : Status(NKikimrProto::OK) + , DependencyGraph(graph) , GroupReadBytes(std::move(read)) , GroupReadOps(std::move(readOps)) , Trace(trace) - {} - }; - - struct TEvFindLatestLogEntryResult : public TEventLocal<TEvFindLatestLogEntryResult, EvFindLatestLogEntryResult> { - const NKikimrProto::EReplyStatus Status; - const TLogoBlobID Latest; - const ui32 BlockedGeneration; + {} + }; + + struct TEvFindLatestLogEntryResult : public TEventLocal<TEvFindLatestLogEntryResult, EvFindLatestLogEntryResult> { + const NKikimrProto::EReplyStatus Status; + const TLogoBlobID Latest; + const ui32 BlockedGeneration; const TString Buffer; const TString ErrorReason; - + TEvFindLatestLogEntryResult(NKikimrProto::EReplyStatus status, const TString &reason = TString()) - : Status(status) - , BlockedGeneration(0) + : Status(status) + , BlockedGeneration(0) , ErrorReason(reason) - { + { Y_VERIFY_DEBUG(status != NKikimrProto::OK); - } - + } + TEvFindLatestLogEntryResult(const TLogoBlobID &latest, ui32 blockedGeneration, const TString &buffer) - : Status(NKikimrProto::OK) - , Latest(latest) - , BlockedGeneration(blockedGeneration) - , Buffer(buffer) - {} - }; - - struct TEvWriteLogResult : public TEventLocal<TEvWriteLogResult, EvWriteLogResult> { - const NKikimrProto::EReplyStatus Status; - const TLogoBlobID EntryId; + : Status(NKikimrProto::OK) + , Latest(latest) + , BlockedGeneration(blockedGeneration) + , Buffer(buffer) + {} + }; + + struct TEvWriteLogResult : public TEventLocal<TEvWriteLogResult, EvWriteLogResult> { + const NKikimrProto::EReplyStatus Status; + const TLogoBlobID EntryId; TVector<ui32> YellowMoveChannels; TVector<ui32> YellowStopChannels; NMetrics::TTabletThroughputRawValue GroupWrittenBytes; NMetrics::TTabletIopsRawValue GroupWrittenOps; const TString ErrorReason; - - struct TErrorCondition { - - } ErrorCondition; - + + struct TErrorCondition { + + } ErrorCondition; + TEvWriteLogResult( NKikimrProto::EReplyStatus status, const TLogoBlobID &entryId, @@ -125,36 +125,36 @@ struct TEvTabletBase { NMetrics::TTabletThroughputRawValue&& written, NMetrics::TTabletIopsRawValue&& writtenOps, const TString &reason = TString()) - : Status(status) - , EntryId(entryId) + : Status(status) + , EntryId(entryId) , YellowMoveChannels(std::move(yellowMoveChannels)) , YellowStopChannels(std::move(yellowStopChannels)) , GroupWrittenBytes(std::move(written)) , GroupWrittenOps(std::move(writtenOps)) , ErrorReason(reason) - {} - }; - + {} + }; + struct TEvFollowerRetry : public TEventLocal<TEvFollowerRetry, EvFollowerRetry> { - const ui32 Round; - + const ui32 Round; + TEvFollowerRetry(ui32 round) - : Round(round) - {} - }; + : Round(round) + {} + }; struct TEvTrySyncFollower : public TEventLocal<TEvTrySyncFollower, EvTrySyncFollower> { const TActorId FollowerId; - TSchedulerCookieHolder CookieHolder; - + TSchedulerCookieHolder CookieHolder; + TEvTrySyncFollower(TActorId followerId, ISchedulerCookie *cookie) : FollowerId(followerId) - , CookieHolder(cookie) - {} - }; - + , CookieHolder(cookie) + {} + }; + struct TEvTryBuildFollowerGraph : public TEventLocal<TEvTryBuildFollowerGraph, EvTryBuildFollowerGraph> {}; - + struct TEvDeleteTabletResult : public TEventLocal<TEvDeleteTabletResult, EvDeleteTabletResult> { const NKikimrProto::EReplyStatus Status; const ui64 TabletId; @@ -164,6 +164,6 @@ struct TEvTabletBase { , TabletId(tabletId) {} }; -}; - -} +}; + +} diff --git a/ydb/core/tablet/tablet_monitoring_proxy.cpp b/ydb/core/tablet/tablet_monitoring_proxy.cpp index c867aefeb7..a61a43b7e5 100644 --- a/ydb/core/tablet/tablet_monitoring_proxy.cpp +++ b/ydb/core/tablet/tablet_monitoring_proxy.cpp @@ -169,7 +169,7 @@ TTabletMonitoringProxyActor::Bootstrap(const TActorContext &ctx) { } } -static ui64 TryParseTabletId(TStringBuf tabletIdParam) { +static ui64 TryParseTabletId(TStringBuf tabletIdParam) { if (tabletIdParam.StartsWith("0x")) { ui64 result = 0; TryIntFromString<16, ui64>(tabletIdParam.substr(2), result); @@ -177,8 +177,8 @@ static ui64 TryParseTabletId(TStringBuf tabletIdParam) { } else { return FromStringWithDefault<ui64>(tabletIdParam); } -} - +} + //////////////////////////////////////////// void TTabletMonitoringProxyActor::Handle(NMon::TEvHttpInfo::TPtr &ev, const TActorContext &ctx) { @@ -208,10 +208,10 @@ TTabletMonitoringProxyActor::Handle(NMon::TEvHttpInfo::TPtr &ev, const TActorCon if (tabletId) { TString url = TStringBuilder() << msg->Request.GetPathInfo() << "?" << cgi->Print(); ctx.ExecutorThread.RegisterActor(new TForwardingActor(Config, tabletId, true, ev->Sender, std::move(url))); - return; - } - } - + return; + } + } + bool hasIdParam = cgi->Has("TabletID"); if (hasIdParam) { const TString &tabletIdParam = cgi->Get("TabletID"); @@ -229,11 +229,11 @@ TTabletMonitoringProxyActor::Handle(NMon::TEvHttpInfo::TPtr &ev, const TActorCon if (tabletId) { TString url = TStringBuilder() << msg->Request.GetPathInfo() << "?" << cgi->Print(); ctx.ExecutorThread.RegisterActor(CreateStateStorageMonitoringActor(tabletId, ev->Sender, std::move(url))); - return; - } - } - - + return; + } + } + + TStringStream str; const NKikimr::TDomainsInfo* domainsInfo = AppData(ctx)->DomainsInfo.Get(); diff --git a/ydb/core/tablet/tablet_pipe_client.cpp b/ydb/core/tablet/tablet_pipe_client.cpp index 8c9dc53a33..2fa35af9a0 100644 --- a/ydb/core/tablet/tablet_pipe_client.cpp +++ b/ydb/core/tablet/tablet_pipe_client.cpp @@ -10,16 +10,16 @@ #include <ydb/core/base/appdata.h> #include <library/cpp/actors/util/queue_oneone_inplace.h> -#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR - #error log macro definition clash -#endif - -#define BLOG_D(stream) LOG_DEBUG_S(ctx, NKikimrServices::PIPE_CLIENT, "TClient[" << TabletId << "] " << stream << " " << ctx.SelfID) - -#define BLOG_I(stream) LOG_INFO_S(ctx, NKikimrServices::PIPE_CLIENT, "TClient[" << TabletId << "] " << stream << " " << ctx.SelfID) - -#define BLOG_ERROR(stream) LOG_ERROR_S(ctx, NKikimrServices::PIPE_CLIENT, "TClient[" << TabletId << "] " << stream << " " << ctx.SelfID) - +#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR + #error log macro definition clash +#endif + +#define BLOG_D(stream) LOG_DEBUG_S(ctx, NKikimrServices::PIPE_CLIENT, "TClient[" << TabletId << "] " << stream << " " << ctx.SelfID) + +#define BLOG_I(stream) LOG_INFO_S(ctx, NKikimrServices::PIPE_CLIENT, "TClient[" << TabletId << "] " << stream << " " << ctx.SelfID) + +#define BLOG_ERROR(stream) LOG_ERROR_S(ctx, NKikimrServices::PIPE_CLIENT, "TClient[" << TabletId << "] " << stream << " " << ctx.SelfID) + #define BLOG_TRACE(stream) LOG_TRACE_S(ctx, NKikimrServices::PIPE_CLIENT, "TClient[" << TabletId << "] " << stream << " " << ctx.SelfID) namespace NKikimr { @@ -44,18 +44,18 @@ namespace NTabletPipe { } void Bootstrap(const TActorContext& ctx) { - BLOG_D("::Bootstrap"); - + BLOG_D("::Bootstrap"); + Lookup(ctx); } private: void StateLookup(STFUNC_SIG) { switch (ev->GetTypeRewrite()) { - FFunc(TEvTabletPipe::EvSend, HandleSendQueued); + FFunc(TEvTabletPipe::EvSend, HandleSendQueued); FFunc(TEvTabletPipe::EvMessage, HandleSendQueued); HFunc(TEvTabletPipe::TEvShutdown, HandleConnect); - HFunc(TEvents::TEvPoisonPill, HandleConnect); + HFunc(TEvents::TEvPoisonPill, HandleConnect); HFunc(TEvTabletResolver::TEvForwardResult, HandleLookup); HFunc(TEvInterconnect::TEvNodeDisconnected, HandleRelaxed); HFunc(TEvTabletPipe::TEvConnectResult, HandleOutdated); @@ -66,39 +66,39 @@ namespace NTabletPipe { switch (ev->GetTypeRewrite()) { FFunc(TEvTabletPipe::EvSend, HandleSendQueued); FFunc(TEvTabletPipe::EvMessage, HandleSendQueued); - HFunc(TEvTabletPipe::TEvShutdown, HandleConnect); + HFunc(TEvTabletPipe::TEvShutdown, HandleConnect); HFunc(TEvents::TEvPoisonPill, HandleConnect); HFunc(TEvInterconnect::TEvNodeConnected, HandleConnectNode); - HFunc(TEvInterconnect::TEvNodeDisconnected, HandleConnect); + HFunc(TEvInterconnect::TEvNodeDisconnected, HandleConnect); HFunc(TEvTabletPipe::TEvConnectResult, HandleOutdated); - } - } - + } + } + void StateConnect(STFUNC_SIG) { - switch (ev->GetTypeRewrite()) { - FFunc(TEvTabletPipe::EvSend, HandleSendQueued); + switch (ev->GetTypeRewrite()) { + FFunc(TEvTabletPipe::EvSend, HandleSendQueued); FFunc(TEvTabletPipe::EvMessage, HandleSendQueued); HFunc(TEvTabletPipe::TEvShutdown, HandleConnect); - HFunc(TEvents::TEvPoisonPill, HandleConnect); + HFunc(TEvents::TEvPoisonPill, HandleConnect); HFunc(TEvents::TEvUndelivered, HandleConnect); HFunc(TEvTabletPipe::TEvPeerClosed, HandleConnect); HFunc(TEvTabletPipe::TEvConnectResult, HandleConnect); HFunc(TEvInterconnect::TEvNodeDisconnected, HandleConnect); - } - } - - void StateWait(STFUNC_SIG) { - switch (ev->GetTypeRewrite()) { - FFunc(TEvTabletPipe::EvSend, HandleSendQueued); + } + } + + void StateWait(STFUNC_SIG) { + switch (ev->GetTypeRewrite()) { + FFunc(TEvTabletPipe::EvSend, HandleSendQueued); FFunc(TEvTabletPipe::EvMessage, HandleSendQueued); HFunc(TEvTabletPipe::TEvShutdown, HandleConnect); - HFunc(TEvents::TEvPoisonPill, HandleConnect); + HFunc(TEvents::TEvPoisonPill, HandleConnect); HFunc(TEvTabletPipe::TEvClientRetry, HandleWait); HFunc(TEvInterconnect::TEvNodeDisconnected, HandleRelaxed); HFunc(TEvTabletPipe::TEvConnectResult, HandleOutdated); - } - } - + } + } + void StateCheckDead(STFUNC_SIG) { switch (ev->GetTypeRewrite()) { HFunc(TEvents::TEvPoisonPill, Handle); @@ -112,8 +112,8 @@ namespace NTabletPipe { } } - void StateWork(STFUNC_SIG) { - switch (ev->GetTypeRewrite()) { + void StateWork(STFUNC_SIG) { + switch (ev->GetTypeRewrite()) { FFunc(TEvTabletPipe::EvSend, HandleSend); FFunc(TEvTabletPipe::EvMessage, HandleSend); HFunc(TEvTabletPipe::TEvShutdown, Handle); @@ -126,25 +126,25 @@ namespace NTabletPipe { } } - bool IsLocalNode(const TActorContext& ctx) const { + bool IsLocalNode(const TActorContext& ctx) const { auto leader = GetTabletLeader(); return leader.NodeId() == 0 || ctx.ExecutorThread.ActorSystem->NodeId == leader.NodeId(); - } - + } + TActorId GetTabletLeader() const { return Config.ConnectToUserTablet ? LastKnownLeaderTablet : LastKnownLeader; - } - - void HandleSendQueued(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) { - BLOG_D("queue send"); - Y_VERIFY(!IsShutdown); - PayloadQueue->Push(ev.Release()); - } - + } + + void HandleSendQueued(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) { + BLOG_D("queue send"); + Y_VERIFY(!IsShutdown); + PayloadQueue->Push(ev.Release()); + } + void HandleSend(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) { - BLOG_D("send"); + BLOG_D("send"); Y_VERIFY(!IsShutdown); - Push(ctx, ev); + Push(ctx, ev); } ui32 GenerateConnectFeatures() const { @@ -156,24 +156,24 @@ namespace NTabletPipe { } void HandleLookup(TEvTabletResolver::TEvForwardResult::TPtr& ev, const TActorContext &ctx) { - Y_VERIFY(ev->Get()->TabletID == TabletId); - + Y_VERIFY(ev->Get()->TabletID == TabletId); + if (ev->Get()->Status != NKikimrProto::OK || (Config.ConnectToUserTablet && !ev->Get()->TabletActor)) { - BLOG_D("forward result error, check reconnect"); - return TryToReconnect(ctx); + BLOG_D("forward result error, check reconnect"); + return TryToReconnect(ctx); } LastKnownLeaderTablet = ev->Get()->TabletActor; LastKnownLeader = ev->Get()->Tablet; LastCacheEpoch = ev->Get()->CacheEpoch; - + if (IsLocalNode(ctx)) { - BLOG_D("forward result local node, try to connect"); + BLOG_D("forward result local node, try to connect"); UnsubscribeNetworkSession(ctx); Connect(ctx); } else { const ui32 nodeId = GetTabletLeader().NodeId(); - BLOG_D("forward result remote node " << nodeId); + BLOG_D("forward result remote node " << nodeId); if (InterconnectNodeId == nodeId) { // Already connected to correct remote node Y_VERIFY(InterconnectSessionId); @@ -206,7 +206,7 @@ namespace NTabletPipe { return; } - BLOG_D("remote node connected"); + BLOG_D("remote node connected"); Y_VERIFY(!InterconnectSessionId); InterconnectSessionId = ev->Sender; Connect(ctx); @@ -216,7 +216,7 @@ namespace NTabletPipe { if (ev->Cookie != InterconnectCookie) { BLOG_D("ignored outdated TEvNodeDisconnected"); return; - } + } BLOG_D("remote node disonnected while connecting, check retry"); if (InterconnectSessionId) { @@ -226,13 +226,13 @@ namespace NTabletPipe { ForgetNetworkSession(); } - void HandleConnect(TEvInterconnect::TEvNodeDisconnected::TPtr& ev, const TActorContext &ctx) { + void HandleConnect(TEvInterconnect::TEvNodeDisconnected::TPtr& ev, const TActorContext &ctx) { if (ev->Cookie != InterconnectCookie) { BLOG_D("ignored outdated TEvNodeDisconnected"); return; } - BLOG_D("remote node disonnected while connecting, check retry"); + BLOG_D("remote node disonnected while connecting, check retry"); if (InterconnectSessionId) { Y_VERIFY(ev->Sender == InterconnectSessionId); } @@ -241,13 +241,13 @@ namespace NTabletPipe { TryToReconnect(ctx); } - void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr& ev, const TActorContext &ctx) { + void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr& ev, const TActorContext &ctx) { if (ev->Cookie != InterconnectCookie) { BLOG_D("ignored outdated TEvNodeDisconnected"); return; } - BLOG_D("remote node disconnected while working, drop pipe"); + BLOG_D("remote node disconnected while working, drop pipe"); NotifyNodeProblem(ctx); ForgetNetworkSession(); NotifyDisconnect(ctx); @@ -259,18 +259,18 @@ namespace NTabletPipe { Become(&TThis::StateConnect); } - void HandleConnect(TEvTabletPipe::TEvPeerClosed::TPtr& ev, const TActorContext &ctx) { + void HandleConnect(TEvTabletPipe::TEvPeerClosed::TPtr& ev, const TActorContext &ctx) { if (ev->InterconnectSession != InterconnectSessionId) { // Ingnore TEvPeerClosed from an unexpected interconnect session BLOG_D("ignore outdated peer closed from " << ev->Sender); return; } - BLOG_D("peer closed while connecting, check reconnect"); - return TryToReconnect(ctx); - } - - void HandleConnect(TEvTabletPipe::TEvConnectResult::TPtr& ev, const TActorContext &ctx) { + BLOG_D("peer closed while connecting, check reconnect"); + return TryToReconnect(ctx); + } + + void HandleConnect(TEvTabletPipe::TEvConnectResult::TPtr& ev, const TActorContext &ctx) { if (ev->InterconnectSession != InterconnectSessionId || ev->Cookie != 0 && ev->Cookie != ConnectCookie) { // Ignore TEvConnectResult from an unexpected interconnect session or retry attempt BLOG_D("ignored outdated connection result from " << ev->Sender); @@ -283,27 +283,27 @@ namespace NTabletPipe { ServerId = ActorIdFromProto(record.GetServerId()); Leader = record.GetLeader(); - - Y_VERIFY(!ServerId || record.GetStatus() == NKikimrProto::OK); + + Y_VERIFY(!ServerId || record.GetStatus() == NKikimrProto::OK); BLOG_D("connected with status " << record.GetStatus() << " role: " << (Leader ? "Leader" : "Follower")); - - if (!ServerId) { - return TryToReconnect(ctx); + + if (!ServerId) { + return TryToReconnect(ctx); } - Become(&TThis::StateWork); + Become(&TThis::StateWork); + + BLOG_D("send queued"); + while (TAutoPtr<IEventHandle> x = PayloadQueue->Pop()) + Push(ctx, x); + + PayloadQueue.Destroy(); - BLOG_D("send queued"); - while (TAutoPtr<IEventHandle> x = PayloadQueue->Pop()) - Push(ctx, x); - - PayloadQueue.Destroy(); - ctx.Send(Owner, new TEvTabletPipe::TEvClientConnected(TabletId, NKikimrProto::OK, ctx.SelfID, ServerId, Leader, false)); - - if (IsShutdown) { - BLOG_D("shutdown pipe due to pending shutdown request"); - return NotifyDisconnect(ctx); + + if (IsShutdown) { + BLOG_D("shutdown pipe due to pending shutdown request"); + return NotifyDisconnect(ctx); } } @@ -312,21 +312,21 @@ namespace NTabletPipe { ctx.Send(ev->Sender, new TEvTabletPipe::TEvPeerClosed(TabletId, ctx.SelfID, ev->Sender)); } - void HandleConnect(TEvents::TEvUndelivered::TPtr& ev, const TActorContext &ctx) { + void HandleConnect(TEvents::TEvUndelivered::TPtr& ev, const TActorContext &ctx) { const auto* msg = ev->Get(); if (msg->SourceType != TEvTabletPipe::TEvConnect::EventType || ev->Cookie != ConnectCookie) { BLOG_D("ignored unexpected TEvUndelivered of event " << msg->SourceType << " with cookie " << ev->Cookie); return; } - BLOG_D("connect request undelivered"); - TryToReconnect(ctx); + BLOG_D("connect request undelivered"); + TryToReconnect(ctx); } void Handle(TEvents::TEvUndelivered::TPtr& ev, const TActorContext& ctx) { Y_UNUSED(ev); - BLOG_D("pipe event not delivered, drop pipe"); - return NotifyDisconnect(ctx); + BLOG_D("pipe event not delivered, drop pipe"); + return NotifyDisconnect(ctx); } void Handle(TEvTabletPipe::TEvPeerClosed::TPtr& ev, const TActorContext& ctx) { @@ -337,8 +337,8 @@ namespace NTabletPipe { } Y_VERIFY(ev->Get()->Record.GetTabletId() == TabletId); - BLOG_D("peer closed"); - return NotifyDisconnect(ctx); + BLOG_D("peer closed"); + return NotifyDisconnect(ctx); } void Handle(TEvTabletPipe::TEvPeerShutdown::TPtr& ev, const TActorContext& ctx) { @@ -350,42 +350,42 @@ namespace NTabletPipe { } } - void HandleConnect(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx) { - BLOG_D("poison pill while connecting"); + void HandleConnect(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx) { + BLOG_D("poison pill while connecting"); Y_UNUSED(ev); - if (ServerId) + if (ServerId) ctx.Send(ServerId, new TEvTabletPipe::TEvPeerClosed(TabletId, ctx.SelfID, ServerId)); - return NotifyConnectFail(ctx); + return NotifyConnectFail(ctx); + } + + void Handle(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx) { + Y_UNUSED(ev); + BLOG_D("received poison pill"); + ctx.Send(ServerId, new TEvTabletPipe::TEvPeerClosed(TabletId, ctx.SelfID, ServerId)); + return NotifyDisconnect(ctx); + } + + void Handle(TEvTabletPipe::TEvShutdown::TPtr& ev, const TActorContext& ctx) { + Y_UNUSED(ev); + BLOG_D("received shutdown"); + ctx.Send(ServerId, new TEvTabletPipe::TEvPeerClosed(TabletId, SelfId(), ServerId)); + return NotifyDisconnect(ctx); } - void Handle(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx) { + void HandleConnect(TEvTabletPipe::TEvShutdown::TPtr& ev, const TActorContext& ctx) { Y_UNUSED(ev); - BLOG_D("received poison pill"); - ctx.Send(ServerId, new TEvTabletPipe::TEvPeerClosed(TabletId, ctx.SelfID, ServerId)); - return NotifyDisconnect(ctx); - } - - void Handle(TEvTabletPipe::TEvShutdown::TPtr& ev, const TActorContext& ctx) { - Y_UNUSED(ev); - BLOG_D("received shutdown"); - ctx.Send(ServerId, new TEvTabletPipe::TEvPeerClosed(TabletId, SelfId(), ServerId)); - return NotifyDisconnect(ctx); - } - - void HandleConnect(TEvTabletPipe::TEvShutdown::TPtr& ev, const TActorContext& ctx) { - Y_UNUSED(ev); - BLOG_D("received pending shutdown"); - IsShutdown = true; - } - + BLOG_D("received pending shutdown"); + IsShutdown = true; + } + void HandleWait(TEvTabletPipe::TEvClientRetry::TPtr& ev, const TActorContext& ctx) { - Y_UNUSED(ev); - BLOG_D("client retry"); - + Y_UNUSED(ev); + BLOG_D("client retry"); + LastKnownLeaderTablet = TActorId(); LastKnownLeader = TActorId(); - + Lookup(ctx); } @@ -395,9 +395,9 @@ namespace NTabletPipe { NTabletPipe::SendData(SelfId(), HiveClient, new TEvHive::TEvRequestHiveInfo(TabletId, false)); } - // check aliveness section - void Handle(TEvHive::TEvResponseHiveInfo::TPtr &ev, const TActorContext &ctx) { - const auto &record = ev->Get()->Record; + // check aliveness section + void Handle(TEvHive::TEvResponseHiveInfo::TPtr &ev, const TActorContext &ctx) { + const auto &record = ev->Get()->Record; if (record.HasForwardRequest() && (++CurrentHiveForwards < MAX_HIVE_FORWARDS)) { BLOG_I("hive request forwarded to " << record.GetForwardRequest().GetHiveTabletId()); CloseClient(ctx, HiveClient); @@ -416,61 +416,61 @@ namespace NTabletPipe { } ctx.Send(Owner, new TEvTabletPipe::TEvClientConnected(TabletId, NKikimrProto::ERROR, SelfId(), TActorId(), Leader, definitelyDead)); - return Die(ctx); - } - - void Handle(TEvTabletPipe::TEvClientCheckDelay::TPtr &ev, const TActorContext &ctx) { - Y_UNUSED(ev); - Y_UNUSED(ctx); - - const ui64 hiveUid = HiveUidFromTabletID(TabletId); - const ui64 hiveTabletId = AppData()->DomainsInfo->GetHive(hiveUid); - - if (hiveUid == 0) - BLOG_ERROR("trying to check aliveness of hand-made tablet! would definitely fail"); - - RequestHiveInfo(hiveTabletId); - } - - void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx) { - if (HiveClient != ev->Sender) + return Die(ctx); + } + + void Handle(TEvTabletPipe::TEvClientCheckDelay::TPtr &ev, const TActorContext &ctx) { + Y_UNUSED(ev); + Y_UNUSED(ctx); + + const ui64 hiveUid = HiveUidFromTabletID(TabletId); + const ui64 hiveTabletId = AppData()->DomainsInfo->GetHive(hiveUid); + + if (hiveUid == 0) + BLOG_ERROR("trying to check aliveness of hand-made tablet! would definitely fail"); + + RequestHiveInfo(hiveTabletId); + } + + void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx) { + if (HiveClient != ev->Sender) return; - auto *msg = ev->Get(); - if (msg->Status != NKikimrProto::OK) { + auto *msg = ev->Get(); + if (msg->Status != NKikimrProto::OK) { ctx.Send(Owner, new TEvTabletPipe::TEvClientConnected(TabletId, NKikimrProto::ERROR, SelfId(), TActorId(), Leader, false)); - return Die(ctx); + return Die(ctx); } - } + } - void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx) { - if (HiveClient != ev->Sender) - return; + void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx) { + if (HiveClient != ev->Sender) + return; ctx.Send(Owner, new TEvTabletPipe::TEvClientConnected(TabletId, NKikimrProto::ERROR, SelfId(), TActorId(), Leader, false)); - return Die(ctx); + return Die(ctx); } - void NotifyConnectFail(const TActorContext &ctx) { + void NotifyConnectFail(const TActorContext &ctx) { UnsubscribeNetworkSession(ctx); if (Config.CheckAliveness && !IsReservedTabletId(TabletId)) { - BLOG_D("connect failed, check aliveness"); - - if (!Config.RetryPolicy) - BLOG_ERROR("check aliveness w/o retry policy, possible perfomance hit"); - - Become(&TThis::StateCheckDead, RetryState.MakeCheckDelay(), new TEvTabletPipe::TEvClientCheckDelay()); - } else { - BLOG_D("connect failed"); + BLOG_D("connect failed, check aliveness"); + + if (!Config.RetryPolicy) + BLOG_ERROR("check aliveness w/o retry policy, possible perfomance hit"); + + Become(&TThis::StateCheckDead, RetryState.MakeCheckDelay(), new TEvTabletPipe::TEvClientCheckDelay()); + } else { + BLOG_D("connect failed"); ctx.Send(Owner, new TEvTabletPipe::TEvClientConnected(TabletId, NKikimrProto::ERROR, SelfId(), TActorId(), Leader, false)); - return Die(ctx); + return Die(ctx); } } - void NotifyDisconnect(const TActorContext &ctx) { - BLOG_D("notify reset"); - ctx.Send(Owner, new TEvTabletPipe::TEvClientDestroyed(TabletId, ctx.SelfID, ServerId)); - return Die(ctx); - } - + void NotifyDisconnect(const TActorContext &ctx) { + BLOG_D("notify reset"); + ctx.Send(Owner, new TEvTabletPipe::TEvClientDestroyed(TabletId, ctx.SelfID, ServerId)); + return Die(ctx); + } + void NotifyNodeProblem(const TActorContext &ctx) { ctx.Send(MakeTabletResolverID(), new TEvTabletResolver::TEvNodeProblem(InterconnectNodeId, LastCacheEpoch)); } @@ -490,36 +490,36 @@ namespace NTabletPipe { } void Lookup(const TActorContext& ctx) { - BLOG_D("lookup"); + BLOG_D("lookup"); TEvTabletResolver::TEvForward::TResolveFlags resolveFlags; resolveFlags.SetAllowFollower(Config.AllowFollower); resolveFlags.SetForceFollower(Config.ForceFollower); resolveFlags.SetPreferLocal(Config.PreferLocal); resolveFlags.SetForceLocal(Config.ForceLocal); - - ctx.Send(MakeTabletResolverID(), new TEvTabletResolver::TEvForward(TabletId, nullptr, resolveFlags)); - Become(&TThis::StateLookup); + + ctx.Send(MakeTabletResolverID(), new TEvTabletResolver::TEvForward(TabletId, nullptr, resolveFlags)); + Become(&TThis::StateLookup); } - void TryToReconnect(const TActorContext& ctx) { + void TryToReconnect(const TActorContext& ctx) { if (LastKnownLeaderTablet) ctx.Send(MakeTabletResolverID(), new TEvTabletResolver::TEvTabletProblem(TabletId, LastKnownLeaderTablet)); LastKnownLeaderTablet = TActorId(); LastKnownLeader = TActorId(); - TDuration waitDuration; + TDuration waitDuration; if (Config.RetryPolicy && RetryState.IsAllowedToRetry(waitDuration, Config.RetryPolicy)) { - if (waitDuration == TDuration::Zero()) { - BLOG_D("immediate retry"); - Lookup(ctx); - } else { - BLOG_D("schedule retry"); - ctx.Schedule(waitDuration, new TEvTabletPipe::TEvClientRetry); - Become(&TThis::StateWait); - } - } else { - return NotifyConnectFail(ctx); + if (waitDuration == TDuration::Zero()) { + BLOG_D("immediate retry"); + Lookup(ctx); + } else { + BLOG_D("schedule retry"); + ctx.Schedule(waitDuration, new TEvTabletPipe::TEvClientRetry); + Become(&TThis::StateWait); + } + } else { + return NotifyConnectFail(ctx); } } @@ -599,8 +599,8 @@ namespace NTabletPipe { }; void Push(const TActorContext& ctx, TAutoPtr<IEventHandle>& ev) { - BLOG_D("push event to server"); - + BLOG_D("push event to server"); + if (!InterconnectSessionId) { switch (ev->GetTypeRewrite()) { case TEvTabletPipe::EvMessage: { @@ -638,28 +638,28 @@ namespace NTabletPipe { } } - void SendEvent(IEventHandle* ev, const TActorContext& ctx) { - LOG_DEBUG(ctx, NKikimrServices::PIPE_CLIENT, "TClient[%" PRIu64 "]::SendEvent %s", TabletId, - ctx.SelfID.ToString().c_str()); + void SendEvent(IEventHandle* ev, const TActorContext& ctx) { + LOG_DEBUG(ctx, NKikimrServices::PIPE_CLIENT, "TClient[%" PRIu64 "]::SendEvent %s", TabletId, + ctx.SelfID.ToString().c_str()); if (InterconnectSessionId) { Y_VERIFY(ev->Recipient.NodeId() == InterconnectNodeId, "Sending event to %s via remote node %" PRIu32, ev->Recipient.ToString().c_str(), InterconnectNodeId); - ev->Rewrite(TEvInterconnect::EvForward, InterconnectSessionId); + ev->Rewrite(TEvInterconnect::EvForward, InterconnectSessionId); } else { Y_VERIFY(ev->Recipient.NodeId() == ctx.SelfID.NodeId(), "Sending event to %s via local node %" PRIu32, ev->Recipient.ToString().c_str(), ctx.SelfID.NodeId()); } - ctx.ExecutorThread.Send(ev); + ctx.ExecutorThread.Send(ev); } - void Die(const TActorContext& ctx) override { - if (HiveClient) - CloseClient(ctx, HiveClient); + void Die(const TActorContext& ctx) override { + if (HiveClient) + CloseClient(ctx, HiveClient); UnsubscribeNetworkSession(ctx); - IActor::Die(ctx); - } + IActor::Die(ctx); + } private: const TActorId Owner; @@ -689,11 +689,11 @@ namespace NTabletPipe { } void SendData(TActorId self, TActorId clientId, IEventBase *payload, ui64 cookie) { - auto ev = new IEventHandle(clientId, self, payload, 0, cookie); - ev->Rewrite(TEvTabletPipe::EvSend, clientId); - TActivationContext::Send(ev); - } - + auto ev = new IEventHandle(clientId, self, payload, 0, cookie); + ev->Rewrite(TEvTabletPipe::EvSend, clientId); + TActivationContext::Send(ev); + } + void SendData(TActorId self, TActorId clientId, THolder<IEventBase>&& payload, ui64 cookie) { SendData(self, clientId, payload.Release(), cookie); } @@ -707,10 +707,10 @@ namespace NTabletPipe { void SendData(TActorId self, TActorId clientId, ui32 eventType, TIntrusivePtr<TEventSerializedData> buffer, ui64 cookie) { auto ev = new IEventHandle(eventType, 0, clientId, self, buffer, cookie); - ev->Rewrite(TEvTabletPipe::EvSend, clientId); - TActivationContext::Send(ev); - } - + ev->Rewrite(TEvTabletPipe::EvSend, clientId); + TActivationContext::Send(ev); + } + void SendData(const TActorContext& ctx, const TActorId& clientId, IEventBase* payload, ui64 cookie) { auto ev = new IEventHandle(clientId, ctx.SelfID, payload, 0, cookie); ev->Rewrite(TEvTabletPipe::EvSend, clientId); @@ -732,35 +732,35 @@ namespace NTabletPipe { } void CloseClient(TActorIdentity self, TActorId clientId) { - self.Send(clientId, new TEvents::TEvPoisonPill()); - } - + self.Send(clientId, new TEvents::TEvPoisonPill()); + } + void CloseAndForgetClient(TActorIdentity self, TActorId &clientId) { - if (clientId) { - CloseClient(self, clientId); + if (clientId) { + CloseClient(self, clientId); clientId = TActorId(); - } - } - + } + } + bool TClientRetryState::IsAllowedToRetry(TDuration& wait, const TClientRetryPolicy& policy) { if (RetryNumber == 0) { wait = policy.DoFirstRetryInstantly ? TDuration::Zero() : policy.MinRetryTime; } else { - const ui64 baseRetryDuration = RetryDuration.GetValue() * policy.BackoffMultiplier; - const ui64 croppedRetryDuration = Min(policy.MaxRetryTime.GetValue(), baseRetryDuration); - const ui64 randomizedRetryDuration = croppedRetryDuration * AppData()->RandomProvider->Uniform(100, 115) / 100; - wait = TDuration::FromValue(randomizedRetryDuration); + const ui64 baseRetryDuration = RetryDuration.GetValue() * policy.BackoffMultiplier; + const ui64 croppedRetryDuration = Min(policy.MaxRetryTime.GetValue(), baseRetryDuration); + const ui64 randomizedRetryDuration = croppedRetryDuration * AppData()->RandomProvider->Uniform(100, 115) / 100; + wait = TDuration::FromValue(randomizedRetryDuration); wait = Max(policy.MinRetryTime, wait); } ++RetryNumber; RetryDuration = wait; return !policy.RetryLimitCount || RetryNumber <= policy.RetryLimitCount; } - - TDuration TClientRetryState::MakeCheckDelay() { - const ui64 randomizedRetryDuration = RetryDuration.GetValue() * AppData()->RandomProvider->Uniform(100, 133) / 100; - return TDuration::FromValue(randomizedRetryDuration); - } + + TDuration TClientRetryState::MakeCheckDelay() { + const ui64 randomizedRetryDuration = RetryDuration.GetValue() * AppData()->RandomProvider->Uniform(100, 133) / 100; + return TDuration::FromValue(randomizedRetryDuration); + } } } diff --git a/ydb/core/tablet/tablet_pipe_client_cache.cpp b/ydb/core/tablet/tablet_pipe_client_cache.cpp index f8b350b393..47b81e4568 100644 --- a/ydb/core/tablet/tablet_pipe_client_cache.cpp +++ b/ydb/core/tablet/tablet_pipe_client_cache.cpp @@ -164,7 +164,7 @@ namespace NTabletPipe { TActorId client = currentClient->Client; if (!PoolContainer) { - CloseClient(ctx, client); + CloseClient(ctx, client); Container->Erase(tabletId); } else { if (currentClient->Flags & TClientCacheEntry::Opened) { diff --git a/ydb/core/tablet/tablet_pipe_server.cpp b/ydb/core/tablet/tablet_pipe_server.cpp index b34418de3b..b7c669e72c 100644 --- a/ydb/core/tablet/tablet_pipe_server.cpp +++ b/ydb/core/tablet/tablet_pipe_server.cpp @@ -34,7 +34,7 @@ namespace NTabletPipe { switch (ev->GetTypeRewrite()) { HFunc(TEvTabletPipe::TEvPush, Handle); HFunc(TEvTabletPipe::TEvMessage, Handle); - FFunc(TEvTabletPipe::EvSend, HandleSend); // only for direct (one-node) sends, for generic send see EvPush + FFunc(TEvTabletPipe::EvSend, HandleSend); // only for direct (one-node) sends, for generic send see EvPush HFunc(TEvTabletPipe::TEvPeerClosed, Handle); HFunc(TEvTabletPipe::TEvShutdown, Handle); HFunc(TEvents::TEvPoisonPill, Handle); @@ -268,7 +268,7 @@ namespace NTabletPipe { const TActorId clientId = ActorIdFromProto(ev->Get()->Record.GetClientId()); IActor* server = CreateServer(TabletId, clientId, ev->InterconnectSession, ev->Get()->Record.GetFeatures(), ev->Cookie); TActorId serverId = TActivationContext::Register(server); - LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::PIPE_SERVER, "[" << TabletId << "]" + LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::PIPE_SERVER, "[" << TabletId << "]" << " Accept Connect Originator# " << ev->Sender); ServerIds.insert(serverId); ActivateServer(TabletId, serverId, owner, recipientId, leader); @@ -278,7 +278,7 @@ namespace NTabletPipe { void Reject(TEvTabletPipe::TEvConnect::TPtr &ev, TActorIdentity owner, NKikimrProto::EReplyStatus status, bool leader) override { Y_VERIFY(ev->Get()->Record.GetTabletId() == TabletId); const TActorId clientId = ActorIdFromProto(ev->Get()->Record.GetClientId()); - LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::PIPE_SERVER, "[" << TabletId << "]" + LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::PIPE_SERVER, "[" << TabletId << "]" << " Reject Connect Originator# " << ev->Sender); owner.Send(clientId, new TEvTabletPipe::TEvConnectResult(status, TabletId, clientId, TActorId(), leader)); } @@ -292,23 +292,23 @@ namespace NTabletPipe { Stopped = true; } - void Detach(TActorIdentity owner) override { - LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::PIPE_SERVER, "[" << TabletId << "]" << " Detach"); + void Detach(TActorIdentity owner) override { + LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::PIPE_SERVER, "[" << TabletId << "]" << " Detach"); for (const auto& serverId : ServerIds) { - CloseServer(owner, serverId); + CloseServer(owner, serverId); } Active = false; ServerIds.clear(); - ActivatePending.clear(); + ActivatePending.clear(); } TActorId Enqueue(TEvTabletPipe::TEvConnect::TPtr &ev, TActorIdentity owner) override { - Y_UNUSED(owner); + Y_UNUSED(owner); Y_VERIFY(ev->Get()->Record.GetTabletId() == TabletId); const TActorId clientId = ActorIdFromProto(ev->Get()->Record.GetClientId()); IActor* server = CreateServer(TabletId, clientId, ev->InterconnectSession, ev->Get()->Record.GetFeatures(), ev->Cookie); TActorId serverId = TActivationContext::Register(server); - LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::PIPE_SERVER, "[" << TabletId << "]" + LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::PIPE_SERVER, "[" << TabletId << "]" << " Enqueue Connect Originator# " << ev->Sender); ServerIds.insert(serverId); ActivatePending.insert(serverId); @@ -316,7 +316,7 @@ namespace NTabletPipe { } void Activate(TActorIdentity owner, TActorId recipientId, bool leader) override { - LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::PIPE_SERVER, "[" << TabletId << "]" << " Activate"); + LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::PIPE_SERVER, "[" << TabletId << "]" << " Activate"); for (const auto& serverId : ActivatePending) { ActivateServer(TabletId, serverId, owner, recipientId, leader); } @@ -361,7 +361,7 @@ namespace NTabletPipe { } void CloseServer(TActorIdentity owner, TActorId serverId) { - owner.Send(serverId, new TEvents::TEvPoisonPill); + owner.Send(serverId, new TEvents::TEvPoisonPill); } } diff --git a/ydb/core/tablet/tablet_pipe_ut.cpp b/ydb/core/tablet/tablet_pipe_ut.cpp index ef920c8b91..2a528070fb 100644 --- a/ydb/core/tablet/tablet_pipe_ut.cpp +++ b/ydb/core/tablet/tablet_pipe_ut.cpp @@ -8,7 +8,7 @@ #include <ydb/core/tablet_flat/tablet_flat_executed.h> #include <library/cpp/actors/core/hfunc.h> - + namespace NKikimr { struct TEvProducerTablet { enum EEv { @@ -54,10 +54,10 @@ namespace NKikimr { struct TEvReject : public TEventLocal<TEvReject, EvReject> {}; }; - class TProducerTablet : public TActor<TProducerTablet>, public NTabletFlatExecutor::TTabletExecutedFlat { + class TProducerTablet : public TActor<TProducerTablet>, public NTabletFlatExecutor::TTabletExecutedFlat { public: TProducerTablet(const TActorId &tablet, TTabletStorageInfo *info) - : TActor(&TThis::StateInit) + : TActor(&TThis::StateInit) , TTabletExecutedFlat(info, tablet, nullptr) , HasData(false) , IsOpened(false) @@ -69,13 +69,13 @@ namespace NKikimr { private: using IActor::Send; // name is used by IActor API - STFUNC(StateInit) { - StateInitImpl(ev, ctx); - } - - STFUNC(StateWork) { + STFUNC(StateInit) { + StateInitImpl(ev, ctx); + } + + STFUNC(StateWork) { switch (ev->GetTypeRewrite()) { - HFunc(TEvTablet::TEvTabletDead, HandleTabletDead); + HFunc(TEvTablet::TEvTabletDead, HandleTabletDead); HFunc(TEvProducerTablet::TEvConnect, Handle); HFunc(TEvProducerTablet::TEvSend, Handle); HFunc(TEvTabletPipe::TEvClientConnected, Handle); @@ -170,9 +170,9 @@ namespace NKikimr { return Die(ctx); } - void OnActivateExecutor(const TActorContext &ctx) override { + void OnActivateExecutor(const TActorContext &ctx) override { Y_UNUSED(ctx); - Become(&TThis::StateWork); + Become(&TThis::StateWork); Cout << "Producer loaded\n"; } @@ -206,10 +206,10 @@ namespace NKikimr { }; }; - class TConsumerTablet : public TActor<TConsumerTablet>, public NTabletFlatExecutor::TTabletExecutedFlat { + class TConsumerTablet : public TActor<TConsumerTablet>, public NTabletFlatExecutor::TTabletExecutedFlat { public: TConsumerTablet(const TActorId &tablet, TTabletStorageInfo *info) - : TActor(&TThis::StateInit) + : TActor(&TThis::StateInit) , TTabletExecutedFlat(info, tablet, nullptr) , PipeConnectAcceptor(NTabletPipe::CreateConnectAcceptor(TabletID())) , RejectAll(false) @@ -219,19 +219,19 @@ namespace NKikimr { } private: - void OnActivateExecutor(const TActorContext&) override { - Become(&TThis::StateWork); + void OnActivateExecutor(const TActorContext&) override { + Become(&TThis::StateWork); Cout << "Consumer loaded\n"; - PipeConnectAcceptor->Activate(SelfId(), SelfId()); + PipeConnectAcceptor->Activate(SelfId(), SelfId()); + } + + STFUNC(StateInit) { + StateInitImpl(ev, ctx); } - STFUNC(StateInit) { - StateInitImpl(ev, ctx); - } - - STFUNC(StateWork) { + STFUNC(StateWork) { switch (ev->GetTypeRewrite()) { - HFunc(TEvTablet::TEvTabletDead, HandleTabletDead); + HFunc(TEvTablet::TEvTabletDead, HandleTabletDead); HFunc(TEvTabletPipe::TEvConnect, Handle); HFunc(TEvTabletPipe::TEvServerConnected, Handle); HFunc(TEvTabletPipe::TEvServerDisconnected, Handle); @@ -245,21 +245,21 @@ namespace NKikimr { } } - void Handle(TEvTabletPipe::TEvConnect::TPtr &ev, const TActorContext &) { + void Handle(TEvTabletPipe::TEvConnect::TPtr &ev, const TActorContext &) { Cout << "Get connect request from another tablet\n"; if (RejectAll) { - PipeConnectAcceptor->Reject(ev, SelfId(), NKikimrProto::BLOCKED); + PipeConnectAcceptor->Reject(ev, SelfId(), NKikimrProto::BLOCKED); } else { - LastServerId = PipeConnectAcceptor->Accept(ev, SelfId(), SelfId()); + LastServerId = PipeConnectAcceptor->Accept(ev, SelfId(), SelfId()); } } - void HandleQueued(TEvTabletPipe::TEvConnect::TPtr &ev, const TActorContext &) { + void HandleQueued(TEvTabletPipe::TEvConnect::TPtr &ev, const TActorContext &) { Cout << "Enqueue connect request from another tablet\n"; if (RejectAll) { - PipeConnectAcceptor->Reject(ev, SelfId(), NKikimrProto::BLOCKED); + PipeConnectAcceptor->Reject(ev, SelfId(), NKikimrProto::BLOCKED); } else { - LastServerId = PipeConnectAcceptor->Enqueue(ev, SelfId()); + LastServerId = PipeConnectAcceptor->Enqueue(ev, SelfId()); } } @@ -295,10 +295,10 @@ namespace NKikimr { Cout << "Cleanup of pipe reset on server\n"; } - void Handle(TEvConsumerTablet::TEvReject::TPtr &ev, const TActorContext &) { + void Handle(TEvConsumerTablet::TEvReject::TPtr &ev, const TActorContext &) { Y_UNUSED(ev); Cout << "Drop & reject all connects\n"; - PipeConnectAcceptor->Detach(SelfId()); + PipeConnectAcceptor->Detach(SelfId()); RejectAll = true; } @@ -309,14 +309,14 @@ namespace NKikimr { void OnDetach(const TActorContext &ctx) override { Cout << "Consumer dead\n"; - PipeConnectAcceptor->Detach(SelfId()); + PipeConnectAcceptor->Detach(SelfId()); return Die(ctx); } void OnTabletDead(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext &ctx) override { Cout << "Consumer dead\n"; Y_UNUSED(ev); - PipeConnectAcceptor->Detach(SelfId()); + PipeConnectAcceptor->Detach(SelfId()); return Die(ctx); } @@ -333,28 +333,28 @@ namespace NKikimr { ui32 ServerPipesClosed; }; - class TConsumerTabletWithoutAcceptor : public TActor<TConsumerTabletWithoutAcceptor>, public NTabletFlatExecutor::TTabletExecutedFlat { + class TConsumerTabletWithoutAcceptor : public TActor<TConsumerTabletWithoutAcceptor>, public NTabletFlatExecutor::TTabletExecutedFlat { public: TConsumerTabletWithoutAcceptor(const TActorId &tablet, TTabletStorageInfo *info) - : TActor(&TThis::StateInit) + : TActor(&TThis::StateInit) , TTabletExecutedFlat(info, tablet, nullptr) { } private: - void OnActivateExecutor(const TActorContext& ctx) override { + void OnActivateExecutor(const TActorContext& ctx) override { Y_UNUSED(ctx); - Become(&TThis::StateWork); + Become(&TThis::StateWork); Cout << "Consumer loaded\n"; } - STFUNC(StateInit) { - StateInitImpl(ev, ctx); - } - - STFUNC(StateWork) { + STFUNC(StateInit) { + StateInitImpl(ev, ctx); + } + + STFUNC(StateWork) { switch (ev->GetTypeRewrite()) { - HFunc(TEvTablet::TEvTabletDead, HandleTabletDead); + HFunc(TEvTablet::TEvTabletDead, HandleTabletDead); HFunc(TEvTabletPipe::TEvServerConnected, Handle); HFunc(TEvTabletPipe::TEvServerDisconnected, Handle); HFunc(TEvents::TEvPing, Handle); diff --git a/ydb/core/tablet/tablet_pipecache.cpp b/ydb/core/tablet/tablet_pipecache.cpp index 1feb1a21c3..292571f661 100644 --- a/ydb/core/tablet/tablet_pipecache.cpp +++ b/ydb/core/tablet/tablet_pipecache.cpp @@ -1,16 +1,16 @@ #include <ydb/core/base/tablet_pipecache.h> #include <ydb/core/base/tablet_pipe.h> -#include <util/generic/set.h> -#include <util/generic/hash.h> +#include <util/generic/set.h> +#include <util/generic/hash.h> #include <util/generic/hash_set.h> #include <library/cpp/actors/core/hfunc.h> - -namespace NKikimr { - -class TPipePeNodeCache : public TActor<TPipePeNodeCache> { - TIntrusiveConstPtr<TPipePeNodeCacheConfig> Config; + +namespace NKikimr { + +class TPipePeNodeCache : public TActor<TPipePeNodeCache> { + TIntrusiveConstPtr<TPipePeNodeCacheConfig> Config; NTabletPipe::TClientConfig PipeConfig; - + struct TCounters { NMonitoring::TDynamicCounters::TCounterPtr Tablets; NMonitoring::TDynamicCounters::TCounterPtr Subscribers; @@ -66,30 +66,30 @@ class TPipePeNodeCache : public TActor<TPipePeNodeCache> { ui32 NodeId = 0; bool Connected = false; }; - + struct TTabletState { THashMap<TActorId, TClientState> ByClient; THashMap<TActorId, TClientState*> ByPeer; TActorId LastClient; - TInstant LastCreated; - + TInstant LastCreated; + TClientState* FindClient(const TActorId& clientId) { auto it = ByClient.find(clientId); if (it == ByClient.end()) { return nullptr; } return &it->second; - } - }; - + } + }; + struct TPeerState { THashSet<ui64> ConnectedToTablet; - }; - + }; + using TByTablet = THashMap<ui64, TTabletState>; using TByPeer = THashMap<TActorId, TPeerState>; - + TByTablet ByTablet; TByPeer ByPeer; @@ -122,7 +122,7 @@ class TPipePeNodeCache : public TActor<TPipePeNodeCache> { auto *tabletState = FindTablet(tablet); if (Y_UNLIKELY(!tabletState)) return; - + auto byPeerIt = tabletState->ByPeer.find(peer); if (byPeerIt == tabletState->ByPeer.end()) return; @@ -144,40 +144,40 @@ class TPipePeNodeCache : public TActor<TPipePeNodeCache> { } NTabletPipe::CloseClient(SelfId(), clientId); tabletState->ByClient.erase(clientId); - } + } // Avoid keeping dead tablets forever if (tabletState->ByClient.empty() && !tabletState->LastClient) { ForgetTablet(tablet); } - } - + } + void DropClient(ui64 tablet, TActorId client, bool notDelivered) { auto *tabletState = FindTablet(tablet); if (Y_UNLIKELY(!tabletState)) - return; - + return; + auto *clientState = tabletState->FindClient(client); if (!clientState) return; - + for (auto &kv : clientState->Peers) { const auto &peer = kv.first; const ui64 seqNo = kv.second; const bool msgNotDelivered = notDelivered || seqNo > clientState->MaxForwardedSeqNo; Send(peer, new TEvPipeCache::TEvDeliveryProblem(tablet, msgNotDelivered)); - + tabletState->ByPeer.erase(peer); - auto byPeerIt = ByPeer.find(peer); - Y_VERIFY(byPeerIt != ByPeer.end()); - byPeerIt->second.ConnectedToTablet.erase(tablet); + auto byPeerIt = ByPeer.find(peer); + Y_VERIFY(byPeerIt != ByPeer.end()); + byPeerIt->second.ConnectedToTablet.erase(tablet); if (byPeerIt->second.ConnectedToTablet.empty()) { ForgetPeer(byPeerIt); } - } + } clientState->Peers.clear(); - + for (auto &req : clientState->NodeRequests) { Send(req.Sender, new TEvPipeCache::TEvGetTabletNodeResult(tablet, 0), 0, req.Cookie); } @@ -198,13 +198,13 @@ class TPipePeNodeCache : public TActor<TPipePeNodeCache> { if (tabletState->LastClient == client) { tabletState->LastClient = TActorId(); } - + // Avoid keeping dead tablets forever if (tabletState->ByClient.empty() && !tabletState->LastClient) { ForgetTablet(tablet); - } - } - + } + } + TClientState* EnsureClient(TTabletState *tabletState, ui64 tabletId) { TClientState *clientState = nullptr; if (!tabletState->LastClient || Config->PipeRefreshTime && tabletState->ByClient.size() < 2 && Config->PipeRefreshTime < (TActivationContext::Now() - tabletState->LastCreated)) { @@ -236,10 +236,10 @@ class TPipePeNodeCache : public TActor<TPipePeNodeCache> { } else { clientState = tabletState->FindClient(tabletState->LastClient); Y_VERIFY(clientState, "Missing expected client state for active client"); - } + } return clientState; } - + void Handle(TEvPipeCache::TEvGetTabletNode::TPtr &ev) { const ui64 tablet = ev->Get()->TabletId; @@ -312,48 +312,48 @@ class TPipePeNodeCache : public TActor<TPipePeNodeCache> { NTabletPipe::SendDataWithSeqNo(peer, tabletState->LastClient, msg->Ev.Release(), seqNo, cookie); } else { NTabletPipe::SendData(peer, tabletState->LastClient, msg->Ev.Release(), cookie); - } - } - - void Handle(TEvPipeCache::TEvUnlink::TPtr &ev) { - TEvPipeCache::TEvUnlink *msg = ev->Get(); - const ui64 tablet = msg->TabletId; + } + } + + void Handle(TEvPipeCache::TEvUnlink::TPtr &ev) { + TEvPipeCache::TEvUnlink *msg = ev->Get(); + const ui64 tablet = msg->TabletId; const TActorId peer = ev->Sender; - - auto byPeerIt = ByPeer.find(peer); - if (byPeerIt == ByPeer.end()) - return; - - auto &connectedTo = byPeerIt->second.ConnectedToTablet; - if (tablet == 0) { // unlink everything - for (ui64 x : connectedTo) - UnlinkOne(peer, x); + + auto byPeerIt = ByPeer.find(peer); + if (byPeerIt == ByPeer.end()) + return; + + auto &connectedTo = byPeerIt->second.ConnectedToTablet; + if (tablet == 0) { // unlink everything + for (ui64 x : connectedTo) + UnlinkOne(peer, x); ForgetPeer(byPeerIt); - return; - } else { - UnlinkOne(peer, tablet); - connectedTo.erase(tablet); + return; + } else { + UnlinkOne(peer, tablet); + connectedTo.erase(tablet); if (connectedTo.empty()) { ForgetPeer(byPeerIt); } - return; - } - } - - void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev) { - const TEvTabletPipe::TEvClientConnected *msg = ev->Get(); - + return; + } + } + + void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev) { + const TEvTabletPipe::TEvClientConnected *msg = ev->Get(); + if (msg->Status != NKikimrProto::OK) { if (Counters) { Counters.EventConnectFailure->Inc(); } - return DropClient(msg->TabletId, msg->ClientId, true); + return DropClient(msg->TabletId, msg->ClientId, true); } else { if (Counters) { Counters.EventConnectOk->Inc(); } } - + auto *tabletState = FindTablet(msg->TabletId); if (tabletState) { auto *clientState = tabletState->FindClient(msg->ClientId); @@ -374,12 +374,12 @@ class TPipePeNodeCache : public TActor<TPipePeNodeCache> { } return; } - } - + } + // Unknown client (dropped before it connected) - NTabletPipe::CloseClient(SelfId(), msg->ClientId); - } - + NTabletPipe::CloseClient(SelfId(), msg->ClientId); + } + void Handle(TEvTabletPipe::TEvClientShuttingDown::TPtr &ev) { const auto *msg = ev->Get(); @@ -420,51 +420,51 @@ class TPipePeNodeCache : public TActor<TPipePeNodeCache> { } } - void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev) { - const TEvTabletPipe::TEvClientDestroyed *msg = ev->Get(); + void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev) { + const TEvTabletPipe::TEvClientDestroyed *msg = ev->Get(); if (Counters) { Counters.EventDisconnect->Inc(); } - DropClient(msg->TabletId, msg->ClientId, false); - } + DropClient(msg->TabletId, msg->ClientId, false); + } -public: +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TABLET_PIPE_SERVER; } - TPipePeNodeCache(const TIntrusivePtr<TPipePeNodeCacheConfig> &config) - : TActor(&TThis::StateWork) - , Config(config) + TPipePeNodeCache(const TIntrusivePtr<TPipePeNodeCacheConfig> &config) + : TActor(&TThis::StateWork) + , Config(config) , PipeConfig(Config->PipeConfig) , Counters(Config->Counters) { PipeConfig.ExpectShutdown = true; } - - STFUNC(StateWork) { - Y_UNUSED(ctx); - switch (ev->GetTypeRewrite()) { + + STFUNC(StateWork) { + Y_UNUSED(ctx); + switch (ev->GetTypeRewrite()) { hFunc(TEvPipeCache::TEvGetTabletNode, Handle); - hFunc(TEvPipeCache::TEvForward, Handle); - hFunc(TEvPipeCache::TEvUnlink, Handle); - hFunc(TEvTabletPipe::TEvClientConnected, Handle); + hFunc(TEvPipeCache::TEvForward, Handle); + hFunc(TEvPipeCache::TEvUnlink, Handle); + hFunc(TEvTabletPipe::TEvClientConnected, Handle); hFunc(TEvTabletPipe::TEvClientShuttingDown, Handle); - hFunc(TEvTabletPipe::TEvClientDestroyed, Handle); - } - } -}; - -IActor* CreatePipePeNodeCache(const TIntrusivePtr<TPipePeNodeCacheConfig> &config) { - return new TPipePeNodeCache(config); -} - + hFunc(TEvTabletPipe::TEvClientDestroyed, Handle); + } + } +}; + +IActor* CreatePipePeNodeCache(const TIntrusivePtr<TPipePeNodeCacheConfig> &config) { + return new TPipePeNodeCache(config); +} + TActorId MakePipePeNodeCacheID(bool allowFollower) { - char x[12] = "PipeCache"; + char x[12] = "PipeCache"; x[9] = allowFollower ? 'F' : 'A'; return TActorId(0, TStringBuf(x, 12)); -} - -} +} + +} diff --git a/ydb/core/tablet/tablet_req_blockbs.cpp b/ydb/core/tablet/tablet_req_blockbs.cpp index 47a82eff2e..7e2e94ec95 100644 --- a/ydb/core/tablet/tablet_req_blockbs.cpp +++ b/ydb/core/tablet/tablet_req_blockbs.cpp @@ -1,164 +1,164 @@ -#include "tablet_impl.h" +#include "tablet_impl.h" #include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/actors/core/hfunc.h> -#include <util/generic/set.h> - -namespace NKikimr { - +#include <util/generic/set.h> + +namespace NKikimr { + constexpr ui32 MAX_ATTEMPTS = 3; -class TTabletReqBlockBlobStorageGroup : public TActorBootstrapped<TTabletReqBlockBlobStorageGroup> { +class TTabletReqBlockBlobStorageGroup : public TActorBootstrapped<TTabletReqBlockBlobStorageGroup> { const TActorId Owner; - const ui64 TabletId; - const ui32 GroupId; - const ui32 Generation; + const ui64 TabletId; + const ui32 GroupId; + const ui32 Generation; ui32 ErrorCount; - + void ReplyAndDie(NKikimrProto::EReplyStatus status, const TString &reason = { }) { Send(Owner, new TEvTabletBase::TEvBlockBlobStorageResult(status, TabletId, reason)); - PassAway(); - } - - void SendRequest() { + PassAway(); + } + + void SendRequest() { const TActorId proxy = MakeBlobStorageProxyID(GroupId); THolder<TEvBlobStorage::TEvBlock> event(new TEvBlobStorage::TEvBlock(TabletId, Generation, TInstant::Max())); event->IsMonitored = false; SendToBSProxy(TlsActivationContext->AsActorContext(), proxy, event.Release()); - } - + } + void Handle(TEvents::TEvUndelivered::TPtr&) { return ReplyAndDie(NKikimrProto::ERROR, "BlobStorage proxy unavailable"); } - void Handle(TEvBlobStorage::TEvBlockResult::TPtr &ev) { - const TEvBlobStorage::TEvBlockResult *msg = ev->Get(); - - switch (msg->Status) { - case NKikimrProto::OK: - return ReplyAndDie(NKikimrProto::OK); + void Handle(TEvBlobStorage::TEvBlockResult::TPtr &ev) { + const TEvBlobStorage::TEvBlockResult *msg = ev->Get(); + + switch (msg->Status) { + case NKikimrProto::OK: + return ReplyAndDie(NKikimrProto::OK); case NKikimrProto::BLOCKED: case NKikimrProto::RACE: case NKikimrProto::NO_GROUP: // The request will never succeed return ReplyAndDie(msg->Status, msg->ErrorReason); - default: + default: ++ErrorCount; if (ErrorCount >= MAX_ATTEMPTS) { return ReplyAndDie(NKikimrProto::ERROR, msg->ErrorReason); } - return SendRequest(); - } - } - - STFUNC(StateWait) { - Y_UNUSED(ctx); - switch (ev->GetTypeRewrite()) { - hFunc(TEvBlobStorage::TEvBlockResult, Handle); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + return SendRequest(); + } + } + + STFUNC(StateWait) { + Y_UNUSED(ctx); + switch (ev->GetTypeRewrite()) { + hFunc(TEvBlobStorage::TEvBlockResult, Handle); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); hFunc(TEvents::TEvUndelivered, Handle); - } - } - -public: + } + } + +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TABLET_REQ_BLOCK_BS; } - void Bootstrap() { - SendRequest(); - Become(&TThis::StateWait); - } - + void Bootstrap() { + SendRequest(); + Become(&TThis::StateWait); + } + TTabletReqBlockBlobStorageGroup(const TActorId &owner, ui64 tabletId, ui32 groupId, ui32 gen) - : Owner(owner) - , TabletId(tabletId) - , GroupId(groupId) - , Generation(gen) + : Owner(owner) + , TabletId(tabletId) + , GroupId(groupId) + , Generation(gen) , ErrorCount(0) {} -}; - -class TTabletReqBlockBlobStorage : public TActorBootstrapped<TTabletReqBlockBlobStorage> { +}; + +class TTabletReqBlockBlobStorage : public TActorBootstrapped<TTabletReqBlockBlobStorage> { const TActorId Owner; - TIntrusiveConstPtr<TTabletStorageInfo> Info; - const ui32 Generation; - const bool BlockPrevEntry; - - ui32 Replied = 0; + TIntrusiveConstPtr<TTabletStorageInfo> Info; + const ui32 Generation; + const bool BlockPrevEntry; + + ui32 Replied = 0; TVector<TActorId> ReqActors; - - void PassAway() override { - for (auto &x : ReqActors) - if (x) - Send(x, new TEvents::TEvPoisonPill()); - - TActor::PassAway(); - } - + + void PassAway() override { + for (auto &x : ReqActors) + if (x) + Send(x, new TEvents::TEvPoisonPill()); + + TActor::PassAway(); + } + void ReplyAndDie(NKikimrProto::EReplyStatus status, const TString &reason = { }) { Send(Owner, new TEvTabletBase::TEvBlockBlobStorageResult(status, Info->TabletID, reason)); - PassAway(); - } - - void Handle(TEvTabletBase::TEvBlockBlobStorageResult::TPtr &ev) { - auto *msg = ev->Get(); - auto it = Find(ReqActors, ev->Sender); - Y_VERIFY(it != ReqActors.end(), "must not get response from unknown actor"); + PassAway(); + } + + void Handle(TEvTabletBase::TEvBlockBlobStorageResult::TPtr &ev) { + auto *msg = ev->Get(); + auto it = Find(ReqActors, ev->Sender); + Y_VERIFY(it != ReqActors.end(), "must not get response from unknown actor"); *it = TActorId(); - - switch (msg->Status) { - case NKikimrProto::OK: - if (++Replied == ReqActors.size()) - return ReplyAndDie(NKikimrProto::OK); + + switch (msg->Status) { + case NKikimrProto::OK: + if (++Replied == ReqActors.size()) + return ReplyAndDie(NKikimrProto::OK); break; - default: + default: return ReplyAndDie(msg->Status, msg->ErrorReason); - } - } -public: + } + } +public: TTabletReqBlockBlobStorage(TActorId owner, TTabletStorageInfo *info, ui32 generation, bool blockPrevEntry) - : Owner(owner) - , Info(info) - , Generation(generation) - , BlockPrevEntry(blockPrevEntry) - {} - + : Owner(owner) + , Info(info) + , Generation(generation) + , BlockPrevEntry(blockPrevEntry) + {} + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TABLET_REQ_BLOCK_BS; - } - - void Bootstrap() { - TSet<ui32> blocked; - - const ui64 tabletId = Info->TabletID; - ReqActors.reserve(Info->Channels.size()); - for (auto &x : Info->Channels) { - if (auto *g = x.LatestEntry()) { - if (blocked.insert(g->GroupID).second) + } + + void Bootstrap() { + TSet<ui32> blocked; + + const ui64 tabletId = Info->TabletID; + ReqActors.reserve(Info->Channels.size()); + for (auto &x : Info->Channels) { + if (auto *g = x.LatestEntry()) { + if (blocked.insert(g->GroupID).second) ReqActors.push_back(RegisterWithSameMailbox(new TTabletReqBlockBlobStorageGroup(SelfId(), tabletId, g->GroupID, Generation))); - } - - if (BlockPrevEntry) { - if (auto *pg = x.PreviousEntry()) - if (blocked.insert(pg->GroupID).second) + } + + if (BlockPrevEntry) { + if (auto *pg = x.PreviousEntry()) + if (blocked.insert(pg->GroupID).second) ReqActors.push_back(RegisterWithSameMailbox(new TTabletReqBlockBlobStorageGroup(SelfId(), tabletId, pg->GroupID, Generation))); - } - } - - Become(&TThis::StateWait); - } - - STFUNC(StateWait) { - Y_UNUSED(ctx); - switch (ev->GetTypeRewrite()) { - hFunc(TEvTabletBase::TEvBlockBlobStorageResult, Handle); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); - } - } -}; - + } + } + + Become(&TThis::StateWait); + } + + STFUNC(StateWait) { + Y_UNUSED(ctx); + switch (ev->GetTypeRewrite()) { + hFunc(TEvTabletBase::TEvBlockBlobStorageResult, Handle); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + } + } +}; + IActor* CreateTabletReqBlockBlobStorage(const TActorId &owner, TTabletStorageInfo *info, ui32 generation, bool blockPrevEntry) { - return new TTabletReqBlockBlobStorage(owner, info, generation, blockPrevEntry); -} - -} + return new TTabletReqBlockBlobStorage(owner, info, generation, blockPrevEntry); +} + +} diff --git a/ydb/core/tablet/tablet_req_delete.cpp b/ydb/core/tablet/tablet_req_delete.cpp index 6bac6464c2..754c79bb32 100644 --- a/ydb/core/tablet/tablet_req_delete.cpp +++ b/ydb/core/tablet/tablet_req_delete.cpp @@ -86,8 +86,8 @@ class TTabletReqDelete : public TActorBootstrapped<TTabletReqDelete> { const TActorId proxyActorID = MakeStateStorageProxyID(StateStorageId); ctx.Send(proxyActorID, new TEvStateStorage::TEvDelete(TabletStorageInfo->TabletID)); } - - ReplyAndDie(NKikimrProto::OK, ctx); + + ReplyAndDie(NKikimrProto::OK, ctx); } break; default: diff --git a/ydb/core/tablet/tablet_req_findlatest.cpp b/ydb/core/tablet/tablet_req_findlatest.cpp index ccedd48f93..ca3d09aa43 100644 --- a/ydb/core/tablet/tablet_req_findlatest.cpp +++ b/ydb/core/tablet/tablet_req_findlatest.cpp @@ -1,103 +1,103 @@ -#include "tablet_impl.h" +#include "tablet_impl.h" #include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/actors/core/hfunc.h> - -#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR -#error log macro definition clash -#endif - -#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, stream) -#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, stream) -#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, stream) -#define BLOG_TRACE(stream) LOG_TRACE_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, stream) - -namespace NKikimr { - -class TTabletReqFindLatestLogEntry : public TActorBootstrapped<TTabletReqFindLatestLogEntry> { + +#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR +#error log macro definition clash +#endif + +#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, stream) +#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, stream) +#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, stream) +#define BLOG_TRACE(stream) LOG_TRACE_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, stream) + +namespace NKikimr { + +class TTabletReqFindLatestLogEntry : public TActorBootstrapped<TTabletReqFindLatestLogEntry> { const TActorId Owner; - const bool ReadBody; - const ui32 BlockedGeneration; - TIntrusivePtr<TTabletStorageInfo> Info; - const TTabletChannelInfo *ChannelInfo; - ui64 CurrentHistoryIndex; - - void ReplyAndDie(NKikimrProto::EReplyStatus status, const TString &reason) { - Send(Owner, new TEvTabletBase::TEvFindLatestLogEntryResult(status, reason)); - PassAway(); - } - - void FindLastEntryNext() { - if (CurrentHistoryIndex == 0) - return ReplyAndDie(NKikimrProto::NODATA, "Tablet has no data"); - --CurrentHistoryIndex; - - const ui32 group = ChannelInfo->History[CurrentHistoryIndex].GroupID; - const ui32 minGeneration = ChannelInfo->History[CurrentHistoryIndex].FromGeneration; - auto request = MakeHolder<TEvBlobStorage::TEvDiscover>(Info->TabletID, minGeneration, ReadBody, true, TInstant::Max(), BlockedGeneration); - SendToBSProxy(SelfId(), group, request.Release()); - } - - void Handle(TEvents::TEvUndelivered::TPtr&) { - return ReplyAndDie(NKikimrProto::ERROR, "BlobStorage proxy unavailable"); + const bool ReadBody; + const ui32 BlockedGeneration; + TIntrusivePtr<TTabletStorageInfo> Info; + const TTabletChannelInfo *ChannelInfo; + ui64 CurrentHistoryIndex; + + void ReplyAndDie(NKikimrProto::EReplyStatus status, const TString &reason) { + Send(Owner, new TEvTabletBase::TEvFindLatestLogEntryResult(status, reason)); + PassAway(); + } + + void FindLastEntryNext() { + if (CurrentHistoryIndex == 0) + return ReplyAndDie(NKikimrProto::NODATA, "Tablet has no data"); + --CurrentHistoryIndex; + + const ui32 group = ChannelInfo->History[CurrentHistoryIndex].GroupID; + const ui32 minGeneration = ChannelInfo->History[CurrentHistoryIndex].FromGeneration; + auto request = MakeHolder<TEvBlobStorage::TEvDiscover>(Info->TabletID, minGeneration, ReadBody, true, TInstant::Max(), BlockedGeneration); + SendToBSProxy(SelfId(), group, request.Release()); + } + + void Handle(TEvents::TEvUndelivered::TPtr&) { + return ReplyAndDie(NKikimrProto::ERROR, "BlobStorage proxy unavailable"); } - void Handle(TEvBlobStorage::TEvDiscoverResult::TPtr &ev) { - TEvBlobStorage::TEvDiscoverResult *msg = ev->Get(); - - switch (msg->Status) { - case NKikimrProto::OK: - // as we can assign groups in ABA order, we must check that found entry is not from outdated generation - if (ChannelInfo->History[CurrentHistoryIndex].FromGeneration > msg->Id.Generation()) { - return FindLastEntryNext(); - } else { - Send(Owner, new TEvTabletBase::TEvFindLatestLogEntryResult(msg->Id, msg->BlockedGeneration, msg->Buffer)); - return PassAway(); - } - case NKikimrProto::NODATA: - return FindLastEntryNext(); - case NKikimrProto::RACE: - case NKikimrProto::ERROR: - case NKikimrProto::TIMEOUT: + void Handle(TEvBlobStorage::TEvDiscoverResult::TPtr &ev) { + TEvBlobStorage::TEvDiscoverResult *msg = ev->Get(); + + switch (msg->Status) { + case NKikimrProto::OK: + // as we can assign groups in ABA order, we must check that found entry is not from outdated generation + if (ChannelInfo->History[CurrentHistoryIndex].FromGeneration > msg->Id.Generation()) { + return FindLastEntryNext(); + } else { + Send(Owner, new TEvTabletBase::TEvFindLatestLogEntryResult(msg->Id, msg->BlockedGeneration, msg->Buffer)); + return PassAway(); + } + case NKikimrProto::NODATA: + return FindLastEntryNext(); + case NKikimrProto::RACE: + case NKikimrProto::ERROR: + case NKikimrProto::TIMEOUT: case NKikimrProto::NO_GROUP: - BLOG_ERROR("Handle::TEvDiscoverResult, result status " << NKikimrProto::EReplyStatus_Name(msg->Status)); - return ReplyAndDie(msg->Status, msg->ErrorReason); - default: + BLOG_ERROR("Handle::TEvDiscoverResult, result status " << NKikimrProto::EReplyStatus_Name(msg->Status)); + return ReplyAndDie(msg->Status, msg->ErrorReason); + default: Y_VERIFY(false, "default case status %s", NKikimrProto::EReplyStatus_Name(msg->Status).c_str()); - return ReplyAndDie(NKikimrProto::ERROR, msg->ErrorReason); - } - } -public: + return ReplyAndDie(NKikimrProto::ERROR, msg->ErrorReason); + } + } +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TABLET_REQ_FIND_LATEST; } TTabletReqFindLatestLogEntry(const TActorId &owner, bool readBody, TTabletStorageInfo *info, ui32 blockedGeneration) - : Owner(owner) - , ReadBody(readBody) - , BlockedGeneration(blockedGeneration) - , Info(info) - , ChannelInfo(Info->ChannelInfo(0)) - , CurrentHistoryIndex(ChannelInfo->History.size()) + : Owner(owner) + , ReadBody(readBody) + , BlockedGeneration(blockedGeneration) + , Info(info) + , ChannelInfo(Info->ChannelInfo(0)) + , CurrentHistoryIndex(ChannelInfo->History.size()) { Y_VERIFY(CurrentHistoryIndex > 0); } - - void Bootstrap() { - Become(&TThis::StateInit); - FindLastEntryNext(); - } - - STATEFN(StateInit) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvBlobStorage::TEvDiscoverResult, Handle); - hFunc(TEvents::TEvUndelivered, Handle); - } - } -}; - + + void Bootstrap() { + Become(&TThis::StateInit); + FindLastEntryNext(); + } + + STATEFN(StateInit) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvBlobStorage::TEvDiscoverResult, Handle); + hFunc(TEvents::TEvUndelivered, Handle); + } + } +}; + IActor* CreateTabletFindLastEntry(const TActorId &owner, bool readBody, TTabletStorageInfo *info, ui32 blockedGeneration) { - return new TTabletReqFindLatestLogEntry(owner, readBody, info, blockedGeneration); -} - -} + return new TTabletReqFindLatestLogEntry(owner, readBody, info, blockedGeneration); +} + +} diff --git a/ydb/core/tablet/tablet_req_rebuildhistory.cpp b/ydb/core/tablet/tablet_req_rebuildhistory.cpp index fa17afe467..c0b4c0c2bc 100644 --- a/ydb/core/tablet/tablet_req_rebuildhistory.cpp +++ b/ydb/core/tablet/tablet_req_rebuildhistory.cpp @@ -1,506 +1,506 @@ -#include "tablet_impl.h" +#include "tablet_impl.h" #include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/actors/core/hfunc.h> #include <ydb/core/tablet/tablet_metrics.h> -#include <util/generic/map.h> -#include <util/generic/set.h> +#include <util/generic/map.h> +#include <util/generic/set.h> #include <util/string/builder.h> - + #include <library/cpp/actors/core/log.h> #include <ydb/core/protos/services.pb.h> #include <google/protobuf/text_format.h> #include "tablet_tracing_signals.h" -#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR -#error log macro definition clash -#endif - +#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR +#error log macro definition clash +#endif + #define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, "TabletId# " << Info->TabletID << (FollowerCookie ? "f " : " ") << stream) #define BLOG_W(stream) LOG_WARN_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, "TabletId# " << Info->TabletID << (FollowerCookie ? "f " : " ") << stream) #define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, "TabletId# " << Info->TabletID << (FollowerCookie ? "f " : " ") << stream) #define BLOG_TRACE(stream) LOG_TRACE_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, "TabletId# " << Info->TabletID << (FollowerCookie ? "f " : " ") << stream) #define BLOG_CRIT(stream) LOG_CRIT_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, "TabletId# " << Info->TabletID << (FollowerCookie ? "f " : " ") << stream) - -namespace NKikimr { - - // TODO: handle input error condition with Panic notification - -class TTabletReqRebuildHistoryGraph : public TActorBootstrapped<TTabletReqRebuildHistoryGraph> { - struct TLogEntry { - enum EStatus { - StatusUnknown, - StatusOk, - StatusBody, - - // set by zero-entry tail definition - StatusMustBePresent, - StatusMustBeIgnored, - StatusMustBeIgnoredBody, - } Status; - + +namespace NKikimr { + + // TODO: handle input error condition with Panic notification + +class TTabletReqRebuildHistoryGraph : public TActorBootstrapped<TTabletReqRebuildHistoryGraph> { + struct TLogEntry { + enum EStatus { + StatusUnknown, + StatusOk, + StatusBody, + + // set by zero-entry tail definition + StatusMustBePresent, + StatusMustBeIgnored, + StatusMustBeIgnoredBody, + } Status; + TVector<TLogoBlobID> References; TVector<ui32> DependsOn; - bool IsSnapshot; - bool IsTotalSnapshot; + bool IsSnapshot; + bool IsTotalSnapshot; TString EmbeddedLogBody; - + TVector<TLogoBlobID> GcDiscovered; TVector<TLogoBlobID> GcLeft; - - void BecomeConfirmed() { - switch (Status) { - case StatusUnknown: - Status = StatusMustBePresent; - break; - case StatusOk: - break; - case StatusBody: - Status = StatusOk; - break; - case StatusMustBePresent: - break; - case StatusMustBeIgnored: - Status = StatusMustBePresent; - break; - case StatusMustBeIgnoredBody: - Status = StatusOk; - break; - default: + + void BecomeConfirmed() { + switch (Status) { + case StatusUnknown: + Status = StatusMustBePresent; + break; + case StatusOk: + break; + case StatusBody: + Status = StatusOk; + break; + case StatusMustBePresent: + break; + case StatusMustBeIgnored: + Status = StatusMustBePresent; + break; + case StatusMustBeIgnoredBody: + Status = StatusOk; + break; + default: Y_FAIL(); - } - } - - void BecomeDeclined() { - switch (Status) { - case StatusUnknown: - Status = StatusMustBeIgnored; - break; - case StatusOk: - case StatusBody: - Status = StatusMustBeIgnoredBody; - break; - case StatusMustBePresent: - Status = StatusMustBeIgnored; - break; - case StatusMustBeIgnored: - case StatusMustBeIgnoredBody: - break; - default: + } + } + + void BecomeDeclined() { + switch (Status) { + case StatusUnknown: + Status = StatusMustBeIgnored; + break; + case StatusOk: + case StatusBody: + Status = StatusMustBeIgnoredBody; + break; + case StatusMustBePresent: + Status = StatusMustBeIgnored; + break; + case StatusMustBeIgnored: + case StatusMustBeIgnoredBody: + break; + default: Y_FAIL(); - } - } - - void UpdateReferences(const NKikimrTabletBase::TTabletLogEntry &x) { + } + } + + void UpdateReferences(const NKikimrTabletBase::TTabletLogEntry &x) { if (const ui32 referencesSz = (ui32)x.ReferencesSize()) { - References.resize(referencesSz); - for (ui32 i = 0; i != referencesSz; ++i) - References[i] = LogoBlobIDFromLogoBlobID(x.GetReferences(i)); - } - - if (x.DependsOnSize()) - DependsOn.insert(DependsOn.begin(), x.GetDependsOn().begin(), x.GetDependsOn().end()); - - if (x.HasIsTotalSnapshot()) - IsTotalSnapshot = x.GetIsTotalSnapshot(); - - if (x.HasIsSnapshot()) - IsSnapshot = x.GetIsSnapshot(); - - if (x.HasEmbeddedLogBody()) { + References.resize(referencesSz); + for (ui32 i = 0; i != referencesSz; ++i) + References[i] = LogoBlobIDFromLogoBlobID(x.GetReferences(i)); + } + + if (x.DependsOnSize()) + DependsOn.insert(DependsOn.begin(), x.GetDependsOn().begin(), x.GetDependsOn().end()); + + if (x.HasIsTotalSnapshot()) + IsTotalSnapshot = x.GetIsTotalSnapshot(); + + if (x.HasIsSnapshot()) + IsSnapshot = x.GetIsSnapshot(); + + if (x.HasEmbeddedLogBody()) { Y_VERIFY(References.empty(), "must not mix embedded and referenced log bodies"); Y_VERIFY(IsSnapshot == false, "log snapshot could not be embedded"); - EmbeddedLogBody = x.GetEmbeddedLogBody(); - } - - if (const ui32 gcDiscoveredSize = x.GcDiscoveredSize()) { - GcDiscovered.resize(gcDiscoveredSize); - for (ui32 i= 0; i != gcDiscoveredSize; ++i) - GcDiscovered[i] = LogoBlobIDFromLogoBlobID(x.GetGcDiscovered(i)); - } - - if (const ui32 gcLeftSize = x.GcLeftSize()) { - GcLeft.resize(gcLeftSize); - for (ui32 i= 0; i != gcLeftSize; ++i) - GcLeft[i] = LogoBlobIDFromLogoBlobID(x.GetGcLeft(i)); - } - - switch (Status) { - case StatusUnknown: - Status = StatusBody; - break; - case StatusOk: + EmbeddedLogBody = x.GetEmbeddedLogBody(); + } + + if (const ui32 gcDiscoveredSize = x.GcDiscoveredSize()) { + GcDiscovered.resize(gcDiscoveredSize); + for (ui32 i= 0; i != gcDiscoveredSize; ++i) + GcDiscovered[i] = LogoBlobIDFromLogoBlobID(x.GetGcDiscovered(i)); + } + + if (const ui32 gcLeftSize = x.GcLeftSize()) { + GcLeft.resize(gcLeftSize); + for (ui32 i= 0; i != gcLeftSize; ++i) + GcLeft[i] = LogoBlobIDFromLogoBlobID(x.GetGcLeft(i)); + } + + switch (Status) { + case StatusUnknown: + Status = StatusBody; + break; + case StatusOk: Y_VERIFY_DEBUG(false); - break; - case StatusBody: - break; - case StatusMustBePresent: - Status = StatusOk; - break; - case StatusMustBeIgnored: - Status = StatusMustBeIgnoredBody; - break; - case StatusMustBeIgnoredBody: - break; - default: + break; + case StatusBody: + break; + case StatusMustBePresent: + Status = StatusOk; + break; + case StatusMustBeIgnored: + Status = StatusMustBeIgnoredBody; + break; + case StatusMustBeIgnoredBody: + break; + default: Y_FAIL(); - } - } - - TLogEntry() - : Status(StatusUnknown) - , IsSnapshot(false) - , IsTotalSnapshot(false) - {} - }; - - struct TGenerationEntry { + } + } + + TLogEntry() + : Status(StatusUnknown) + , IsSnapshot(false) + , IsTotalSnapshot(false) + {} + }; + + struct TGenerationEntry { TVector<TLogEntry> Body; std::pair<ui32, ui32> PrevGeneration; // gen : confirmed-state - ui32 NextGeneration; - ui32 Base; - ui32 Cutoff; - bool HasZeroEntry; - NKikimrTabletBase::TTabletLogEntry ZeroEntryContent; - - TGenerationEntry() - : NextGeneration(0) - , Base(1) - , Cutoff(Max<ui32>()) - , HasZeroEntry(false) - {} - - TLogEntry& Entry(ui32 step) { + ui32 NextGeneration; + ui32 Base; + ui32 Cutoff; + bool HasZeroEntry; + NKikimrTabletBase::TTabletLogEntry ZeroEntryContent; + + TGenerationEntry() + : NextGeneration(0) + , Base(1) + , Cutoff(Max<ui32>()) + , HasZeroEntry(false) + {} + + TLogEntry& Entry(ui32 step) { Y_VERIFY(step >= Base); - const ui32 idx = step - Base; + const ui32 idx = step - Base; Y_VERIFY(idx < Body.size()); - return Body[idx]; - } - - void Ensure(ui32 step) { + return Body[idx]; + } + + void Ensure(ui32 step) { Y_VERIFY(step >= Base); - const ui32 idx = step - Base; - if (idx >= Body.size()) - Body.resize(idx + 1); - } - }; - + const ui32 idx = step - Base; + if (idx >= Body.size()) + Body.resize(idx + 1); + } + }; + const TActorId Owner; - TIntrusivePtr<TTabletStorageInfo> Info; - const ui32 BlockedGen; - + TIntrusivePtr<TTabletStorageInfo> Info; + const ui32 BlockedGen; + std::pair<ui32, ui32> LatestKnownStep; std::pair<ui32, ui32> Snapshot; std::pair<ui32, ui32> Confirmed; - + TMap<ui32, TGenerationEntry> LogInfo; TSet<TLogoBlobID> RefsToCheck; - TMap<ui32, TVector<TLogoBlobID>> RefsToCheckByGroup; + TMap<ui32, TVector<TLogoBlobID>> RefsToCheckByGroup; TSet<TLogoBlobID> RangesToDiscover; - - ui32 RequestsLeft; + + ui32 RequestsLeft; NMetrics::TTabletThroughputRawValue GroupReadBytes; NMetrics::TTabletIopsRawValue GroupReadOps; - + THolder<NTracing::ITrace> IntrospectionTrace; const ui64 FollowerCookie; - TGenerationEntry& GenerationInfo(ui32 gen) { - TGenerationEntry& x = LogInfo[gen]; + TGenerationEntry& GenerationInfo(ui32 gen) { + TGenerationEntry& x = LogInfo[gen]; if (gen == Snapshot.first) x.Base = Snapshot.second; - return x; - } - - void ReplyAndDie(NKikimrProto::EReplyStatus status, const TString &reason) { + return x; + } + + void ReplyAndDie(NKikimrProto::EReplyStatus status, const TString &reason) { Send(Owner, new TEvTabletBase::TEvRebuildGraphResult(status, IntrospectionTrace.Release(), reason), 0, FollowerCookie); - PassAway(); - } - - void ProcessZeroEntry(ui32 gen, NKikimrTabletBase::TTabletLogEntry &logEntry) { - - BLOG_D("TTabletReqRebuildHistoryGraph::ProcessZeroEntry - generation " << gen); + PassAway(); + } + + void ProcessZeroEntry(ui32 gen, NKikimrTabletBase::TTabletLogEntry &logEntry) { + + BLOG_D("TTabletReqRebuildHistoryGraph::ProcessZeroEntry - generation " << gen); if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TOnProcessZeroEntry>(gen, Snapshot, Confirmed)); } - + Y_VERIFY(logEntry.HasZeroConfirmed() && logEntry.HasZeroTailSz()); - - TGenerationEntry ¤t = GenerationInfo(gen); - - current.HasZeroEntry = true; - current.ZeroEntryContent.CopyFrom(logEntry); - } - - bool RebuildGenSequenceByZeroEntries() { - if (LogInfo.empty()) - return true; - - // not reverse iterators cuz of simpler erase logic - auto it = LogInfo.end(); - --it; - - for (;;) { - const ui32 gen = it->first; - - TGenerationEntry ¤t = it->second; - if (!current.HasZeroEntry || gen == Snapshot.first) { - break; - } - - NKikimrTabletBase::TTabletLogEntry &zeroLogEntry = current.ZeroEntryContent; - std::pair<ui32, ui32> confirmed = ExpandGenStepPair(zeroLogEntry.GetZeroConfirmed()); - const ui32 prevGeneration = confirmed.first; - - if (prevGeneration < Snapshot.first) { - BLOG_CRIT("snapshot overrun in gen " << gen << " zero entry, declared prev gen " << prevGeneration << " while known snapshot is " << Snapshot.first << ":" << Snapshot.second); - - if (IntrospectionTrace) + + TGenerationEntry ¤t = GenerationInfo(gen); + + current.HasZeroEntry = true; + current.ZeroEntryContent.CopyFrom(logEntry); + } + + bool RebuildGenSequenceByZeroEntries() { + if (LogInfo.empty()) + return true; + + // not reverse iterators cuz of simpler erase logic + auto it = LogInfo.end(); + --it; + + for (;;) { + const ui32 gen = it->first; + + TGenerationEntry ¤t = it->second; + if (!current.HasZeroEntry || gen == Snapshot.first) { + break; + } + + NKikimrTabletBase::TTabletLogEntry &zeroLogEntry = current.ZeroEntryContent; + std::pair<ui32, ui32> confirmed = ExpandGenStepPair(zeroLogEntry.GetZeroConfirmed()); + const ui32 prevGeneration = confirmed.first; + + if (prevGeneration < Snapshot.first) { + BLOG_CRIT("snapshot overrun in gen " << gen << " zero entry, declared prev gen " << prevGeneration << " while known snapshot is " << Snapshot.first << ":" << Snapshot.second); + + if (IntrospectionTrace) IntrospectionTrace->Attach(MakeHolder<NTracing::TErrorRebuildGraph>(gen, 0)); - - return false; - } - - current.PrevGeneration = confirmed; - - TGenerationEntry &prev = GenerationInfo(prevGeneration); - prev.NextGeneration = gen; - + + return false; + } + + current.PrevGeneration = confirmed; + + TGenerationEntry &prev = GenerationInfo(prevGeneration); + prev.NextGeneration = gen; + if (confirmed.first > 0) - FillGenerationEntries(confirmed, prev, zeroLogEntry); - - // here we could erase intermediate entries but who cares as they would be skipped? - - it = LogInfo.find(prevGeneration); - } - - // cleanup front entries - LogInfo.erase(LogInfo.begin(), it); - return true; - } - + FillGenerationEntries(confirmed, prev, zeroLogEntry); + + // here we could erase intermediate entries but who cares as they would be skipped? + + it = LogInfo.find(prevGeneration); + } + + // cleanup front entries + LogInfo.erase(LogInfo.begin(), it); + return true; + } + void FillGenerationEntries(std::pair<ui32, ui32> &confirmed, TGenerationEntry &prev, NKikimrTabletBase::TTabletLogEntry &logEntry) { if (confirmed.first == Snapshot.first) prev.Base = Snapshot.second; - - const ui32 tailsz = logEntry.GetZeroTailSz(); + + const ui32 tailsz = logEntry.GetZeroTailSz(); Y_VERIFY(logEntry.ZeroTailBitmaskSize() == ((tailsz + 63) / 64)); - + const ui32 gensz = confirmed.second + tailsz; - prev.Ensure(gensz); - prev.Cutoff = gensz; // last entry we interested in, later entries has no interest for us - - { // static part, mark as confirmed - ui32 step = prev.Base; + prev.Ensure(gensz); + prev.Cutoff = gensz; // last entry we interested in, later entries has no interest for us + + { // static part, mark as confirmed + ui32 step = prev.Base; for (ui32 end = confirmed.second; step <= end; ++step) { - TLogEntry &x = prev.Entry(step); - x.BecomeConfirmed(); - } - } - - { // tail part, mark accordingly to flags - ui64 mask = 0; - ui64 val = 0; + TLogEntry &x = prev.Entry(step); + x.BecomeConfirmed(); + } + } + + { // tail part, mark accordingly to flags + ui64 mask = 0; + ui64 val = 0; ui32 step = confirmed.second + 1; - for (ui32 i = 0; i < tailsz; ++i, mask <<= 1, ++step) { - if (mask == 0) { - mask = 1; - val = logEntry.GetZeroTailBitmask(i / 64); - } - const bool ok = val & mask; - - if (step >= prev.Base) { - TLogEntry &x = prev.Entry(step); - if (ok) - x.BecomeConfirmed(); - else - x.BecomeDeclined(); - } - } - - for (ui32 end = (ui32)(prev.Body.size() + prev.Base); step < end; ++step) { - TLogEntry &x = prev.Entry(step); - x.BecomeDeclined(); - } - } - } - - void ProcessLogEntry(const TLogoBlobID &id, NKikimrTabletBase::TTabletLogEntry &logEntry) { + for (ui32 i = 0; i < tailsz; ++i, mask <<= 1, ++step) { + if (mask == 0) { + mask = 1; + val = logEntry.GetZeroTailBitmask(i / 64); + } + const bool ok = val & mask; + + if (step >= prev.Base) { + TLogEntry &x = prev.Entry(step); + if (ok) + x.BecomeConfirmed(); + else + x.BecomeDeclined(); + } + } + + for (ui32 end = (ui32)(prev.Body.size() + prev.Base); step < end; ++step) { + TLogEntry &x = prev.Entry(step); + x.BecomeDeclined(); + } + } + } + + void ProcessLogEntry(const TLogoBlobID &id, NKikimrTabletBase::TTabletLogEntry &logEntry) { if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TOnProcessLogEntry>(id, Snapshot, Confirmed, logEntry)); } Y_VERIFY(logEntry.HasSnapshot() && logEntry.HasConfirmed()); - - LOG_DEBUG(*TlsActivationContext, NKikimrServices::TABLET_MAIN, [&](){ - TStringBuilder sb; + + LOG_DEBUG(*TlsActivationContext, NKikimrServices::TABLET_MAIN, [&](){ + TStringBuilder sb; sb << "TTabletReqRebuildHistoryGraph::ProcessLogEntry - TabletID: " << id.TabletID() << ", id " << id - << ", refs: ["; - - for (auto&& t : logEntry.GetReferences()) - sb << LogoBlobIDFromLogoBlobID(t).ToString() << ","; - - sb << "] for " << Info->TabletID; + << ", refs: ["; + + for (auto&& t : logEntry.GetReferences()) + sb << LogoBlobIDFromLogoBlobID(t).ToString() << ","; + + sb << "] for " << Info->TabletID; return (TString)sb; - }()); - - const ui32 step = id.Step(); - TGenerationEntry &gx = GenerationInfo(id.Generation()); - - gx.Ensure(step); - + }()); + + const ui32 step = id.Step(); + TGenerationEntry &gx = GenerationInfo(id.Generation()); + + gx.Ensure(step); + // ignore synth log entries, they are for follower sync only - if (id.Cookie() == 0) { - gx.Entry(step).UpdateReferences(logEntry); - } - } - - void DiscoverRange(std::pair<ui32, ui32> from, std::pair<ui32, ui32> to, bool mustRestoreFirst) { - const TTabletChannelInfo * const channel = Info->ChannelInfo(0); - const ui64 tabletId = Info->TabletID; - - auto it = channel->History.begin(); - auto endIt = channel->History.end(); - do { - const ui32 fromGen = it->FromGeneration; - const ui32 group = it->GroupID; - - const bool last = (++it == endIt); - const ui32 toGen = last ? Max<ui32>() : it->FromGeneration; - - if (toGen <= from.first) - continue; - - if (fromGen > to.first) - return; - - const bool lastGen = (to.first < toGen); - - const TLogoBlobID fromId(tabletId, from.first, from.second, 0, 0, 0); - const TLogoBlobID toId(tabletId, lastGen ? to.first : toGen - 1, lastGen ? to.second : Max<ui32>(), 0, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie); - - SendToBSProxy(SelfId(), group, new TEvBlobStorage::TEvRange(tabletId, fromId, toId, mustRestoreFirst, TInstant::Max(), false, BlockedGen)); - RangesToDiscover.insert(toId); + if (id.Cookie() == 0) { + gx.Entry(step).UpdateReferences(logEntry); + } + } + + void DiscoverRange(std::pair<ui32, ui32> from, std::pair<ui32, ui32> to, bool mustRestoreFirst) { + const TTabletChannelInfo * const channel = Info->ChannelInfo(0); + const ui64 tabletId = Info->TabletID; + + auto it = channel->History.begin(); + auto endIt = channel->History.end(); + do { + const ui32 fromGen = it->FromGeneration; + const ui32 group = it->GroupID; + + const bool last = (++it == endIt); + const ui32 toGen = last ? Max<ui32>() : it->FromGeneration; + + if (toGen <= from.first) + continue; + + if (fromGen > to.first) + return; + + const bool lastGen = (to.first < toGen); + + const TLogoBlobID fromId(tabletId, from.first, from.second, 0, 0, 0); + const TLogoBlobID toId(tabletId, lastGen ? to.first : toGen - 1, lastGen ? to.second : Max<ui32>(), 0, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie); + + SendToBSProxy(SelfId(), group, new TEvBlobStorage::TEvRange(tabletId, fromId, toId, mustRestoreFirst, TInstant::Max(), false, BlockedGen)); + RangesToDiscover.insert(toId); if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TOnDiscoverRangeRequest>(group, fromId, toId)); } - - if (lastGen) - return; - - from = std::make_pair(toGen, 0); - } while (it != endIt); - } - - void ProcessKeyEntry(const TLogoBlobID &id, const TString &logBody) { - NKikimrTabletBase::TTabletLogEntry logEntry; + + if (lastGen) + return; + + from = std::make_pair(toGen, 0); + } while (it != endIt); + } + + void ProcessKeyEntry(const TLogoBlobID &id, const TString &logBody) { + NKikimrTabletBase::TTabletLogEntry logEntry; if (!logEntry.ParseFromString(logBody)) { - BLOG_ERROR("TTabletReqRebuildHistoryGraph::ProcessKeyEntry logBody ParseFromString error, id# " << id); + BLOG_ERROR("TTabletReqRebuildHistoryGraph::ProcessKeyEntry logBody ParseFromString error, id# " << id); if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TErrorParsingFromString>(id)); } - return ReplyAndDie(NKikimrProto::ERROR, "Log entry parse failed"); + return ReplyAndDie(NKikimrProto::ERROR, "Log entry parse failed"); } - + LatestKnownStep = std::pair<ui32, ui32>(id.Generation(), id.Step()); - Snapshot = ExpandGenStepPair(logEntry.GetSnapshot()); - - BLOG_D("TTabletReqRebuildHistoryGraph::ProcessKeyEntry, LastBlobID: " << id.ToString() - << " Snap: " << Snapshot.first << ":" << Snapshot.second - << " for " << Info->TabletID); - - const bool isZeroStep = id.Step() == 0; - const bool isSynthEntry = id.Cookie() != 0; - - ui32 lastGen = 0; - ui32 lastStep = 0; - - if (isZeroStep) { + Snapshot = ExpandGenStepPair(logEntry.GetSnapshot()); + + BLOG_D("TTabletReqRebuildHistoryGraph::ProcessKeyEntry, LastBlobID: " << id.ToString() + << " Snap: " << Snapshot.first << ":" << Snapshot.second + << " for " << Info->TabletID); + + const bool isZeroStep = id.Step() == 0; + const bool isSynthEntry = id.Cookie() != 0; + + ui32 lastGen = 0; + ui32 lastStep = 0; + + if (isZeroStep) { Confirmed = std::pair<ui32, ui32>(LatestKnownStep.first, 0); - - ProcessZeroEntry(id.Generation(), logEntry); + + ProcessZeroEntry(id.Generation(), logEntry); lastGen = LatestKnownStep.first; lastStep = 0; - } else { + } else { Confirmed = std::pair<ui32, ui32>(LatestKnownStep.first, logEntry.GetConfirmed()); - - ProcessLogEntry(id, logEntry); - lastGen = LatestKnownStep.first; - lastStep = isSynthEntry ? (LatestKnownStep.second) : (LatestKnownStep.second - 1); - - TGenerationEntry &gx = GenerationInfo(lastGen); - + + ProcessLogEntry(id, logEntry); + lastGen = LatestKnownStep.first; + lastStep = isSynthEntry ? (LatestKnownStep.second) : (LatestKnownStep.second - 1); + + TGenerationEntry &gx = GenerationInfo(lastGen); + for (ui32 i = gx.Base, e = Confirmed.second; i <= e; ++i) - gx.Entry(i).BecomeConfirmed(); - } - - // request snapshot to confirmed range - if (Confirmed.first) - DiscoverRange(Snapshot, Confirmed, false); - + gx.Entry(i).BecomeConfirmed(); + } + + // request snapshot to confirmed range + if (Confirmed.first) + DiscoverRange(Snapshot, Confirmed, false); + if (FollowerCookie == 0) { - if (lastGen != Confirmed.first || lastStep != Confirmed.second) - DiscoverRange({ Confirmed.first, Confirmed.second + 1 }, { lastGen, lastStep }, true); - } - - Become(&TThis::StateReadLog); - } - - void ApplyDiscoveryRange(TEvBlobStorage::TEvRangeResult *msg) { + if (lastGen != Confirmed.first || lastStep != Confirmed.second) + DiscoverRange({ Confirmed.first, Confirmed.second + 1 }, { lastGen, lastStep }, true); + } + + Become(&TThis::StateReadLog); + } + + void ApplyDiscoveryRange(TEvBlobStorage::TEvRangeResult *msg) { if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TOnApplyDiscoveryRange>(msg->GroupId, msg->From, msg->To)); } Y_VERIFY(RangesToDiscover.erase(msg->To)); for (TVector<TEvBlobStorage::TEvRangeResult::TResponse>::iterator it = msg->Responses.begin(), end = msg->Responses.end(); it != end; ++it) { - const TLogoBlobID &id = it->Id; - + const TLogoBlobID &id = it->Id; + GroupReadBytes[std::make_pair(id.Channel(), msg->GroupId)] += it->Buffer.size(); GroupReadOps[std::make_pair(id.Channel(), msg->GroupId)] += 1; - NKikimrTabletBase::TTabletLogEntry logEntry; + NKikimrTabletBase::TTabletLogEntry logEntry; if (!logEntry.ParseFromString(it->Buffer)) { - BLOG_ERROR("TTabletReqRebuildHistoryGraph::ApplyDiscoveryRange it->Buffer ParseFromString error, id# " << id); - return ReplyAndDie(NKikimrProto::ERROR, "Log entry parse failed"); + BLOG_ERROR("TTabletReqRebuildHistoryGraph::ApplyDiscoveryRange it->Buffer ParseFromString error, id# " << id); + return ReplyAndDie(NKikimrProto::ERROR, "Log entry parse failed"); } - - const bool isZeroStep = (id.Step() == 0); - if (isZeroStep) { - ProcessZeroEntry(id.Generation(), logEntry); - } else { - ProcessLogEntry(id, logEntry); - } - } - } - - void MakeHistory() { - if (!RebuildGenSequenceByZeroEntries()) { - return ReplyAndDie(NKikimrProto::ERROR, "RebuildGenSequenceByZeroEntries failed"); - } - - ScanRefsToCheck(); + + const bool isZeroStep = (id.Step() == 0); + if (isZeroStep) { + ProcessZeroEntry(id.Generation(), logEntry); + } else { + ProcessLogEntry(id, logEntry); + } + } + } + + void MakeHistory() { + if (!RebuildGenSequenceByZeroEntries()) { + return ReplyAndDie(NKikimrProto::ERROR, "RebuildGenSequenceByZeroEntries failed"); + } + + ScanRefsToCheck(); if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TOnMakeHistory>(RefsToCheck)); } - if (RefsToCheckByGroup.empty()) - return BuildHistory(); - - for (auto &xpair : RefsToCheckByGroup) { - if (!SendRefsCheck(xpair.second, xpair.first)) { - BLOG_ERROR("TTabletReqRebuildHistoryGraph::MakeHistory SendRefsCheck A error"); + if (RefsToCheckByGroup.empty()) + return BuildHistory(); + + for (auto &xpair : RefsToCheckByGroup) { + if (!SendRefsCheck(xpair.second, xpair.first)) { + BLOG_ERROR("TTabletReqRebuildHistoryGraph::MakeHistory SendRefsCheck A error"); if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TErrorSendRefsCheck>()); } - return ReplyAndDie(NKikimrProto::ERROR, "SendRefsCheck failed"); + return ReplyAndDie(NKikimrProto::ERROR, "SendRefsCheck failed"); } - } - - RefsToCheckByGroup.clear(); - Become(&TThis::StateCheckReferences); - } - - bool SendRefsCheck(const TVector<TLogoBlobID> &refs, ui32 group) { - if (refs.empty()) - return true; - + } + + RefsToCheckByGroup.clear(); + Become(&TThis::StateCheckReferences); + } + + bool SendRefsCheck(const TVector<TLogoBlobID> &refs, ui32 group) { + if (refs.empty()) + return true; + ui64 endIdx = refs.size(); ui64 firstRequestIdx = 0; while(firstRequestIdx < endIdx) { @@ -509,10 +509,10 @@ class TTabletReqRebuildHistoryGraph : public TActorBootstrapped<TTabletReqRebuil for (ui64 i = firstRequestIdx; i != endIdx; ++i) { ui64 size = refs[i].BlobSize(); Y_VERIFY(size != 0); - + const ui64 replyDataSize = totalSize + size + NKikimr::BlobProtobufHeaderMaxSize; - if (replyDataSize <= NKikimr::MaxProtobufSize) { - totalSize += size + NKikimr::BlobProtobufHeaderMaxSize; + if (replyDataSize <= NKikimr::MaxProtobufSize) { + totalSize += size + NKikimr::BlobProtobufHeaderMaxSize; } else { endRequestIdx = i; break; @@ -526,395 +526,395 @@ class TTabletReqRebuildHistoryGraph : public TActorBootstrapped<TTabletReqRebuil for (ui64 i = 0; i < count; ++i) { q[i].Set(refs[i + firstRequestIdx] /*must be index read*/); } - SendToBSProxy(SelfId(), group, new TEvBlobStorage::TEvGet(q, (ui32)count, TInstant::Max(), - NKikimrBlobStorage::EGetHandleClass::FastRead, true, true, BlockedGen)); + SendToBSProxy(SelfId(), group, new TEvBlobStorage::TEvGet(q, (ui32)count, TInstant::Max(), + NKikimrBlobStorage::EGetHandleClass::FastRead, true, true, BlockedGen)); ++RequestsLeft; firstRequestIdx = endRequestIdx; - } - - return true; - } - - void ScanRefsToCheck() { + } + + return true; + } + + void ScanRefsToCheck() { if (LatestKnownStep.first != Confirmed.first) - return; - + return; + const ui32 tailGeneration = LatestKnownStep.first; - TGenerationEntry *gx = LogInfo.FindPtr(tailGeneration); - if (!gx) - return; - - const ui64 tabletId = Info->TabletID; - - for (i64 pi = gx->Body.size() - 1; pi >= 0; --pi) { - const ui32 step = gx->Base + (ui32)pi; + TGenerationEntry *gx = LogInfo.FindPtr(tailGeneration); + if (!gx) + return; + + const ui64 tabletId = Info->TabletID; + + for (i64 pi = gx->Body.size() - 1; pi >= 0; --pi) { + const ui32 step = gx->Base + (ui32)pi; if (step <= Confirmed.second) - break; - TLogEntry &entry = gx->Entry(step); - - if (entry.Status == TLogEntry::StatusBody) { - for (TLogoBlobID &ref : entry.References) { - if (ref.TabletID() != tabletId) - continue; - - const ui32 group = Info->GroupFor(ref.Channel(), ref.Generation()); - RefsToCheckByGroup[group].push_back(ref); - RefsToCheck.insert(ref); - } - } - } - } - - void CheckReferences(TEvBlobStorage::TEvGetResult *msg) { + break; + TLogEntry &entry = gx->Entry(step); + + if (entry.Status == TLogEntry::StatusBody) { + for (TLogoBlobID &ref : entry.References) { + if (ref.TabletID() != tabletId) + continue; + + const ui32 group = Info->GroupFor(ref.Channel(), ref.Generation()); + RefsToCheckByGroup[group].push_back(ref); + RefsToCheck.insert(ref); + } + } + } + } + + void CheckReferences(TEvBlobStorage::TEvGetResult *msg) { if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TOnCheckRefsGetResult>(msg->ResponseSz)); } Y_VERIFY_DEBUG(msg->Status == NKikimrProto::OK); - - for (ui32 i = 0, e = msg->ResponseSz; i != e; ++i) { - const TEvBlobStorage::TEvGetResult::TResponse &response = msg->Responses[i]; - switch (response.Status) { - case NKikimrProto::OK: + + for (ui32 i = 0, e = msg->ResponseSz; i != e; ++i) { + const TEvBlobStorage::TEvGetResult::TResponse &response = msg->Responses[i]; + switch (response.Status) { + case NKikimrProto::OK: Y_VERIFY(1 == RefsToCheck.erase(response.Id)); GroupReadBytes[std::make_pair(response.Id.Channel(), msg->GroupId)] += response.Buffer.size(); GroupReadOps[std::make_pair(response.Id.Channel(), msg->GroupId)] += 1; - break; - case NKikimrProto::NODATA: - BLOG_W("TTabletReqRebuildHistoryGraph::CheckReferences - NODATA for blob " << response.Id); - break; // must left as unchecked - default: - BLOG_ERROR("TTabletReqRebuildHistoryGraph::CheckReferences - blob " << response.Id + break; + case NKikimrProto::NODATA: + BLOG_W("TTabletReqRebuildHistoryGraph::CheckReferences - NODATA for blob " << response.Id); + break; // must left as unchecked + default: + BLOG_ERROR("TTabletReqRebuildHistoryGraph::CheckReferences - blob " << response.Id << " Status# " << NKikimrProto::EReplyStatus_Name(response.Status)); if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TErrorUnknownStatus>(response.Status, msg->ErrorReason)); } - return ReplyAndDie(NKikimrProto::ERROR, msg->ErrorReason); - } - } - - --RequestsLeft; - if (RequestsLeft == 0) - return BuildHistory(); - } - - void BuildHistory() { - TAutoPtr<TEvTablet::TDependencyGraph> graph(new TEvTablet::TDependencyGraph(Snapshot)); - + return ReplyAndDie(NKikimrProto::ERROR, msg->ErrorReason); + } + } + + --RequestsLeft; + if (RequestsLeft == 0) + return BuildHistory(); + } + + void BuildHistory() { + TAutoPtr<TEvTablet::TDependencyGraph> graph(new TEvTablet::TDependencyGraph(Snapshot)); + std::pair<ui32, ui32> invalidLogEntry = std::make_pair(Max<ui32>(), Max<ui32>()); ui32 lastUnbrokenTailEntry = Confirmed.second; for (TMap<ui32, TGenerationEntry>::iterator gen = LogInfo.begin(), egen = LogInfo.end();;) { - const ui32 generation = gen->first; - TGenerationEntry &gx = gen->second; + const ui32 generation = gen->first; + TGenerationEntry &gx = gen->second; const bool isTailGeneration = LatestKnownStep.first == generation && Confirmed.first == generation; - bool hasSnapshotInGeneration = (generation == 0); - - BLOG_D("TTabletReqRebuildHistoryGraph::BuildHistory - Process generation " << generation - << " from " << (ui32)gx.Base << " with " << gx.Body.size() << " steps"); - + bool hasSnapshotInGeneration = (generation == 0); + + BLOG_D("TTabletReqRebuildHistoryGraph::BuildHistory - Process generation " << generation + << " from " << (ui32)gx.Base << " with " << gx.Body.size() << " steps"); + for (ui32 i = 0, e = (ui32)gx.Body.size(); i != e; ++i) { - const ui32 step = gx.Base + i; + const ui32 step = gx.Base + i; const bool isTail = isTailGeneration && step > Confirmed.second; - ui32 generationSnapshotStep = 0; - - TLogEntry &entry = gx.Entry(step); + ui32 generationSnapshotStep = 0; + + TLogEntry &entry = gx.Entry(step); std::pair<ui32, ui32> id(generation, step); - - if (isTail) { + + if (isTail) { // Ignore unconfirmed commits on followers if (FollowerCookie != 0) { break; } - switch (entry.Status) { - case TLogEntry::StatusUnknown: - break; - case TLogEntry::StatusOk: + switch (entry.Status) { + case TLogEntry::StatusUnknown: + break; + case TLogEntry::StatusOk: Y_FAIL(); - case TLogEntry::StatusBody: - { - bool dependsOk = true; + case TLogEntry::StatusBody: + { + bool dependsOk = true; for (TVector<ui32>::const_iterator it = entry.DependsOn.begin(), end = entry.DependsOn.end(); dependsOk && it != end; ++it) { - const ui32 x = *it; - Y_VERIFY(x < step, "depends on future step %" PRIu32 " from %" PRIu32 ":%" PRIu32, x, generation, step); - dependsOk = x < gx.Base || x <= Confirmed.second || gx.Entry(x).Status == TLogEntry::StatusOk || x <= generationSnapshotStep; - } - - bool refsOk = true; + const ui32 x = *it; + Y_VERIFY(x < step, "depends on future step %" PRIu32 " from %" PRIu32 ":%" PRIu32, x, generation, step); + dependsOk = x < gx.Base || x <= Confirmed.second || gx.Entry(x).Status == TLogEntry::StatusOk || x <= generationSnapshotStep; + } + + bool refsOk = true; for (TVector<TLogoBlobID>::const_iterator it = entry.References.begin(), end = entry.References.end(); refsOk && it != end; ++it) { - const TLogoBlobID &x = *it; + const TLogoBlobID &x = *it; refsOk = !RefsToCheck.contains(x); - } - - const bool snapOk = entry.IsTotalSnapshot || (entry.IsSnapshot && (id.second == lastUnbrokenTailEntry + 1)); - const bool satisfied = refsOk && (snapOk || dependsOk); - - if (satisfied) { - entry.Status = TLogEntry::StatusOk; - - LOG_DEBUG(*TlsActivationContext, NKikimrServices::TABLET_MAIN, [&](){ + } + + const bool snapOk = entry.IsTotalSnapshot || (entry.IsSnapshot && (id.second == lastUnbrokenTailEntry + 1)); + const bool satisfied = refsOk && (snapOk || dependsOk); + + if (satisfied) { + entry.Status = TLogEntry::StatusOk; + + LOG_DEBUG(*TlsActivationContext, NKikimrServices::TABLET_MAIN, [&](){ TStringBuilder sb; - sb << "TTabletReqRebuildHistoryGraph::BuildHistory - THE TAIL - "; + sb << "TTabletReqRebuildHistoryGraph::BuildHistory - THE TAIL - "; sb << "References: ["; - for (auto&& t : entry.References) - sb << t.ToString() << ","; - sb << "] for " << Info->TabletID; - - if (entry.GcDiscovered) { - sb << ", Gc+: ["; - for (auto&& t : entry.GcDiscovered) - sb << t.ToString() << ","; - sb << "]"; - } - - if (entry.GcLeft) { - sb << ", Gc-: ["; - for (auto&& t : entry.GcLeft) - sb << t.ToString() << ","; - sb << "]"; - } - + for (auto&& t : entry.References) + sb << t.ToString() << ","; + sb << "] for " << Info->TabletID; + + if (entry.GcDiscovered) { + sb << ", Gc+: ["; + for (auto&& t : entry.GcDiscovered) + sb << t.ToString() << ","; + sb << "]"; + } + + if (entry.GcLeft) { + sb << ", Gc-: ["; + for (auto&& t : entry.GcLeft) + sb << t.ToString() << ","; + sb << "]"; + } + return (TString) sb; }()); - if (entry.EmbeddedLogBody) - graph->AddEntry(id, entry.EmbeddedLogBody, entry.GcDiscovered, entry.GcLeft); - else - graph->AddEntry(id, entry.References, entry.IsSnapshot, entry.GcDiscovered, entry.GcLeft); - + if (entry.EmbeddedLogBody) + graph->AddEntry(id, entry.EmbeddedLogBody, entry.GcDiscovered, entry.GcLeft); + else + graph->AddEntry(id, entry.References, entry.IsSnapshot, entry.GcDiscovered, entry.GcLeft); + if (lastUnbrokenTailEntry + 1 == id.second) lastUnbrokenTailEntry = id.second; - - if (entry.IsSnapshot) { - generationSnapshotStep = step; - hasSnapshotInGeneration = true; - } - } else { - BLOG_D("TTabletReqRebuildHistoryGraph::BuildHistory - THE TAIL - miss " << id.first << ":" << id.second); - } - } - break; - default: + + if (entry.IsSnapshot) { + generationSnapshotStep = step; + hasSnapshotInGeneration = true; + } + } else { + BLOG_D("TTabletReqRebuildHistoryGraph::BuildHistory - THE TAIL - miss " << id.first << ":" << id.second); + } + } + break; + default: Y_FAIL(); - } - } else { - if (step <= gx.Cutoff) { - switch (entry.Status) { - case TLogEntry::StatusOk: + } + } else { + if (step <= gx.Cutoff) { + switch (entry.Status) { + case TLogEntry::StatusOk: - LOG_DEBUG(*TlsActivationContext, NKikimrServices::TABLET_MAIN, [&](){ + LOG_DEBUG(*TlsActivationContext, NKikimrServices::TABLET_MAIN, [&](){ TStringBuilder sb; - sb << "TTabletReqRebuildHistoryGraph::BuildHistory - NOT A TAIL - "; + sb << "TTabletReqRebuildHistoryGraph::BuildHistory - NOT A TAIL - "; sb << "References: ["; for (auto&& t : entry.References) { sb << t.ToString(); sb << ","; } - sb << "] for " << Info->TabletID; + sb << "] for " << Info->TabletID; return (TString) sb; }()); - if (entry.EmbeddedLogBody) - graph->AddEntry(id, entry.EmbeddedLogBody, entry.GcDiscovered, entry.GcLeft); - else - graph->AddEntry(id, entry.References, entry.IsSnapshot, entry.GcDiscovered, entry.GcLeft); - - hasSnapshotInGeneration |= entry.IsSnapshot; - break; - case TLogEntry::StatusMustBeIgnored: - case TLogEntry::StatusMustBeIgnoredBody: - break; - default: - graph->Invalidate(); - invalidLogEntry = id; - break; - } - } - } - } - - if (!hasSnapshotInGeneration && !gx.HasZeroEntry) { - graph->Invalidate(); - if (invalidLogEntry.first < generation) + if (entry.EmbeddedLogBody) + graph->AddEntry(id, entry.EmbeddedLogBody, entry.GcDiscovered, entry.GcLeft); + else + graph->AddEntry(id, entry.References, entry.IsSnapshot, entry.GcDiscovered, entry.GcLeft); + + hasSnapshotInGeneration |= entry.IsSnapshot; + break; + case TLogEntry::StatusMustBeIgnored: + case TLogEntry::StatusMustBeIgnoredBody: + break; + default: + graph->Invalidate(); + invalidLogEntry = id; + break; + } + } + } + } + + if (!hasSnapshotInGeneration && !gx.HasZeroEntry) { + graph->Invalidate(); + if (invalidLogEntry.first < generation) invalidLogEntry = std::make_pair(generation, 0); - } - - if (gx.NextGeneration == 0) { - ++gen; - if (gen == egen) - break; - - graph->Invalidate(); + } + + if (gx.NextGeneration == 0) { + ++gen; + if (gen == egen) + break; + + graph->Invalidate(); invalidLogEntry = std::make_pair(generation, Max<ui32>()); - } else { - gen = LogInfo.find(gx.NextGeneration); + } else { + gen = LogInfo.find(gx.NextGeneration); Y_VERIFY(gen != egen); - } - } - - if (!graph->IsValid()) { - LOG_ALERT(*TlsActivationContext, NKikimrServices::TABLET_MAIN, [&]() { - TStringBuilder sb; - sb << "TTabletReqRebuildHistoryGraph::BuildHistory - Graph rebuild error - no Log entry for "; + } + } + + if (!graph->IsValid()) { + LOG_ALERT(*TlsActivationContext, NKikimrServices::TABLET_MAIN, [&]() { + TStringBuilder sb; + sb << "TTabletReqRebuildHistoryGraph::BuildHistory - Graph rebuild error - no Log entry for "; sb << Info->TabletID << ":" << invalidLogEntry.first << ":" << invalidLogEntry.second; return (TString)sb; - }()); + }()); if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TErrorRebuildGraph>(invalidLogEntry.first, invalidLogEntry.second)); } - - return ReplyAndDie(NKikimrProto::ERROR, "Graph has missing log entries"); - } + + return ReplyAndDie(NKikimrProto::ERROR, "Graph has missing log entries"); + } if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TOnBuildHistoryGraph>(graph.Get())); } - - Send(Owner, new TEvTabletBase::TEvRebuildGraphResult( - graph.Release(), - std::move(GroupReadBytes), - std::move(GroupReadOps), - IntrospectionTrace.Release()), + + Send(Owner, new TEvTabletBase::TEvRebuildGraphResult( + graph.Release(), + std::move(GroupReadBytes), + std::move(GroupReadOps), + IntrospectionTrace.Release()), 0, FollowerCookie); - - PassAway(); - } - - void Handle(TEvents::TEvUndelivered::TPtr&) { - return ReplyAndDie(NKikimrProto::ERROR, "BlobStorage proxy unavailable"); + + PassAway(); + } + + void Handle(TEvents::TEvUndelivered::TPtr&) { + return ReplyAndDie(NKikimrProto::ERROR, "BlobStorage proxy unavailable"); } - void Handle(TEvTabletBase::TEvFindLatestLogEntryResult::TPtr &ev) { - TEvTabletBase::TEvFindLatestLogEntryResult *msg = ev->Get(); - - switch (msg->Status) { - case NKikimrProto::OK: + void Handle(TEvTabletBase::TEvFindLatestLogEntryResult::TPtr &ev) { + TEvTabletBase::TEvFindLatestLogEntryResult *msg = ev->Get(); + + switch (msg->Status) { + case NKikimrProto::OK: if (FollowerCookie == 0 && msg->Latest.Generation() > BlockedGen) { - BLOG_ERROR("TTabletReqRebuildHistoryGraph - Found entry beyond blocked generation" + BLOG_ERROR("TTabletReqRebuildHistoryGraph - Found entry beyond blocked generation" << " LastBlobID: " << msg->Latest.ToString() << ". Blocked: " << BlockedGen); if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TErrorEntryBeyondBlocked>(msg->Latest, BlockedGen)); } - return ReplyAndDie(NKikimrProto::ERROR, "Found entry beyond blocked generation"); - } - + return ReplyAndDie(NKikimrProto::ERROR, "Found entry beyond blocked generation"); + } + if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TOnProcessKeyEntry>(msg->Latest)); } - - return ProcessKeyEntry(msg->Latest, msg->Buffer); + + return ProcessKeyEntry(msg->Latest, msg->Buffer); case NKikimrProto::RACE: - case NKikimrProto::NODATA: - return ReplyAndDie(msg->Status, msg->ErrorReason); // valid condition, nothing known in blob-storage - default: - BLOG_ERROR("TTabletReqRebuildHistoryGraph::Handle TEvFindLatestLogEntryResult" + case NKikimrProto::NODATA: + return ReplyAndDie(msg->Status, msg->ErrorReason); // valid condition, nothing known in blob-storage + default: + BLOG_ERROR("TTabletReqRebuildHistoryGraph::Handle TEvFindLatestLogEntryResult" << " Status# " << NKikimrProto::EReplyStatus_Name(msg->Status)); if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TErrorUnknownStatus>(msg->Status, msg->ErrorReason)); } - return ReplyAndDie(NKikimrProto::ERROR, msg->ErrorReason); - } - } - - void Handle(TEvBlobStorage::TEvRangeResult::TPtr &ev) { - TEvBlobStorage::TEvRangeResult *msg = ev->Get(); - - switch (msg->Status) { - case NKikimrProto::OK: - ApplyDiscoveryRange(msg); - break; - case NKikimrProto::RACE: - return ReplyAndDie(NKikimrProto::RACE, msg->ErrorReason); - default: - BLOG_ERROR("TTabletReqRebuildHistoryGraph::HandleDiscover TEvRangeResult" + return ReplyAndDie(NKikimrProto::ERROR, msg->ErrorReason); + } + } + + void Handle(TEvBlobStorage::TEvRangeResult::TPtr &ev) { + TEvBlobStorage::TEvRangeResult *msg = ev->Get(); + + switch (msg->Status) { + case NKikimrProto::OK: + ApplyDiscoveryRange(msg); + break; + case NKikimrProto::RACE: + return ReplyAndDie(NKikimrProto::RACE, msg->ErrorReason); + default: + BLOG_ERROR("TTabletReqRebuildHistoryGraph::HandleDiscover TEvRangeResult" << " Status# " << NKikimrProto::EReplyStatus_Name(msg->Status) << " Result# " << msg->Print(false)); if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TErrorUnknownStatus>(msg->Status, msg->ErrorReason)); } - return ReplyAndDie(NKikimrProto::ERROR, msg->ErrorReason); - } - - if (!RangesToDiscover.empty()) - return; - - MakeHistory(); - } - - void Handle(TEvBlobStorage::TEvGetResult::TPtr &ev) { - TEvBlobStorage::TEvGetResult *msg = ev->Get(); - - switch (msg->Status) { - case NKikimrProto::OK: - return CheckReferences(msg); - case NKikimrProto::RACE: - return ReplyAndDie(NKikimrProto::RACE, msg->ErrorReason); - default: - BLOG_ERROR("TTabletReqRebuildHistoryGraph::Handle TEvGetResult" + return ReplyAndDie(NKikimrProto::ERROR, msg->ErrorReason); + } + + if (!RangesToDiscover.empty()) + return; + + MakeHistory(); + } + + void Handle(TEvBlobStorage::TEvGetResult::TPtr &ev) { + TEvBlobStorage::TEvGetResult *msg = ev->Get(); + + switch (msg->Status) { + case NKikimrProto::OK: + return CheckReferences(msg); + case NKikimrProto::RACE: + return ReplyAndDie(NKikimrProto::RACE, msg->ErrorReason); + default: + BLOG_ERROR("TTabletReqRebuildHistoryGraph::Handle TEvGetResult" << " Status# " << NKikimrProto::EReplyStatus_Name(msg->Status) << " Result# " << msg->Print(false)); if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TErrorUnknownStatus>(msg->Status, msg->ErrorReason)); } - return ReplyAndDie(NKikimrProto::ERROR, msg->ErrorReason); - } - } - -public: + return ReplyAndDie(NKikimrProto::ERROR, msg->ErrorReason); + } + } + +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TABLET_REQ_REBUILD_GRAPH; } TTabletReqRebuildHistoryGraph(const TActorId &owner, TTabletStorageInfo *info, ui32 blockedGen, NTracing::ITrace *trace, ui64 followerCookie) - : Owner(owner) - , Info(info) - , BlockedGen(blockedGen) - , RequestsLeft(0) + : Owner(owner) + , Info(info) + , BlockedGen(blockedGen) + , RequestsLeft(0) , IntrospectionTrace(trace) , FollowerCookie(followerCookie) {} - - void Bootstrap() { + + void Bootstrap() { if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TRebuildGraphBootstrap>(BlockedGen)); } if (FollowerCookie == 0) - Register(CreateTabletFindLastEntry(SelfId(), true, Info.Get(), BlockedGen)); - else - Register(CreateTabletFindLastEntry(SelfId(), true, Info.Get(), 0)); - - Become(&TThis::StateWaitLatestEntry); - } - - STATEFN(StateWaitLatestEntry) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvTabletBase::TEvFindLatestLogEntryResult, Handle); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); - } - } - - STATEFN(StateReadLog) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvBlobStorage::TEvRangeResult, Handle); - hFunc(TEvents::TEvUndelivered, Handle); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); - } - } - - STATEFN(StateCheckReferences) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvBlobStorage::TEvGetResult, Handle); - hFunc(TEvents::TEvUndelivered, Handle); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); - } - } -}; - + Register(CreateTabletFindLastEntry(SelfId(), true, Info.Get(), BlockedGen)); + else + Register(CreateTabletFindLastEntry(SelfId(), true, Info.Get(), 0)); + + Become(&TThis::StateWaitLatestEntry); + } + + STATEFN(StateWaitLatestEntry) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvTabletBase::TEvFindLatestLogEntryResult, Handle); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + } + } + + STATEFN(StateReadLog) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvBlobStorage::TEvRangeResult, Handle); + hFunc(TEvents::TEvUndelivered, Handle); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + } + } + + STATEFN(StateCheckReferences) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvBlobStorage::TEvGetResult, Handle); + hFunc(TEvents::TEvUndelivered, Handle); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + } + } +}; + IActor* CreateTabletReqRebuildHistoryGraph(const TActorId &owner, TTabletStorageInfo *info, ui32 blockedGen, NTracing::ITrace *trace, ui64 followerCookie) { return new TTabletReqRebuildHistoryGraph(owner, info, blockedGen, trace, followerCookie); -} - - -} +} + + +} diff --git a/ydb/core/tablet/tablet_req_reset.cpp b/ydb/core/tablet/tablet_req_reset.cpp index c57f95b806..b73c68c120 100644 --- a/ydb/core/tablet/tablet_req_reset.cpp +++ b/ydb/core/tablet/tablet_req_reset.cpp @@ -43,20 +43,20 @@ class TTabletReqReset : public TActorBootstrapped<TTabletReqReset> { } void BlockBlobStorage(const TActorContext& ctx) { - ctx.Register(CreateTabletReqBlockBlobStorage(ctx.SelfID, TabletStorageInfo.Get(), Generation, false)); + ctx.Register(CreateTabletReqBlockBlobStorage(ctx.SelfID, TabletStorageInfo.Get(), Generation, false)); Become(&TTabletReqReset::StateBlockBlobStorage); } void Handle(TEvTabletBase::TEvBlockBlobStorageResult::TPtr& ev, const TActorContext& ctx) { if (ev->Get()->Status == NKikimrProto::RACE) { ++Generation; - ctx.Register(CreateTabletReqBlockBlobStorage(ctx.SelfID, TabletStorageInfo.Get(), Generation, false)); + ctx.Register(CreateTabletReqBlockBlobStorage(ctx.SelfID, TabletStorageInfo.Get(), Generation, false)); return; } if (ev->Get()->Status != NKikimrProto::OK) { return ReplyAndDie(ev->Get()->Status, ctx); } - TTablet::ExternalWriteZeroEntry(TabletStorageInfo.Get(), Generation + 1, SelfId()); + TTablet::ExternalWriteZeroEntry(TabletStorageInfo.Get(), Generation + 1, SelfId()); Become(&TTabletReqReset::StateWriteZeroEntry); } diff --git a/ydb/core/tablet/tablet_req_writelog.cpp b/ydb/core/tablet/tablet_req_writelog.cpp index def4adf504..7c4d02c405 100644 --- a/ydb/core/tablet/tablet_req_writelog.cpp +++ b/ydb/core/tablet/tablet_req_writelog.cpp @@ -1,37 +1,37 @@ -#include "tablet_impl.h" +#include "tablet_impl.h" #include <ydb/core/base/blobstorage.h> #include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/actors/core/hfunc.h> #include <ydb/core/tablet/tablet_metrics.h> - + #include <util/random/random.h> -namespace NKikimr { - -class TTabletReqWriteLog : public TActorBootstrapped<TTabletReqWriteLog> { +namespace NKikimr { + +class TTabletReqWriteLog : public TActorBootstrapped<TTabletReqWriteLog> { const TActorId Owner; - const TLogoBlobID LogEntryID; - TAutoPtr<NKikimrTabletBase::TTabletLogEntry> LogEntry; + const TLogoBlobID LogEntryID; + TAutoPtr<NKikimrTabletBase::TTabletLogEntry> LogEntry; TVector<TEvTablet::TLogEntryReference> References; - const TEvBlobStorage::TEvPut::ETactic CommitTactic; - - TIntrusivePtr<TTabletStorageInfo> Info; + const TEvBlobStorage::TEvPut::ETactic CommitTactic; + + TIntrusivePtr<TTabletStorageInfo> Info; NMetrics::TTabletThroughputRawValue GroupWrittenBytes; NMetrics::TTabletIopsRawValue GroupWrittenOps; - + ui64 RequestCookies = 0; ui64 ResponseCookies = 0; - ui32 RepliesToWait; + ui32 RepliesToWait; TVector<ui32> YellowMoveChannels; TVector<ui32> YellowStopChannels; - + void Handle(TEvents::TEvUndelivered::TPtr&, const TActorContext &ctx) { return ReplyAndDie(NKikimrProto::ERROR, "BlobStorage proxy unavailable", ctx); } - void Handle(TEvBlobStorage::TEvPutResult::TPtr &ev, const TActorContext &ctx) { - TEvBlobStorage::TEvPutResult *msg = ev->Get(); + void Handle(TEvBlobStorage::TEvPutResult::TPtr &ev, const TActorContext &ctx) { + TEvBlobStorage::TEvPutResult *msg = ev->Get(); if (msg->StatusFlags.Check(NKikimrBlobStorage::StatusDiskSpaceLightYellowMove)) { YellowMoveChannels.push_back(msg->Id.Channel()); @@ -40,8 +40,8 @@ class TTabletReqWriteLog : public TActorBootstrapped<TTabletReqWriteLog> { YellowStopChannels.push_back(msg->Id.Channel()); } - switch (msg->Status) { - case NKikimrProto::OK: + switch (msg->Status) { + case NKikimrProto::OK: LOG_DEBUG_S(ctx, NKikimrServices::TABLET_MAIN, "Put Result: " << msg->Print(false)); GroupWrittenBytes[std::make_pair(msg->Id.Channel(), msg->GroupId)] += msg->Id.BlobSize(); @@ -56,16 +56,16 @@ class TTabletReqWriteLog : public TActorBootstrapped<TTabletReqWriteLog> { return ReplyAndDie(NKikimrProto::OK, { }, ctx); } - - return; - case NKikimrProto::RACE: // TODO: must be handled with retry - case NKikimrProto::BLOCKED: + + return; + case NKikimrProto::RACE: // TODO: must be handled with retry + case NKikimrProto::BLOCKED: return ReplyAndDie(NKikimrProto::BLOCKED, msg->ErrorReason, ctx); - default: + default: return ReplyAndDie(NKikimrProto::ERROR, msg->ErrorReason, ctx); - } - } - + } + } + void ReplyAndDie(NKikimrProto::EReplyStatus status, const TString &reason, const TActorContext &ctx) { if (YellowMoveChannels) { SortUnique(YellowMoveChannels); @@ -82,74 +82,74 @@ class TTabletReqWriteLog : public TActorBootstrapped<TTabletReqWriteLog> { std::move(GroupWrittenBytes), std::move(GroupWrittenOps), reason)); - Die(ctx); - } - + Die(ctx); + } + void SendToBS(const TLogoBlobID &id, const TString &buffer, const TActorContext &ctx, const NKikimrBlobStorage::EPutHandleClass handleClass) { Y_VERIFY(id.TabletID() == Info->TabletID); - const TTabletChannelInfo *channelInfo = Info->ChannelInfo(id.Channel()); + const TTabletChannelInfo *channelInfo = Info->ChannelInfo(id.Channel()); Y_VERIFY(channelInfo); - const TTabletChannelInfo::THistoryEntry *x = channelInfo->LatestEntry(); + const TTabletChannelInfo::THistoryEntry *x = channelInfo->LatestEntry(); Y_VERIFY(x->FromGeneration <= id.Generation()); ui64 cookie = RandomNumber<ui64>(); RequestCookies ^= cookie; SendPutToGroup(ctx, x->GroupID, Info.Get(), MakeHolder<TEvBlobStorage::TEvPut>(id, buffer, TInstant::Max(), handleClass, CommitTactic), cookie); - } - -public: + } + +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TABLET_REQ_WRITE_LOG; } TTabletReqWriteLog(const TActorId &owner, const TLogoBlobID &logid, NKikimrTabletBase::TTabletLogEntry *entry, TVector<TEvTablet::TLogEntryReference> &refs, TEvBlobStorage::TEvPut::ETactic commitTactic, TTabletStorageInfo *info) - : Owner(owner) - , LogEntryID(logid) - , LogEntry(entry) - , CommitTactic(commitTactic) - , Info(info) - , RepliesToWait(Max<ui32>()) - { - References.swap(refs); + : Owner(owner) + , LogEntryID(logid) + , LogEntry(entry) + , CommitTactic(commitTactic) + , Info(info) + , RepliesToWait(Max<ui32>()) + { + References.swap(refs); Y_VERIFY(Info); - } - - void Bootstrap(const TActorContext &ctx) { + } + + void Bootstrap(const TActorContext &ctx) { TString logEntryBuffer = LogEntry->SerializeAsString(); - - // todo: adaptive save-with-retry and timeouts - // todo: cancelation - - const auto handleClass = NKikimrBlobStorage::TabletLog; - for (const auto &ref : References) - SendToBS(ref.Id, ref.Buffer, ctx, handleClass); - - const TLogoBlobID actualLogEntryId = TLogoBlobID( - LogEntryID.TabletID(), - LogEntryID.Generation(), - LogEntryID.Step(), - LogEntryID.Channel(), + + // todo: adaptive save-with-retry and timeouts + // todo: cancelation + + const auto handleClass = NKikimrBlobStorage::TabletLog; + for (const auto &ref : References) + SendToBS(ref.Id, ref.Buffer, ctx, handleClass); + + const TLogoBlobID actualLogEntryId = TLogoBlobID( + LogEntryID.TabletID(), + LogEntryID.Generation(), + LogEntryID.Step(), + LogEntryID.Channel(), logEntryBuffer.size(), - LogEntryID.Cookie() - ); + LogEntryID.Cookie() + ); SendToBS(actualLogEntryId, logEntryBuffer, ctx, NKikimrBlobStorage::TabletLog); - - RepliesToWait = References.size() + 1; - Become(&TThis::StateWait); - } - - STFUNC(StateWait) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvBlobStorage::TEvPutResult, Handle); + + RepliesToWait = References.size() + 1; + Become(&TThis::StateWait); + } + + STFUNC(StateWait) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvBlobStorage::TEvPutResult, Handle); HFunc(TEvents::TEvUndelivered, Handle); - } - } -}; - + } + } +}; + IActor* CreateTabletReqWriteLog(const TActorId &owner, const TLogoBlobID &entryId, NKikimrTabletBase::TTabletLogEntry *entry, TVector<TEvTablet::TLogEntryReference> &refs, TEvBlobStorage::TEvPut::ETactic commitTactic, TTabletStorageInfo *info) { - return new TTabletReqWriteLog(owner, entryId, entry, refs, commitTactic, info); -} - -} + return new TTabletReqWriteLog(owner, entryId, entry, refs, commitTactic, info); +} + +} diff --git a/ydb/core/tablet/tablet_resolver.cpp b/ydb/core/tablet/tablet_resolver.cpp index b206261fe0..c0a39a2216 100644 --- a/ydb/core/tablet/tablet_resolver.cpp +++ b/ydb/core/tablet/tablet_resolver.cpp @@ -12,70 +12,70 @@ #include <library/cpp/actors/interconnect/interconnect.h> #include <ydb/core/util/cache.h> #include <ydb/core/util/queue_oneone_inplace.h> -#include <util/generic/map.h> -#include <util/generic/deque.h> - -namespace NKikimr { - -const TDuration TabletResolverNegativeCacheTimeout = TDuration::MilliSeconds(300); +#include <util/generic/map.h> +#include <util/generic/deque.h> + +namespace NKikimr { + +const TDuration TabletResolverNegativeCacheTimeout = TDuration::MilliSeconds(300); const TDuration TabletResolverRefreshNodesPeriod = TDuration::Seconds(60); - -class TTabletResolver : public TActorBootstrapped<TTabletResolver> { - struct TEvPrivate { - enum EEv { - EvPingTimeout = EventSpaceBegin(TEvents::ES_PRIVATE), - EvStopListRemoval, + +class TTabletResolver : public TActorBootstrapped<TTabletResolver> { + struct TEvPrivate { + enum EEv { + EvPingTimeout = EventSpaceBegin(TEvents::ES_PRIVATE), + EvStopListRemoval, EvRefreshNodes, - EvEnd - }; - - struct TEvPingTimeout : public TEventLocal<TEvPingTimeout, EvPingTimeout> { - const ui64 TabletID; - TSchedulerCookieHolder Cookie; - - TEvPingTimeout(ui64 tabletId, ISchedulerCookie *cookie) - : TabletID(tabletId) - , Cookie(cookie) - {} + EvEnd + }; + + struct TEvPingTimeout : public TEventLocal<TEvPingTimeout, EvPingTimeout> { + const ui64 TabletID; + TSchedulerCookieHolder Cookie; + + TEvPingTimeout(ui64 tabletId, ISchedulerCookie *cookie) + : TabletID(tabletId) + , Cookie(cookie) + {} TString ToString() const { TStringStream str; str << "{EvPingTimeout TabletID: " << TabletID; if (Cookie.Get()) { str << " Cookie: present"; - } - else { + } + else { str << " Cookie: nullptr"; } str << "}"; return str.Str(); } - }; - - struct TEvStopListRemoval : public TEventLocal<TEvStopListRemoval, EvStopListRemoval> { - const ui64 TabletID; - - TEvStopListRemoval(ui64 tabletId) - : TabletID(tabletId) - {} - }; - + }; + + struct TEvStopListRemoval : public TEventLocal<TEvStopListRemoval, EvStopListRemoval> { + const ui64 TabletID; + + TEvStopListRemoval(ui64 tabletId) + : TabletID(tabletId) + {} + }; + struct TEvRefreshNodes : public TEventLocal<TEvRefreshNodes, EvRefreshNodes> { }; static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)"); - }; - - struct TEntry { - enum EState { - StInit, - StInitResolve, - StNormal, - StProblemResolve, - StProblemPing, + }; + + struct TEntry { + enum EState { + StInit, + StInitResolve, + StNormal, + StProblemResolve, + StProblemPing, StFollowerUpdate, - }; - + }; + static const char* StateToString(EState state) { switch (state) { case StInit: return "StInit"; @@ -89,36 +89,36 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> { } struct TQueueEntry { - TInstant AddInstant; - TEvTabletResolver::TEvForward::TPtr Ev; - - TQueueEntry(TInstant instant, TEvTabletResolver::TEvForward::TPtr &ev) - : AddInstant(instant) - , Ev(ev) - {} - }; - + TInstant AddInstant; + TEvTabletResolver::TEvForward::TPtr Ev; + + TQueueEntry(TInstant instant, TEvTabletResolver::TEvForward::TPtr &ev) + : AddInstant(instant) + , Ev(ev) + {} + }; + typedef TOneOneQueueInplace<TQueueEntry *, 64> TQueueType; - + EState State = StInit; - + TAutoPtr<TQueueType, TQueueType::TPtrCleanDestructor> Queue; TActorId KnownLeader; TActorId KnownLeaderTablet; - - TInstant LastResolved; - TInstant LastPing; - - TSchedulerCookieHolder Cookie; - + + TInstant LastResolved; + TInstant LastPing; + + TSchedulerCookieHolder Cookie; + TVector<std::pair<TActorId, TActorId>> KnownFollowers; - + ui64 CacheEpoch = 0; ui64 LastCheckEpoch = 0; TEntry() {} - }; - + }; + struct TResolveInfo { public: TEvTabletResolver::TEvForward::TResolveFlags ResFlags; @@ -160,14 +160,14 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> { typedef NCache::TUnboundedCacheOnMap<ui64, TAutoPtr<TEntry>> TUnresolvedTablets; typedef NCache::T2QCache<ui64, TAutoPtr<TEntry>> TResolvedTablets; - + TIntrusivePtr<TTabletResolverConfig> Config; TActorSystem* ActorSystem; TUnresolvedTablets UnresolvedTablets; TResolvedTablets ResolvedTablets; - THashSet<ui64> TabletsOnStopList; + THashSet<ui64> TabletsOnStopList; THashMap<ui32, TString> NodeToDcMapping; - + THashMap<ui32, ui64> NodeProblems; ui64 LastNodeProblemsUpdateEpoch = 0; @@ -183,33 +183,33 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> { NMonitoring::TDynamicCounters::TCounterPtr SelectedNone; - NMonitoring::TDynamicCounters::TCounterPtr InFlyResolveCounter; - + NMonitoring::TDynamicCounters::TCounterPtr InFlyResolveCounter; + std::optional<TString> FindNodeDc(ui32 nodeId) const { - auto it = NodeToDcMapping.find(nodeId); + auto it = NodeToDcMapping.find(nodeId); return it != NodeToDcMapping.end() ? std::make_optional(it->second) : std::nullopt; - } - - void ResolveRequest(ui64 tabletId, const TActorContext &ctx) { + } + + void ResolveRequest(ui64 tabletId, const TActorContext &ctx) { const TActorId ssproxy = MakeStateStorageProxyID(StateStorageGroupFromTabletID(tabletId)); - ctx.Send(ssproxy, new TEvStateStorage::TEvLookup(tabletId, 0), IEventHandle::FlagTrackDelivery, tabletId); - - InFlyResolveCounter->Inc(); - } - - bool PushQueue(TEvTabletResolver::TEvForward::TPtr &ev, TEntry &entry, const TActorContext &ctx) { - if (!entry.Queue) + ctx.Send(ssproxy, new TEvStateStorage::TEvLookup(tabletId, 0), IEventHandle::FlagTrackDelivery, tabletId); + + InFlyResolveCounter->Inc(); + } + + bool PushQueue(TEvTabletResolver::TEvForward::TPtr &ev, TEntry &entry, const TActorContext &ctx) { + if (!entry.Queue) entry.Queue.Reset(new TEntry::TQueueType()); - entry.Queue->Push(new TEntry::TQueueEntry(ctx.Now(), ev)); - return true; - } - + entry.Queue->Push(new TEntry::TQueueEntry(ctx.Now(), ev)); + return true; + } + std::pair<TActorId, TActorId> SelectForward(const TActorContext& ctx, const TEntry& entry, TResolveInfo& info, ui64 tabletId) { - const ui32 selfNode = ctx.SelfID.NodeId(); + const ui32 selfNode = ctx.SelfID.NodeId(); const std::optional<TString> selfDc = FindNodeDc(selfNode); const std::optional<TString> leaderDc = FindNodeDc(entry.KnownLeader.NodeId()); - + struct TCandidate { TActorId KnownLeader; TActorId KnownLeaderTablet; @@ -244,8 +244,8 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> { addCandidate(prio, TCandidate{ entry.KnownLeader, entry.KnownLeaderTablet, isLocal, isLocalDc, true }); else ++disallowed; - } - + } + if (info.ResFlags.AllowFollower()) { for (const auto &x : entry.KnownFollowers) { bool isLocal = (x.first.NodeId() == selfNode); @@ -257,9 +257,9 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> { addCandidate(prio, TCandidate{ x.first, x.second, isLocal, isLocalDc, false }); else ++disallowed; - } - } - + } + } + auto dcName = [](const std::optional<TString>& x) { return x ? x->data() : "<none>"; }; if (!winners.empty()) { @@ -275,7 +275,7 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> { info.NumLocal, info.NumLocalDc, info.NumOtherDc, disallowed, tabletId, entry.KnownFollowers.size(), countLeader, info.ResFlags.AllowFollower(), winner.KnownLeader.ToString().c_str()); - + if (winner.IsLeader) { if (winner.IsLocal) SelectedLeaderLocal->Inc(); @@ -293,8 +293,8 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> { } return std::make_pair(winner.KnownLeader, winner.KnownLeaderTablet); - } - + } + LOG_INFO(ctx, NKikimrServices::TABLET_RESOLVER, "No candidates for SelectForward, node %" PRIu32 " selfDC %s leaderDC %s %s" " local %" PRIu32 " localDc %" PRIu32 " other %" PRIu32 " disallowed %" PRIu32, @@ -304,72 +304,72 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> { SelectedNone->Inc(); return std::make_pair(TActorId(), TActorId()); - } - + } + bool SendForward(const TActorId &sender, const TEntry &entry, TEvTabletResolver::TEvForward *msg, const TActorContext &ctx, bool * needFollowerUpdate = nullptr) { TResolveInfo info(*msg, ctx.Now() - entry.LastResolved, needFollowerUpdate); // fills needFollowerUpdate in dtor const std::pair<TActorId, TActorId> endpoint = SelectForward(ctx, entry, info, msg->TabletID); - if (endpoint.first) { + if (endpoint.first) { ctx.Send(sender, new TEvTabletResolver::TEvForwardResult(msg->TabletID, endpoint.second, endpoint.first, LastCacheEpoch)); - if (!!msg->Ev) + if (!!msg->Ev) ctx.ExecutorThread.Send(msg->Ev->Forward(msg->SelectActor(endpoint.second, endpoint.first))); - return true; - } else { - return false; - } - } - - void SendQueued(ui64 tabletId, TEntry &entry, const TActorContext &ctx) { + return true; + } else { + return false; + } + } + + void SendQueued(ui64 tabletId, TEntry &entry, const TActorContext &ctx) { if (TEntry::TQueueType *queue = entry.Queue.Get()) { - for (TAutoPtr<TEntry::TQueueEntry> x = queue->Pop(); !!x; x.Reset(queue->Pop())) { - TEvTabletResolver::TEvForward *msg = x->Ev->Get(); - if (!SendForward(x->Ev->Sender, entry, msg, ctx)) - ctx.Send(x->Ev->Sender, new TEvTabletResolver::TEvForwardResult(NKikimrProto::ERROR, tabletId)); - } - entry.Queue.Destroy(); - } - } - - void SendPing(ui64 tabletId, TEntry &entry, const TActorContext &ctx) { + for (TAutoPtr<TEntry::TQueueEntry> x = queue->Pop(); !!x; x.Reset(queue->Pop())) { + TEvTabletResolver::TEvForward *msg = x->Ev->Get(); + if (!SendForward(x->Ev->Sender, entry, msg, ctx)) + ctx.Send(x->Ev->Sender, new TEvTabletResolver::TEvForwardResult(NKikimrProto::ERROR, tabletId)); + } + entry.Queue.Destroy(); + } + } + + void SendPing(ui64 tabletId, TEntry &entry, const TActorContext &ctx) { ctx.Send(entry.KnownLeader, new TEvTablet::TEvPing(tabletId, 0), IEventHandle::FlagTrackDelivery, tabletId); // no subscribe for reason - entry.Cookie.Reset(ISchedulerCookie::Make3Way()); - - const TDuration timeout = TDuration::MilliSeconds(500); - ctx.Schedule(timeout, new TEvPrivate::TEvPingTimeout(tabletId, entry.Cookie.Get()), entry.Cookie.Get()); - } - + entry.Cookie.Reset(ISchedulerCookie::Make3Way()); + + const TDuration timeout = TDuration::MilliSeconds(500); + ctx.Schedule(timeout, new TEvPrivate::TEvPingTimeout(tabletId, entry.Cookie.Get()), entry.Cookie.Get()); + } + void ApplyEntryInfo(TEvStateStorage::TEvInfo& msg, TEntry &entry, const TActorContext &ctx) { entry.KnownLeader = msg.CurrentLeader; entry.KnownLeaderTablet = msg.CurrentLeaderTablet; - entry.LastResolved = ctx.Now(); + entry.LastResolved = ctx.Now(); entry.KnownFollowers = std::move(msg.Followers); entry.CacheEpoch = ++LastCacheEpoch; - + LOG_DEBUG(ctx, NKikimrServices::TABLET_RESOLVER, "ApplyEntry leader tabletId: %" PRIu64 " followers: %" PRIu64, msg.TabletID, entry.KnownFollowers.size()); - SendQueued(msg.TabletID, entry, ctx); - } - + SendQueued(msg.TabletID, entry, ctx); + } + void DropEntry(ui64 tabletId, TEntry& entry, const TActorContext &ctx) { LOG_DEBUG(ctx, NKikimrServices::TABLET_RESOLVER, "DropEntry tabletId: %" PRIu64 " followers: %" PRIu64, tabletId, entry.KnownFollowers.size()); if (TEntry::TQueueType *queue = entry.Queue.Get()) { - for (TAutoPtr<TEntry::TQueueEntry> x = queue->Pop(); !!x; x.Reset(queue->Pop())) { - ctx.Send(x->Ev->Sender, new TEvTabletResolver::TEvForwardResult(NKikimrProto::ERROR, tabletId)); - } - } + for (TAutoPtr<TEntry::TQueueEntry> x = queue->Pop(); !!x; x.Reset(queue->Pop())) { + ctx.Send(x->Ev->Sender, new TEvTabletResolver::TEvForwardResult(NKikimrProto::ERROR, tabletId)); + } + } ResolvedTablets.Erase(tabletId); UnresolvedTablets.Erase(tabletId); - - if (TabletResolverNegativeCacheTimeout) { - if (TabletsOnStopList.emplace(tabletId).second) - Schedule(TabletResolverNegativeCacheTimeout, new TEvPrivate::TEvStopListRemoval(tabletId)); - } - } - + + if (TabletResolverNegativeCacheTimeout) { + if (TabletsOnStopList.emplace(tabletId).second) + Schedule(TabletResolverNegativeCacheTimeout, new TEvPrivate::TEvStopListRemoval(tabletId)); + } + } + TAutoPtr<TEntry>& GetEntry(ui64 tabletId, const TActorContext &ctx) { TAutoPtr<TEntry>* entryPtr; if (!ResolvedTablets.Find(tabletId, entryPtr)) { @@ -395,8 +395,8 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> { void MoveEntryToResolved(ui64 tabletId, TAutoPtr<TEntry>& entry) { TAutoPtr<TEntry>* resolvedEntryPtr; - Y_VERIFY(ResolvedTablets.Insert(tabletId, entry, resolvedEntryPtr)); - Y_VERIFY(UnresolvedTablets.Erase(tabletId)); + Y_VERIFY(ResolvedTablets.Insert(tabletId, entry, resolvedEntryPtr)); + Y_VERIFY(UnresolvedTablets.Erase(tabletId)); } void MoveEntryToUnresolved(ui64 tabletId, TAutoPtr<TEntry>& entry) { @@ -461,16 +461,16 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> { } } - void Handle(TEvTabletResolver::TEvForward::TPtr &ev, const TActorContext &ctx) { - TEvTabletResolver::TEvForward *msg = ev->Get(); - const ui64 tabletId = msg->TabletID; - - // allow some requests to bypass negative caching in low-load case - if (InFlyResolveCounter->Val() > 20 && TabletsOnStopList.contains(tabletId)) { - Send(ev->Sender, new TEvTabletResolver::TEvForwardResult(NKikimrProto::ERROR, tabletId)); - return; - } - + void Handle(TEvTabletResolver::TEvForward::TPtr &ev, const TActorContext &ctx) { + TEvTabletResolver::TEvForward *msg = ev->Get(); + const ui64 tabletId = msg->TabletID; + + // allow some requests to bypass negative caching in low-load case + if (InFlyResolveCounter->Val() > 20 && TabletsOnStopList.contains(tabletId)) { + Send(ev->Sender, new TEvTabletResolver::TEvForwardResult(NKikimrProto::ERROR, tabletId)); + return; + } + CheckDelayedNodeProblem(tabletId, ctx); TAutoPtr<TEntry> &entryHolder = GetEntry(tabletId, ctx); @@ -480,95 +480,95 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> { "Handle TEvForward tabletId: %" PRIu64 " entry.State: %s ev: %s", tabletId, TEntry::StateToString(entry.State), msg->ToString().data()); - switch (entry.State) { - case TEntry::StInit: - { - PushQueue(ev, entry, ctx); - ResolveRequest(tabletId, ctx); - entry.State = TEntry::StInitResolve; - } - break; - case TEntry::StInitResolve: - PushQueue(ev, entry, ctx); - break; + switch (entry.State) { + case TEntry::StInit: + { + PushQueue(ev, entry, ctx); + ResolveRequest(tabletId, ctx); + entry.State = TEntry::StInitResolve; + } + break; + case TEntry::StInitResolve: + PushQueue(ev, entry, ctx); + break; case TEntry::StNormal: { bool needFollowerUpdate = false; if (!SendForward(ev->Sender, entry, msg, ctx, &needFollowerUpdate)) { - PushQueue(ev, entry, ctx); - ResolveRequest(tabletId, ctx); + PushQueue(ev, entry, ctx); + ResolveRequest(tabletId, ctx); entry.State = TEntry::StFollowerUpdate; } if (needFollowerUpdate) { - ResolveRequest(tabletId, ctx); + ResolveRequest(tabletId, ctx); entry.State = TEntry::StFollowerUpdate; - } - break; + } + break; } - case TEntry::StProblemResolve: - case TEntry::StProblemPing: - PushQueue(ev, entry, ctx); - break; + case TEntry::StProblemResolve: + case TEntry::StProblemPing: + PushQueue(ev, entry, ctx); + break; case TEntry::StFollowerUpdate: - if (!SendForward(ev->Sender, entry, msg, ctx)) - PushQueue(ev, entry, ctx); - break; - default: + if (!SendForward(ev->Sender, entry, msg, ctx)) + PushQueue(ev, entry, ctx); + break; + default: Y_FAIL(); - } - } - - void Handle(TEvTabletResolver::TEvTabletProblem::TPtr &ev, const TActorContext &ctx) { - TEvTabletResolver::TEvTabletProblem *msg = ev->Get(); - const ui64 tabletId = msg->TabletID; - + } + } + + void Handle(TEvTabletResolver::TEvTabletProblem::TPtr &ev, const TActorContext &ctx) { + TEvTabletResolver::TEvTabletProblem *msg = ev->Get(); + const ui64 tabletId = msg->TabletID; + TAutoPtr<TEntry>* entryHolder = FindEntry(tabletId); if (!entryHolder) { LOG_DEBUG(ctx, NKikimrServices::TABLET_RESOLVER, "Handle TEvTabletProblem tabletId: %" PRIu64 " no entyHolder", tabletId); - return; + return; } TEntry &entry = *entryHolder->Get(); - + LOG_DEBUG(ctx, NKikimrServices::TABLET_RESOLVER, "Handle TEvTabletProblem tabletId: %" PRIu64 " entry.State: %s", tabletId, TEntry::StateToString(entry.State)); - switch (entry.State) { - case TEntry::StInit: - case TEntry::StInitResolve: - break; - case TEntry::StNormal: + switch (entry.State) { + case TEntry::StInit: + case TEntry::StInitResolve: + break; + case TEntry::StNormal: if (!msg->TabletActor || entry.KnownLeaderTablet == msg->TabletActor) { - ResolveRequest(tabletId, ctx); - entry.State = TEntry::StProblemResolve; + ResolveRequest(tabletId, ctx); + entry.State = TEntry::StProblemResolve; MoveEntryToUnresolved(tabletId, *entryHolder); - } else { + } else { // find in follower list for (auto it = entry.KnownFollowers.begin(), end = entry.KnownFollowers.end(); it != end; ++it) { - if (it->second == msg->TabletActor) { + if (it->second == msg->TabletActor) { entry.KnownFollowers.erase(it); - ResolveRequest(tabletId, ctx); + ResolveRequest(tabletId, ctx); entry.State = TEntry::StFollowerUpdate; - break; - } - } - } - - break; - case TEntry::StProblemResolve: - case TEntry::StProblemPing: + break; + } + } + } + + break; + case TEntry::StProblemResolve: + case TEntry::StProblemPing: case TEntry::StFollowerUpdate: for (auto it = entry.KnownFollowers.begin(), end = entry.KnownFollowers.end(); it != end; ++it) { - if (it->second == msg->TabletActor) { + if (it->second == msg->TabletActor) { entry.KnownFollowers.erase(it); - break; - } - } - break; - default: + break; + } + } + break; + default: Y_FAIL(); - } - } - + } + } + void Handle(TEvTabletResolver::TEvNodeProblem::TPtr &ev, const TActorContext &ctx) { TEvTabletResolver::TEvNodeProblem *msg = ev->Get(); const ui32 nodeId = msg->NodeId; @@ -587,30 +587,30 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> { } } - void Handle(TEvStateStorage::TEvInfo::TPtr &ev, const TActorContext &ctx) { - InFlyResolveCounter->Dec(); - - TEvStateStorage::TEvInfo *msg = ev->Get(); - const ui64 tabletId = msg->TabletID; - const bool success = (msg->Status == NKikimrProto::OK); // todo: handle 'locked' state - + void Handle(TEvStateStorage::TEvInfo::TPtr &ev, const TActorContext &ctx) { + InFlyResolveCounter->Dec(); + + TEvStateStorage::TEvInfo *msg = ev->Get(); + const ui64 tabletId = msg->TabletID; + const bool success = (msg->Status == NKikimrProto::OK); // todo: handle 'locked' state + TAutoPtr<TEntry>* entryHolder = FindEntry(tabletId); if (!entryHolder) { LOG_DEBUG(ctx, NKikimrServices::TABLET_RESOLVER, "Handle TEvInfo tabletId: %" PRIu64 " no entryHolder", tabletId); - return; + return; } TEntry &entry = *entryHolder->Get(); - + LOG_DEBUG(ctx, NKikimrServices::TABLET_RESOLVER, "Handle TEvInfo tabletId: %" PRIu64 " entry.State: %s success: %s ev: %s", tabletId, TEntry::StateToString(entry.State), (success ? "true" : "false"), ev->GetBase()->ToString().data()); - switch (entry.State) { - case TEntry::StInit: + switch (entry.State) { + case TEntry::StInit: Y_FAIL("must not happens"); - case TEntry::StInitResolve: - if (success) { + case TEntry::StInitResolve: + if (success) { if (msg->CurrentLeaderTablet) { entry.State = TEntry::StNormal; ApplyEntryInfo(*msg, entry, ctx); @@ -621,176 +621,176 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> { ApplyEntryInfo(*msg, entry, ctx); DropEntry(tabletId, entry, ctx); } - } else { + } else { DropEntry(tabletId, entry, ctx); - } - break; + } + break; case TEntry::StFollowerUpdate: - if (success) { + if (success) { if (msg->CurrentLeaderTablet) { - entry.State = TEntry::StNormal; + entry.State = TEntry::StNormal; ApplyEntryInfo(*msg, entry, ctx); - } else { + } else { // HACK: Don't cache invalid CurrentLeaderTablet - // FIXME: Use subscription + cache here to reduce the workload + // FIXME: Use subscription + cache here to reduce the workload ApplyEntryInfo(*msg, entry, ctx); - DropEntry(tabletId, entry, ctx); - } - } else { - DropEntry(tabletId, entry, ctx); - } - break; - case TEntry::StProblemResolve: - if (success) { + DropEntry(tabletId, entry, ctx); + } + } else { + DropEntry(tabletId, entry, ctx); + } + break; + case TEntry::StProblemResolve: + if (success) { if (entry.KnownLeader == msg->CurrentLeader) { if (!(entry.KnownLeaderTablet == msg->CurrentLeaderTablet || !entry.KnownLeaderTablet)) { - DropEntry(tabletId, entry, ctx); // got info but not full, occurs on transitional cluster states - } else { + DropEntry(tabletId, entry, ctx); // got info but not full, occurs on transitional cluster states + } else { entry.KnownLeaderTablet = msg->CurrentLeaderTablet; - entry.State = TEntry::StProblemPing; - SendPing(tabletId, entry, ctx); - } - } else { + entry.State = TEntry::StProblemPing; + SendPing(tabletId, entry, ctx); + } + } else { if (msg->CurrentLeaderTablet) { - entry.State = TEntry::StNormal; + entry.State = TEntry::StNormal; ApplyEntryInfo(*msg, entry, ctx); - MoveEntryToResolved(tabletId, *entryHolder); - } else { + MoveEntryToResolved(tabletId, *entryHolder); + } else { ApplyEntryInfo(*msg, entry, ctx); - DropEntry(tabletId, entry, ctx); - } - } - } else { + DropEntry(tabletId, entry, ctx); + } + } + } else { DropEntry(tabletId, entry, ctx); - } - break; - case TEntry::StProblemPing: + } + break; + case TEntry::StProblemPing: case TEntry::StNormal: - break; - default: + break; + default: Y_FAIL(); - } - } - - void Handle(TEvTablet::TEvPong::TPtr &ev, const TActorContext &ctx) { - NKikimrTabletBase::TEvPong &record = ev->Get()->Record; - const ui64 tabletId = record.GetTabletID(); - + } + } + + void Handle(TEvTablet::TEvPong::TPtr &ev, const TActorContext &ctx) { + NKikimrTabletBase::TEvPong &record = ev->Get()->Record; + const ui64 tabletId = record.GetTabletID(); + TAutoPtr<TEntry>* entryHolder = FindEntry(tabletId); if (!entryHolder) { LOG_DEBUG(ctx, NKikimrServices::TABLET_RESOLVER, "Handle TEvPong tabletId: %" PRIu64 " no entryHolder", tabletId); - return; + return; } TEntry &entry = *entryHolder->Get(); - + LOG_DEBUG(ctx, NKikimrServices::TABLET_RESOLVER, "Handle TEvPong tabletId: %" PRIu64 " entry.State: %s", tabletId, TEntry::StateToString(entry.State)); - switch (entry.State) { - case TEntry::StInit: - case TEntry::StInitResolve: - case TEntry::StNormal: - case TEntry::StProblemResolve: - break; - case TEntry::StProblemPing: + switch (entry.State) { + case TEntry::StInit: + case TEntry::StInitResolve: + case TEntry::StNormal: + case TEntry::StProblemResolve: + break; + case TEntry::StProblemPing: if (ev->Sender == entry.KnownLeader) { - entry.Cookie.Detach(); + entry.Cookie.Detach(); entry.State = TEntry::StNormal; - SendQueued(tabletId, entry, ctx); + SendQueued(tabletId, entry, ctx); MoveEntryToResolved(tabletId, *entryHolder); - } - break; - default: + } + break; + default: Y_FAIL(); - } - } - - void Handle(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) { - // cold be Ping or Initial Statestorage resolve - const ui64 tabletId = ev->Cookie; - TAutoPtr<TEntry>* entryHolder = FindEntry(tabletId); - if (!entryHolder) - return; - - TEntry &entry = *entryHolder->Get(); - if (ev->Get()->SourceType == TEvStateStorage::TEvLookup::EventType) { - InFlyResolveCounter->Dec(); - DropEntry(tabletId, entry, ctx); - return; - } - - switch (entry.State) { - case TEntry::StInit: - case TEntry::StInitResolve: - case TEntry::StNormal: - case TEntry::StProblemResolve: + } + } + + void Handle(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) { + // cold be Ping or Initial Statestorage resolve + const ui64 tabletId = ev->Cookie; + TAutoPtr<TEntry>* entryHolder = FindEntry(tabletId); + if (!entryHolder) + return; + + TEntry &entry = *entryHolder->Get(); + if (ev->Get()->SourceType == TEvStateStorage::TEvLookup::EventType) { + InFlyResolveCounter->Dec(); + DropEntry(tabletId, entry, ctx); + return; + } + + switch (entry.State) { + case TEntry::StInit: + case TEntry::StInitResolve: + case TEntry::StNormal: + case TEntry::StProblemResolve: case TEntry::StFollowerUpdate: - break; - case TEntry::StProblemPing: + break; + case TEntry::StProblemPing: if (ev->Sender == entry.KnownLeader) { - DropEntry(tabletId, entry, ctx); - } - break; - default: - Y_FAIL(); - } - } - - void Handle(TEvPrivate::TEvPingTimeout::TPtr &ev, const TActorContext &ctx) { - TEvPrivate::TEvPingTimeout *msg = ev->Get(); - const ui64 tabletId = msg->TabletID; - + DropEntry(tabletId, entry, ctx); + } + break; + default: + Y_FAIL(); + } + } + + void Handle(TEvPrivate::TEvPingTimeout::TPtr &ev, const TActorContext &ctx) { + TEvPrivate::TEvPingTimeout *msg = ev->Get(); + const ui64 tabletId = msg->TabletID; + TAutoPtr<TEntry>* entryHolder = FindEntry(tabletId); if (!entryHolder) { LOG_DEBUG(ctx, NKikimrServices::TABLET_RESOLVER, "Handle TEvPingTimeout tabletId: %" PRIu64 " no entryHolder", tabletId); - return; + return; } TEntry &entry = *entryHolder->Get(); LOG_DEBUG(ctx, NKikimrServices::TABLET_RESOLVER, "Handle TEvPingTimeout tabletId: %" PRIu64 " entry.State: %s", tabletId, TEntry::StateToString(entry.State)); - switch (entry.State) { - case TEntry::StInit: - case TEntry::StInitResolve: - case TEntry::StNormal: - case TEntry::StProblemResolve: + switch (entry.State) { + case TEntry::StInit: + case TEntry::StInitResolve: + case TEntry::StNormal: + case TEntry::StProblemResolve: case TEntry::StFollowerUpdate: - break; - case TEntry::StProblemPing: - if (msg->Cookie.DetachEvent()) { + break; + case TEntry::StProblemPing: + if (msg->Cookie.DetachEvent()) { DropEntry(tabletId, entry, ctx); - } - break; - default: + } + break; + default: Y_FAIL(); - } - } - - void Handle(TEvPrivate::TEvStopListRemoval::TPtr &ev, const TActorContext &) { - TEvPrivate::TEvStopListRemoval *msg = ev->Get(); - TabletsOnStopList.erase(msg->TabletID); - } - - void Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev, const TActorContext &ctx) { - Y_UNUSED(ctx); - - const TEvInterconnect::TEvNodesInfo *msg = ev->Get(); - bool distinct = false; - for (const auto &nodeInfo : msg->Nodes) { + } + } + + void Handle(TEvPrivate::TEvStopListRemoval::TPtr &ev, const TActorContext &) { + TEvPrivate::TEvStopListRemoval *msg = ev->Get(); + TabletsOnStopList.erase(msg->TabletID); + } + + void Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev, const TActorContext &ctx) { + Y_UNUSED(ctx); + + const TEvInterconnect::TEvNodesInfo *msg = ev->Get(); + bool distinct = false; + for (const auto &nodeInfo : msg->Nodes) { if (nodeInfo.Location.GetDataCenterId() != msg->Nodes[0].Location.GetDataCenterId()) - distinct = true; + distinct = true; NodeToDcMapping[nodeInfo.NodeId] = nodeInfo.Location.GetDataCenterId(); - } - - if (!distinct) - NodeToDcMapping.clear(); + } + + if (!distinct) + NodeToDcMapping.clear(); ctx.Schedule(TabletResolverRefreshNodesPeriod, new TEvPrivate::TEvRefreshNodes); - } - + } + void Handle(TEvPrivate::TEvRefreshNodes::TPtr &, const TActorContext &ctx) { RefreshNodes(ctx); } @@ -799,13 +799,13 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> { ctx.Send(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes()); } -public: +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TABLET_RESOLVER_ACTOR; } TTabletResolver(const TIntrusivePtr<TTabletResolverConfig> &config) - : Config(config) + : Config(config) , ActorSystem(nullptr) , ResolvedTablets(new NCache::T2QCacheConfig()) { @@ -821,20 +821,20 @@ public: if (TEntry::TQueueType *queue = value->Queue.Get()) { for (TAutoPtr<TEntry::TQueueEntry> x = queue->Pop(); !!x; x.Reset(queue->Pop())) { - ActorSystem->Send(x->Ev->Sender, new TEvTabletResolver::TEvForwardResult(NKikimrProto::RACE, key)); + ActorSystem->Send(x->Ev->Sender, new TEvTabletResolver::TEvForwardResult(NKikimrProto::RACE, key)); } } }); } - + ~TTabletResolver() { ResolvedTablets.SetEvictionCallback(&TResolvedTablets::DefaultEvictionCallback); } - void Bootstrap(const TActorContext &ctx) { + void Bootstrap(const TActorContext &ctx) { RefreshNodes(ctx); - Become(&TThis::StateWork); - + Become(&TThis::StateWork); + auto tablets = GetServiceCounters(AppData()->Counters, "tablets"); SelectedLeaderLocal = tablets->GetCounter("TabletResolver/SelectedLeaderLocal", true); @@ -846,35 +846,35 @@ public: SelectedNone = tablets->GetCounter("TabletResolver/SelectedNone", true); InFlyResolveCounter = tablets->GetCounter("TabletResolver/InFly"); - } - - STFUNC(StateWork) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvTabletResolver::TEvForward, Handle); - HFunc(TEvTabletResolver::TEvTabletProblem, Handle); + } + + STFUNC(StateWork) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvTabletResolver::TEvForward, Handle); + HFunc(TEvTabletResolver::TEvTabletProblem, Handle); HFunc(TEvTabletResolver::TEvNodeProblem, Handle); - HFunc(TEvStateStorage::TEvInfo, Handle); - HFunc(TEvTablet::TEvPong, Handle); - HFunc(TEvPrivate::TEvPingTimeout, Handle); - HFunc(TEvPrivate::TEvStopListRemoval, Handle); - HFunc(TEvInterconnect::TEvNodesInfo, Handle); + HFunc(TEvStateStorage::TEvInfo, Handle); + HFunc(TEvTablet::TEvPong, Handle); + HFunc(TEvPrivate::TEvPingTimeout, Handle); + HFunc(TEvPrivate::TEvStopListRemoval, Handle); + HFunc(TEvInterconnect::TEvNodesInfo, Handle); HFunc(TEvPrivate::TEvRefreshNodes, Handle); - HFunc(TEvents::TEvUndelivered, Handle); + HFunc(TEvents::TEvUndelivered, Handle); default: LOG_WARN(ctx, NKikimrServices::TABLET_RESOLVER, "TTabletResolver::StateWork unexpected event type: %" PRIx32 " event: %s", ev->GetTypeRewrite(), ev->HasEvent() ? ev->GetBase()->ToString().data() : "serialized?"); break; - } - } -}; - + } + } +}; + IActor* CreateTabletResolver(const TIntrusivePtr<TTabletResolverConfig> &config) { return new TTabletResolver(config); -} - +} + TActorId MakeTabletResolverID() { - const char x[12] = "TabletProxy"; + const char x[12] = "TabletProxy"; return TActorId(0, TStringBuf(x, 12)); -} - -} +} + +} diff --git a/ydb/core/tablet/tablet_responsiveness_pinger.cpp b/ydb/core/tablet/tablet_responsiveness_pinger.cpp index c4ed29ddaa..8d29408d25 100644 --- a/ydb/core/tablet/tablet_responsiveness_pinger.cpp +++ b/ydb/core/tablet/tablet_responsiveness_pinger.cpp @@ -1,60 +1,60 @@ -#include "tablet_responsiveness_pinger.h" +#include "tablet_responsiveness_pinger.h" #include <ydb/core/base/appdata.h> - -namespace NKikimr { - -TTabletResponsivenessPinger::TTabletResponsivenessPinger(TTabletSimpleCounter &counter, TDuration pingInterval) - : Counter(counter) - , PingInterval(pingInterval) - , LastResponseTime(TDuration::Zero()) - , SelfPingSentTime(TInstant::Zero()) -{} - -void TTabletResponsivenessPinger::Bootstrap(const TActorContext &ctx) { - SelfPingSentTime = TInstant::Zero(); - Become(&TThis::StateWait, ctx, PingInterval, new TEvents::TEvWakeup()); -} - -void TTabletResponsivenessPinger::OnAnyEvent(const TActorContext &ctx) { - if (SelfPingSentTime) { - const TInstant now = AppData(ctx)->TimeProvider->Now(); - const TDuration responseTime = now - SelfPingSentTime; - LastResponseTime = Max(LastResponseTime, responseTime); - Counter.Set(LastResponseTime.MicroSeconds()); - } -} - -void TTabletResponsivenessPinger::Detach(const TActorContext &ctx) { - Die(ctx); -} - -void TTabletResponsivenessPinger::DoPing(const TActorContext &ctx) { - ctx.Send(ctx.SelfID, new TEvents::TEvPing()); - SelfPingSentTime = AppData(ctx)->TimeProvider->Now(); - Become(&TThis::StatePing); -} - -void TTabletResponsivenessPinger::ReceivePing(const TActorContext &ctx) { - const TInstant now = AppData(ctx)->TimeProvider->Now(); - const TDuration responseTime = now - SelfPingSentTime; - LastResponseTime = responseTime; - Counter.Set(LastResponseTime.MicroSeconds()); - if (responseTime > PingInterval) - DoPing(ctx); - else - Bootstrap(ctx); -} - -STFUNC(TTabletResponsivenessPinger::StateWait) { - switch (ev->GetTypeRewrite()) { - CFunc(TEvents::TEvWakeup::EventType, DoPing); - } -} - -STFUNC(TTabletResponsivenessPinger::StatePing) { - switch (ev->GetTypeRewrite()) { - CFunc(TEvents::TEvPing::EventType, ReceivePing); - } -} - -} + +namespace NKikimr { + +TTabletResponsivenessPinger::TTabletResponsivenessPinger(TTabletSimpleCounter &counter, TDuration pingInterval) + : Counter(counter) + , PingInterval(pingInterval) + , LastResponseTime(TDuration::Zero()) + , SelfPingSentTime(TInstant::Zero()) +{} + +void TTabletResponsivenessPinger::Bootstrap(const TActorContext &ctx) { + SelfPingSentTime = TInstant::Zero(); + Become(&TThis::StateWait, ctx, PingInterval, new TEvents::TEvWakeup()); +} + +void TTabletResponsivenessPinger::OnAnyEvent(const TActorContext &ctx) { + if (SelfPingSentTime) { + const TInstant now = AppData(ctx)->TimeProvider->Now(); + const TDuration responseTime = now - SelfPingSentTime; + LastResponseTime = Max(LastResponseTime, responseTime); + Counter.Set(LastResponseTime.MicroSeconds()); + } +} + +void TTabletResponsivenessPinger::Detach(const TActorContext &ctx) { + Die(ctx); +} + +void TTabletResponsivenessPinger::DoPing(const TActorContext &ctx) { + ctx.Send(ctx.SelfID, new TEvents::TEvPing()); + SelfPingSentTime = AppData(ctx)->TimeProvider->Now(); + Become(&TThis::StatePing); +} + +void TTabletResponsivenessPinger::ReceivePing(const TActorContext &ctx) { + const TInstant now = AppData(ctx)->TimeProvider->Now(); + const TDuration responseTime = now - SelfPingSentTime; + LastResponseTime = responseTime; + Counter.Set(LastResponseTime.MicroSeconds()); + if (responseTime > PingInterval) + DoPing(ctx); + else + Bootstrap(ctx); +} + +STFUNC(TTabletResponsivenessPinger::StateWait) { + switch (ev->GetTypeRewrite()) { + CFunc(TEvents::TEvWakeup::EventType, DoPing); + } +} + +STFUNC(TTabletResponsivenessPinger::StatePing) { + switch (ev->GetTypeRewrite()) { + CFunc(TEvents::TEvPing::EventType, ReceivePing); + } +} + +} diff --git a/ydb/core/tablet/tablet_responsiveness_pinger.h b/ydb/core/tablet/tablet_responsiveness_pinger.h index c628ab4d33..93954ea0b4 100644 --- a/ydb/core/tablet/tablet_responsiveness_pinger.h +++ b/ydb/core/tablet/tablet_responsiveness_pinger.h @@ -1,32 +1,32 @@ -#pragma once -#include "defs.h" -#include "tablet_counters.h" +#pragma once +#include "defs.h" +#include "tablet_counters.h" #include <library/cpp/actors/core/actor_bootstrapped.h> - -namespace NKikimr { - -class TTabletResponsivenessPinger : public TActorBootstrapped<TTabletResponsivenessPinger> { - TTabletSimpleCounter &Counter; - const TDuration PingInterval; - TDuration LastResponseTime; - TInstant SelfPingSentTime; - - STFUNC(StateWait); - STFUNC(StatePing); - - void DoPing(const TActorContext &ctx); - void ReceivePing(const TActorContext &ctx); -public: + +namespace NKikimr { + +class TTabletResponsivenessPinger : public TActorBootstrapped<TTabletResponsivenessPinger> { + TTabletSimpleCounter &Counter; + const TDuration PingInterval; + TDuration LastResponseTime; + TInstant SelfPingSentTime; + + STFUNC(StateWait); + STFUNC(StatePing); + + void DoPing(const TActorContext &ctx); + void ReceivePing(const TActorContext &ctx); +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TABLET_RESPONSIVENESS_PINGER; } - TTabletResponsivenessPinger(TTabletSimpleCounter &counter, TDuration pingInterval); - - void Bootstrap(const TActorContext &ctx); - - void OnAnyEvent(const TActorContext &ctx); - void Detach(const TActorContext &ctx); -}; - -} + TTabletResponsivenessPinger(TTabletSimpleCounter &counter, TDuration pingInterval); + + void Bootstrap(const TActorContext &ctx); + + void OnAnyEvent(const TActorContext &ctx); + void Detach(const TActorContext &ctx); +}; + +} diff --git a/ydb/core/tablet/tablet_setup.h b/ydb/core/tablet/tablet_setup.h index 231b79cea9..57ea7d6edb 100644 --- a/ydb/core/tablet/tablet_setup.h +++ b/ydb/core/tablet/tablet_setup.h @@ -1,35 +1,35 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include <ydb/core/base/appdata.h> #include <ydb/core/base/shared_quota.h> #include <ydb/core/base/tablet_types.h> #include <functional> - -namespace NKikimr { - + +namespace NKikimr { + class TTabletStorageInfo; - -class TTabletSetupInfo : public TThrRefBase { + +class TTabletSetupInfo : public TThrRefBase { public: typedef std::function<IActor* (const TActorId &, TTabletStorageInfo*)> TTabletCreationFunc; using TPtr = TIntrusivePtr<TTabletSetupInfo>; private: - const TTabletCreationFunc Op; - const TMailboxType::EType MailboxType; - const TMailboxType::EType TabletMailboxType; - const ui32 PoolId; - const ui32 TabletPoolId; - -public: - TTabletSetupInfo(TTabletCreationFunc op, TMailboxType::EType mailboxType, ui32 poolId, TMailboxType::EType tabletMailboxType, ui32 tabletPoolId) - : Op(op) - , MailboxType(mailboxType) - , TabletMailboxType(tabletMailboxType) - , PoolId(poolId) - , TabletPoolId(tabletPoolId) - {} - + const TTabletCreationFunc Op; + const TMailboxType::EType MailboxType; + const TMailboxType::EType TabletMailboxType; + const ui32 PoolId; + const ui32 TabletPoolId; + +public: + TTabletSetupInfo(TTabletCreationFunc op, TMailboxType::EType mailboxType, ui32 poolId, TMailboxType::EType tabletMailboxType, ui32 tabletPoolId) + : Op(op) + , MailboxType(mailboxType) + , TabletMailboxType(tabletMailboxType) + , PoolId(poolId) + , TabletPoolId(tabletPoolId) + {} + TActorId Apply(TTabletStorageInfo *info, TActorIdentity owner); TActorId Apply(TTabletStorageInfo *info, const TActorContext &ctx); TActorId Tablet(TTabletStorageInfo *info, const TActorId &launcher, const TActorContext &ctx, @@ -38,15 +38,15 @@ public: TActorId Follower(TTabletStorageInfo *info, const TActorId &launcher, const TActorContext &ctx, ui32 followerID, TResourceProfilesPtr profiles = nullptr, TSharedQuotaPtr txCacheQuota = nullptr); -}; - +}; + IActor* CreateTablet(const TActorId &launcher, TTabletStorageInfo *info, TTabletSetupInfo *setupInfo, ui32 suggestedGeneration, TResourceProfilesPtr profiles = nullptr, TSharedQuotaPtr txCacheQuota = nullptr); IActor* CreateTabletFollower(const TActorId &launcher, TTabletStorageInfo *info, TTabletSetupInfo *setupInfo, ui32 followerID, TResourceProfilesPtr profiles = nullptr, TSharedQuotaPtr txCacheQuota = nullptr); - + struct ITabletFactory: public virtual TThrRefBase { virtual TIntrusivePtr<TTabletSetupInfo> CreateTablet( @@ -55,4 +55,4 @@ struct ITabletFactory: public virtual TThrRefBase { const TAppData& appData) = 0; }; -} +} diff --git a/ydb/core/tablet/tablet_sys.cpp b/ydb/core/tablet/tablet_sys.cpp index 216d7328e2..44bfac7b2d 100644 --- a/ydb/core/tablet/tablet_sys.cpp +++ b/ydb/core/tablet/tablet_sys.cpp @@ -1,31 +1,31 @@ -#include "tablet_sys.h" +#include "tablet_sys.h" #include "tablet_tracing_signals.h" #include <ydb/core/base/compile_time_flags.h> #include <ydb/core/base/hive.h> #include <ydb/core/base/tablet_pipecache.h> #include <ydb/core/protos/services.pb.h> - + #include <library/cpp/actors/core/log.h> -#include <util/generic/deque.h> -#include <util/generic/hash.h> +#include <util/generic/deque.h> +#include <util/generic/hash.h> #include <util/generic/queue.h> -#include <util/generic/set.h> +#include <util/generic/set.h> #include <util/stream/str.h> - -#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR -#error log macro definition clash -#endif - -#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, "Tablet: " << TabletID() << " " << stream) -#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, "Tablet: " << TabletID() << " " << stream) -#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, "Tablet: " << TabletID() << " " << stream) -#define BLOG_TRACE(stream) LOG_TRACE_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, "Tablet: " << TabletID() << " " << stream) - - -namespace NKikimr { - + +#if defined BLOG_D || defined BLOG_I || defined BLOG_ERROR +#error log macro definition clash +#endif + +#define BLOG_D(stream) LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, "Tablet: " << TabletID() << " " << stream) +#define BLOG_I(stream) LOG_INFO_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, "Tablet: " << TabletID() << " " << stream) +#define BLOG_ERROR(stream) LOG_ERROR_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, "Tablet: " << TabletID() << " " << stream) +#define BLOG_TRACE(stream) LOG_TRACE_S(*TlsActivationContext, NKikimrServices::TABLET_MAIN, "Tablet: " << TabletID() << " " << stream) + + +namespace NKikimr { + namespace { static constexpr size_t MaxStepsInFlight = 10000; @@ -36,481 +36,481 @@ namespace { } -ui64 TTablet::StateStorageGroup() const { - return StateStorageGroupFromTabletID(Info->TabletID); -} - -ui64 TTablet::TabletID() const { - return Info->TabletID; -} - +ui64 TTablet::StateStorageGroup() const { + return StateStorageGroupFromTabletID(Info->TabletID); +} + +ui64 TTablet::TabletID() const { + return Info->TabletID; +} + void TTablet::NextFollowerAttempt() { const ui32 node = FollowerInfo.KnownLeaderID.NodeId(); - if (node && node != SelfId().NodeId()) { + if (node && node != SelfId().NodeId()) { const TActorId proxy = TActivationContext::InterconnectProxy(node); - Send(proxy, new TEvents::TEvUnsubscribe); - } + Send(proxy, new TEvents::TEvUnsubscribe); + } FollowerInfo.NextAttempt(); -} - -void TTablet::ReportTabletStateChange(ETabletState state) { +} + +void TTablet::ReportTabletStateChange(ETabletState state) { const TActorId tabletStateServiceId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(SelfId().NodeId()); if (state == TTabletStateInfo::Created || state == TTabletStateInfo::ResolveLeader) { Send(tabletStateServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvTabletStateUpdate(TabletID(), FollowerId, state, Info, StateStorageInfo.KnownGeneration, Leader)); } else { Send(tabletStateServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvTabletStateUpdate(TabletID(), FollowerId, state, StateStorageInfo.KnownGeneration)); } -} - -void TTablet::PromoteToCandidate(ui32 gen) { - if (SuggestedGeneration != 0) { - if (gen >= SuggestedGeneration) - return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootRace); - StateStorageInfo.KnownGeneration = SuggestedGeneration; - } else { - StateStorageInfo.KnownGeneration = 1 + Max(gen, StateStorageInfo.KnownGeneration); - } - - StateStorageInfo.KnownStep = 0; - - Y_VERIFY_DEBUG(SetupInfo); - if (!UserTablet) - UserTablet = SetupInfo->Apply(Info.Get(), SelfId()); +} + +void TTablet::PromoteToCandidate(ui32 gen) { + if (SuggestedGeneration != 0) { + if (gen >= SuggestedGeneration) + return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootRace); + StateStorageInfo.KnownGeneration = SuggestedGeneration; + } else { + StateStorageInfo.KnownGeneration = 1 + Max(gen, StateStorageInfo.KnownGeneration); + } + + StateStorageInfo.KnownStep = 0; + + Y_VERIFY_DEBUG(SetupInfo); + if (!UserTablet) + UserTablet = SetupInfo->Apply(Info.Get(), SelfId()); if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TOnPromoteToCandidate>(StateStorageInfo.KnownGeneration)); } - - // todo: handle 'proxy not found' case - Send(StateStorageInfo.ProxyID, new TEvStateStorage::TEvUpdate(TabletID(), 0, SelfId(), UserTablet, StateStorageInfo.KnownGeneration, 0, StateStorageInfo.Signature.Get(), StateStorageInfo.SignatureSz, TEvStateStorage::TProxyOptions::SigAsync)); - - Become(&TThis::StateBecomeCandidate); - ReportTabletStateChange(TTabletStateInfo::Candidate); -} - -void TTablet::TabletBlockBlobStorage() { - Y_VERIFY(Info); - - IActor * const x = CreateTabletReqBlockBlobStorage(SelfId(), Info.Get(), StateStorageInfo.KnownGeneration - 1, false); + + // todo: handle 'proxy not found' case + Send(StateStorageInfo.ProxyID, new TEvStateStorage::TEvUpdate(TabletID(), 0, SelfId(), UserTablet, StateStorageInfo.KnownGeneration, 0, StateStorageInfo.Signature.Get(), StateStorageInfo.SignatureSz, TEvStateStorage::TProxyOptions::SigAsync)); + + Become(&TThis::StateBecomeCandidate); + ReportTabletStateChange(TTabletStateInfo::Candidate); +} + +void TTablet::TabletBlockBlobStorage() { + Y_VERIFY(Info); + + IActor * const x = CreateTabletReqBlockBlobStorage(SelfId(), Info.Get(), StateStorageInfo.KnownGeneration - 1, false); TActorId newActorId = Register(x); - + if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TOnTabletBlockBlobStorage>(newActorId, StateStorageInfo.KnownGeneration)); } - Become(&TThis::StateBlockBlobStorage); - ReportTabletStateChange(TTabletStateInfo::BlockBlobStorage); -} - -void TTablet::TabletRebuildGraph() { + Become(&TThis::StateBlockBlobStorage); + ReportTabletStateChange(TTabletStateInfo::BlockBlobStorage); +} + +void TTablet::TabletRebuildGraph() { THolder<NTracing::ITrace> newTrace; NTracing::TTraceID rebuildGraphTraceID; if (IntrospectionTrace) { newTrace = THolder<NTracing::ITrace>(IntrospectionTrace->CreateTrace(NTracing::ITrace::TypeReqRebuildHistoryGraph)); rebuildGraphTraceID = newTrace->GetSelfID(); } - - RebuildGraphRequest = Register(CreateTabletReqRebuildHistoryGraph( - SelfId(), Info.Get(), StateStorageInfo.KnownGeneration - 1, IntrospectionTrace ? newTrace.Release() : nullptr, 0) - ); - + + RebuildGraphRequest = Register(CreateTabletReqRebuildHistoryGraph( + SelfId(), Info.Get(), StateStorageInfo.KnownGeneration - 1, IntrospectionTrace ? newTrace.Release() : nullptr, 0) + ); + if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TOnTabletRebuildGraph>(RebuildGraphRequest, rebuildGraphTraceID)); } - Become(&TThis::StateRebuildGraph); - ReportTabletStateChange(TTabletStateInfo::RebuildGraph); -} - -void TTablet::WriteZeroEntry(TEvTablet::TDependencyGraph *graph) { - // rebuild zero entry - std::pair<ui32, ui32> snapshot(0, 0); - - ui32 lastGeneration = 0; - ui32 confirmedStep = 0; - ui32 lastInGeneration = 0; - + Become(&TThis::StateRebuildGraph); + ReportTabletStateChange(TTabletStateInfo::RebuildGraph); +} + +void TTablet::WriteZeroEntry(TEvTablet::TDependencyGraph *graph) { + // rebuild zero entry + std::pair<ui32, ui32> snapshot(0, 0); + + ui32 lastGeneration = 0; + ui32 confirmedStep = 0; + ui32 lastInGeneration = 0; + TDeque<TEvTablet::TDependencyGraph::TEntry>::iterator it = graph->Entries.begin(); TDeque<TEvTablet::TDependencyGraph::TEntry>::iterator end = graph->Entries.end(); - + TDeque<TEvTablet::TDependencyGraph::TEntry>::iterator snapIterator = it; TDeque<TEvTablet::TDependencyGraph::TEntry>::iterator confirmedIterator = it; - - // find tail (todo: do it in reverse order?) - for (; it != end; ++it) { - const ui32 gen = it->Id.first; - const ui32 step = it->Id.second; - - if (gen > lastGeneration) { - lastGeneration = gen; - - // do not skip unconfirmed ranges at start of generation except snapshot case - if (step == 1 || it->IsSnapshot) - confirmedStep = step; - else - confirmedStep = 0; - - confirmedIterator = it; - } - - Y_VERIFY(gen == lastGeneration); - - lastInGeneration = step; - - if (it->IsSnapshot) { - snapshot = std::pair<ui32, ui32>(gen, step); - snapIterator = it; - } - - // if see continuous confirmed range - extend it on next entry - if (confirmedStep + 1 == step) { - confirmedStep = step; - confirmedIterator = it; - } - } - + + // find tail (todo: do it in reverse order?) + for (; it != end; ++it) { + const ui32 gen = it->Id.first; + const ui32 step = it->Id.second; + + if (gen > lastGeneration) { + lastGeneration = gen; + + // do not skip unconfirmed ranges at start of generation except snapshot case + if (step == 1 || it->IsSnapshot) + confirmedStep = step; + else + confirmedStep = 0; + + confirmedIterator = it; + } + + Y_VERIFY(gen == lastGeneration); + + lastInGeneration = step; + + if (it->IsSnapshot) { + snapshot = std::pair<ui32, ui32>(gen, step); + snapIterator = it; + } + + // if see continuous confirmed range - extend it on next entry + if (confirmedStep + 1 == step) { + confirmedStep = step; + confirmedIterator = it; + } + } + if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TOnWriteZeroEntry>(snapshot, lastGeneration, confirmedStep, lastInGeneration)); } - // fill tail bitmask (beyond continuous confirmed range) (if any present) - - TAutoPtr<NKikimrTabletBase::TTabletLogEntry> entry(new NKikimrTabletBase::TTabletLogEntry()); - - entry->SetSnapshot(MakeGenStepPair(snapshot.first, snapshot.second)); - entry->SetZeroConfirmed(MakeGenStepPair(lastGeneration, confirmedStep)); - - { - const ui32 tailLength = lastInGeneration - confirmedStep; - entry->SetZeroTailSz(tailLength); - entry->MutableZeroTailBitmask()->Reserve((tailLength + 63) / 64); - - if (tailLength > 0) { - ui64 mask = 1; - ui64 value = 0; - - // if confirmed iterator points to already confirmed step - move iterator on next confirmed entry - if (confirmedStep) - ++confirmedIterator; - - for (ui32 i = confirmedStep + 1; i <= lastInGeneration; ++i) { - Y_VERIFY_DEBUG(confirmedIterator != end); - if (confirmedIterator->Id.second == i) { - value |= mask; - ++confirmedIterator; - } - - mask = mask << 1; - if (mask == 0) { - entry->MutableZeroTailBitmask()->Add(value); - mask = 1; - value = 0; - } - } - - if (mask != 1) - entry->MutableZeroTailBitmask()->Add(value); - } - } - - if (snapIterator != graph->Entries.begin()) - graph->Entries.erase(graph->Entries.begin(), snapIterator); // erase head of graph - - Graph.Snapshot = snapshot; - - const TLogoBlobID logid(TabletID(), StateStorageInfo.KnownGeneration, 0, 0, 0, 0); + // fill tail bitmask (beyond continuous confirmed range) (if any present) + + TAutoPtr<NKikimrTabletBase::TTabletLogEntry> entry(new NKikimrTabletBase::TTabletLogEntry()); + + entry->SetSnapshot(MakeGenStepPair(snapshot.first, snapshot.second)); + entry->SetZeroConfirmed(MakeGenStepPair(lastGeneration, confirmedStep)); + + { + const ui32 tailLength = lastInGeneration - confirmedStep; + entry->SetZeroTailSz(tailLength); + entry->MutableZeroTailBitmask()->Reserve((tailLength + 63) / 64); + + if (tailLength > 0) { + ui64 mask = 1; + ui64 value = 0; + + // if confirmed iterator points to already confirmed step - move iterator on next confirmed entry + if (confirmedStep) + ++confirmedIterator; + + for (ui32 i = confirmedStep + 1; i <= lastInGeneration; ++i) { + Y_VERIFY_DEBUG(confirmedIterator != end); + if (confirmedIterator->Id.second == i) { + value |= mask; + ++confirmedIterator; + } + + mask = mask << 1; + if (mask == 0) { + entry->MutableZeroTailBitmask()->Add(value); + mask = 1; + value = 0; + } + } + + if (mask != 1) + entry->MutableZeroTailBitmask()->Add(value); + } + } + + if (snapIterator != graph->Entries.begin()) + graph->Entries.erase(graph->Entries.begin(), snapIterator); // erase head of graph + + Graph.Snapshot = snapshot; + + const TLogoBlobID logid(TabletID(), StateStorageInfo.KnownGeneration, 0, 0, 0, 0); TVector<TEvTablet::TLogEntryReference> refs; - Register(CreateTabletReqWriteLog(SelfId(), logid, entry.Release(), refs, TEvBlobStorage::TEvPut::TacticMinLatency, Info.Get())); - - BLOG_D(" TTablet::WriteZeroEntry. logid# " << logid.ToString()); - - Become(&TThis::StateWriteZeroEntry); - ReportTabletStateChange(TTabletStateInfo::WriteZeroEntry); -} - -void TTablet::StartActivePhase() { - Graph.NextEntry = 1; + Register(CreateTabletReqWriteLog(SelfId(), logid, entry.Release(), refs, TEvBlobStorage::TEvPut::TacticMinLatency, Info.Get())); + + BLOG_D(" TTablet::WriteZeroEntry. logid# " << logid.ToString()); + + Become(&TThis::StateWriteZeroEntry); + ReportTabletStateChange(TTabletStateInfo::WriteZeroEntry); +} + +void TTablet::StartActivePhase() { + Graph.NextEntry = 1; Graph.MinFollowerUpdate = 1; - - Send(Launcher, new TEvTablet::TEvRestored(TabletID(), StateStorageInfo.KnownGeneration, UserTablet, false)); - Send(UserTablet, new TEvTablet::TEvRestored(TabletID(), StateStorageInfo.KnownGeneration, UserTablet, false)); - - Become(&TThis::StateActivePhase); - ReportTabletStateChange(TTabletStateInfo::Restored); - - StateStorageGuardian = Register(CreateStateStorageTabletGuardian(TabletID(), SelfId(), UserTablet, StateStorageInfo.KnownGeneration)); - - // if nowhere to sync - then declare sync done + + Send(Launcher, new TEvTablet::TEvRestored(TabletID(), StateStorageInfo.KnownGeneration, UserTablet, false)); + Send(UserTablet, new TEvTablet::TEvRestored(TabletID(), StateStorageInfo.KnownGeneration, UserTablet, false)); + + Become(&TThis::StateActivePhase); + ReportTabletStateChange(TTabletStateInfo::Restored); + + StateStorageGuardian = Register(CreateStateStorageTabletGuardian(TabletID(), SelfId(), UserTablet, StateStorageInfo.KnownGeneration)); + + // if nowhere to sync - then declare sync done TryFinishFollowerSync(); -} - -void TTablet::TryPumpWaitingForGc() { - if (WaitingForGcAck.empty()) - return; - - ui32 minConfirmedGcStep = Max<ui32>(); +} + +void TTablet::TryPumpWaitingForGc() { + if (WaitingForGcAck.empty()) + return; + + ui32 minConfirmedGcStep = Max<ui32>(); for (auto &xpair : LeaderInfo) { const TLeaderInfo &followerInfo = xpair.second; if (followerInfo.SyncState == EFollowerSyncState::Ignore) - continue; + continue; minConfirmedGcStep = Min(followerInfo.ConfirmedGCStep, minConfirmedGcStep); - } - - while (WaitingForGcAck) { - auto ackFront = WaitingForGcAck.front(); - const ui32 gcStep = ackFront.first; - if (gcStep > minConfirmedGcStep) - break; - const TInstant commitMoment = ackFront.second; - const TDuration delay = TActivationContext::Now() - commitMoment ; + } + + while (WaitingForGcAck) { + auto ackFront = WaitingForGcAck.front(); + const ui32 gcStep = ackFront.first; + if (gcStep > minConfirmedGcStep) + break; + const TInstant commitMoment = ackFront.second; + const TDuration delay = TActivationContext::Now() - commitMoment ; Send(UserTablet, new TEvTablet::TEvFollowerGcApplied(TabletID(), StateStorageInfo.KnownGeneration, gcStep, delay)); - WaitingForGcAck.pop_front(); - } -} - + WaitingForGcAck.pop_front(); + } +} + void TTablet::TryFinishFollowerSync() { if (InitialFollowerSyncDone) - return; - - // explicit state check is evil, but parallel flag is even more evil. Conceptually correct way is defining dedicated - // handlers for active/not-active phases (eg by template<bool>) but would lead to code bloat. - // So for now this check is here - if (CurrentStateFunc() != &TThis::StateActivePhase) - return; - + return; + + // explicit state check is evil, but parallel flag is even more evil. Conceptually correct way is defining dedicated + // handlers for active/not-active phases (eg by template<bool>) but would lead to code bloat. + // So for now this check is here + if (CurrentStateFunc() != &TThis::StateActivePhase) + return; + for (const auto &xpair : LeaderInfo) { EFollowerSyncState syncState = xpair.second.SyncState; if (syncState == EFollowerSyncState::NeedSync || syncState == EFollowerSyncState::Pending) - return; - } - + return; + } + InitialFollowerSyncDone = true; Send(UserTablet, new TEvTablet::TEvFollowerSyncComplete()); -} - -void TTablet::UpdateStateStorageSignature(TEvStateStorage::TEvUpdateSignature::TPtr &ev) { - const TEvStateStorage::TEvUpdateSignature *msg = ev->Get(); - StateStorageInfo.MergeSignature(msg->Signature.Get(), msg->Sz); -} - -void TTablet::HandlePingBoot(TEvTablet::TEvPing::TPtr &ev) { - // todo: handle wait-boot flag - NKikimrTabletBase::TEvPing &record = ev->Get()->Record; - Y_VERIFY(record.GetTabletID() == TabletID()); +} + +void TTablet::UpdateStateStorageSignature(TEvStateStorage::TEvUpdateSignature::TPtr &ev) { + const TEvStateStorage::TEvUpdateSignature *msg = ev->Get(); + StateStorageInfo.MergeSignature(msg->Signature.Get(), msg->Sz); +} + +void TTablet::HandlePingBoot(TEvTablet::TEvPing::TPtr &ev) { + // todo: handle wait-boot flag + NKikimrTabletBase::TEvPing &record = ev->Get()->Record; + Y_VERIFY(record.GetTabletID() == TabletID()); Send(ev->Sender, new TEvTablet::TEvPong(TabletID(), TEvTablet::TEvPong::FlagBoot | TEvTablet::TEvPong::FlagLeader)); -} - +} + void TTablet::HandlePingFollower(TEvTablet::TEvPing::TPtr &ev) { - NKikimrTabletBase::TEvPing &record = ev->Get()->Record; - Y_VERIFY(record.GetTabletID() == TabletID()); + NKikimrTabletBase::TEvPing &record = ev->Get()->Record; + Y_VERIFY(record.GetTabletID() == TabletID()); Send(ev->Sender, new TEvTablet::TEvPong(TabletID(), TEvTablet::TEvPong::FlagFollower)); -} - +} + void TTablet::HandleStateStorageLeaderResolve(TEvStateStorage::TEvInfo::TPtr &ev) { - TEvStateStorage::TEvInfo *msg = ev->Get(); - - if (msg->SignatureSz) { - StateStorageInfo.SignatureSz = msg->SignatureSz; - StateStorageInfo.Signature.Reset(msg->Signature.Release()); - } - - StateStorageInfo.KnownGeneration = msg->CurrentGeneration; - StateStorageInfo.Signature.Reset(msg->Signature.Release()); - + TEvStateStorage::TEvInfo *msg = ev->Get(); + + if (msg->SignatureSz) { + StateStorageInfo.SignatureSz = msg->SignatureSz; + StateStorageInfo.Signature.Reset(msg->Signature.Release()); + } + + StateStorageInfo.KnownGeneration = msg->CurrentGeneration; + StateStorageInfo.Signature.Reset(msg->Signature.Release()); + if (msg->Status == NKikimrProto::OK && msg->CurrentLeader) { FollowerInfo.KnownLeaderID = msg->CurrentLeader; Send(FollowerInfo.KnownLeaderID, new TEvTablet::TEvFollowerAttach(TabletID(), FollowerInfo.FollowerAttempt), - IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession); + IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession); Become(&TThis::StateFollowerSubscribe); - } else { // something goes weird, try again a bit later + } else { // something goes weird, try again a bit later NextFollowerAttempt(); - - TActivationContext::Schedule(TDuration::MilliSeconds(100), - new IEventHandle(SelfId(), SelfId(), + + TActivationContext::Schedule(TDuration::MilliSeconds(100), + new IEventHandle(SelfId(), SelfId(), new TEvTabletBase::TEvFollowerRetry(++FollowerInfo.RetryRound), 0, FollowerInfo.FollowerAttempt) - ); - } -} - + ); + } +} + void TTablet::HandleFollowerRetry(TEvTabletBase::TEvFollowerRetry::TPtr &ev) { if (ev->Cookie != FollowerInfo.FollowerAttempt) - return; - + return; + BootstrapFollower(); -} - +} + void TTablet::HandleByFollower(TEvTabletBase::TEvTryBuildFollowerGraph::TPtr &ev) { - Y_UNUSED(ev); - + Y_UNUSED(ev); + BLOG_TRACE("Follower starting to rebuild history"); - Y_VERIFY_DEBUG(!RebuildGraphRequest); + Y_VERIFY_DEBUG(!RebuildGraphRequest); RebuildGraphRequest = Register(CreateTabletReqRebuildHistoryGraph(SelfId(), Info.Get(), 0, nullptr, ++FollowerInfo.RebuildGraphCookie)); - - // todo: tracing? at least as event -} - + + // todo: tracing? at least as event +} + void TTablet::HandleByFollower(TEvTabletBase::TEvRebuildGraphResult::TPtr &ev) { if (ev->Sender != RebuildGraphRequest || ev->Cookie != FollowerInfo.RebuildGraphCookie || UserTablet) { BLOG_D("Outdated TEvRebuildGraphResult ignored"); - return; + return; } - + RebuildGraphRequest = TActorId(); // check consistency?? - TEvTabletBase::TEvRebuildGraphResult *msg = ev->Get(); + TEvTabletBase::TEvRebuildGraphResult *msg = ev->Get(); BLOG_TRACE("Follower received rebuild history result Status# " << msg->Status); - - switch (msg->Status) { - case NKikimrProto::OK: - { - UserTablet = SetupInfo->Apply(Info.Get(), SelfId()); - Send(UserTablet, + + switch (msg->Status) { + case NKikimrProto::OK: + { + UserTablet = SetupInfo->Apply(Info.Get(), SelfId()); + Send(UserTablet, new TEvTablet::TEvFBoot(TabletID(), FollowerId, 0, - Launcher, msg->DependencyGraph.Get(), Info, - ResourceProfiles, TxCacheQuota)); - - Send(Launcher, new TEvTablet::TEvRestored(TabletID(), StateStorageInfo.KnownGeneration, UserTablet, true)); - BLOG_TRACE("SBoot with rebuilt graph"); - } - break; - case NKikimrProto::NODATA: // any not-positive cases ignored and handled by long retry - default: + Launcher, msg->DependencyGraph.Get(), Info, + ResourceProfiles, TxCacheQuota)); + + Send(Launcher, new TEvTablet::TEvRestored(TabletID(), StateStorageInfo.KnownGeneration, UserTablet, true)); + BLOG_TRACE("SBoot with rebuilt graph"); + } + break; + case NKikimrProto::NODATA: // any not-positive cases ignored and handled by long retry + default: Schedule(OfflineFollowerWaitRetry, new TEvTabletBase::TEvTryBuildFollowerGraph()); - break; - } -} - + break; + } +} + bool TTablet::CheckFollowerUpdate(const TActorId &sender, ui32 attempt, ui64 counter) { if (sender != FollowerInfo.KnownLeaderID || attempt != FollowerInfo.FollowerAttempt) - return false; - + return false; + if (counter != FollowerInfo.StreamCounter) { Send(FollowerInfo.KnownLeaderID, new TEvTablet::TEvFollowerDetach(TabletID(), FollowerInfo.FollowerAttempt)); NextFollowerAttempt(); RetryFollowerBootstrapOrWait(); - return false; - } - - return true; -} - + return false; + } + + return true; +} + void TTablet::HandleByFollower(TEvents::TEvUndelivered::TPtr &ev) { if (ev->Sender == FollowerInfo.KnownLeaderID) { NextFollowerAttempt(); RetryFollowerBootstrapOrWait(); - return; + return; } - + if (ev->Sender == UserTablet && ev->Get()->SourceType == TEvTablet::TEvTabletStop::EventType) { return HandleStopped(); } -} - +} + void TTablet::HandleByFollower(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) { if (ev->Get()->NodeId != FollowerInfo.KnownLeaderID.NodeId()) - return; - + return; + BLOG_TRACE("Follower got TEvNodeDisconnected NodeId# " << ev->Get()->NodeId); NextFollowerAttempt(); RetryFollowerBootstrapOrWait(); -} - +} + void TTablet::HandleByFollower(TEvTablet::TEvFollowerDisconnect::TPtr &ev) { // sent from PassAway of leader if (ev->Sender != FollowerInfo.KnownLeaderID) - return; - + return; + BLOG_TRACE("Follower got TEvFollowerDisconnect Sender# " << ev->Sender); NextFollowerAttempt(); RetryFollowerBootstrapOrWait(); -} - +} + void TTablet::HandleByFollower(TEvTablet::TEvFollowerRefresh::TPtr &ev) { - const auto &record = ev->Get()->Record; - Y_VERIFY(record.GetTabletId() == TabletID()); + const auto &record = ev->Get()->Record; + Y_VERIFY(record.GetTabletId() == TabletID()); if (record.GetGeneration() < ExpandGenStepPair(FollowerInfo.EpochGenStep).first) { Send(ev->Sender, new TEvTablet::TEvFollowerDetach(TabletID(), Max<ui32>())); - return; - } - + return; + } + NextFollowerAttempt(); - + FollowerInfo.KnownLeaderID = ev->Sender; Send(FollowerInfo.KnownLeaderID, new TEvTablet::TEvFollowerAttach(TabletID(), FollowerInfo.FollowerAttempt), - IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession); - + IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession); + Become(&TThis::StateFollowerSubscribe); -} - +} + void TTablet::HandleByFollower(TEvTablet::TEvFollowerAuxUpdate::TPtr &ev) { - const auto &record = ev->Get()->Record; + const auto &record = ev->Get()->Record; if (!CheckFollowerUpdate(ev->Sender, record.GetFollowerAttempt(), record.GetStreamCounter())) - return; - + return; + Y_VERIFY(FollowerInfo.StreamCounter != 0); - Y_VERIFY(UserTablet); - + Y_VERIFY(UserTablet); + Send(UserTablet, new TEvTablet::TEvFAuxUpdate(record.GetAuxPayload())); - + ++FollowerInfo.StreamCounter; -} - +} + void TTablet::HandleByFollower(TEvTablet::TEvFollowerUpdate::TPtr &ev) { - const auto &record = ev->Get()->Record; - + const auto &record = ev->Get()->Record; + BLOG_TRACE("FollowerUpdate attempt: " << record.GetFollowerAttempt() << ":" << record.GetStreamCounter() - << ", " << record.GetGeneration() << ":" << record.GetStep()); - + << ", " << record.GetGeneration() << ":" << record.GetStep()); + if (!CheckFollowerUpdate(ev->Sender, record.GetFollowerAttempt(), record.GetStreamCounter())) - return; - + return; + if (FollowerInfo.StreamCounter == 0) { FollowerInfo.RetryRound = 0; // reset retry round counter to enable fast sync with leader - - // first event, must be snapshot - Y_VERIFY(record.GetIsSnapshot()); - - // update storage info for case of channel history upgrade - if (record.HasTabletStorageInfo()) { + + // first event, must be snapshot + Y_VERIFY(record.GetIsSnapshot()); + + // update storage info for case of channel history upgrade + if (record.HasTabletStorageInfo()) { Info = TabletStorageInfoFromProto(record.GetTabletStorageInfo()); - } - + } + // Drop currently running graph rebuild request if (RebuildGraphRequest) { Send(RebuildGraphRequest, new TEvents::TEvPoisonPill()); RebuildGraphRequest = TActorId(); } - if (!UserTablet) { - UserTablet = SetupInfo->Apply(Info.Get(), SelfId()); - Send(Launcher, new TEvTablet::TEvRestored(TabletID(), StateStorageInfo.KnownGeneration, UserTablet, true)); - } - + if (!UserTablet) { + UserTablet = SetupInfo->Apply(Info.Get(), SelfId()); + Send(Launcher, new TEvTablet::TEvRestored(TabletID(), StateStorageInfo.KnownGeneration, UserTablet, true)); + } + if (!FollowerStStGuardian) FollowerStStGuardian = Register(CreateStateStorageFollowerGuardian(TabletID(), SelfId())); - + FollowerInfo.EpochGenStep = MakeGenStepPair(record.GetGeneration(), record.GetStep()); - - Send(UserTablet, + + Send(UserTablet, new TEvTablet::TEvFBoot(TabletID(), FollowerId, record.GetGeneration(), Launcher, *ev->Get(), Info, ResourceProfiles, TxCacheQuota)); - + BLOG_TRACE("SBoot attempt: " << FollowerInfo.FollowerAttempt - << ", " << record.GetGeneration() << ":" << record.GetStep()); - - } else { - Y_VERIFY(UserTablet); + << ", " << record.GetGeneration() << ":" << record.GetStep()); + + } else { + Y_VERIFY(UserTablet); Send(UserTablet, new TEvTablet::TEvFUpdate(*ev->Get())); - + BLOG_TRACE("SUpdate attempt: " << FollowerInfo.FollowerAttempt - << ", " << record.GetGeneration() << ":" << record.GetStep()); - } - + << ", " << record.GetGeneration() << ":" << record.GetStep()); + } + ++FollowerInfo.StreamCounter; -} - +} + void TTablet::HandleByFollower(TEvTablet::TEvPromoteToLeader::TPtr &ev) { TEvTablet::TEvPromoteToLeader *msg = ev->Get(); BLOG_TRACE("Follower got TEvPromoteToLeader Sender# " << ev->Sender << " Generation# " << msg->SuggestedGeneration); @@ -522,74 +522,74 @@ void TTablet::HandleByFollower(TEvTablet::TEvPromoteToLeader::TPtr &ev) { , FollowerStStGuardian)); } - Info = msg->TabletStorageInfo; - + Info = msg->TabletStorageInfo; + // detach from leader if (FollowerInfo.KnownLeaderID) { Send(FollowerInfo.KnownLeaderID, new TEvTablet::TEvFollowerDetach(TabletID(), FollowerInfo.FollowerAttempt)); NextFollowerAttempt(); - } - + } + if (FollowerStStGuardian) { Send(FollowerStStGuardian, new TEvents::TEvPoisonPill()); FollowerStStGuardian = TActorId(); - } - - if (RebuildGraphRequest) { - Send(RebuildGraphRequest, new TEvents::TEvPoisonPill()); + } + + if (RebuildGraphRequest) { + Send(RebuildGraphRequest, new TEvents::TEvPoisonPill()); RebuildGraphRequest = TActorId(); - } - - // setup start info - SuggestedGeneration = msg->SuggestedGeneration; + } + + // setup start info + SuggestedGeneration = msg->SuggestedGeneration; Leader = true; FollowerId = 0; - Bootstrap(); -} - + Bootstrap(); +} + void TTablet::HandleByFollower(TEvTablet::TEvFGcAck::TPtr &ev) { const TEvTablet::TEvFGcAck *msg = ev->Get(); - + if (FollowerInfo.EpochGenStep <= MakeGenStepPair(msg->Generation, msg->Step)) Send(FollowerInfo.KnownLeaderID, new TEvTablet::TEvFollowerGcAck(TabletID(), FollowerInfo.FollowerAttempt, msg->Generation, msg->Step)); -} - +} + TMap<TActorId, TTablet::TLeaderInfo>::iterator TTablet::EraseFollowerInfo(TMap<TActorId, TLeaderInfo>::iterator followerIt) { const ui32 followerNode = followerIt->first.NodeId(); - + auto retIt = LeaderInfo.erase(followerIt); - - TryPumpWaitingForGc(); + + TryPumpWaitingForGc(); TryFinishFollowerSync(); - + if (followerNode != SelfId().NodeId()) { bool noMoreFollowersOnNode = true; for (const auto &xpair : LeaderInfo) { if (xpair.first.NodeId() == followerNode) { noMoreFollowersOnNode = false; - break; - } - } - + break; + } + } + if (noMoreFollowersOnNode) Send(TActivationContext::InterconnectProxy(followerNode), new TEvents::TEvUnsubscribe); - } - - return retIt; -} - + } + + return retIt; +} + TMap<TActorId, TTablet::TLeaderInfo>::iterator TTablet::HandleFollowerConnectionProblem(TMap<TActorId, TLeaderInfo>::iterator followerIt) { TLeaderInfo &followerInfo = followerIt->second; - bool shouldEraseEntry = false; - + bool shouldEraseEntry = false; + switch (followerInfo.SyncState) { case EFollowerSyncState::Pending: case EFollowerSyncState::Active: followerInfo.SyncState = EFollowerSyncState::NeedSync; followerInfo.SyncAttempt = 0; BLOG_D("HandleFollowerConnectionProblem " << followerIt->first << " moved to NeedSync state"); - break; + break; case EFollowerSyncState::NeedSync: if (!followerInfo.SyncCookieHolder && followerInfo.SyncAttempt > 3) { shouldEraseEntry = !followerInfo.PresentInList; @@ -597,187 +597,187 @@ TMap<TActorId, TTablet::TLeaderInfo>::iterator TTablet::HandleFollowerConnection BLOG_D("HandleFollowerConnectionProblem " << followerIt->first << " moved to Ignore state, shouldEraseEntry# " << shouldEraseEntry); } else { BLOG_D("HandleFollowerConnectionProblem " << followerIt->first << " kept in NeedSync state"); - } - break; + } + break; case EFollowerSyncState::Ignore: BLOG_D("HandleFollowerConnectionProblem " << followerIt->first << " kept in Ignore state"); - break; - } - - if (shouldEraseEntry) { + break; + } + + if (shouldEraseEntry) { followerIt = EraseFollowerInfo(followerIt); - } else { + } else { TrySyncToFollower(followerIt); ++followerIt; - } - - TryPumpWaitingForGc(); + } + + TryPumpWaitingForGc(); TryFinishFollowerSync(); - + return followerIt; -} - +} + void TTablet::TrySyncToFollower(TMap<TActorId, TLeaderInfo>::iterator followerIt) { TLeaderInfo &followerInfo = followerIt->second; if (followerInfo.SyncCookieHolder) // already awaiting - return; - + return; + TDuration delay = TDuration::MilliSeconds(250 + Min<ui32>(3, followerInfo.SyncAttempt) * 250); followerInfo.SyncCookieHolder.Reset(new TSchedulerCookieHolder(ISchedulerCookie::Make3Way())); auto *schedCookie = followerInfo.SyncCookieHolder->Get(); Schedule(delay, new TEvTabletBase::TEvTrySyncFollower(followerIt->first, schedCookie), schedCookie); -} - +} + void TTablet::DoSyncToFollower(TMap<TActorId, TLeaderInfo>::iterator followerIt) { TLeaderInfo &followerInfo = followerIt->second; - + Send(followerIt->first, new TEvTablet::TEvFollowerRefresh(TabletID(), StateStorageInfo.KnownGeneration), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession); - + ++followerInfo.SyncAttempt; followerInfo.LastSyncAttempt = TActivationContext::Now(); -} - - +} + + void TTablet::HandleByLeader(TEvents::TEvUndelivered::TPtr &ev) { auto followerIt = LeaderInfo.find(ev->Sender); if (followerIt != LeaderInfo.end()) { HandleFollowerConnectionProblem(followerIt); - return; + return; } - + if (ev->Sender == UserTablet && ev->Get()->SourceType == TEvTablet::TEvTabletStop::EventType) { return HandleStopped(); } -} - +} + void TTablet::HandleByLeader(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) { // typical number if followers on one node is one. so we don't bother with batched check for unsubscribe - // and we still need to unsubscribe 'cuz of possible races - const TEvInterconnect::TEvNodeDisconnected *msg = ev->Get(); + // and we still need to unsubscribe 'cuz of possible races + const TEvInterconnect::TEvNodeDisconnected *msg = ev->Get(); for (auto it = LeaderInfo.begin(); it != LeaderInfo.end(); ) { - if (it->first.NodeId() == msg->NodeId) + if (it->first.NodeId() == msg->NodeId) it = HandleFollowerConnectionProblem(it); - else - ++it; - } -} - + else + ++it; + } +} + void TTablet::HandleByLeader(TEvTablet::TEvFollowerListRefresh::TPtr &ev) { - auto *msg = ev->Get(); + auto *msg = ev->Get(); TMap<TActorId, TLeaderInfo>::iterator infoIt = LeaderInfo.begin(); - + for (auto it = msg->FollowerList.begin(), end = msg->FollowerList.end(); it != end; ++it) { while (infoIt != LeaderInfo.end() && infoIt->first < *it) { if (infoIt->second.SyncState == EFollowerSyncState::Ignore) { infoIt = EraseFollowerInfo(infoIt); - } else { - infoIt->second.PresentInList = false; - ++infoIt; - } - } - + } else { + infoIt->second.PresentInList = false; + ++infoIt; + } + } + if (infoIt != LeaderInfo.end() && infoIt->first == *it) - infoIt->second.PresentInList = true; - } - + infoIt->second.PresentInList = true; + } + while (infoIt != LeaderInfo.end()) { if (infoIt->second.SyncState == EFollowerSyncState::Ignore) { infoIt = EraseFollowerInfo(infoIt); - } else { - infoIt->second.PresentInList = false; - ++infoIt; - } - } -} - + } else { + infoIt->second.PresentInList = false; + ++infoIt; + } + } +} + void TTablet::HandleByLeader(TEvTabletBase::TEvTrySyncFollower::TPtr &ev) { TEvTabletBase::TEvTrySyncFollower *msg = ev->Get(); - if (msg->CookieHolder.DetachEvent()) { + if (msg->CookieHolder.DetachEvent()) { auto it = LeaderInfo.find(msg->FollowerId); if (it == LeaderInfo.end()) - return; - it->second.SyncCookieHolder.Destroy(); + return; + it->second.SyncCookieHolder.Destroy(); DoSyncToFollower(it); - } -} - + } +} + void TTablet::HandleByLeader(TEvTablet::TEvFollowerRefresh::TPtr &ev) { // could be received by promoted leader Send(ev->Sender, new TEvTablet::TEvFollowerDetach(TabletID(), Max<ui32>())); -} - +} + void TTablet::HandleByLeader(TEvTablet::TEvFollowerDetach::TPtr &ev) { // could be received by leader from promoted leader, just cleanup and wait for normal termination - const auto &record = ev->Get()->Record; + const auto &record = ev->Get()->Record; auto followerIt = LeaderInfo.find(ev->Sender); if (followerIt == LeaderInfo.end() || followerIt->second.FollowerAttempt != record.GetFollowerAttempt()) - return; + return; EraseFollowerInfo(followerIt); -} - +} + void TTablet::HandleByLeader(TEvTablet::TEvFollowerAttach::TPtr &ev) { const TActorId followerId = ev->Sender; - const auto &record = ev->Get()->Record; - + const auto &record = ev->Get()->Record; + auto followerIt = LeaderInfo.find(followerId); if (followerIt != LeaderInfo.end()) { // attaching follower known Y_VERIFY(followerIt->second.FollowerAttempt < record.GetFollowerAttempt() || followerIt->second.FollowerAttempt == Max<ui32>()); - + followerIt->second.SyncState = EFollowerSyncState::Pending; // keep ConfirmedGCStep and FromList - } else { + } else { if (LeaderInfo.empty()) { // Consider sending follower updates starting with the next commit Graph.MinFollowerUpdate = Graph.NextEntry; } auto followerItPair = LeaderInfo.insert(decltype(LeaderInfo)::value_type(ev->Sender, TLeaderInfo(EFollowerSyncState::Pending))); Y_VERIFY(followerItPair.second); - + followerIt = followerItPair.first; - } - + } + TLeaderInfo &followerInfo = followerIt->second; - + followerInfo.FollowerAttempt = record.GetFollowerAttempt(); followerInfo.StreamCounter = 0; followerInfo.SyncAttempt = 0; followerInfo.SyncCookieHolder.Destroy(); - - if (UserTablet) + + if (UserTablet) Send(UserTablet, new TEvTablet::TEvNewFollowerAttached(LeaderInfo.size())); -} - +} + void TTablet::HandleByLeader(TEvTablet::TEvFollowerGcAck::TPtr &ev) { const TActorId followerId = ev->Sender; TLeaderInfo *followerInfo = LeaderInfo.FindPtr(followerId); if (!followerInfo || followerInfo->SyncState != EFollowerSyncState::Active) - return; - - const auto &record = ev->Get()->Record; + return; + + const auto &record = ev->Get()->Record; if (record.GetGeneration() != StateStorageInfo.KnownGeneration || followerInfo->FollowerAttempt != record.GetFollowerAttempt()) - return; - - const ui32 step = record.GetStep(); + return; + + const ui32 step = record.GetStep(); Y_VERIFY_DEBUG(followerInfo->ConfirmedGCStep < step); followerInfo->ConfirmedGCStep = Max(step, followerInfo->ConfirmedGCStep); - - TryPumpWaitingForGc(); -} - -void TTablet::HandleStateStorageInfoResolve(TEvStateStorage::TEvInfo::TPtr &ev) { - TEvStateStorage::TEvInfo *msg = ev->Get(); - - if (msg->SignatureSz) { - StateStorageInfo.SignatureSz = msg->SignatureSz; - StateStorageInfo.Signature.Reset(msg->Signature.Release()); - } - - StateStorageInfo.KnownGeneration = msg->CurrentGeneration; - StateStorageInfo.KnownStep = msg->CurrentStep; - - if (SuggestedGeneration && StateStorageInfo.KnownGeneration >= SuggestedGeneration) - return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootSuggestOutdated); - + + TryPumpWaitingForGc(); +} + +void TTablet::HandleStateStorageInfoResolve(TEvStateStorage::TEvInfo::TPtr &ev) { + TEvStateStorage::TEvInfo *msg = ev->Get(); + + if (msg->SignatureSz) { + StateStorageInfo.SignatureSz = msg->SignatureSz; + StateStorageInfo.Signature.Reset(msg->Signature.Release()); + } + + StateStorageInfo.KnownGeneration = msg->CurrentGeneration; + StateStorageInfo.KnownStep = msg->CurrentStep; + + if (SuggestedGeneration && StateStorageInfo.KnownGeneration >= SuggestedGeneration) + return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootSuggestOutdated); + if (IntrospectionTrace) { IntrospectionTrace->Attach( MakeHolder<NTracing::TOnHandleStateStorageInfoResolve>( @@ -786,51 +786,51 @@ void TTablet::HandleStateStorageInfoResolve(TEvStateStorage::TEvInfo::TPtr &ev) , StateStorageInfo.SignatureSz)); } - switch (msg->Status) { - case NKikimrProto::OK: - { // enough replicas replied and we have state info now - Y_VERIFY(msg->TabletID == TabletID()); - - if (msg->Locked) { - // tablet already locked, check lock threshold or die - const ui64 lockedForThreshold = 2 * 1000 * 1000; - if (msg->LockedFor > lockedForThreshold) { - return LockedInitializationPath(); - } else { - return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootLocked); - } - } - - if (SuggestedGeneration && SuggestedGeneration <= StateStorageInfo.KnownGeneration) { - return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootRace); - } - + switch (msg->Status) { + case NKikimrProto::OK: + { // enough replicas replied and we have state info now + Y_VERIFY(msg->TabletID == TabletID()); + + if (msg->Locked) { + // tablet already locked, check lock threshold or die + const ui64 lockedForThreshold = 2 * 1000 * 1000; + if (msg->LockedFor > lockedForThreshold) { + return LockedInitializationPath(); + } else { + return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootLocked); + } + } + + if (SuggestedGeneration && SuggestedGeneration <= StateStorageInfo.KnownGeneration) { + return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootRace); + } + if (!msg->CurrentLeader || !msg->CurrentGeneration) { - return LockedInitializationPath(); - } - - BLOG_D("HandleStateStorageInfoResolve, KnownGeneration: " << msg->CurrentGeneration << " Promote"); - - return PromoteToCandidate(0); - } - case NKikimrProto::ERROR: - case NKikimrProto::RACE: - case NKikimrProto::TIMEOUT: - return LockedInitializationPath(); - default: - Y_FAIL(); - } -} - -void TTablet::HandleStateStorageInfoLock(TEvStateStorage::TEvInfo::TPtr &ev) { - const TEvStateStorage::TEvInfo *msg = ev->Get(); - - StateStorageInfo.MergeSignature(msg->Signature.Get(), msg->SignatureSz); - - switch (msg->Status) { - case NKikimrProto::OK: - { // ok, we had successfully locked state storage for synthetic generation, now find actual one - StateStorageInfo.Update(msg); + return LockedInitializationPath(); + } + + BLOG_D("HandleStateStorageInfoResolve, KnownGeneration: " << msg->CurrentGeneration << " Promote"); + + return PromoteToCandidate(0); + } + case NKikimrProto::ERROR: + case NKikimrProto::RACE: + case NKikimrProto::TIMEOUT: + return LockedInitializationPath(); + default: + Y_FAIL(); + } +} + +void TTablet::HandleStateStorageInfoLock(TEvStateStorage::TEvInfo::TPtr &ev) { + const TEvStateStorage::TEvInfo *msg = ev->Get(); + + StateStorageInfo.MergeSignature(msg->Signature.Get(), msg->SignatureSz); + + switch (msg->Status) { + case NKikimrProto::OK: + { // ok, we had successfully locked state storage for synthetic generation, now find actual one + StateStorageInfo.Update(msg); if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TOnHandleStateStorageInfoLock>( @@ -839,128 +839,128 @@ void TTablet::HandleStateStorageInfoLock(TEvStateStorage::TEvInfo::TPtr &ev) { , StateStorageInfo.SignatureSz)); } - Register(CreateTabletFindLastEntry(SelfId(), false, Info.Get(), 0)); - Become(&TThis::StateDiscover); - ReportTabletStateChange(TTabletStateInfo::Discover); - } - return; - case NKikimrProto::ERROR: - return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootSSError); - case NKikimrProto::TIMEOUT: - return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootSSTimeout); - case NKikimrProto::RACE: - return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootRace); - default: - Y_FAIL(); - } -} - -void TTablet::HandleStateStorageInfoUpgrade(TEvStateStorage::TEvInfo::TPtr &ev) { - const TEvStateStorage::TEvInfo *msg = ev->Get(); - - StateStorageInfo.MergeSignature(msg->Signature.Get(), msg->SignatureSz); - - switch (msg->Status){ - case NKikimrProto::OK: - { // ok, we marked ourselves as generation owner - NeedCleanupOnLockedPath = false; - StateStorageInfo.Update(msg); + Register(CreateTabletFindLastEntry(SelfId(), false, Info.Get(), 0)); + Become(&TThis::StateDiscover); + ReportTabletStateChange(TTabletStateInfo::Discover); + } + return; + case NKikimrProto::ERROR: + return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootSSError); + case NKikimrProto::TIMEOUT: + return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootSSTimeout); + case NKikimrProto::RACE: + return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootRace); + default: + Y_FAIL(); + } +} + +void TTablet::HandleStateStorageInfoUpgrade(TEvStateStorage::TEvInfo::TPtr &ev) { + const TEvStateStorage::TEvInfo *msg = ev->Get(); + + StateStorageInfo.MergeSignature(msg->Signature.Get(), msg->SignatureSz); + + switch (msg->Status){ + case NKikimrProto::OK: + { // ok, we marked ourselves as generation owner + NeedCleanupOnLockedPath = false; + StateStorageInfo.Update(msg); for (const auto &xpair : msg->Followers) { - if (xpair.first == SelfId()) - continue; + if (xpair.first == SelfId()) + continue; if (LeaderInfo.empty()) { // Consider sending follower updates starting with the next commit Graph.MinFollowerUpdate = Graph.NextEntry; } auto itPair = LeaderInfo.insert(decltype(LeaderInfo)::value_type(xpair.first, TLeaderInfo(EFollowerSyncState::NeedSync))); // some followers could be already present by active TEvFollowerAttach - if (itPair.second) + if (itPair.second) TrySyncToFollower(itPair.first); - } - - return TabletBlockBlobStorage(); - } - case NKikimrProto::ERROR: - return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootSSError); - case NKikimrProto::TIMEOUT: - return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootSSTimeout); - case NKikimrProto::RACE: - return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootRace); - default: - Y_FAIL(); - } -} - -void TTablet::HandleFindLatestLogEntry(TEvTabletBase::TEvFindLatestLogEntryResult::TPtr &ev) { - TEvTabletBase::TEvFindLatestLogEntryResult *msg = ev->Get(); - switch (msg->Status) { - case NKikimrProto::OK: - { - DiscoveredLastBlocked = msg->BlockedGeneration; - if (msg->Latest.Generation() > msg->BlockedGeneration + 1) { - BLOG_ERROR("HandleFindLatestLogEntry inconsistency. LatestGeneration: " - << msg->Latest.Generation() << ", blocked: " << msg->BlockedGeneration); - } - - const ui32 latestKnownGeneration = Max(msg->Latest.Generation(), msg->BlockedGeneration); - BLOG_D("HandleFindLatestLogEntry, latestKnownGeneration: " << latestKnownGeneration << " Promote"); - - return PromoteToCandidate(latestKnownGeneration); - } - case NKikimrProto::NODATA: - BLOG_D("HandleFindLatestLogEntry, NODATA Promote"); - - DiscoveredLastBlocked = 0; - return PromoteToCandidate(0); - default: - { - BLOG_ERROR("HandleFindLatestLogEntry, msg->Status: " << NKikimrProto::EReplyStatus_Name(msg->Status)); - return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootBSError, msg->ErrorReason); - } - } -} - -void TTablet::HandleBlockBlobStorageResult(TEvTabletBase::TEvBlockBlobStorageResult::TPtr &ev) { - TEvTabletBase::TEvBlockBlobStorageResult *msg = ev->Get(); - switch (msg->Status) { - case NKikimrProto::OK: - return TabletRebuildGraph(); - default: - { - BLOG_ERROR("HandleBlockBlobStorageResult, msg->Status: " << NKikimrProto::EReplyStatus_Name(msg->Status) - << (DiscoveredLastBlocked == Max<ui32>()) ? "not discovered" : Sprintf("discovered gen was: %u", DiscoveredLastBlocked).c_str()); - - return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootBSError, msg->ErrorReason); - } - } -} - -void TTablet::HandleRebuildGraphResult(TEvTabletBase::TEvRebuildGraphResult::TPtr &ev) { + } + + return TabletBlockBlobStorage(); + } + case NKikimrProto::ERROR: + return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootSSError); + case NKikimrProto::TIMEOUT: + return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootSSTimeout); + case NKikimrProto::RACE: + return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootRace); + default: + Y_FAIL(); + } +} + +void TTablet::HandleFindLatestLogEntry(TEvTabletBase::TEvFindLatestLogEntryResult::TPtr &ev) { + TEvTabletBase::TEvFindLatestLogEntryResult *msg = ev->Get(); + switch (msg->Status) { + case NKikimrProto::OK: + { + DiscoveredLastBlocked = msg->BlockedGeneration; + if (msg->Latest.Generation() > msg->BlockedGeneration + 1) { + BLOG_ERROR("HandleFindLatestLogEntry inconsistency. LatestGeneration: " + << msg->Latest.Generation() << ", blocked: " << msg->BlockedGeneration); + } + + const ui32 latestKnownGeneration = Max(msg->Latest.Generation(), msg->BlockedGeneration); + BLOG_D("HandleFindLatestLogEntry, latestKnownGeneration: " << latestKnownGeneration << " Promote"); + + return PromoteToCandidate(latestKnownGeneration); + } + case NKikimrProto::NODATA: + BLOG_D("HandleFindLatestLogEntry, NODATA Promote"); + + DiscoveredLastBlocked = 0; + return PromoteToCandidate(0); + default: + { + BLOG_ERROR("HandleFindLatestLogEntry, msg->Status: " << NKikimrProto::EReplyStatus_Name(msg->Status)); + return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootBSError, msg->ErrorReason); + } + } +} + +void TTablet::HandleBlockBlobStorageResult(TEvTabletBase::TEvBlockBlobStorageResult::TPtr &ev) { + TEvTabletBase::TEvBlockBlobStorageResult *msg = ev->Get(); + switch (msg->Status) { + case NKikimrProto::OK: + return TabletRebuildGraph(); + default: + { + BLOG_ERROR("HandleBlockBlobStorageResult, msg->Status: " << NKikimrProto::EReplyStatus_Name(msg->Status) + << (DiscoveredLastBlocked == Max<ui32>()) ? "not discovered" : Sprintf("discovered gen was: %u", DiscoveredLastBlocked).c_str()); + + return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootBSError, msg->ErrorReason); + } + } +} + +void TTablet::HandleRebuildGraphResult(TEvTabletBase::TEvRebuildGraphResult::TPtr &ev) { if (ev->Cookie != 0) // remains from follower past - return; - + return; + RebuildGraphRequest = TActorId(); // check consistency?? - - TEvTabletBase::TEvRebuildGraphResult *msg = ev->Get(); + + TEvTabletBase::TEvRebuildGraphResult *msg = ev->Get(); if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TOnRebuildGraphResult>(msg->Trace.Get())); } TIntrusivePtr<TEvTablet::TDependencyGraph> graph; - switch (msg->Status) { - case NKikimrProto::OK: + switch (msg->Status) { + case NKikimrProto::OK: graph = msg->DependencyGraph; break; - case NKikimrProto::NODATA: + case NKikimrProto::NODATA: graph = new TEvTablet::TDependencyGraph(std::pair<ui32, ui32>(0, 0)); break; - default: + default: break; } switch (msg->Status) { case NKikimrProto::OK: case NKikimrProto::NODATA: - WriteZeroEntry(graph.Get()); - Send(UserTablet, + WriteZeroEntry(graph.Get()); + Send(UserTablet, new TEvTablet::TEvBoot(TabletID(), StateStorageInfo.KnownGeneration, graph.Get(), Launcher, Info, ResourceProfiles, TxCacheQuota, @@ -968,118 +968,118 @@ void TTablet::HandleRebuildGraphResult(TEvTabletBase::TEvRebuildGraphResult::TPt std::move(msg->GroupReadOps))); return; default: - { - BLOG_ERROR("HandleRebuildGraphResult, msg->Status: " << NKikimrProto::EReplyStatus_Name(msg->Status)); - return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootBSError, msg->ErrorReason); - } - } -} - -void TTablet::HandleWriteZeroEntry(TEvTabletBase::TEvWriteLogResult::TPtr &ev) { - TEvTabletBase::TEvWriteLogResult *msg = ev->Get(); - switch (msg->Status) { - case NKikimrProto::OK: - return StartActivePhase(); - default: - { - BLOG_ERROR("HandleWriteZeroEntry, msg->Status: " << NKikimrProto::EReplyStatus_Name(msg->Status)); + { + BLOG_ERROR("HandleRebuildGraphResult, msg->Status: " << NKikimrProto::EReplyStatus_Name(msg->Status)); + return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootBSError, msg->ErrorReason); + } + } +} + +void TTablet::HandleWriteZeroEntry(TEvTabletBase::TEvWriteLogResult::TPtr &ev) { + TEvTabletBase::TEvWriteLogResult *msg = ev->Get(); + switch (msg->Status) { + case NKikimrProto::OK: + return StartActivePhase(); + default: + { + BLOG_ERROR("HandleWriteZeroEntry, msg->Status: " << NKikimrProto::EReplyStatus_Name(msg->Status)); ReassignYellowChannels(std::move(msg->YellowMoveChannels)); - return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootBSError, msg->ErrorReason); // TODO: detect 'need channel reconfiguration' case - } - } -} - -void TTablet::Handle(TEvTablet::TEvPing::TPtr &ev) { - NKikimrTabletBase::TEvPing &record = ev->Get()->Record; - Y_VERIFY(record.GetTabletID() == TabletID()); + return CancelTablet(TEvTablet::TEvTabletDead::ReasonBootBSError, msg->ErrorReason); // TODO: detect 'need channel reconfiguration' case + } + } +} + +void TTablet::Handle(TEvTablet::TEvPing::TPtr &ev) { + NKikimrTabletBase::TEvPing &record = ev->Get()->Record; + Y_VERIFY(record.GetTabletID() == TabletID()); Send(ev->Sender, new TEvTablet::TEvPong(TabletID(), TEvTablet::TEvPong::FlagLeader)); -} - +} + void TTablet::HandleByLeader(TEvTablet::TEvTabletActive::TPtr &ev) { - Y_UNUSED(ev); - ReportTabletStateChange(TTabletStateInfo::Active); - ActivateTime = AppData()->TimeProvider->Now(); - BLOG_I("Active! Generation: " << StateStorageInfo.KnownGeneration - << ", Type: " << TTabletTypes::TypeToStr((TTabletTypes::EType)Info->TabletType) - << " started in " << (ActivateTime-BoostrapTime).MilliSeconds() << "msec"); - - PipeConnectAcceptor->Activate(SelfId(), UserTablet, true); -} - + Y_UNUSED(ev); + ReportTabletStateChange(TTabletStateInfo::Active); + ActivateTime = AppData()->TimeProvider->Now(); + BLOG_I("Active! Generation: " << StateStorageInfo.KnownGeneration + << ", Type: " << TTabletTypes::TypeToStr((TTabletTypes::EType)Info->TabletType) + << " started in " << (ActivateTime-BoostrapTime).MilliSeconds() << "msec"); + + PipeConnectAcceptor->Activate(SelfId(), UserTablet, true); +} + void TTablet::HandleByFollower(TEvTablet::TEvTabletActive::TPtr &ev) { - Y_UNUSED(ev); + Y_UNUSED(ev); BLOG_D("Follower TabletStateActive"); - - PipeConnectAcceptor->Activate(SelfId(), UserTablet, false); - + + PipeConnectAcceptor->Activate(SelfId(), UserTablet, false); + Send(FollowerStStGuardian, new TEvTablet::TEvFollowerUpdateState(false, SelfId(), UserTablet)); - ReportTabletStateChange(TTabletStateInfo::Active); -} - -TTablet::TLogEntry* TTablet::MakeLogEntry(TEvTablet::TCommitInfo &commitInfo, NKikimrTabletBase::TTabletLogEntry *commitEv) { + ReportTabletStateChange(TTabletStateInfo::Active); +} + +TTablet::TLogEntry* TTablet::MakeLogEntry(TEvTablet::TCommitInfo &commitInfo, NKikimrTabletBase::TTabletLogEntry *commitEv) { Y_VERIFY(commitInfo.TabletID == TabletID() && commitInfo.Generation == StateStorageInfo.KnownGeneration && commitInfo.Step == Graph.NextEntry, "commitInfo.TabletID=%ld, tablet=%ld, commitInfo.Generation=%d, KnownGeneration=%d, commitInfo.Step=%d, nextEntry=%d", commitInfo.TabletID, TabletID(), commitInfo.Generation, StateStorageInfo.KnownGeneration, commitInfo.Step, Graph.NextEntry); - - const ui32 step = Graph.NextEntry++; - - TLogEntry *entry = new TLogEntry(step, Graph.Confirmed, 0); + + const ui32 step = Graph.NextEntry++; + + TLogEntry *entry = new TLogEntry(step, Graph.Confirmed, 0); Graph.Queue.push_back(std::unique_ptr<TLogEntry>(entry)); - Graph.Index[step] = entry; - entry->IsSnapshot = commitInfo.IsSnapshot || commitInfo.IsTotalSnapshot; - entry->IsTotalSnapshot = commitInfo.IsTotalSnapshot; + Graph.Index[step] = entry; + entry->IsSnapshot = commitInfo.IsSnapshot || commitInfo.IsTotalSnapshot; + entry->IsTotalSnapshot = commitInfo.IsTotalSnapshot; entry->Source = TActorId(); - - for (ui32 dependsOn : commitInfo.DependsOn) { - TGraph::TIndex::iterator it = Graph.Index.find(dependsOn); - if (it != Graph.Index.end()) { - if (commitEv) - commitEv->AddDependsOn(dependsOn); - it->second->Dependent.push_back(step); - ++entry->DependenciesLeft; - } - } - - return entry; -} - -TTablet::TLogEntry* TTablet::FindLogEntry(TEvTablet::TCommitInfo &commitInfo, NKikimrTabletBase::TTabletLogEntry &commitEv) { - TLogEntry **entryPtr = Graph.Index.FindPtr(commitInfo.Step); - if (!entryPtr) - return nullptr; - TLogEntry *entry = *entryPtr; - - if (entry->IsSnapshot != commitInfo.IsSnapshot || entry->IsTotalSnapshot != commitInfo.IsTotalSnapshot) - return nullptr; - - for (ui32 dependsOn : commitInfo.DependsOn) { - TGraph::TIndex::iterator it = Graph.Index.find(dependsOn); - if (it != Graph.Index.end()) - commitEv.AddDependsOn(dependsOn); - } - - if (commitEv.DependsOnSize() != entry->DependenciesLeft) - return nullptr; - - return entry; -} - -void TTablet::Handle(TEvTablet::TEvPreCommit::TPtr &ev) { - TEvTablet::TEvPreCommit *msg = ev->Get(); - MakeLogEntry(*msg, nullptr); -} - -void TTablet::Handle(TEvTablet::TEvAux::TPtr &ev) { + + for (ui32 dependsOn : commitInfo.DependsOn) { + TGraph::TIndex::iterator it = Graph.Index.find(dependsOn); + if (it != Graph.Index.end()) { + if (commitEv) + commitEv->AddDependsOn(dependsOn); + it->second->Dependent.push_back(step); + ++entry->DependenciesLeft; + } + } + + return entry; +} + +TTablet::TLogEntry* TTablet::FindLogEntry(TEvTablet::TCommitInfo &commitInfo, NKikimrTabletBase::TTabletLogEntry &commitEv) { + TLogEntry **entryPtr = Graph.Index.FindPtr(commitInfo.Step); + if (!entryPtr) + return nullptr; + TLogEntry *entry = *entryPtr; + + if (entry->IsSnapshot != commitInfo.IsSnapshot || entry->IsTotalSnapshot != commitInfo.IsTotalSnapshot) + return nullptr; + + for (ui32 dependsOn : commitInfo.DependsOn) { + TGraph::TIndex::iterator it = Graph.Index.find(dependsOn); + if (it != Graph.Index.end()) + commitEv.AddDependsOn(dependsOn); + } + + if (commitEv.DependsOnSize() != entry->DependenciesLeft) + return nullptr; + + return entry; +} + +void TTablet::Handle(TEvTablet::TEvPreCommit::TPtr &ev) { + TEvTablet::TEvPreCommit *msg = ev->Get(); + MakeLogEntry(*msg, nullptr); +} + +void TTablet::Handle(TEvTablet::TEvAux::TPtr &ev) { TString& auxUpdate = ev->Get()->FollowerAux; - - if (!Graph.Queue.empty()) { + + if (!Graph.Queue.empty()) { Graph.Queue.back()->FollowerAuxUpdates.emplace_back(std::move(auxUpdate)); - } else { + } else { SpreadFollowerAuxUpdate(auxUpdate); - } -} - -void TTablet::Handle(TEvTablet::TEvCommit::TPtr &ev) { + } +} + +void TTablet::Handle(TEvTablet::TEvCommit::TPtr &ev) { if (Graph.StepsInFlight >= MaxStepsInFlight || Graph.BytesInFlight >= MaxBytesInFlight) { // Delay commit handling until inflight goes down Graph.DelayCommitQueue.push_back(std::move(ev)); @@ -1091,79 +1091,79 @@ void TTablet::Handle(TEvTablet::TEvCommit::TPtr &ev) { } bool TTablet::HandleNext(TEvTablet::TEvCommit::TPtr &ev) { - TEvTablet::TEvCommit *msg = ev->Get(); - + TEvTablet::TEvCommit *msg = ev->Get(); + std::unique_ptr<NKikimrTabletBase::TTabletLogEntry> x(new NKikimrTabletBase::TTabletLogEntry()); - + TLogEntry *entry = msg->PreCommited ? FindLogEntry(*msg, *x) : MakeLogEntry(*msg, x.get()); - + if (entry == nullptr) { CancelTablet(TEvTablet::TEvTabletDead::ReasonInconsistentCommit); return false; } - - entry->Source = ev->Sender; - entry->SourceCookie = ev->Cookie; + + entry->Source = ev->Sender; + entry->SourceCookie = ev->Cookie; entry->WaitFollowerGcAck = msg->WaitFollowerGcAck; - - x->SetSnapshot(MakeGenStepPair(Graph.Snapshot.first, Graph.Snapshot.second)); - x->SetConfirmed(Graph.Confirmed); - + + x->SetSnapshot(MakeGenStepPair(Graph.Snapshot.first, Graph.Snapshot.second)); + x->SetConfirmed(Graph.Confirmed); + const bool saveFollowerUpdate = !LeaderInfo.empty(); if (saveFollowerUpdate) entry->FollowerUpdate.Reset(new TFollowerUpdate()); - - if (entry->IsSnapshot) - x->SetIsSnapshot(true); - if (entry->IsTotalSnapshot) - x->SetIsTotalSnapshot(true); - - x->MutableReferences()->Reserve((i32)(msg->ExternalReferences.size() + msg->References.size())); - + + if (entry->IsSnapshot) + x->SetIsSnapshot(true); + if (entry->IsTotalSnapshot) + x->SetIsTotalSnapshot(true); + + x->MutableReferences()->Reserve((i32)(msg->ExternalReferences.size() + msg->References.size())); + if (saveFollowerUpdate) entry->FollowerUpdate->References.reserve(msg->References.size()); - + for (TVector<TLogoBlobID>::const_iterator it = msg->ExternalReferences.begin(), end = msg->ExternalReferences.end(); it != end; ++it) - LogoBlobIDFromLogoBlobID(*it, x->AddReferences()); - + LogoBlobIDFromLogoBlobID(*it, x->AddReferences()); + for (TVector<TEvTablet::TLogEntryReference>::const_iterator it = msg->References.begin(), end = msg->References.end(); it != end; ++it) { - const TLogoBlobID &id = it->Id; - Y_VERIFY(id.TabletID() == TabletID() && id.Generation() == StateStorageInfo.KnownGeneration); - LogoBlobIDFromLogoBlobID(id, x->AddReferences()); - + const TLogoBlobID &id = it->Id; + Y_VERIFY(id.TabletID() == TabletID() && id.Generation() == StateStorageInfo.KnownGeneration); + LogoBlobIDFromLogoBlobID(id, x->AddReferences()); + if (saveFollowerUpdate) entry->FollowerUpdate->References.push_back(std::make_pair(it->Id, it->Buffer)); - } - - if (!msg->GcDiscovered.empty()) { - x->MutableGcDiscovered()->Reserve((i32)msg->GcDiscovered.size()); - for (auto &gcx : msg->GcDiscovered) - LogoBlobIDFromLogoBlobID(gcx, x->AddGcDiscovered()); - + } + + if (!msg->GcDiscovered.empty()) { + x->MutableGcDiscovered()->Reserve((i32)msg->GcDiscovered.size()); + for (auto &gcx : msg->GcDiscovered) + LogoBlobIDFromLogoBlobID(gcx, x->AddGcDiscovered()); + if (saveFollowerUpdate) entry->FollowerUpdate->GcDiscovered.swap(msg->GcDiscovered); - } - - if (!msg->GcLeft.empty()) { - x->MutableGcLeft()->Reserve((i32)msg->GcLeft.size()); - for (auto &gcx : msg->GcLeft) - LogoBlobIDFromLogoBlobID(gcx, x->AddGcLeft()); - + } + + if (!msg->GcLeft.empty()) { + x->MutableGcLeft()->Reserve((i32)msg->GcLeft.size()); + for (auto &gcx : msg->GcLeft) + LogoBlobIDFromLogoBlobID(gcx, x->AddGcLeft()); + if (saveFollowerUpdate) entry->FollowerUpdate->GcLeft.swap(msg->GcLeft); - } - - if (msg->EmbeddedLogBody) { - Y_VERIFY(x->ReferencesSize() == 0); - x->SetEmbeddedLogBody(msg->EmbeddedLogBody); - + } + + if (msg->EmbeddedLogBody) { + Y_VERIFY(x->ReferencesSize() == 0); + x->SetEmbeddedLogBody(msg->EmbeddedLogBody); + if (saveFollowerUpdate) entry->FollowerUpdate->Body = msg->EmbeddedLogBody; - } - + } + if (saveFollowerUpdate && msg->FollowerAux) entry->FollowerUpdate->AuxPayload = msg->FollowerAux; - + entry->ByteSize = x->ByteSizeLong(); for (const auto& ref : msg->References) { entry->ByteSize += ref.Buffer.size(); @@ -1174,43 +1174,43 @@ bool TTablet::HandleNext(TEvTablet::TEvCommit::TPtr &ev) { return true; } - const TLogoBlobID logid(TabletID(), StateStorageInfo.KnownGeneration, entry->Step, 0, 0, 0); - - entry->StateStorageConfirmed = true; // todo: do real query against state-storage (optionally?) - entry->Task = Register( + const TLogoBlobID logid(TabletID(), StateStorageInfo.KnownGeneration, entry->Step, 0, 0, 0); + + entry->StateStorageConfirmed = true; // todo: do real query against state-storage (optionally?) + entry->Task = Register( CreateTabletReqWriteLog(SelfId(), logid, x.release(), msg->References, msg->CommitTactic, Info.Get()) - ); + ); Graph.StepsInFlight += 1; Graph.BytesInFlight += entry->ByteSize; return true; -} - -void TTablet::CheckEntry(TGraph::TIndex::iterator it) { - ui32 step = it->first; - TLogEntry *entry = it->second; - - if (!entry->BlobStorageConfirmed || !entry->StateStorageConfirmed || entry->DependenciesLeft > 0) - return; - - TStackVec<ui32> cleanupQueue; - do { - while (!entry && cleanupQueue) { - it = Graph.Index.find(cleanupQueue.back()); - cleanupQueue.pop_back(); - Y_VERIFY(it != Graph.Index.end()); - TLogEntry *ex = it->second; - if (--ex->DependenciesLeft == 0 && ex->StateStorageConfirmed && ex->BlobStorageConfirmed) { - step = it->first; - entry = ex; - } - } - - while (entry) { - Graph.Index.erase(it); - entry->Commited = true; - entry->CommitedMoment = TActivationContext::Now(); - Send(entry->Source, +} + +void TTablet::CheckEntry(TGraph::TIndex::iterator it) { + ui32 step = it->first; + TLogEntry *entry = it->second; + + if (!entry->BlobStorageConfirmed || !entry->StateStorageConfirmed || entry->DependenciesLeft > 0) + return; + + TStackVec<ui32> cleanupQueue; + do { + while (!entry && cleanupQueue) { + it = Graph.Index.find(cleanupQueue.back()); + cleanupQueue.pop_back(); + Y_VERIFY(it != Graph.Index.end()); + TLogEntry *ex = it->second; + if (--ex->DependenciesLeft == 0 && ex->StateStorageConfirmed && ex->BlobStorageConfirmed) { + step = it->first; + entry = ex; + } + } + + while (entry) { + Graph.Index.erase(it); + entry->Commited = true; + entry->CommitedMoment = TActivationContext::Now(); + Send(entry->Source, new TEvTablet::TEvCommitResult( NKikimrProto::OK, TabletID(), @@ -1222,37 +1222,37 @@ void TTablet::CheckEntry(TGraph::TIndex::iterator it) { std::move(entry->GroupWrittenBytes), std::move(entry->GroupWrittenOps)), 0, entry->SourceCookie); - - const auto &dependent = entry->Dependent; - entry = nullptr; - step = 0; - - for (ui32 i : dependent) { - if (entry) - cleanupQueue.push_back(i); - else { - it = Graph.Index.find(i); - Y_VERIFY(it != Graph.Index.end()); - TLogEntry *ex = it->second; - if (--ex->DependenciesLeft == 0 && ex->StateStorageConfirmed && ex->BlobStorageConfirmed) { - step = it->first; - entry = ex; - } - } - } - } - } while (cleanupQueue); -} - -void TTablet::Handle(TEvBlobStorage::TEvCollectGarbageResult::TPtr &ev) { - Y_VERIFY(GcInFly > 0); - --GcInFly; - + + const auto &dependent = entry->Dependent; + entry = nullptr; + step = 0; + + for (ui32 i : dependent) { + if (entry) + cleanupQueue.push_back(i); + else { + it = Graph.Index.find(i); + Y_VERIFY(it != Graph.Index.end()); + TLogEntry *ex = it->second; + if (--ex->DependenciesLeft == 0 && ex->StateStorageConfirmed && ex->BlobStorageConfirmed) { + step = it->first; + entry = ex; + } + } + } + } + } while (cleanupQueue); +} + +void TTablet::Handle(TEvBlobStorage::TEvCollectGarbageResult::TPtr &ev) { + Y_VERIFY(GcInFly > 0); + --GcInFly; + TEvBlobStorage::TEvCollectGarbageResult *msg = ev->Get(); switch (msg->Status) { - case NKikimrProto::RACE: - case NKikimrProto::BLOCKED: + case NKikimrProto::RACE: + case NKikimrProto::BLOCKED: case NKikimrProto::NO_GROUP: // We want to stop after current graph is committed if (BlobStorageStatus == NKikimrProto::OK) { @@ -1266,106 +1266,106 @@ void TTablet::Handle(TEvBlobStorage::TEvCollectGarbageResult::TPtr &ev) { if (GcInFly == 0 && GcNextStep != 0) { GcLogChannel(std::exchange(GcNextStep, 0)); } - return; - } + return; + } CheckBlobStorageError(); -} - -void TTablet::GcLogChannel(ui32 step) { - const ui64 tabletid = TabletID(); - const ui32 gen = StateStorageInfo.KnownGeneration; - +} + +void TTablet::GcLogChannel(ui32 step) { + const ui64 tabletid = TabletID(); + const ui32 gen = StateStorageInfo.KnownGeneration; + if (GcInFly != 0 || Graph.SyncCommit.SyncStep != 0 && Graph.SyncCommit.SyncStep <= step) { if (GcInFlyStep < step) { BLOG_D("GcCollect 0 channel postponed, tablet:gen:step => " << gen << ":" << step); GcNextStep = step; return; } - BLOG_D("GcCollect 0 channel skipped, tablet:gen:step => " << gen << ":" << step); - return; - } - - BLOG_D("GcCollect 0 channel, tablet:gen:step => " << gen << ":" << step); - - const TTabletChannelInfo *channelInfo = Info->ChannelInfo(0); - if (GcCounter == 0) { + BLOG_D("GcCollect 0 channel skipped, tablet:gen:step => " << gen << ":" << step); + return; + } + + BLOG_D("GcCollect 0 channel, tablet:gen:step => " << gen << ":" << step); + + const TTabletChannelInfo *channelInfo = Info->ChannelInfo(0); + if (GcCounter == 0) { TSet<ui32> alreadySent; - for (const auto &x : channelInfo->History) { - const ui32 groupId = x.GroupID; - if (!alreadySent.insert(groupId).second) - continue; - ++GcInFly; - SendToBSProxy(SelfId(), groupId, - new TEvBlobStorage::TEvCollectGarbage( - tabletid, gen, ++GcCounter, 0, - true, - gen, step, + for (const auto &x : channelInfo->History) { + const ui32 groupId = x.GroupID; + if (!alreadySent.insert(groupId).second) + continue; + ++GcInFly; + SendToBSProxy(SelfId(), groupId, + new TEvBlobStorage::TEvCollectGarbage( + tabletid, gen, ++GcCounter, 0, + true, + gen, step, nullptr, nullptr, TInstant::Max(), false - ) - ); - } - } else { - ++GcInFly; - SendToBSProxy(SelfId(), channelInfo->LatestEntry()->GroupID, - new TEvBlobStorage::TEvCollectGarbage( - tabletid, gen, ++GcCounter, 0, - true, - gen, step, + ) + ); + } + } else { + ++GcInFly; + SendToBSProxy(SelfId(), channelInfo->LatestEntry()->GroupID, + new TEvBlobStorage::TEvCollectGarbage( + tabletid, gen, ++GcCounter, 0, + true, + gen, step, nullptr, nullptr, TInstant::Max(), false - ) - ); - } + ) + ); + } GcInFlyStep = step; GcNextStep = 0; -} - +} + void TTablet::SpreadFollowerAuxUpdate(const TString& auxUpdate) { for (auto &xpair : LeaderInfo) { SendFollowerAuxUpdate(xpair.second, xpair.first, auxUpdate); } } - + void TTablet::SendFollowerAuxUpdate(TLeaderInfo& info, const TActorId& follower, const TString& auxUpdate) { if (info.FollowerAttempt == Max<ui32>()) return; if (info.StreamCounter == 0) return; - + const ui64 tabletId = TabletID(); auto notify = MakeHolder<TEvTablet::TEvFollowerAuxUpdate>(tabletId, info.FollowerAttempt, info.StreamCounter); notify->Record.SetAuxPayload(auxUpdate); Send(follower, notify.Release(), 0, IEventHandle::FlagTrackDelivery); ++info.StreamCounter; -} - +} + bool TTablet::ProgressCommitQueue() { - const ui64 tabletId = TabletID(); - while (!Graph.Queue.empty()) { + const ui64 tabletId = TabletID(); + while (!Graph.Queue.empty()) { TLogEntry *entry = Graph.Queue.front().get(); - if (!entry->Commited) - break; - - const ui32 step = entry->Step; - - if (entry->IsSnapshot) { - Graph.Snapshot = std::pair<ui32, ui32>(StateStorageInfo.KnownGeneration, step); - GcLogChannel(entry->ConfirmedOnSend); - } - + if (!entry->Commited) + break; + + const ui32 step = entry->Step; + + if (entry->IsSnapshot) { + Graph.Snapshot = std::pair<ui32, ui32>(StateStorageInfo.KnownGeneration, step); + GcLogChannel(entry->ConfirmedOnSend); + } + if (entry->FollowerUpdate && LeaderInfo && step >= Graph.MinFollowerUpdate) { Graph.PostponedFollowerUpdates.emplace_back(std::move(Graph.Queue.front())); } else if (entry->WaitFollowerGcAck) { Send(UserTablet, new TEvTablet::TEvFollowerGcApplied(tabletId, StateStorageInfo.KnownGeneration, step, TDuration::Max())); - } - - Graph.Confirmed = step; - Graph.Queue.pop_front(); - } - + } + + Graph.Confirmed = step; + Graph.Queue.pop_front(); + } + if (CheckBlobStorageError()) { return false; } @@ -1373,19 +1373,19 @@ bool TTablet::ProgressCommitQueue() { ProgressFollowerQueue(); TryFinishFollowerSync(); return true; -} - +} + void TTablet::ProgressFollowerQueue() { const ui32 goodUntil = LeaderInfo ? Graph.ConfirmedCommited : Max<ui32>(); - + while (!Graph.PostponedFollowerUpdates.empty()) { TLogEntry *entry = Graph.PostponedFollowerUpdates.front().get(); - const ui32 step = entry->Step; - if (step > goodUntil) - break; - + const ui32 step = entry->Step; + if (step > goodUntil) + break; + auto *sup = entry->FollowerUpdate.Get(); - + bool needWaitForFollowerGcAck = false; for (auto &xpair : LeaderInfo) { if (step < Graph.MinFollowerUpdate) { @@ -1396,166 +1396,166 @@ void TTablet::ProgressFollowerQueue() { } TLeaderInfo &followerInfo = xpair.second; - + if (!needWaitForFollowerGcAck) { if (followerInfo.SyncState != EFollowerSyncState::Ignore) needWaitForFollowerGcAck = true; - } - + } + if (followerInfo.FollowerAttempt == Max<ui32>()) - continue; - + continue; + if (followerInfo.SyncState == EFollowerSyncState::Active || followerInfo.SyncState == EFollowerSyncState::Pending && entry->IsSnapshot) - { + { auto notify = MakeHolder<TEvTablet::TEvFollowerUpdate>(TabletID(), followerInfo.FollowerAttempt, followerInfo.StreamCounter); - auto &record = notify->Record; - - record.SetGeneration(StateStorageInfo.KnownGeneration); - record.SetStep(step); - record.SetIsSnapshot(entry->IsSnapshot); + auto &record = notify->Record; + + record.SetGeneration(StateStorageInfo.KnownGeneration); + record.SetStep(step); + record.SetIsSnapshot(entry->IsSnapshot); record.SetNeedGCApplyAck(entry->WaitFollowerGcAck); - - if (sup->Body) - record.SetBody(sup->Body); - - if (sup->AuxPayload) - record.SetAuxPayload(sup->AuxPayload); - - if (sup->References) { - record.MutableReferences()->Reserve(sup->References.size()); - record.MutableReferencesIds()->Reserve(sup->References.size()); - - for (auto &refpair : sup->References) { - record.AddReferences(refpair.second); - LogoBlobIDFromLogoBlobID(refpair.first, record.AddReferencesIds()); - } - } - + + if (sup->Body) + record.SetBody(sup->Body); + + if (sup->AuxPayload) + record.SetAuxPayload(sup->AuxPayload); + + if (sup->References) { + record.MutableReferences()->Reserve(sup->References.size()); + record.MutableReferencesIds()->Reserve(sup->References.size()); + + for (auto &refpair : sup->References) { + record.AddReferences(refpair.second); + LogoBlobIDFromLogoBlobID(refpair.first, record.AddReferencesIds()); + } + } + if (followerInfo.StreamCounter == 0) { - TabletStorageInfoToProto(*Info, record.MutableTabletStorageInfo()); + TabletStorageInfoToProto(*Info, record.MutableTabletStorageInfo()); followerInfo.SyncState = EFollowerSyncState::Active; - } - + } + const ui32 subscFlag = (followerInfo.StreamCounter == 0) ? IEventHandle::FlagSubscribeOnSession : 0; - Send(xpair.first, notify.Release(), IEventHandle::FlagTrackDelivery | subscFlag); - - ++xpair.second.StreamCounter; - } - + Send(xpair.first, notify.Release(), IEventHandle::FlagTrackDelivery | subscFlag); + + ++xpair.second.StreamCounter; + } + for (const TString &x : entry->FollowerAuxUpdates) SendFollowerAuxUpdate(xpair.second, xpair.first, x); - } - + } + if (entry->WaitFollowerGcAck) { if (needWaitForFollowerGcAck) { - WaitingForGcAck.emplace_back(step, entry->CommitedMoment); - } else { + WaitingForGcAck.emplace_back(step, entry->CommitedMoment); + } else { Send(UserTablet, new TEvTablet::TEvFollowerGcApplied(TabletID(), StateStorageInfo.KnownGeneration, step, TDuration::Max())); - } - } - + } + } + Graph.PostponedFollowerUpdates.pop_front(); } - + if (Graph.PostponedFollowerUpdates && Graph.Queue.empty() && Graph.SyncCommit.SyncStep == 0) { - Graph.SyncCommit.SyncStep = Graph.NextEntry - 1; + Graph.SyncCommit.SyncStep = Graph.NextEntry - 1; if (GcInFly) { // Since we always confirm the last commit it should be impossible // to ever try to commit inside a garbage collected range. Y_VERIFY_DEBUG(GcInFlyStep < Graph.SyncCommit.SyncStep); Y_VERIFY_DEBUG(GcNextStep < Graph.SyncCommit.SyncStep); } - - TLogoBlobID entryId(TabletID(), StateStorageInfo.KnownGeneration, Graph.SyncCommit.SyncStep, 0, 0, 1); - THolder<NKikimrTabletBase::TTabletLogEntry> entry(new NKikimrTabletBase::TTabletLogEntry()); - - entry->SetSnapshot(MakeGenStepPair(Graph.Snapshot.first, Graph.Snapshot.second)); - entry->SetConfirmed(Graph.Confirmed); - entry->SetIsSnapshot(false); - entry->SetIsTotalSnapshot(false); - - Y_VERIFY_DEBUG(Graph.Confirmed == Graph.SyncCommit.SyncStep); // last entry must be confirmed - Y_VERIFY_DEBUG(Graph.SyncCommit.SyncStep > Graph.ConfirmedCommited); // commit should make some progress - - TVector<TEvTablet::TLogEntryReference> refs; - Register( - CreateTabletReqWriteLog(SelfId(), entryId, entry.Release(), refs, TEvBlobStorage::TEvPut::ETactic::TacticMinLatency, Info.Get()) - ); - } -} - -void TTablet::Handle(TEvTabletPipe::TEvConnect::TPtr& ev) { + + TLogoBlobID entryId(TabletID(), StateStorageInfo.KnownGeneration, Graph.SyncCommit.SyncStep, 0, 0, 1); + THolder<NKikimrTabletBase::TTabletLogEntry> entry(new NKikimrTabletBase::TTabletLogEntry()); + + entry->SetSnapshot(MakeGenStepPair(Graph.Snapshot.first, Graph.Snapshot.second)); + entry->SetConfirmed(Graph.Confirmed); + entry->SetIsSnapshot(false); + entry->SetIsTotalSnapshot(false); + + Y_VERIFY_DEBUG(Graph.Confirmed == Graph.SyncCommit.SyncStep); // last entry must be confirmed + Y_VERIFY_DEBUG(Graph.SyncCommit.SyncStep > Graph.ConfirmedCommited); // commit should make some progress + + TVector<TEvTablet::TLogEntryReference> refs; + Register( + CreateTabletReqWriteLog(SelfId(), entryId, entry.Release(), refs, TEvBlobStorage::TEvPut::ETactic::TacticMinLatency, Info.Get()) + ); + } +} + +void TTablet::Handle(TEvTabletPipe::TEvConnect::TPtr& ev) { if (PipeConnectAcceptor->IsStopped()) { PipeConnectAcceptor->Reject(ev, SelfId(), NKikimrProto::TRYLATER, Leader); } else if (PipeConnectAcceptor->IsActive()) { PipeConnectAcceptor->Accept(ev, SelfId(), UserTablet, Leader); } else { - PipeConnectAcceptor->Enqueue(ev, SelfId()); + PipeConnectAcceptor->Enqueue(ev, SelfId()); } -} +} -void TTablet::Handle(TEvTabletPipe::TEvServerDestroyed::TPtr& ev) { - PipeConnectAcceptor->Erase(ev); -} - -void TTablet::HandleQueued(TEvTabletPipe::TEvConnect::TPtr& ev) { +void TTablet::Handle(TEvTabletPipe::TEvServerDestroyed::TPtr& ev) { + PipeConnectAcceptor->Erase(ev); +} + +void TTablet::HandleQueued(TEvTabletPipe::TEvConnect::TPtr& ev) { if (PipeConnectAcceptor->IsStopped()) { // FIXME: do we really need it? PipeConnectAcceptor->Reject(ev, SelfId(), NKikimrProto::TRYLATER, Leader); } else { PipeConnectAcceptor->Enqueue(ev, SelfId()); } -} - +} + void TTablet::HandleByFollower(TEvTabletPipe::TEvConnect::TPtr &ev) { Y_VERIFY_DEBUG(!Leader); if (PipeConnectAcceptor->IsActive() && !PipeConnectAcceptor->IsStopped()) { - PipeConnectAcceptor->Accept(ev, SelfId(), UserTablet, false); - } else { - PipeConnectAcceptor->Reject(ev, SelfId(), NKikimrProto::TRYLATER, false); - } -} - -void TTablet::Handle(TEvTabletBase::TEvWriteLogResult::TPtr &ev) { - TEvTabletBase::TEvWriteLogResult *msg = ev->Get(); - const NKikimrProto::EReplyStatus status = msg->Status; + PipeConnectAcceptor->Accept(ev, SelfId(), UserTablet, false); + } else { + PipeConnectAcceptor->Reject(ev, SelfId(), NKikimrProto::TRYLATER, false); + } +} + +void TTablet::Handle(TEvTabletBase::TEvWriteLogResult::TPtr &ev) { + TEvTabletBase::TEvWriteLogResult *msg = ev->Get(); + const NKikimrProto::EReplyStatus status = msg->Status; const TLogoBlobID &logid = msg->EntryId; - - // todo: channel reconfiguration - switch (status) { - case NKikimrProto::OK: - { - Y_VERIFY_DEBUG(logid.Generation() == StateStorageInfo.KnownGeneration && logid.TabletID() == TabletID()); - const ui32 step = logid.Step(); - - if (logid.Cookie() == 0) { - TGraph::TIndex::iterator indexIt = Graph.Index.find(step); - - Y_VERIFY(indexIt != Graph.Index.end()); - - TLogEntry *entry = indexIt->second; - entry->BlobStorageConfirmed = true; + + // todo: channel reconfiguration + switch (status) { + case NKikimrProto::OK: + { + Y_VERIFY_DEBUG(logid.Generation() == StateStorageInfo.KnownGeneration && logid.TabletID() == TabletID()); + const ui32 step = logid.Step(); + + if (logid.Cookie() == 0) { + TGraph::TIndex::iterator indexIt = Graph.Index.find(step); + + Y_VERIFY(indexIt != Graph.Index.end()); + + TLogEntry *entry = indexIt->second; + entry->BlobStorageConfirmed = true; entry->YellowMoveChannels = std::move(msg->YellowMoveChannels); entry->YellowStopChannels = std::move(msg->YellowStopChannels); - entry->GroupWrittenBytes = std::move(msg->GroupWrittenBytes); - entry->GroupWrittenOps = std::move(msg->GroupWrittenOps); - - Graph.ConfirmedCommited = Max(Graph.ConfirmedCommited, entry->ConfirmedOnSend); + entry->GroupWrittenBytes = std::move(msg->GroupWrittenBytes); + entry->GroupWrittenOps = std::move(msg->GroupWrittenOps); + + Graph.ConfirmedCommited = Max(Graph.ConfirmedCommited, entry->ConfirmedOnSend); Graph.StepsInFlight -= 1; Graph.BytesInFlight -= entry->ByteSize; - - CheckEntry(indexIt); - } else { - Y_VERIFY_DEBUG(logid.Cookie() == 1 && step == Graph.SyncCommit.SyncStep); - - Graph.ConfirmedCommited = Max(Graph.ConfirmedCommited, step); - Graph.SyncCommit.SyncStep = 0; + + CheckEntry(indexIt); + } else { + Y_VERIFY_DEBUG(logid.Cookie() == 1 && step == Graph.SyncCommit.SyncStep); + + Graph.ConfirmedCommited = Max(Graph.ConfirmedCommited, step); + Graph.SyncCommit.SyncStep = 0; if (GcInFly == 0 && GcNextStep != 0) { GcLogChannel(std::exchange(GcNextStep, 0)); } - } - + } + if (!ProgressCommitQueue()) { return; // we died } @@ -1572,11 +1572,11 @@ void TTablet::Handle(TEvTabletBase::TEvWriteLogResult::TPtr &ev) { Graph.DelayCommitQueue.pop_front(); } - return; - } - default: + return; + } + default: break; - } + } if (msg->YellowMoveChannels) { ReassignYellowChannels(std::move(msg->YellowMoveChannels)); @@ -1591,8 +1591,8 @@ void TTablet::Handle(TEvTabletBase::TEvWriteLogResult::TPtr &ev) { } CheckBlobStorageError(); -} - +} + void TTablet::HandleFeatures(TEvTablet::TEvFeatures::TPtr &ev) { SupportedFeatures = ev->Get()->Features; } @@ -1610,24 +1610,24 @@ void TTablet::HandleStopped() { } } -void TTablet::HandlePoisonPill() { - return CancelTablet(TEvTablet::TEvTabletDead::ReasonPill); -} +void TTablet::HandlePoisonPill() { + return CancelTablet(TEvTablet::TEvTabletDead::ReasonPill); +} -void TTablet::HandleDemoted() { +void TTablet::HandleDemoted() { StopTablet(TEvTablet::TEvTabletStop::ReasonDemoted, TEvTablet::TEvTabletDead::ReasonDemotedByStateStorage); -} - -void TTablet::Handle(TEvTablet::TEvDemoted::TPtr &ev) { +} + +void TTablet::Handle(TEvTablet::TEvDemoted::TPtr &ev) { const auto deadReason = - ev->Get()->ByIsolation ? TEvTablet::TEvTabletDead::ReasonIsolated - : TEvTablet::TEvTabletDead::ReasonDemotedByStateStorage; + ev->Get()->ByIsolation ? TEvTablet::TEvTabletDead::ReasonIsolated + : TEvTablet::TEvTabletDead::ReasonDemotedByStateStorage; const auto stopReason = ev->Get()->ByIsolation ? TEvTablet::TEvTabletStop::ReasonIsolated : TEvTablet::TEvTabletStop::ReasonDemoted; StopTablet(stopReason, deadReason); -} - +} + bool TTablet::CheckBlobStorageError() { if (Y_LIKELY(BlobStorageStatus == NKikimrProto::OK)) { return false; @@ -1723,17 +1723,17 @@ void TTablet::ReassignYellowChannels(TVector<ui32> &&yellowMoveChannels) { /* subscribe */ false)); } -void TTablet::CancelTablet(TEvTablet::TEvTabletDead::EReason reason, const TString &details) { - BLOG_ERROR( - " Type: " << TTabletTypes::TypeToStr((TTabletTypes::EType)Info->TabletType) - << ", EReason: " << TEvTablet::TEvTabletDead::Str(reason) - << ", SuggestedGeneration: " << SuggestedGeneration - << ", KnownGeneration: " << StateStorageInfo.KnownGeneration - << (details ? ", Details: " : "") << details.data()); - - PipeConnectAcceptor->Detach(SelfId()); - const ui32 reportedGeneration = SuggestedGeneration ? SuggestedGeneration : StateStorageInfo.KnownGeneration; - +void TTablet::CancelTablet(TEvTablet::TEvTabletDead::EReason reason, const TString &details) { + BLOG_ERROR( + " Type: " << TTabletTypes::TypeToStr((TTabletTypes::EType)Info->TabletType) + << ", EReason: " << TEvTablet::TEvTabletDead::Str(reason) + << ", SuggestedGeneration: " << SuggestedGeneration + << ", KnownGeneration: " << StateStorageInfo.KnownGeneration + << (details ? ", Details: " : "") << details.data()); + + PipeConnectAcceptor->Detach(SelfId()); + const ui32 reportedGeneration = SuggestedGeneration ? SuggestedGeneration : StateStorageInfo.KnownGeneration; + if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TOnCancelTablet>( this->TabletID() @@ -1741,213 +1741,213 @@ void TTablet::CancelTablet(TEvTablet::TEvTabletDead::EReason reason, const TStri , reason , SuggestedGeneration , StateStorageInfo.KnownGeneration)); - SendIntrospectionData(); + SendIntrospectionData(); } - Send(Launcher, new TEvTablet::TEvTabletDead(TabletID(), reason, reportedGeneration)); - - if (UserTablet) - Send(UserTablet, new TEvTablet::TEvTabletDead(TabletID(), reason, reportedGeneration)); - - if (StateStorageGuardian) - Send(StateStorageGuardian, new TEvents::TEvPoisonPill()); - + Send(Launcher, new TEvTablet::TEvTabletDead(TabletID(), reason, reportedGeneration)); + + if (UserTablet) + Send(UserTablet, new TEvTablet::TEvTabletDead(TabletID(), reason, reportedGeneration)); + + if (StateStorageGuardian) + Send(StateStorageGuardian, new TEvents::TEvPoisonPill()); + if (FollowerStStGuardian) Send(FollowerStStGuardian, new TEvents::TEvPoisonPill()); - if (RebuildGraphRequest) - Send(RebuildGraphRequest, new TEvents::TEvPoisonPill()); - - TSet<ui32> nodesToUnsubsribe; + if (RebuildGraphRequest) + Send(RebuildGraphRequest, new TEvents::TEvPoisonPill()); + + TSet<ui32> nodesToUnsubsribe; for (auto &xpair : LeaderInfo) { Send(xpair.first, new TEvTablet::TEvFollowerDisconnect(TabletID(), xpair.second.FollowerAttempt)); const ui32 followerNode = xpair.first.NodeId(); if (followerNode && followerNode != SelfId().NodeId()) nodesToUnsubsribe.emplace(followerNode); - } + } LeaderInfo.clear(); - + if (FollowerInfo.KnownLeaderID) Send(FollowerInfo.KnownLeaderID, new TEvTablet::TEvFollowerDetach(TabletID(), FollowerInfo.FollowerAttempt)); - - if (NeedCleanupOnLockedPath) - Send(StateStorageInfo.ProxyID, new TEvStateStorage::TEvCleanup(TabletID(), SelfId())); - - ReportTabletStateChange(TTabletStateInfo::Dead); - + + if (NeedCleanupOnLockedPath) + Send(StateStorageInfo.ProxyID, new TEvStateStorage::TEvCleanup(TabletID(), SelfId())); + + ReportTabletStateChange(TTabletStateInfo::Dead); + const ui32 leaderNode = FollowerInfo.KnownLeaderID.NodeId(); if (leaderNode && leaderNode != SelfId().NodeId()) nodesToUnsubsribe.emplace(leaderNode); - - for (ui32 x : nodesToUnsubsribe) { - Send(TActivationContext::InterconnectProxy(x), new TEvents::TEvUnsubscribe()); - } - - PassAway(); -} - -void TTablet::Handle(TEvTablet::TEvUpdateConfig::TPtr &ev) { + + for (ui32 x : nodesToUnsubsribe) { + Send(TActivationContext::InterconnectProxy(x), new TEvents::TEvUnsubscribe()); + } + + PassAway(); +} + +void TTablet::Handle(TEvTablet::TEvUpdateConfig::TPtr &ev) { ResourceProfiles = ev->Get()->ResourceProfiles; if (UserTablet) - TActivationContext::Send(ev->Forward(UserTablet)); -} - -void TTablet::LockedInitializationPath() { - const ui32 latestChangeGeneration = SuggestedGeneration ? SuggestedGeneration - 1 : Info->ChannelInfo(0)->LatestEntry()->FromGeneration; - - BLOG_D("LockedInitializationPath"); - - if (StateStorageInfo.KnownGeneration < latestChangeGeneration) { - StateStorageInfo.KnownGeneration = latestChangeGeneration; - StateStorageInfo.KnownStep = 0; - } + TActivationContext::Send(ev->Forward(UserTablet)); +} + +void TTablet::LockedInitializationPath() { + const ui32 latestChangeGeneration = SuggestedGeneration ? SuggestedGeneration - 1 : Info->ChannelInfo(0)->LatestEntry()->FromGeneration; + + BLOG_D("LockedInitializationPath"); + + if (StateStorageInfo.KnownGeneration < latestChangeGeneration) { + StateStorageInfo.KnownGeneration = latestChangeGeneration; + StateStorageInfo.KnownStep = 0; + } if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TOnLockedInitializationPath>( StateStorageInfo.KnownGeneration , StateStorageInfo.KnownStep , StateStorageInfo.SignatureSz)); } - - // lock => find latest => update => normal path - Send(StateStorageInfo.ProxyID, new TEvStateStorage::TEvLock(TabletID(), 0, SelfId(), StateStorageInfo.KnownGeneration + 1, StateStorageInfo.Signature.Get(), StateStorageInfo.SignatureSz, TEvStateStorage::TProxyOptions::SigAsync)); - - NeedCleanupOnLockedPath = true; - Become(&TThis::StateLock); - ReportTabletStateChange(TTabletStateInfo::Lock); -} - + + // lock => find latest => update => normal path + Send(StateStorageInfo.ProxyID, new TEvStateStorage::TEvLock(TabletID(), 0, SelfId(), StateStorageInfo.KnownGeneration + 1, StateStorageInfo.Signature.Get(), StateStorageInfo.SignatureSz, TEvStateStorage::TProxyOptions::SigAsync)); + + NeedCleanupOnLockedPath = true; + Become(&TThis::StateLock); + ReportTabletStateChange(TTabletStateInfo::Lock); +} + TTablet::TTablet(const TActorId &launcher, TTabletStorageInfo *info, TTabletSetupInfo *setupInfo, bool leader, ui32 suggestedGeneration, ui32 followerId, TResourceProfilesPtr profiles, TSharedQuotaPtr txCacheQuota) : TActor(leader ? &TThis::StateBootstrapNormal : &TThis::StateBootstrapFollower) , InitialFollowerSyncDone(false) - , Launcher(launcher) - , Info(info) - , SetupInfo(setupInfo) - , SuggestedGeneration(suggestedGeneration) - , NeedCleanupOnLockedPath(false) - , GcCounter(0) - , PipeConnectAcceptor(NTabletPipe::CreateConnectAcceptor(info->TabletID)) + , Launcher(launcher) + , Info(info) + , SetupInfo(setupInfo) + , SuggestedGeneration(suggestedGeneration) + , NeedCleanupOnLockedPath(false) + , GcCounter(0) + , PipeConnectAcceptor(NTabletPipe::CreateConnectAcceptor(info->TabletID)) , Leader(leader) , FollowerId(followerId) - , DiscoveredLastBlocked(Max<ui32>()) - , GcInFly(0) + , DiscoveredLastBlocked(Max<ui32>()) + , GcInFly(0) , GcInFlyStep(0) , GcNextStep(0) , ResourceProfiles(profiles) , TxCacheQuota(txCacheQuota) -{ +{ Y_VERIFY(!info->Channels.empty() && !info->Channels[0].History.empty()); - Y_VERIFY(TTabletTypes::TYPE_INVALID != info->TabletType); -} - + Y_VERIFY(TTabletTypes::TYPE_INVALID != info->TabletType); +} + TAutoPtr<IEventHandle> TTablet::AfterRegister(const TActorId &self, const TActorId& parentId) { - Y_UNUSED(parentId); - return new IEventHandle(self, self, new TEvents::TEvBootstrap()); -} - + Y_UNUSED(parentId); + return new IEventHandle(self, self, new TEvents::TEvBootstrap()); +} + void TTablet::RetryFollowerBootstrapOrWait() { if (FollowerInfo.RetryRound) { ReportTabletStateChange(TTabletStateInfo::ResolveLeader); - - TActivationContext::Schedule(TDuration::MilliSeconds(2000), new IEventHandle( - SelfId(), SelfId(), + + TActivationContext::Schedule(TDuration::MilliSeconds(2000), new IEventHandle( + SelfId(), SelfId(), new TEvTabletBase::TEvFollowerRetry(++FollowerInfo.RetryRound), 0, FollowerInfo.FollowerAttempt)); Become(&TThis::StateResolveLeader); - } else { + } else { FollowerInfo.RetryRound = 1; BootstrapFollower(); - } -} - + } +} + void TTablet::BootstrapFollower() { // create guardians right now and schedule offline follower boot if (!FollowerStStGuardian) { FollowerStStGuardian = Register(CreateStateStorageFollowerGuardian(TabletID(), SelfId())); Schedule(OfflineFollowerWaitFirst, new TEvTabletBase::TEvTryBuildFollowerGraph()); - } - + } + Leader = false; - BoostrapTime = AppData()->TimeProvider->Now(); - bool enInt = AppData()->EnableIntrospection; + BoostrapTime = AppData()->TimeProvider->Now(); + bool enInt = AppData()->EnableIntrospection; if (enInt) { IntrospectionTrace.Reset(NTracing::CreateTrace(NTracing::ITrace::TypeSysTabletBootstrap)); } - - StateStorageInfo.ProxyID = MakeStateStorageProxyID(StateStorageGroup()); - Send(StateStorageInfo.ProxyID, new TEvStateStorage::TEvLookup(TabletID(), 0, TEvStateStorage::TProxyOptions(TEvStateStorage::TProxyOptions::SigAsync))); + + StateStorageInfo.ProxyID = MakeStateStorageProxyID(StateStorageGroup()); + Send(StateStorageInfo.ProxyID, new TEvStateStorage::TEvLookup(TabletID(), 0, TEvStateStorage::TProxyOptions(TEvStateStorage::TProxyOptions::SigAsync))); if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TOnTabletBootstrap>(SuggestedGeneration, false, StateStorageInfo.ProxyID)); } - + Become(&TThis::StateResolveLeader); ReportTabletStateChange(TTabletStateInfo::ResolveLeader); -} - -void TTablet::Bootstrap() { - DiscoveredLastBlocked = Max<ui32>(); +} + +void TTablet::Bootstrap() { + DiscoveredLastBlocked = Max<ui32>(); Leader = true; - BoostrapTime = AppData()->TimeProvider->Now(); - bool enInt = AppData()->EnableIntrospection; + BoostrapTime = AppData()->TimeProvider->Now(); + bool enInt = AppData()->EnableIntrospection; if (enInt) { IntrospectionTrace.Reset(NTracing::CreateTrace(NTracing::ITrace::TypeSysTabletBootstrap)); } - ReportTabletStateChange(TTabletStateInfo::Created); // useless? - StateStorageInfo.ProxyID = MakeStateStorageProxyID(StateStorageGroup()); - Send(StateStorageInfo.ProxyID, new TEvStateStorage::TEvLookup(TabletID(), 0, TEvStateStorage::TProxyOptions(TEvStateStorage::TProxyOptions::SigAsync))); + ReportTabletStateChange(TTabletStateInfo::Created); // useless? + StateStorageInfo.ProxyID = MakeStateStorageProxyID(StateStorageGroup()); + Send(StateStorageInfo.ProxyID, new TEvStateStorage::TEvLookup(TabletID(), 0, TEvStateStorage::TProxyOptions(TEvStateStorage::TProxyOptions::SigAsync))); if (IntrospectionTrace) { IntrospectionTrace->Attach(MakeHolder<NTracing::TOnTabletBootstrap>(SuggestedGeneration, true, StateStorageInfo.ProxyID)); } - // todo: handle "proxy unknown" case (normal timeouts are handled by proxy) - PipeConnectAcceptor->Detach(SelfId()); - Become(&TThis::StateResolveStateStorage); - ReportTabletStateChange(TTabletStateInfo::ResolveStateStorage); -} - -void TTablet::ExternalWriteZeroEntry(TTabletStorageInfo *info, ui32 gen, TActorIdentity owner) { + // todo: handle "proxy unknown" case (normal timeouts are handled by proxy) + PipeConnectAcceptor->Detach(SelfId()); + Become(&TThis::StateResolveStateStorage); + ReportTabletStateChange(TTabletStateInfo::ResolveStateStorage); +} + +void TTablet::ExternalWriteZeroEntry(TTabletStorageInfo *info, ui32 gen, TActorIdentity owner) { THolder<NKikimrTabletBase::TTabletLogEntry> entry = MakeHolder<NKikimrTabletBase::TTabletLogEntry>(); entry->SetSnapshot(MakeGenStepPair(0, 0)); entry->SetZeroConfirmed(MakeGenStepPair(0, 0)); entry->SetZeroTailSz(0); TLogoBlobID logid(info->TabletID, gen, 0, 0, 0, 0); TVector<TEvTablet::TLogEntryReference> refs; - TActivationContext::Register(CreateTabletReqWriteLog(owner, logid, entry.Release(), refs, TEvBlobStorage::TEvPut::TacticDefault, info)); + TActivationContext::Register(CreateTabletReqWriteLog(owner, logid, entry.Release(), refs, TEvBlobStorage::TEvPut::TacticDefault, info)); } TActorId TTabletSetupInfo::Apply(TTabletStorageInfo *info, TActorIdentity owner) { - return TActivationContext::Register(Op(owner, info), owner, MailboxType, PoolId); -} - + return TActivationContext::Register(Op(owner, info), owner, MailboxType, PoolId); +} + TActorId TTabletSetupInfo::Apply(TTabletStorageInfo *info, const TActorContext &ctx) { - return Apply(info, TActorIdentity(ctx.SelfID)); -} - + return Apply(info, TActorIdentity(ctx.SelfID)); +} + TActorId TTabletSetupInfo::Tablet(TTabletStorageInfo *info, const TActorId &launcher, const TActorContext &ctx, ui32 suggestedGeneration, TResourceProfilesPtr profiles, TSharedQuotaPtr txCacheQuota) { return ctx.ExecutorThread.RegisterActor(CreateTablet(launcher, info, this, suggestedGeneration, profiles, txCacheQuota), TabletMailboxType, TabletPoolId); -} - +} + TActorId TTabletSetupInfo::Follower(TTabletStorageInfo *info, const TActorId &launcher, const TActorContext &ctx, ui32 followerId, TResourceProfilesPtr profiles, TSharedQuotaPtr txCacheQuota) { return ctx.ExecutorThread.RegisterActor(CreateTabletFollower(launcher, info, this, followerId, profiles, txCacheQuota), TabletMailboxType, TabletPoolId); -} - +} + IActor* CreateTablet(const TActorId &launcher, TTabletStorageInfo *info, TTabletSetupInfo *setupInfo, ui32 suggestedGeneration, TResourceProfilesPtr profiles, TSharedQuotaPtr txCacheQuota) { return new TTablet(launcher, info, setupInfo, true, suggestedGeneration, 0, profiles, txCacheQuota); -} - +} + IActor* CreateTabletFollower(const TActorId &launcher, TTabletStorageInfo *info, TTabletSetupInfo *setupInfo, ui32 followerId, TResourceProfilesPtr profiles, TSharedQuotaPtr txCacheQuota) { return new TTablet(launcher, info, setupInfo, false, 0, followerId, profiles, txCacheQuota); -} - -void TTablet::SendIntrospectionData() { +} + +void TTablet::SendIntrospectionData() { const TActorId tabletStateServiceId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(SelfId().NodeId()); - Send(tabletStateServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvIntrospectionData(TabletID(), IntrospectionTrace.Release())); - IntrospectionTrace.Reset(NTracing::CreateTrace(NTracing::ITrace::TypeSysTabletBootstrap)); -} + Send(tabletStateServiceId, new NNodeWhiteboard::TEvWhiteboard::TEvIntrospectionData(TabletID(), IntrospectionTrace.Release())); + IntrospectionTrace.Reset(NTracing::CreateTrace(NTracing::ITrace::TypeSysTabletBootstrap)); +} } diff --git a/ydb/core/tablet/tablet_sys.h b/ydb/core/tablet/tablet_sys.h index 1a3b9db19e..661d75a4e0 100644 --- a/ydb/core/tablet/tablet_sys.h +++ b/ydb/core/tablet/tablet_sys.h @@ -1,232 +1,232 @@ -#pragma once -#include "defs.h" -#include "tablet_impl.h" -#include "tablet_setup.h" +#pragma once +#include "defs.h" +#include "tablet_impl.h" +#include "tablet_setup.h" #include <library/cpp/actors/core/interconnect.h> #include <ydb/core/node_whiteboard/node_whiteboard.h> #include <ydb/core/base/tablet_pipe.h> #include <library/cpp/actors/core/hfunc.h> #include <util/generic/intrlist.h> -#include <util/generic/set.h> - -namespace NKikimr { - +#include <util/generic/set.h> + +namespace NKikimr { + class TTablet : public TActor<TTablet> { using TTabletStateInfo = NKikimrWhiteboard::TTabletStateInfo; using ETabletState = TTabletStateInfo::ETabletState; - struct TStateStorageInfo { + struct TStateStorageInfo { TActorId ProxyID; - - ui32 KnownGeneration; - ui32 KnownStep; + + ui32 KnownGeneration; + ui32 KnownStep; TActorId CurrentLeader; - - ui32 SignatureSz; - TArrayHolder<ui64> Signature; - - TStateStorageInfo() - : KnownGeneration(0) - , KnownStep(0) - , SignatureSz(0) - {} - - void Update(const TEvStateStorage::TEvInfo *msg) { - const ui32 xg = msg->CurrentGeneration; - const ui32 xs = msg->CurrentStep; + + ui32 SignatureSz; + TArrayHolder<ui64> Signature; + + TStateStorageInfo() + : KnownGeneration(0) + , KnownStep(0) + , SignatureSz(0) + {} + + void Update(const TEvStateStorage::TEvInfo *msg) { + const ui32 xg = msg->CurrentGeneration; + const ui32 xs = msg->CurrentStep; const TActorId &xm = msg->CurrentLeader; - - if (xg > KnownGeneration) { - KnownGeneration = xg; - KnownStep = xs; + + if (xg > KnownGeneration) { + KnownGeneration = xg; + KnownStep = xs; CurrentLeader = xm; - } else if (xg == KnownGeneration) { - if (KnownStep < xs) - KnownStep = xs; - } else { - // happens? - } - } - - void MergeSignature(ui64 *sig, ui32 sigsz) { - Y_VERIFY(sigsz == SignatureSz); - for (ui32 i = 0; i != sigsz; ++i) - if (const ui64 x = sig[i]) - Signature[i] = x; - } - } StateStorageInfo; - + } else if (xg == KnownGeneration) { + if (KnownStep < xs) + KnownStep = xs; + } else { + // happens? + } + } + + void MergeSignature(ui64 *sig, ui32 sigsz) { + Y_VERIFY(sigsz == SignatureSz); + for (ui32 i = 0; i != sigsz; ++i) + if (const ui64 x = sig[i]) + Signature[i] = x; + } + } StateStorageInfo; + struct TFollowerUpdate { TVector<std::pair<TLogoBlobID, TString>> References; TString Body; TString AuxPayload; - + TVector<TLogoBlobID> GcDiscovered; TVector<TLogoBlobID> GcLeft; - }; - - struct TLogEntry { - const ui32 Step; - const ui32 ConfirmedOnSend; - + }; + + struct TLogEntry { + const ui32 Step; + const ui32 ConfirmedOnSend; + TVector<ui32> Dependent; - bool StateStorageConfirmed; - bool BlobStorageConfirmed; - ui32 DependenciesLeft; - - bool IsSnapshot; - bool IsTotalSnapshot; - bool Commited; + bool StateStorageConfirmed; + bool BlobStorageConfirmed; + ui32 DependenciesLeft; + + bool IsSnapshot; + bool IsTotalSnapshot; + bool Commited; bool WaitFollowerGcAck; - TInstant CommitedMoment; - + TInstant CommitedMoment; + TActorId Source; TActorId Task; - - ui64 SourceCookie; - + + ui64 SourceCookie; + THolder<TFollowerUpdate> FollowerUpdate; TVector<TString> FollowerAuxUpdates; NMetrics::TTabletThroughputRawValue GroupWrittenBytes; NMetrics::TTabletIopsRawValue GroupWrittenOps; - + TVector<ui32> YellowMoveChannels; TVector<ui32> YellowStopChannels; - + size_t ByteSize; - TLogEntry(ui32 step, ui32 confirmedOnSend, ui64 sourceCookie) - : Step(step) - , ConfirmedOnSend(confirmedOnSend) - , StateStorageConfirmed(false) - , BlobStorageConfirmed(false) - , DependenciesLeft(0) - , IsSnapshot(false) - , IsTotalSnapshot(false) - , Commited(false) + TLogEntry(ui32 step, ui32 confirmedOnSend, ui64 sourceCookie) + : Step(step) + , ConfirmedOnSend(confirmedOnSend) + , StateStorageConfirmed(false) + , BlobStorageConfirmed(false) + , DependenciesLeft(0) + , IsSnapshot(false) + , IsTotalSnapshot(false) + , Commited(false) , WaitFollowerGcAck(false) - , CommitedMoment(TInstant::Zero()) - , SourceCookie(sourceCookie) + , CommitedMoment(TInstant::Zero()) + , SourceCookie(sourceCookie) , ByteSize(0) - {} - }; - - struct TGraph { + {} + }; + + struct TGraph { typedef TDeque<std::unique_ptr<TLogEntry>> TQueueType; typedef THashMap<ui32, TLogEntry *> TIndex; - + TQueueType Queue; TQueueType PostponedFollowerUpdates; - TIndex Index; + TIndex Index; TDeque<TEvTablet::TEvCommit::TPtr> DelayCommitQueue; - - ui32 Confirmed; - ui32 ConfirmedCommited; - ui32 NextEntry; + + ui32 Confirmed; + ui32 ConfirmedCommited; + ui32 NextEntry; ui32 MinFollowerUpdate; ui32 StepsInFlight; ui64 BytesInFlight; - - std::pair<ui32, ui32> Snapshot; - - struct { - ui32 SyncStep = 0; - } SyncCommit; - - TGraph() - : Confirmed(0) - , ConfirmedCommited(0) - , NextEntry(0) + + std::pair<ui32, ui32> Snapshot; + + struct { + ui32 SyncStep = 0; + } SyncCommit; + + TGraph() + : Confirmed(0) + , ConfirmedCommited(0) + , NextEntry(0) , MinFollowerUpdate(0) , StepsInFlight(0) , BytesInFlight(0) - {} - } Graph; - + {} + } Graph; + struct TFollowerInfo { TActorId KnownLeaderID; - ui32 RetryRound; + ui32 RetryRound; ui32 FollowerAttempt; - ui64 StreamCounter; - ui64 EpochGenStep; - ui64 RebuildGraphCookie; - + ui64 StreamCounter; + ui64 EpochGenStep; + ui64 RebuildGraphCookie; + TFollowerInfo() - : RetryRound(0) + : RetryRound(0) , FollowerAttempt(0) - , StreamCounter(0) - , EpochGenStep(Max<ui64>()) - , RebuildGraphCookie(1) - {} - - void NextAttempt() { + , StreamCounter(0) + , EpochGenStep(Max<ui64>()) + , RebuildGraphCookie(1) + {} + + void NextAttempt() { KnownLeaderID = TActorId(); - // do not touch RetryRound on retries + // do not touch RetryRound on retries ++FollowerAttempt; - StreamCounter = 0; - // do not reset EpochGenStep for sync actuality check! - } + StreamCounter = 0; + // do not reset EpochGenStep for sync actuality check! + } } FollowerInfo; - + void NextFollowerAttempt(); - + enum class EFollowerSyncState { NeedSync, // follower known but not connected, blocks gc Pending, // follower connected but stream not yet started, blocks gc Active, // follower active, blocks gc Ignore, // could not connect to follower for too long. ignore for gc - }; - + }; + struct TLeaderInfo { ui32 FollowerAttempt; - ui64 StreamCounter; - + ui64 StreamCounter; + EFollowerSyncState SyncState; - TInstant LastSyncAttempt; - ui64 SyncAttempt; - THolder<TSchedulerCookieHolder> SyncCookieHolder; - - ui32 ConfirmedGCStep; - bool PresentInList; - + TInstant LastSyncAttempt; + ui64 SyncAttempt; + THolder<TSchedulerCookieHolder> SyncCookieHolder; + + ui32 ConfirmedGCStep; + bool PresentInList; + TLeaderInfo(EFollowerSyncState syncState = EFollowerSyncState::Pending) : FollowerAttempt(Max<ui32>()) - , StreamCounter(0) - , SyncState(syncState) - , LastSyncAttempt(TInstant::Zero()) - , SyncAttempt(0) - , ConfirmedGCStep(0) - , PresentInList(false) - {} - }; - + , StreamCounter(0) + , SyncState(syncState) + , LastSyncAttempt(TInstant::Zero()) + , SyncAttempt(0) + , ConfirmedGCStep(0) + , PresentInList(false) + {} + }; + TMap<TActorId, TLeaderInfo> LeaderInfo; - TDeque<std::pair<ui32, TInstant>> WaitingForGcAck; // step, commitMoment + TDeque<std::pair<ui32, TInstant>> WaitingForGcAck; // step, commitMoment bool InitialFollowerSyncDone; - + const TActorId Launcher; TActorId UserTablet; TActorId StateStorageGuardian; TActorId FollowerStStGuardian; - TIntrusivePtr<TTabletStorageInfo> Info; - TIntrusivePtr<TTabletSetupInfo> SetupInfo; - ui32 SuggestedGeneration; - bool NeedCleanupOnLockedPath; - ui32 GcCounter; - THolder<NTabletPipe::IConnectAcceptor> PipeConnectAcceptor; + TIntrusivePtr<TTabletStorageInfo> Info; + TIntrusivePtr<TTabletSetupInfo> SetupInfo; + ui32 SuggestedGeneration; + bool NeedCleanupOnLockedPath; + ui32 GcCounter; + THolder<NTabletPipe::IConnectAcceptor> PipeConnectAcceptor; TInstant BoostrapTime; TInstant ActivateTime; bool Leader; ui32 FollowerId; - ui32 DiscoveredLastBlocked; - ui32 GcInFly; + ui32 DiscoveredLastBlocked; + ui32 GcInFly; ui32 GcInFlyStep; ui32 GcNextStep; TResourceProfilesPtr ResourceProfiles; TSharedQuotaPtr TxCacheQuota; THolder<NTracing::ITrace> IntrospectionTrace; TActorId RebuildGraphRequest; - + // Delayed cancellation reason struct TDelayedCancelTablet { const TEvTablet::TEvTabletDead::EReason Reason; @@ -251,34 +251,34 @@ class TTablet : public TActor<TTablet> { TString BlobStorageErrorReason; bool BlobStorageErrorReported = false; - ui64 StateStorageGroup() const; - ui64 TabletID() const; - - void ReportTabletStateChange(ETabletState state); - void PromoteToCandidate(ui32 gen); - void TabletBlockBlobStorage(); - void TabletRebuildGraph(); - void WriteZeroEntry(TEvTablet::TDependencyGraph *graph); - - void StartActivePhase(); - void UpdateStateStorageSignature(TEvStateStorage::TEvUpdateSignature::TPtr &ev); + ui64 StateStorageGroup() const; + ui64 TabletID() const; + + void ReportTabletStateChange(ETabletState state); + void PromoteToCandidate(ui32 gen); + void TabletBlockBlobStorage(); + void TabletRebuildGraph(); + void WriteZeroEntry(TEvTablet::TDependencyGraph *graph); + + void StartActivePhase(); + void UpdateStateStorageSignature(TEvStateStorage::TEvUpdateSignature::TPtr &ev); void TryFinishFollowerSync(); - void TryPumpWaitingForGc(); - - void HandlePingBoot(TEvTablet::TEvPing::TPtr &ev); + void TryPumpWaitingForGc(); + + void HandlePingBoot(TEvTablet::TEvPing::TPtr &ev); void HandlePingFollower(TEvTablet::TEvPing::TPtr &ev); - void HandleStateStorageInfoResolve(TEvStateStorage::TEvInfo::TPtr &ev); + void HandleStateStorageInfoResolve(TEvStateStorage::TEvInfo::TPtr &ev); void HandleStateStorageLeaderResolve(TEvStateStorage::TEvInfo::TPtr &ev); void HandleFollowerRetry(TEvTabletBase::TEvFollowerRetry::TPtr &ev); void HandleByFollower(TEvTabletBase::TEvTryBuildFollowerGraph::TPtr &ev); void HandleByFollower(TEvTabletBase::TEvRebuildGraphResult::TPtr &ev); - - void HandleStateStorageInfoLock(TEvStateStorage::TEvInfo::TPtr &ev); - - void HandleStateStorageInfoUpgrade(TEvStateStorage::TEvInfo::TPtr &ev); - void HandleFindLatestLogEntry(TEvTabletBase::TEvFindLatestLogEntryResult::TPtr &ev); - void HandleBlockBlobStorageResult(TEvTabletBase::TEvBlockBlobStorageResult::TPtr &ev); - + + void HandleStateStorageInfoLock(TEvStateStorage::TEvInfo::TPtr &ev); + + void HandleStateStorageInfoUpgrade(TEvStateStorage::TEvInfo::TPtr &ev); + void HandleFindLatestLogEntry(TEvTabletBase::TEvFindLatestLogEntryResult::TPtr &ev); + void HandleBlockBlobStorageResult(TEvTabletBase::TEvBlockBlobStorageResult::TPtr &ev); + void HandleByFollower(TEvTablet::TEvFollowerDisconnect::TPtr &ev); void HandleByFollower(TEvTablet::TEvFollowerUpdate::TPtr &ev); void HandleByFollower(TEvTablet::TEvFollowerAuxUpdate::TPtr &ev); @@ -289,7 +289,7 @@ class TTablet : public TActor<TTablet> { void HandleByFollower(TEvTablet::TEvFGcAck::TPtr &ev); void HandleByFollower(TEvTablet::TEvTabletActive::TPtr &ev); void HandleByFollower(TEvTabletPipe::TEvConnect::TPtr &ev); - + void HandleByLeader(TEvTablet::TEvFollowerAttach::TPtr &ev); void HandleByLeader(TEvTablet::TEvFollowerDetach::TPtr &ev); void HandleByLeader(TEvTablet::TEvFollowerRefresh::TPtr &ev); @@ -298,264 +298,264 @@ class TTablet : public TActor<TTablet> { void HandleByLeader(TEvTablet::TEvFollowerGcAck::TPtr &ev); void HandleByLeader(TEvInterconnect::TEvNodeDisconnected::TPtr &ev); void HandleByLeader(TEvents::TEvUndelivered::TPtr &ev); - - void HandleRebuildGraphResult(TEvTabletBase::TEvRebuildGraphResult::TPtr &ev); - void HandleWriteZeroEntry(TEvTabletBase::TEvWriteLogResult::TPtr &ev); - - void Handle(TEvTablet::TEvPing::TPtr &ev); + + void HandleRebuildGraphResult(TEvTabletBase::TEvRebuildGraphResult::TPtr &ev); + void HandleWriteZeroEntry(TEvTabletBase::TEvWriteLogResult::TPtr &ev); + + void Handle(TEvTablet::TEvPing::TPtr &ev); void HandleByLeader(TEvTablet::TEvTabletActive::TPtr &ev); - + bool CheckFollowerUpdate(const TActorId &actorId, ui32 attempt, ui64 counter); - - TLogEntry* MakeLogEntry(TEvTablet::TCommitInfo &commitInfo, NKikimrTabletBase::TTabletLogEntry *commitEv); - TLogEntry* FindLogEntry(TEvTablet::TCommitInfo &commitInfo, NKikimrTabletBase::TTabletLogEntry &commitEv); - - void Handle(TEvBlobStorage::TEvCollectGarbageResult::TPtr &ev); - void Handle(TEvTablet::TEvPreCommit::TPtr &ev); - - void Handle(TEvTablet::TEvCommit::TPtr &ev); + + TLogEntry* MakeLogEntry(TEvTablet::TCommitInfo &commitInfo, NKikimrTabletBase::TTabletLogEntry *commitEv); + TLogEntry* FindLogEntry(TEvTablet::TCommitInfo &commitInfo, NKikimrTabletBase::TTabletLogEntry &commitEv); + + void Handle(TEvBlobStorage::TEvCollectGarbageResult::TPtr &ev); + void Handle(TEvTablet::TEvPreCommit::TPtr &ev); + + void Handle(TEvTablet::TEvCommit::TPtr &ev); bool HandleNext(TEvTablet::TEvCommit::TPtr &ev); - void Handle(TEvTablet::TEvAux::TPtr &ev); - void CheckEntry(TGraph::TIndex::iterator it); - - // next funcs return next correct iterator + void Handle(TEvTablet::TEvAux::TPtr &ev); + void CheckEntry(TGraph::TIndex::iterator it); + + // next funcs return next correct iterator TMap<TActorId, TLeaderInfo>::iterator EraseFollowerInfo(TMap<TActorId, TLeaderInfo>::iterator followerIt); TMap<TActorId, TLeaderInfo>::iterator HandleFollowerConnectionProblem(TMap<TActorId, TLeaderInfo>::iterator followerIt); - + void TrySyncToFollower(TMap<TActorId, TLeaderInfo>::iterator followerIt); void DoSyncToFollower(TMap<TActorId, TLeaderInfo>::iterator followerIt); - - void GcLogChannel(ui32 step); - + + void GcLogChannel(ui32 step); + bool ProgressCommitQueue(); void ProgressFollowerQueue(); void SpreadFollowerAuxUpdate(const TString& auxUpdate); void SendFollowerAuxUpdate(TLeaderInfo& info, const TActorId& follower, const TString& auxUpdate); - - void Handle(TEvTabletPipe::TEvConnect::TPtr& ev); - void Handle(TEvTabletPipe::TEvServerDestroyed::TPtr& ev); - void HandleQueued(TEvTabletPipe::TEvConnect::TPtr& ev); - - void Handle(TEvTabletBase::TEvWriteLogResult::TPtr &ev); - + + void Handle(TEvTabletPipe::TEvConnect::TPtr& ev); + void Handle(TEvTabletPipe::TEvServerDestroyed::TPtr& ev); + void HandleQueued(TEvTabletPipe::TEvConnect::TPtr& ev); + + void Handle(TEvTabletBase::TEvWriteLogResult::TPtr &ev); + void HandleFeatures(TEvTablet::TEvFeatures::TPtr &ev); void HandleStop(TEvTablet::TEvTabletStop::TPtr &ev); void HandleStopped(); - void HandlePoisonPill(); - void HandleDemoted(); - void Handle(TEvTablet::TEvDemoted::TPtr &ev); + void HandlePoisonPill(); + void HandleDemoted(); + void Handle(TEvTablet::TEvDemoted::TPtr &ev); bool CheckBlobStorageError(); bool StopTablet(TEvTablet::TEvTabletStop::EReason stopReason, TEvTablet::TEvTabletDead::EReason deadReason, const TString &deadDetails = TString()); void ReassignYellowChannels(TVector<ui32> &&yellowChannels); - void CancelTablet(TEvTablet::TEvTabletDead::EReason reason, const TString &details = TString()); - - void Handle(TEvTablet::TEvUpdateConfig::TPtr &ev); + void CancelTablet(TEvTablet::TEvTabletDead::EReason reason, const TString &details = TString()); + + void Handle(TEvTablet::TEvUpdateConfig::TPtr &ev); - void LockedInitializationPath(); - void Bootstrap(); + void LockedInitializationPath(); + void Bootstrap(); void BootstrapFollower(); void RetryFollowerBootstrapOrWait(); - - void SendIntrospectionData(); - STATEFN(StateResolveStateStorage) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvInfo, HandleStateStorageInfoResolve); - hFunc(TEvTablet::TEvPing, HandlePingBoot); + void SendIntrospectionData(); + + STATEFN(StateResolveStateStorage) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvInfo, HandleStateStorageInfoResolve); + hFunc(TEvTablet::TEvPing, HandlePingBoot); hFunc(TEvTablet::TEvFeatures, HandleFeatures); hFunc(TEvTablet::TEvTabletStop, HandleStop); cFunc(TEvTablet::TEvTabletStopped::EventType, HandleStopped); - cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); + cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); cFunc(TEvStateStorage::TEvReplicaLeaderDemoted::EventType, HandleDemoted); - hFunc(TEvTabletPipe::TEvConnect, HandleQueued); + hFunc(TEvTabletPipe::TEvConnect, HandleQueued); hFunc(TEvTablet::TEvFollowerAttach, HandleByLeader); hFunc(TEvTablet::TEvFollowerDetach, HandleByLeader); hFunc(TEvTablet::TEvFollowerRefresh, HandleByLeader); - hFunc(TEvTablet::TEvUpdateConfig, Handle); + hFunc(TEvTablet::TEvUpdateConfig, Handle); hFunc(TEvInterconnect::TEvNodeDisconnected, HandleByLeader); hFunc(TEvents::TEvUndelivered, HandleByLeader); - } - } - - STATEFN(StateLock) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvInfo, HandleStateStorageInfoLock); - hFunc(TEvStateStorage::TEvUpdateSignature, UpdateStateStorageSignature); - hFunc(TEvTablet::TEvPing, HandlePingBoot); + } + } + + STATEFN(StateLock) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvInfo, HandleStateStorageInfoLock); + hFunc(TEvStateStorage::TEvUpdateSignature, UpdateStateStorageSignature); + hFunc(TEvTablet::TEvPing, HandlePingBoot); hFunc(TEvTablet::TEvFeatures, HandleFeatures); hFunc(TEvTablet::TEvTabletStop, HandleStop); cFunc(TEvTablet::TEvTabletStopped::EventType, HandleStopped); - cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); + cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); cFunc(TEvStateStorage::TEvReplicaLeaderDemoted::EventType, HandleDemoted); - hFunc(TEvTabletPipe::TEvConnect, HandleQueued); + hFunc(TEvTabletPipe::TEvConnect, HandleQueued); hFunc(TEvTablet::TEvFollowerAttach, HandleByLeader); hFunc(TEvTablet::TEvFollowerDetach, HandleByLeader); hFunc(TEvTablet::TEvFollowerRefresh, HandleByLeader); - hFunc(TEvTablet::TEvUpdateConfig, Handle); + hFunc(TEvTablet::TEvUpdateConfig, Handle); hFunc(TEvInterconnect::TEvNodeDisconnected, HandleByLeader); hFunc(TEvents::TEvUndelivered, HandleByLeader); - } - } - - STATEFN(StateDiscover) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvTabletBase::TEvFindLatestLogEntryResult, HandleFindLatestLogEntry); - hFunc(TEvStateStorage::TEvUpdateSignature, UpdateStateStorageSignature); - hFunc(TEvTablet::TEvPing, HandlePingBoot); + } + } + + STATEFN(StateDiscover) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvTabletBase::TEvFindLatestLogEntryResult, HandleFindLatestLogEntry); + hFunc(TEvStateStorage::TEvUpdateSignature, UpdateStateStorageSignature); + hFunc(TEvTablet::TEvPing, HandlePingBoot); hFunc(TEvTablet::TEvFeatures, HandleFeatures); hFunc(TEvTablet::TEvTabletStop, HandleStop); cFunc(TEvTablet::TEvTabletStopped::EventType, HandleStopped); - cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); + cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); cFunc(TEvStateStorage::TEvReplicaLeaderDemoted::EventType, HandleDemoted); - hFunc(TEvTabletPipe::TEvConnect, HandleQueued); + hFunc(TEvTabletPipe::TEvConnect, HandleQueued); hFunc(TEvTablet::TEvFollowerAttach, HandleByLeader); hFunc(TEvTablet::TEvFollowerDetach, HandleByLeader); hFunc(TEvTablet::TEvFollowerRefresh, HandleByLeader); hFunc(TEvTabletBase::TEvTrySyncFollower, HandleByLeader); - hFunc(TEvTablet::TEvUpdateConfig, Handle); + hFunc(TEvTablet::TEvUpdateConfig, Handle); hFunc(TEvInterconnect::TEvNodeDisconnected, HandleByLeader); hFunc(TEvents::TEvUndelivered, HandleByLeader); - } - } - - STATEFN(StateBecomeCandidate) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvStateStorage::TEvInfo, HandleStateStorageInfoUpgrade); - hFunc(TEvStateStorage::TEvUpdateSignature, UpdateStateStorageSignature); - hFunc(TEvTablet::TEvPing, HandlePingBoot); + } + } + + STATEFN(StateBecomeCandidate) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvStateStorage::TEvInfo, HandleStateStorageInfoUpgrade); + hFunc(TEvStateStorage::TEvUpdateSignature, UpdateStateStorageSignature); + hFunc(TEvTablet::TEvPing, HandlePingBoot); hFunc(TEvTablet::TEvFeatures, HandleFeatures); hFunc(TEvTablet::TEvTabletStop, HandleStop); cFunc(TEvTablet::TEvTabletStopped::EventType, HandleStopped); - cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); + cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); cFunc(TEvStateStorage::TEvReplicaLeaderDemoted::EventType, HandleDemoted); - hFunc(TEvTabletPipe::TEvConnect, HandleQueued); + hFunc(TEvTabletPipe::TEvConnect, HandleQueued); hFunc(TEvTablet::TEvFollowerAttach, HandleByLeader); hFunc(TEvTablet::TEvFollowerDetach, HandleByLeader); hFunc(TEvTablet::TEvFollowerRefresh, HandleByLeader); hFunc(TEvTabletBase::TEvTrySyncFollower, HandleByLeader); - hFunc(TEvTablet::TEvUpdateConfig, Handle); + hFunc(TEvTablet::TEvUpdateConfig, Handle); hFunc(TEvInterconnect::TEvNodeDisconnected, HandleByLeader); hFunc(TEvents::TEvUndelivered, HandleByLeader); - } - } - - STATEFN(StateBlockBlobStorage) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvTabletBase::TEvBlockBlobStorageResult, HandleBlockBlobStorageResult); - hFunc(TEvStateStorage::TEvUpdateSignature, UpdateStateStorageSignature); - hFunc(TEvTablet::TEvPing, HandlePingBoot); + } + } + + STATEFN(StateBlockBlobStorage) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvTabletBase::TEvBlockBlobStorageResult, HandleBlockBlobStorageResult); + hFunc(TEvStateStorage::TEvUpdateSignature, UpdateStateStorageSignature); + hFunc(TEvTablet::TEvPing, HandlePingBoot); hFunc(TEvTablet::TEvFeatures, HandleFeatures); hFunc(TEvTablet::TEvTabletStop, HandleStop); cFunc(TEvTablet::TEvTabletStopped::EventType, HandleStopped); - cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); + cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); cFunc(TEvStateStorage::TEvReplicaLeaderDemoted::EventType, HandleDemoted); - hFunc(TEvTabletPipe::TEvConnect, HandleQueued); + hFunc(TEvTabletPipe::TEvConnect, HandleQueued); hFunc(TEvTablet::TEvFollowerAttach, HandleByLeader); hFunc(TEvTablet::TEvFollowerDetach, HandleByLeader); hFunc(TEvTablet::TEvFollowerRefresh, HandleByLeader); - hFunc(TEvTablet::TEvUpdateConfig, Handle); + hFunc(TEvTablet::TEvUpdateConfig, Handle); hFunc(TEvTabletBase::TEvTrySyncFollower, HandleByLeader); hFunc(TEvInterconnect::TEvNodeDisconnected, HandleByLeader); hFunc(TEvents::TEvUndelivered, HandleByLeader); - } - } - - STATEFN(StateRebuildGraph) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvTabletBase::TEvRebuildGraphResult, HandleRebuildGraphResult); - hFunc(TEvStateStorage::TEvUpdateSignature, UpdateStateStorageSignature); - hFunc(TEvTablet::TEvPing, HandlePingBoot); + } + } + + STATEFN(StateRebuildGraph) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvTabletBase::TEvRebuildGraphResult, HandleRebuildGraphResult); + hFunc(TEvStateStorage::TEvUpdateSignature, UpdateStateStorageSignature); + hFunc(TEvTablet::TEvPing, HandlePingBoot); hFunc(TEvTablet::TEvFeatures, HandleFeatures); hFunc(TEvTablet::TEvTabletStop, HandleStop); cFunc(TEvTablet::TEvTabletStopped::EventType, HandleStopped); - cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); + cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); cFunc(TEvStateStorage::TEvReplicaLeaderDemoted::EventType, HandleDemoted); - hFunc(TEvTabletPipe::TEvConnect, HandleQueued); + hFunc(TEvTabletPipe::TEvConnect, HandleQueued); hFunc(TEvTablet::TEvFollowerAttach, HandleByLeader); hFunc(TEvTablet::TEvFollowerDetach, HandleByLeader); hFunc(TEvTablet::TEvFollowerRefresh, HandleByLeader); - hFunc(TEvTablet::TEvUpdateConfig, Handle); + hFunc(TEvTablet::TEvUpdateConfig, Handle); hFunc(TEvTabletBase::TEvTrySyncFollower, HandleByLeader); hFunc(TEvInterconnect::TEvNodeDisconnected, HandleByLeader); hFunc(TEvents::TEvUndelivered, HandleByLeader); - } - } - - STATEFN(StateWriteZeroEntry) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvTabletBase::TEvWriteLogResult, HandleWriteZeroEntry); - hFunc(TEvStateStorage::TEvUpdateSignature, UpdateStateStorageSignature); - hFunc(TEvTablet::TEvPing, HandlePingBoot); + } + } + + STATEFN(StateWriteZeroEntry) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvTabletBase::TEvWriteLogResult, HandleWriteZeroEntry); + hFunc(TEvStateStorage::TEvUpdateSignature, UpdateStateStorageSignature); + hFunc(TEvTablet::TEvPing, HandlePingBoot); hFunc(TEvTablet::TEvFeatures, HandleFeatures); hFunc(TEvTablet::TEvTabletStop, HandleStop); cFunc(TEvTablet::TEvTabletStopped::EventType, HandleStopped); - cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); + cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); cFunc(TEvStateStorage::TEvReplicaLeaderDemoted::EventType, HandleDemoted); - hFunc(TEvTabletPipe::TEvConnect, HandleQueued); + hFunc(TEvTabletPipe::TEvConnect, HandleQueued); hFunc(TEvTablet::TEvFollowerAttach, HandleByLeader); hFunc(TEvTablet::TEvFollowerDetach, HandleByLeader); hFunc(TEvTablet::TEvFollowerRefresh, HandleByLeader); - hFunc(TEvTablet::TEvUpdateConfig, Handle); + hFunc(TEvTablet::TEvUpdateConfig, Handle); hFunc(TEvTabletBase::TEvTrySyncFollower, HandleByLeader); hFunc(TEvInterconnect::TEvNodeDisconnected, HandleByLeader); hFunc(TEvents::TEvUndelivered, HandleByLeader); - } - } - - STATEFN(StateActivePhase) { - switch (ev->GetTypeRewrite()) { - hFunc(TEvTablet::TEvCommit, Handle); - hFunc(TEvTablet::TEvAux, Handle); - hFunc(TEvTablet::TEvPreCommit, Handle); + } + } + + STATEFN(StateActivePhase) { + switch (ev->GetTypeRewrite()) { + hFunc(TEvTablet::TEvCommit, Handle); + hFunc(TEvTablet::TEvAux, Handle); + hFunc(TEvTablet::TEvPreCommit, Handle); hFunc(TEvTablet::TEvTabletActive, HandleByLeader); hFunc(TEvTablet::TEvFollowerAttach, HandleByLeader); hFunc(TEvTablet::TEvFollowerDetach, HandleByLeader); hFunc(TEvTablet::TEvFollowerRefresh, HandleByLeader); hFunc(TEvTablet::TEvFollowerGcAck, HandleByLeader); hFunc(TEvTablet::TEvFollowerListRefresh, HandleByLeader); - hFunc(TEvTablet::TEvUpdateConfig, Handle); + hFunc(TEvTablet::TEvUpdateConfig, Handle); hFunc(TEvTabletBase::TEvTrySyncFollower, HandleByLeader); - hFunc(TEvTabletBase::TEvWriteLogResult, Handle); - hFunc(TEvStateStorage::TEvUpdateSignature, UpdateStateStorageSignature); - hFunc(TEvTablet::TEvPing, Handle); - hFunc(TEvTablet::TEvDemoted, Handle); + hFunc(TEvTabletBase::TEvWriteLogResult, Handle); + hFunc(TEvStateStorage::TEvUpdateSignature, UpdateStateStorageSignature); + hFunc(TEvTablet::TEvPing, Handle); + hFunc(TEvTablet::TEvDemoted, Handle); cFunc(TEvStateStorage::TEvReplicaLeaderDemoted::EventType, HandleDemoted); hFunc(TEvTablet::TEvFeatures, HandleFeatures); hFunc(TEvTablet::TEvTabletStop, HandleStop); cFunc(TEvTablet::TEvTabletStopped::EventType, HandleStopped); - cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); - hFunc(TEvTabletPipe::TEvConnect, Handle); - hFunc(TEvTabletPipe::TEvServerDestroyed, Handle); + cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); + hFunc(TEvTabletPipe::TEvConnect, Handle); + hFunc(TEvTabletPipe::TEvServerDestroyed, Handle); hFunc(TEvInterconnect::TEvNodeDisconnected, HandleByLeader); hFunc(TEvents::TEvUndelivered, HandleByLeader); - hFunc(TEvBlobStorage::TEvCollectGarbageResult, Handle); - } - } - - STATEFN(StateBootstrapNormal) { - switch (ev->GetTypeRewrite()) { - cFunc(TEvents::TEvBootstrap::EventType, Bootstrap); - default: - Y_FAIL(); - } - } - + hFunc(TEvBlobStorage::TEvCollectGarbageResult, Handle); + } + } + + STATEFN(StateBootstrapNormal) { + switch (ev->GetTypeRewrite()) { + cFunc(TEvents::TEvBootstrap::EventType, Bootstrap); + default: + Y_FAIL(); + } + } + STATEFN(StateBootstrapFollower) { - switch (ev->GetTypeRewrite()) { + switch (ev->GetTypeRewrite()) { cFunc(TEvents::TEvBootstrap::EventType, BootstrapFollower); - default: - Y_FAIL(); - } - } - + default: + Y_FAIL(); + } + } + STATEFN(StateResolveLeader) { - switch (ev->GetTypeRewrite()) { + switch (ev->GetTypeRewrite()) { hFunc(TEvTablet::TEvPromoteToLeader, HandleByFollower); hFunc(TEvTablet::TEvFollowerRefresh, HandleByFollower); hFunc(TEvTablet::TEvTabletActive, HandleByFollower); - hFunc(TEvTablet::TEvUpdateConfig, Handle); + hFunc(TEvTablet::TEvUpdateConfig, Handle); hFunc(TEvStateStorage::TEvInfo, HandleStateStorageLeaderResolve); hFunc(TEvTabletBase::TEvFollowerRetry, HandleFollowerRetry); hFunc(TEvTabletBase::TEvTryBuildFollowerGraph, HandleByFollower); @@ -565,12 +565,12 @@ class TTablet : public TActor<TTablet> { hFunc(TEvTablet::TEvFeatures, HandleFeatures); hFunc(TEvTablet::TEvTabletStop, HandleStop); cFunc(TEvTablet::TEvTabletStopped::EventType, HandleStopped); - cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); - } - } - + cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); + } + } + STATEFN(StateFollowerSubscribe) { - switch (ev->GetTypeRewrite()) { + switch (ev->GetTypeRewrite()) { hFunc(TEvTablet::TEvPromoteToLeader, HandleByFollower); hFunc(TEvTablet::TEvFollowerDisconnect, HandleByFollower); hFunc(TEvTablet::TEvFollowerUpdate, HandleByFollower); @@ -578,25 +578,25 @@ class TTablet : public TActor<TTablet> { hFunc(TEvTablet::TEvFollowerRefresh, HandleByFollower); hFunc(TEvTablet::TEvFGcAck, HandleByFollower); hFunc(TEvTablet::TEvTabletActive, HandleByFollower); - hFunc(TEvTablet::TEvUpdateConfig, Handle); + hFunc(TEvTablet::TEvUpdateConfig, Handle); hFunc(TEvTabletBase::TEvTryBuildFollowerGraph, HandleByFollower); hFunc(TEvTabletBase::TEvRebuildGraphResult, HandleByFollower); hFunc(TEvInterconnect::TEvNodeDisconnected, HandleByFollower); hFunc(TEvents::TEvUndelivered, HandleByFollower); hFunc(TEvTabletPipe::TEvConnect, HandleByFollower); - hFunc(TEvTabletPipe::TEvServerDestroyed, Handle); + hFunc(TEvTabletPipe::TEvServerDestroyed, Handle); hFunc(TEvTablet::TEvFeatures, HandleFeatures); hFunc(TEvTablet::TEvTabletStop, HandleStop); cFunc(TEvTablet::TEvTabletStopped::EventType, HandleStopped); - cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); - } - } - + cFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill); + } + } + public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TABLET_ACTOR; } - + TTablet( const TActorId &launcher, TTabletStorageInfo *info, @@ -607,9 +607,9 @@ public: TResourceProfilesPtr profiles = nullptr, TSharedQuotaPtr txCacheQuota = nullptr ); - + TAutoPtr<IEventHandle> AfterRegister(const TActorId &self, const TActorId &parentId) override; - static void ExternalWriteZeroEntry(TTabletStorageInfo *info, ui32 gen, TActorIdentity owner); -}; - -} + static void ExternalWriteZeroEntry(TTabletStorageInfo *info, ui32 gen, TActorIdentity owner); +}; + +} diff --git a/ydb/core/tablet/ya.make b/ydb/core/tablet/ya.make index 9a37dba57b..25e611b408 100644 --- a/ydb/core/tablet/ya.make +++ b/ydb/core/tablet/ya.make @@ -1,13 +1,13 @@ -LIBRARY() - +LIBRARY() + OWNER( ddoarn vvvv g:kikimr ) -SRCS( - defs.h +SRCS( + defs.h node_tablet_monitor.cpp node_tablet_monitor.h node_whiteboard.cpp @@ -16,15 +16,15 @@ SRCS( resource_broker.cpp resource_broker.h resource_broker_impl.h - tablet_counters.cpp - tablet_counters.h + tablet_counters.cpp + tablet_counters.h tablet_counters_aggregator.cpp tablet_counters_aggregator.h tablet_counters_app.cpp tablet_counters_app.h tablet_counters_protobuf.h tablet_exception.h - tablet_impl.h + tablet_impl.h tablet_tracing_signals.cpp tablet_tracing_signals.h tablet_list_renderer.cpp @@ -33,27 +33,27 @@ SRCS( tablet_metrics.cpp tablet_monitoring_proxy.cpp tablet_monitoring_proxy.h - tablet_pipecache.cpp + tablet_pipecache.cpp tablet_pipe_client.cpp tablet_pipe_client_cache.cpp tablet_pipe_client_cache.h tablet_pipe_server.cpp - tablet_req_blockbs.cpp + tablet_req_blockbs.cpp tablet_req_delete.cpp - tablet_req_findlatest.cpp - tablet_req_rebuildhistory.cpp + tablet_req_findlatest.cpp + tablet_req_rebuildhistory.cpp tablet_req_reset.cpp - tablet_req_writelog.cpp - tablet_resolver.cpp - tablet_responsiveness_pinger.cpp - tablet_responsiveness_pinger.h - tablet_setup.h - tablet_sys.h - tablet_sys.cpp + tablet_req_writelog.cpp + tablet_resolver.cpp + tablet_responsiveness_pinger.cpp + tablet_responsiveness_pinger.h + tablet_setup.h + tablet_sys.h + tablet_sys.cpp bootstrapper.cpp -) - -PEERDIR( +) + +PEERDIR( library/cpp/actors/core library/cpp/actors/helpers library/cpp/actors/protos @@ -71,9 +71,9 @@ PEERDIR( ydb/core/tracing ydb/core/util ydb/library/persqueue/topic_parser -) - -END() +) + +END() RECURSE_FOR_TESTS( ut diff --git a/ydb/core/tablet_flat/defs.h b/ydb/core/tablet_flat/defs.h index 5885c4e4d7..166674c3ff 100644 --- a/ydb/core/tablet_flat/defs.h +++ b/ydb/core/tablet_flat/defs.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once // unique tag to fix pragma once gcc glueing: ./ydb/core/tablet_flat/defs.h #include "flat_page_iface.h" @@ -11,18 +11,18 @@ #include <ydb/core/util/type_alias.h> #include <util/generic/xrange.h> #include <util/generic/ylimits.h> - -namespace NKikimr { - + +namespace NKikimr { + using TTxType = ui32; // App-specific transaction type number (protobuf enum values like TXTYPE_*) constexpr TTxType UnknownTxType = TTxType(-1); -namespace NScheme { - - class TTypeRegistry; - -} // end of NKikimr::NScheme namespace - +namespace NScheme { + + class TTypeRegistry; + +} // end of NKikimr::NScheme namespace + namespace NTable { using TRawVals = TArrayRef<const TRawTypeValue>; @@ -117,5 +117,5 @@ namespace NTable { namespace NTabletFlatExecutor { using TTxStamp = NTable::TTxStamp; using TRawVals = NTable::TRawVals; -} +} } diff --git a/ydb/core/tablet_flat/flat_bio_actor.cpp b/ydb/core/tablet_flat/flat_bio_actor.cpp index 6593a759ca..6a866fb395 100644 --- a/ydb/core/tablet_flat/flat_bio_actor.cpp +++ b/ydb/core/tablet_flat/flat_bio_actor.cpp @@ -56,7 +56,7 @@ void TBlockIO::Inbox(TEventHandlePtr &eh, const ::NActors::TActorContext&) void TBlockIO::Bootstrap(EPriority priority, TAutoPtr<NPageCollection::TFetch> origin) noexcept { - Origin = origin; + Origin = origin; Priority = priority; Y_VERIFY(Origin->Pages, "Got TFetch request without pages list"); diff --git a/ydb/core/tablet_flat/flat_boot_snap.h b/ydb/core/tablet_flat/flat_boot_snap.h index 9ed179af26..0eae48284f 100644 --- a/ydb/core/tablet_flat/flat_boot_snap.h +++ b/ydb/core/tablet_flat/flat_boot_snap.h @@ -283,8 +283,8 @@ namespace NBoot { } else { NPageCollection::TGroupBlobsByCookie chop(entry.References); - while (auto span = chop.Do()) - SortLogoSpan(stamp, span); + while (auto span = chop.Do()) + SortLogoSpan(stamp, span); } ProcessGcLogEntry(entry, false); @@ -295,8 +295,8 @@ namespace NBoot { void ProcessGcLogEntry(TDependency::TEntry &entry, bool snap) { if (Back->Follower) // do nothing for followers - return; - + return; + if (auto logl = Env->Logger()->Log(ELnLev::Debug)) { logl << NFmt::Do(*Back) << " process " << (snap ? "snap" : "log") diff --git a/ydb/core/tablet_flat/flat_cxx_database.h b/ydb/core/tablet_flat/flat_cxx_database.h index 6b441a4f9c..27a260bcb2 100644 --- a/ydb/core/tablet_flat/flat_cxx_database.h +++ b/ydb/core/tablet_flat/flat_cxx_database.h @@ -636,14 +636,14 @@ struct Schema { struct AutoPrecharge {}; template <TTableId _TableId> struct Table { - constexpr static TTableId TableId = _TableId; + constexpr static TTableId TableId = _TableId; using Precharge = AutoPrecharge; template <TColumnId _ColumnId, NScheme::TTypeId _ColumnType, bool _IsNotNull = false> struct Column { - constexpr static TColumnId ColumnId = _ColumnId; - constexpr static NScheme::TTypeId ColumnType = _ColumnType; + constexpr static TColumnId ColumnId = _ColumnId; + constexpr static NScheme::TTypeId ColumnType = _ColumnType; constexpr static bool IsNotNull = _IsNotNull; using Type = typename NSchemeTypeMapper<_ColumnType>::Type; @@ -1831,13 +1831,13 @@ struct Schema { } }; - template <ui32 LimitTxInFly = 0> - struct ExecutorLimitInFlyTx { - static void Materialize(TToughDb& database) { + template <ui32 LimitTxInFly = 0> + struct ExecutorLimitInFlyTx { + static void Materialize(TToughDb& database) { database.Alter().SetExecutorLimitInFlyTx(LimitTxInFly); - } - }; - + } + }; + template <ui64 CacheSize> struct ExecutorCacheSize { static void Materialize(TToughDb& database) { diff --git a/ydb/core/tablet_flat/flat_database.cpp b/ydb/core/tablet_flat/flat_database.cpp index 63e382ead5..c459119515 100644 --- a/ydb/core/tablet_flat/flat_database.cpp +++ b/ydb/core/tablet_flat/flat_database.cpp @@ -1,6 +1,6 @@ #include "defs.h" #include "flat_abi_evol.h" -#include "flat_database.h" +#include "flat_database.h" #include "flat_redo_writer.h" #include "flat_redo_player.h" #include "flat_dbase_naked.h" @@ -13,14 +13,14 @@ #include <ydb/core/util/pb.h> #include <ydb/core/scheme_types/scheme_type_registry.h> #include <util/generic/cast.h> - + #define MAX_REDO_BYTES_PER_COMMIT 268435456U // 256MB -namespace NKikimr { +namespace NKikimr { namespace NTable { - + TDatabase::TDatabase(TDatabaseImpl *databaseImpl) noexcept : DatabaseImpl(databaseImpl ? databaseImpl : new TDatabaseImpl(0, new TScheme, nullptr)) , NoMoreReadsFlag(true) @@ -244,12 +244,12 @@ void TDatabase::Begin(TTxStamp stamp, IPages& env) Change = MakeHolder<TChange>(Stamp = stamp, DatabaseImpl->Serial() + 1); Env = &env; NoMoreReadsFlag = false; -} - +} + TPartView TDatabase::GetPartView(ui32 tableId, const TLogoBlobID &bundle) const { return Require(tableId)->GetPartView(bundle); -} - +} + TVector<TPartView> TDatabase::GetTableParts(ui32 tableId) const { return Require(tableId)->GetAllParts(); } @@ -328,8 +328,8 @@ ui32 TDatabase::TxSnapTable(ui32 table) Require(table); Change->Snapshots.emplace_back(table); return Change->Snapshots.size() - 1; -} - +} + TAutoPtr<TSubset> TDatabase::Subset(ui32 table, TArrayRef<const TLogoBlobID> bundle, TEpoch before) const { return Require(table)->Subset(bundle, before); @@ -553,8 +553,8 @@ TDatabase::TProd TDatabase::Commit(TTxStamp stamp, bool commit, TCookieAllocator Env = nullptr; return { std::move(Change) }; -} - +} + TTable* TDatabase::Require(ui32 table) const noexcept { return DatabaseImpl->Get(table, true).Self.Get(); @@ -562,11 +562,11 @@ TTable* TDatabase::Require(ui32 table) const noexcept TGarbage TDatabase::RollUp(TTxStamp stamp, TArrayRef<const char> delta, TArrayRef<const char> redo, TMemGlobs annex) -{ +{ Y_VERIFY(!annex || redo, "Annex have to be rolled up with redo log"); DatabaseImpl->Switch(stamp); - + if (delta) { TSchemeChanges changes; bool parseOk = ParseFromStringNoSizeLimit(changes, delta); @@ -574,23 +574,23 @@ TGarbage TDatabase::RollUp(TTxStamp stamp, TArrayRef<const char> delta, TArrayRe DatabaseImpl->Apply(changes, nullptr); } - + if (redo) { DatabaseImpl->Assign(std::move(annex)); DatabaseImpl->ApplyRedo(redo); DatabaseImpl->GrabAnnex(); } - + return std::move(DatabaseImpl->Garbage); -} - +} + void TDatabase::RollUpRemoveRowVersions(ui32 table, const TRowVersion& lower, const TRowVersion& upper) { if (auto& wrap = DatabaseImpl->Get(table, false)) { wrap->RemoveRowVersions(lower, upper); } } - + TCompactionStats TDatabase::GetCompactionStats(ui32 table) const { return Require(table)->GetCompactionStats(); @@ -602,4 +602,4 @@ void DebugDumpDb(const TDatabase &db) { db.DebugDump(Cout, typeRegistry); } -}} +}} diff --git a/ydb/core/tablet_flat/flat_database.h b/ydb/core/tablet_flat/flat_database.h index 03481e463c..98baa8f438 100644 --- a/ydb/core/tablet_flat/flat_database.h +++ b/ydb/core/tablet_flat/flat_database.h @@ -1,14 +1,14 @@ -#pragma once +#pragma once #include "flat_row_eggs.h" #include "flat_row_versions.h" -#include "flat_update_op.h" +#include "flat_update_op.h" #include "flat_dbase_scheme.h" #include "flat_dbase_change.h" #include "flat_dbase_misc.h" #include "flat_iterator.h" #include "util_basics.h" - -namespace NKikimr { + +namespace NKikimr { namespace NPageCollection { class TCookieAllocator; @@ -38,11 +38,11 @@ struct TKeyRange { }; class TDatabase { -public: +public: using TMemGlobs = TVector<NPageCollection::TMemGlob>; using TCookieAllocator = NPageCollection::TCookieAllocator; using TCounters = TDbStats; - + struct TProd { THolder<TChange> Change; }; @@ -54,8 +54,8 @@ public: TDatabase(const TDatabase&) = delete; TDatabase(TDatabaseImpl *databaseImpl = nullptr) noexcept; - ~TDatabase(); - + ~TDatabase(); + /* Returns durable monotonic change number for table or entire database on default (table = Max<ui32>()). Serial is incremented for each successful Commit(). AHTUNG: Serial may go to the past in case of @@ -86,7 +86,7 @@ public: TTagsRef tags, ui64 readFlags, ui64 itemsLimit, ui64 bytesLimit, EDirection direction = EDirection::Forward, TRowVersion snapshot = TRowVersion::Max()); - + void CalculateReadSize(TSizeEnv& env, ui32 table, TRawVals minKey, TRawVals maxKey, TTagsRef tags, ui64 readFlags, ui64 itemsLimit, ui64 bytesLimit, EDirection direction = EDirection::Forward, @@ -115,13 +115,13 @@ public: const TRowVersionRanges& GetRemovedRowVersions(ui32 table) const; void NoMoreReadsForTx(); - + TAlter& Alter(); /* Begin DDL ALTER script */ ui32 TxSnapTable(ui32 table); const TScheme& GetScheme() const noexcept; - + TIntrusiveConstPtr<TRowScheme> GetRowScheme(ui32 table) const noexcept; TPartView GetPartView(ui32 table, const TLogoBlobID &bundle) const; @@ -151,17 +151,17 @@ public: void Merge(ui32 table, TPartView); void Merge(ui32 table, TIntrusiveConstPtr<TColdPart>); void Merge(ui32 table, TIntrusiveConstPtr<TTxStatusPart>); - + void DebugDumpTable(ui32 table, IOutputStream& str, const NScheme::TTypeRegistry& typeRegistry) const; void DebugDump(IOutputStream& str, const NScheme::TTypeRegistry& typeRegistry) const; TKeyRangeCache* DebugGetTableErasedKeysCache(ui32 table) const; - // executor interface + // executor interface void Begin(TTxStamp, IPages& env); TProd Commit(TTxStamp, bool commit, TCookieAllocator* = nullptr); TGarbage RollUp(TTxStamp, TArrayRef<const char> delta, TArrayRef<const char> redo, TMemGlobs annex); - + void RollUpRemoveRowVersions(ui32 table, const TRowVersion& lower, const TRowVersion& upper); bool ValidateCommit(TString&); @@ -171,9 +171,9 @@ public: private: TTable* Require(ui32 tableId) const noexcept; -private: +private: const THolder<TDatabaseImpl> DatabaseImpl; - + ui64 Stamp = Max<ui64>(); bool NoMoreReadsFlag; IPages* Env = nullptr; @@ -184,7 +184,7 @@ private: mutable TDeque<TPartSimpleIt> TempIterators; // Keeps the last result of Select() valid mutable THashSet<ui32> IteratedTables; -}; - +}; + -}} +}} diff --git a/ydb/core/tablet_flat/flat_dbase_apply.cpp b/ydb/core/tablet_flat/flat_dbase_apply.cpp index d914ede391..f87b315d33 100644 --- a/ydb/core/tablet_flat/flat_dbase_apply.cpp +++ b/ydb/core/tablet_flat/flat_dbase_apply.cpp @@ -118,8 +118,8 @@ bool TSchemeModifier::Apply(const TAlterRecord &delta) changes |= SetExecutorLimitInFlyTx(delta.GetExecutorLimitInFlyTx()); if (delta.HasExecutorResourceProfile()) changes |= SetExecutorResourceProfile(delta.GetExecutorResourceProfile()); - if (delta.HasExecutorLogFastCommitTactic()) - changes |= SetExecutorLogFastCommitTactic(delta.GetExecutorLogFastCommitTactic()); + if (delta.HasExecutorLogFastCommitTactic()) + changes |= SetExecutorLogFastCommitTactic(delta.GetExecutorLogFastCommitTactic()); } else if (action == TAlterRecord::SetCompactionPolicy) { changes = SetCompactionPolicy(table, delta.GetCompactionPolicy()); } else { @@ -245,11 +245,11 @@ bool TSchemeModifier::SetExecutorAllowLogBatching(bool allow) return std::exchange(Scheme.Executor.AllowLogBatching, allow) != allow; } -bool TSchemeModifier::SetExecutorLogFastCommitTactic(bool allow) -{ - return std::exchange(Scheme.Executor.LogFastTactic, allow) != allow; -} - +bool TSchemeModifier::SetExecutorLogFastCommitTactic(bool allow) +{ + return std::exchange(Scheme.Executor.LogFastTactic, allow) != allow; +} + bool TSchemeModifier::SetExecutorLogFlushPeriod(TDuration delay) { return std::exchange(Scheme.Executor.LogFlushPeriod, delay) != delay; diff --git a/ydb/core/tablet_flat/flat_dbase_apply.h b/ydb/core/tablet_flat/flat_dbase_apply.h index 8d458ee20b..3502030b71 100644 --- a/ydb/core/tablet_flat/flat_dbase_apply.h +++ b/ydb/core/tablet_flat/flat_dbase_apply.h @@ -39,7 +39,7 @@ namespace NTable { bool SetExecutorCacheSize(ui64 cacheSize); bool SetExecutorAllowLogBatching(bool allow); - bool SetExecutorLogFastCommitTactic(bool allow); + bool SetExecutorLogFastCommitTactic(bool allow); bool SetExecutorLogFlushPeriod(TDuration flushPeriod); bool SetExecutorLimitInFlyTx(ui32 limitTxInFly); bool SetExecutorResourceProfile(const TString &name); diff --git a/ydb/core/tablet_flat/flat_dbase_scheme.cpp b/ydb/core/tablet_flat/flat_dbase_scheme.cpp index 3e684e4ed0..fa12005009 100644 --- a/ydb/core/tablet_flat/flat_dbase_scheme.cpp +++ b/ydb/core/tablet_flat/flat_dbase_scheme.cpp @@ -196,47 +196,47 @@ TAlter& TAlter::SetExecutorCacheSize(ui64 cacheSize) { TAlterRecord &delta = *Log.AddDelta(); delta.SetDeltaType(TAlterRecord::UpdateExecutorInfo); - delta.SetExecutorCacheSize(cacheSize); + delta.SetExecutorCacheSize(cacheSize); return *this; -} - -TAlter& TAlter::SetExecutorFastLogPolicy(bool allow) -{ - TAlterRecord &delta = *Log.AddDelta(); - delta.SetDeltaType(TAlterRecord::UpdateExecutorInfo); - delta.SetExecutorLogFastCommitTactic(allow); - - return *this; -} - +} + +TAlter& TAlter::SetExecutorFastLogPolicy(bool allow) +{ + TAlterRecord &delta = *Log.AddDelta(); + delta.SetDeltaType(TAlterRecord::UpdateExecutorInfo); + delta.SetExecutorLogFastCommitTactic(allow); + + return *this; +} + TAlter& TAlter::SetExecutorAllowLogBatching(bool allow) { TAlterRecord &delta = *Log.AddDelta(); delta.SetDeltaType(TAlterRecord::UpdateExecutorInfo); - delta.SetExecutorAllowLogBatching(allow); + delta.SetExecutorAllowLogBatching(allow); return *this; -} - +} + TAlter& TAlter::SetExecutorLogFlushPeriod(TDuration flushPeriod) { TAlterRecord &delta = *Log.AddDelta(); delta.SetDeltaType(TAlterRecord::UpdateExecutorInfo); - delta.SetExecutorLogFlushPeriod(flushPeriod.MicroSeconds()); + delta.SetExecutorLogFlushPeriod(flushPeriod.MicroSeconds()); return *this; -} - +} + TAlter& TAlter::SetExecutorLimitInFlyTx(ui32 limitTxInFly) { TAlterRecord &delta = *Log.AddDelta(); delta.SetDeltaType(TAlterRecord::UpdateExecutorInfo); - delta.SetExecutorLimitInFlyTx(limitTxInFly); + delta.SetExecutorLimitInFlyTx(limitTxInFly); return *this; -} - +} + TAlter& TAlter::SetExecutorResourceProfile(const TString &name) { TAlterRecord &delta = *Log.AddDelta(); diff --git a/ydb/core/tablet_flat/flat_dbase_scheme.h b/ydb/core/tablet_flat/flat_dbase_scheme.h index a8b0424e08..1fd5ed2b48 100644 --- a/ydb/core/tablet_flat/flat_dbase_scheme.h +++ b/ydb/core/tablet_flat/flat_dbase_scheme.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "flat_table_column.h" #include "flat_page_iface.h" @@ -7,29 +7,29 @@ #include <ydb/core/base/localdb.h> #include <ydb/core/protos/scheme_log.pb.h> -#include <util/generic/map.h> +#include <util/generic/map.h> #include <util/generic/hash_set.h> #include <util/generic/list.h> - -namespace NKikimr { + +namespace NKikimr { namespace NTable { - + using namespace NTabletFlatScheme; using NKikimrSchemeOp::ECompactionStrategy; using TCompactionPolicy = NLocalDb::TCompactionPolicy; -class TScheme { -public: +class TScheme { +public: using TTypeId = ui32; using ECache = NPage::ECache; enum EDefault { DefaultRoom = 0, DefaultChannel = 1, - }; - + }; + struct TRoom /* Storage unit settings (page collection) */ { TRoom() = default; @@ -50,8 +50,8 @@ public: ui8 Main = DefaultChannel; /* Primary channel for page collection */ ui8 Blobs = DefaultChannel; /* Channel for external blobs */ ui8 Outer = DefaultChannel; /* Channel for outer values pack*/ - }; - + }; + struct TFamily /* group of columns configuration */ { using ECodec = NPage::ECodec; @@ -73,7 +73,7 @@ public: }; using TColumn = NTable::TColumn; - + struct TTableSchema { using TColumns = THashMap<ui32, TColumn>; using TColumnNames = THashMap<TString, ui32>; @@ -105,7 +105,7 @@ public: ui32 EraseCacheMinRows = 0; // 0 means use default ui32 EraseCacheMaxBytes = 0; // 0 means use default }; - + struct TRedo { /* Do not put cell values below this byte limit to external blobs on writing redo log update entries (annex to log). By default @@ -120,18 +120,18 @@ public: */ ui32 Annex = 512; /* some reasonably low default value */ - }; - - struct TExecutorInfo { + }; + + struct TExecutorInfo { ui64 CacheSize = 384 * 1024; bool AllowLogBatching = false; - bool LogFastTactic = true; + bool LogFastTactic = true; TDuration LogFlushPeriod = TDuration::MicroSeconds(500); ui32 LimitInFlyTx = 0; TString ResourceProfile = "default"; ECompactionStrategy DefaultCompactionStrategy = NKikimrSchemeOp::CompactionStrategyGenerational; - }; - + }; + const TTableInfo* GetTableInfo(ui32 id) const { return const_cast<TScheme*>(this)->GetTableInfo(id); } const TColumn* GetColumnInfo(ui32 table, ui32 id) const { return const_cast<TScheme*>(this)->GetColumnInfo(const_cast<TScheme*>(this)->GetTableInfo(table), id); } @@ -144,7 +144,7 @@ public: inline TColumn* GetColumnInfo(TTableInfo* ptable, ui32 id) { return ptable ? ptable->Columns.FindPtr(id) : nullptr; } - + inline const TColumn* GetColumnInfo(const TTableInfo* ptable, ui32 id) const { return ptable ? ptable->Columns.FindPtr(id) : nullptr; } @@ -198,8 +198,8 @@ public: THashMap<TString, ui32> TableNames; TExecutorInfo Executor; TRedo Redo; -}; - +}; + // scheme delta class TAlter { public: @@ -210,7 +210,7 @@ public: { return Log; } - + TAlter& Merge(const TSchemeChanges &delta); TAlter& AddTable(const TString& name, ui32 id); TAlter& DropTable(ui32 id); @@ -224,7 +224,7 @@ public: TAlter& SetRoom(ui32 table, ui32 room, ui32 main, ui32 blobs, ui32 outer); TAlter& SetRedo(ui32 annex); TAlter& SetExecutorCacheSize(ui64 cacheSize); - TAlter& SetExecutorFastLogPolicy(bool allow); + TAlter& SetExecutorFastLogPolicy(bool allow); TAlter& SetExecutorAllowLogBatching(bool allow); TAlter& SetExecutorLogFlushPeriod(TDuration flushPeriod); TAlter& SetExecutorLimitInFlyTx(ui32 limitTxInFly); @@ -239,4 +239,4 @@ protected: TSchemeChanges Log; }; -}} +}} diff --git a/ydb/core/tablet_flat/flat_executor.cpp b/ydb/core/tablet_flat/flat_executor.cpp index a8e7712371..59afc46215 100644 --- a/ydb/core/tablet_flat/flat_executor.cpp +++ b/ydb/core/tablet_flat/flat_executor.cpp @@ -1,7 +1,7 @@ -#include "flat_executor.h" -#include "flat_executor_bootlogic.h" -#include "flat_executor_txloglogic.h" -#include "flat_executor_borrowlogic.h" +#include "flat_executor.h" +#include "flat_executor_bootlogic.h" +#include "flat_executor_txloglogic.h" +#include "flat_executor_borrowlogic.h" #include "flat_bio_actor.h" #include "flat_executor_snapshot.h" #include "flat_scan_actor.h" @@ -17,7 +17,7 @@ #include "flat_boot_cookie.h" #include "flat_boot_oven.h" #include "flat_executor_tx_env.h" -#include "flat_executor_counters.h" +#include "flat_executor_counters.h" #include "logic_snap_main.h" #include "logic_alter_main.h" #include "flat_abi_evol.h" @@ -33,16 +33,16 @@ #include <ydb/core/scheme/scheme_type_registry.h> #include <ydb/core/tablet/tablet_counters_aggregator.h> #include <ydb/core/util/yverify_stream.h> - + #include <library/cpp/monlib/service/pages/templates.h> #include <library/cpp/actors/core/hfunc.h> #include <util/generic/xrange.h> #include <util/generic/ymath.h> -namespace NKikimr { -namespace NTabletFlatExecutor { - +namespace NKikimr { +namespace NTabletFlatExecutor { + LWTRACE_USING(TABLET_FLAT_PROVIDER) struct TCompactionChangesCtx { @@ -57,39 +57,39 @@ struct TCompactionChangesCtx { { } }; -TTableSnapshotContext::TTableSnapshotContext() = default; -TTableSnapshotContext::~TTableSnapshotContext() = default; - +TTableSnapshotContext::TTableSnapshotContext() = default; +TTableSnapshotContext::~TTableSnapshotContext() = default; + using namespace NResourceBroker; TExecutor::TExecutor( NFlatExecutorSetup::ITablet* owner, const TActorId& ownerActorId) - : TActor(&TThis::StateInit) + : TActor(&TThis::StateInit) , Time(TAppData::TimeProvider) - , Owner(owner) + , Owner(owner) , OwnerActorId(ownerActorId) - , ActivationQueue(new TActivationQueue()) - , PendingQueue(new TActivationQueue()) + , ActivationQueue(new TActivationQueue()) + , PendingQueue(new TActivationQueue()) , Emitter(new TIdEmitter) , CounterEventsInFlight(new TEvTabletCounters::TInFlightCookie) - , Stats(new TExecutorStatsImpl()) + , Stats(new TExecutorStatsImpl()) , LogFlushDelayOverrideUsec(-1, -1, 60*1000*1000) -{} - -TExecutor::~TExecutor() { - -} - +{} + +TExecutor::~TExecutor() { + +} + ui64 TExecutor::Stamp() const noexcept { return CommitManager ? CommitManager->Stamp() : TTxStamp{ Generation0, Step0 }.Raw; } -TActorContext TExecutor::OwnerCtx() const { +TActorContext TExecutor::OwnerCtx() const { return TActivationContext::ActorContextFor(OwnerActorId); -} - +} + void TExecutor::Registered(TActorSystem *sys, const TActorId&) { Logger = new NUtil::TLogger(sys, NKikimrServices::TABLET_EXECUTOR); @@ -98,12 +98,12 @@ void TExecutor::Registered(TActorSystem *sys, const TActorId&) Memory = new TMemory(Logger.Get(), this, Emitter, Sprintf(" at tablet %" PRIu64, Owner->TabletID())); TString myTabletType = TTabletTypes::TypeToStr(Owner->TabletType()); AppData()->Icb->RegisterSharedControl(LogFlushDelayOverrideUsec, myTabletType + "_LogFlushDelayOverrideUsec"); - - // instantiate alert counters so even never reported alerts are created - GetServiceCounters(AppData()->Counters, "tablets")->GetCounter("alerts_pending_nodata", true); - GetServiceCounters(AppData()->Counters, "tablets")->GetCounter("alerts_req_nodata", true); - GetServiceCounters(AppData()->Counters, "tablets")->GetCounter("alerts_scan_nodata", true); - GetServiceCounters(AppData()->Counters, "tablets")->GetCounter("alerts_boot_nodata", true); + + // instantiate alert counters so even never reported alerts are created + GetServiceCounters(AppData()->Counters, "tablets")->GetCounter("alerts_pending_nodata", true); + GetServiceCounters(AppData()->Counters, "tablets")->GetCounter("alerts_req_nodata", true); + GetServiceCounters(AppData()->Counters, "tablets")->GetCounter("alerts_scan_nodata", true); + GetServiceCounters(AppData()->Counters, "tablets")->GetCounter("alerts_boot_nodata", true); } void TExecutor::PassAway() { @@ -123,57 +123,57 @@ void TExecutor::PassAway() { } Scans->Drop(); - Owner = nullptr; - + Owner = nullptr; + Send(MakeSharedPageCacheId(), new NSharedCache::TEvUnregister()); - + return TActor::PassAway(); -} - -void TExecutor::Broken() { - if (BootLogic) +} + +void TExecutor::Broken() { + if (BootLogic) BootLogic->Cancel(); - - if (Owner) { + + if (Owner) { TabletCountersForgetTablet(Owner->TabletID(), Owner->TabletType(), Owner->Info()->TenantPathId, Stats->IsFollower, SelfId()); - Owner->Detach(OwnerCtx()); - } - + Owner->Detach(OwnerCtx()); + } + return PassAway(); -} - +} + void TExecutor::RecreatePageCollectionsCache() noexcept { TCacheCacheConfig cacheConfig(Scheme().Executor.CacheSize, CounterCacheFresh, CounterCacheStaging, CounterCacheMemTable); PrivatePageCache = MakeHolder<TPrivatePageCache>(cacheConfig); Stats->PacksMetaBytes = 0; - + for (const auto &it : Database->GetScheme().Tables) { auto subset = Database->Subset(it.first, NTable::TEpoch::Max(), { }, { }); for (auto &partView : subset->Flatten) AddCachesOfBundle(partView); } - if (TransactionWaitPads) { + if (TransactionWaitPads) { for (auto &xpair : TransactionWaitPads) { auto &seat = xpair.second->Seat; LWTRACK(TransactionEnqueued, seat->Self->Orbit, seat->UniqID); ActivationQueue->Push(seat.Release()); ActivateTransactionWaiting++; } - TransactionWaitPads.clear(); - } - + TransactionWaitPads.clear(); + } + if (CompactionReadWaitPads) { for (auto &xpair : CompactionReadWaitPads) { CompactionReadQueue.push_back(xpair.second->ReadId); } CompactionReadWaitPads.clear(); } -} - +} + void TExecutor::ReflectSchemeSettings() noexcept { for (const auto &it : Scheme().Tables) { @@ -205,9 +205,9 @@ void TExecutor::CheckYellow(TVector<ui32> &&yellowMoveChannels, TVector<ui32> && if (Stats->YellowMoveChannels && terminal) { SendReassignYellowChannels(Stats->YellowMoveChannels); } - return; + return; } - + size_t oldMoveCount = Stats->YellowMoveChannels.size(); size_t oldStopCount = Stats->YellowStopChannels.size(); Stats->YellowMoveChannels.insert(Stats->YellowMoveChannels.end(), yellowMoveChannels.begin(), yellowMoveChannels.end()); @@ -245,10 +245,10 @@ void TExecutor::CheckYellow(TVector<ui32> &&yellowMoveChannels, TVector<ui32> && if (HasYellowCheckInFly || terminal) return; - HasYellowCheckInFly = true; + HasYellowCheckInFly = true; Schedule(TDuration::Seconds(15), new TEvPrivate::TEvCheckYellow()); -} - +} + void TExecutor::SendReassignYellowChannels(const TVector<ui32> &yellowChannels) { if (Owner->ReassignChannelsEnabled()) { auto* info = Owner->Info(); @@ -264,17 +264,17 @@ void TExecutor::SendReassignYellowChannels(const TVector<ui32> &yellowChannels) void TExecutor::UpdateYellow() { Register(CreateTabletDSChecker(SelfId(), Owner->Info())); -} - +} + void TExecutor::UpdateCompactions() { CompactionLogic->UpdateCompactions(); Schedule(TDuration::Minutes(1), new TEvPrivate::TEvUpdateCompactions); } void TExecutor::Handle(TEvTablet::TEvCheckBlobstorageStatusResult::TPtr &ev) { - Y_VERIFY(HasYellowCheckInFly); - HasYellowCheckInFly = false; - + Y_VERIFY(HasYellowCheckInFly); + HasYellowCheckInFly = false; + const auto* info = Owner->Info(); Y_VERIFY(info); @@ -296,7 +296,7 @@ void TExecutor::Handle(TEvTablet::TEvCheckBlobstorageStatusResult::TPtr &ev) { if (itStop != yellowStopGroups.end() && *itStop == group) { yellowStopChannels.push_back(channel); } - } + } Stats->YellowMoveChannels.clear(); Stats->YellowStopChannels.clear(); @@ -304,33 +304,33 @@ void TExecutor::Handle(TEvTablet::TEvCheckBlobstorageStatusResult::TPtr &ev) { Stats->IsAnyChannelYellowStop = false; CheckYellow(std::move(lightYellowMoveChannels), std::move(yellowStopChannels)); -} - +} + void TExecutor::ActivateFollower(const TActorContext &ctx) { if (auto logl = Logger->Log(ELnLev::Info)) logl << NFmt::Do(*this) << " activating executor"; - + auto loadedState = BootLogic->ExtractState(); - BootLogic.Destroy(); - - Y_VERIFY(!GcLogic); + BootLogic.Destroy(); + + Y_VERIFY(!GcLogic); Y_VERIFY(!LogicRedo); Y_VERIFY(!LogicAlter); Database = loadedState->Database; BorrowLogic = loadedState->Loans; - - Y_VERIFY(!CompactionLogic); - if (!Counters) { + + Y_VERIFY(!CompactionLogic); + if (!Counters) { Counters = MakeHolder<TExecutorCounters>(); CountersBaseline = MakeHolder<TExecutorCounters>(); - Counters->RememberCurrentStateAsBaseline(*CountersBaseline); - } - - CounterCacheFresh = new NMonitoring::TCounterForPtr; - CounterCacheStaging = new NMonitoring::TCounterForPtr; + Counters->RememberCurrentStateAsBaseline(*CountersBaseline); + } + + CounterCacheFresh = new NMonitoring::TCounterForPtr; + CounterCacheStaging = new NMonitoring::TCounterForPtr; CounterCacheMemTable = new NMonitoring::TCounterForPtr; - + ResourceMetrics = MakeHolder<NMetrics::TResourceMetrics>(Owner->TabletID(), FollowerId, Launcher); PendingBlobQueue.Config.TabletID = Owner->TabletID(); @@ -341,50 +341,50 @@ void TExecutor::ActivateFollower(const TActorContext &ctx) { ReadResourceProfile(); RecreatePageCollectionsCache(); ReflectSchemeSettings(); - + Become(&TThis::StateFollower); - Stats->IsActive = true; + Stats->IsActive = true; Stats->IsFollower = true; - + PlanTransactionActivation(); - Owner->ActivateExecutor(OwnerCtx()); - - UpdateCounters(ctx); + Owner->ActivateExecutor(OwnerCtx()); + + UpdateCounters(ctx); ApplyFollowerPostponedUpdates(); -} - -void TExecutor::Active(const TActorContext &ctx) { +} + +void TExecutor::Active(const TActorContext &ctx) { if (auto logl = Logger->Log(ELnLev::Info)) logl << NFmt::Do(*this) << " activating executor"; - + auto loadedState = BootLogic->ExtractState(); - BootLogic.Destroy(); - + BootLogic.Destroy(); + Counters = MakeHolder<TExecutorCounters>(); CommitManager = loadedState->CommitManager; Database = loadedState->Database; LogicSnap = loadedState->Snap; - GcLogic = loadedState->GcLogic; + GcLogic = loadedState->GcLogic; LogicRedo = loadedState->Redo; LogicAlter = loadedState->Alter; BorrowLogic = loadedState->Loans; - Stats->CompactedPartLoans = BorrowLogic->GetCompactedLoansList(); - Stats->HasSharedBlobs = BorrowLogic->GetHasFlag(); - + Stats->CompactedPartLoans = BorrowLogic->GetCompactedLoansList(); + Stats->HasSharedBlobs = BorrowLogic->GetHasFlag(); + CommitManager->Start(this, Owner->Tablet(), &Step0, Counters.Get()); CompactionLogic = THolder<TCompactionLogic>(new TCompactionLogic(Logger.Get(), Broker.Get(), this, loadedState->Comp, Sprintf("tablet-%" PRIu64, Owner->TabletID()))); CountersBaseline = MakeHolder<TExecutorCounters>(); - Counters->RememberCurrentStateAsBaseline(*CountersBaseline); + Counters->RememberCurrentStateAsBaseline(*CountersBaseline); LogicRedo->InstallCounters(Counters.Get(), nullptr); - CounterCacheFresh = new NMonitoring::TCounterForPtr; - CounterCacheStaging = new NMonitoring::TCounterForPtr; + CounterCacheFresh = new NMonitoring::TCounterForPtr; + CounterCacheStaging = new NMonitoring::TCounterForPtr; CounterCacheMemTable = new NMonitoring::TCounterForPtr; - + ResourceMetrics = MakeHolder<NMetrics::TResourceMetrics>(Owner->TabletID(), 0, Launcher); PendingBlobQueue.Config.TabletID = Owner->TabletID(); @@ -395,13 +395,13 @@ void TExecutor::Active(const TActorContext &ctx) { ReadResourceProfile(); RecreatePageCollectionsCache(); ReflectSchemeSettings(); - - RequestInMemPagesForDatabase(); - - Become(&TThis::StateWork); - Stats->IsActive = true; + + RequestInMemPagesForDatabase(); + + Become(&TThis::StateWork); + Stats->IsActive = true; Stats->IsFollower = false; - + CompactionLogic->Start(); for (const auto &it: Database->GetScheme().Tables) @@ -409,81 +409,81 @@ void TExecutor::Active(const TActorContext &ctx) { UpdateCompactions(); MakeLogSnapshot(); - + if (auto error = CheckBorrowConsistency()) { if (auto logl = Logger->Log(ELnLev::Crit)) logl << NFmt::Do(*this) << " Borrow consistency failed: " << error; } - + PlanTransactionActivation(); PlanCompactionReadActivation(); - Owner->ActivateExecutor(OwnerCtx()); - - UpdateCounters(ctx); -} - -void TExecutor::TranscriptBootOpResult(ui32 res, const TActorContext &ctx) { - switch (res) { - case TExecutorBootLogic::OpResultUnhandled: - return; // do nothing? - case TExecutorBootLogic::OpResultContinue: - return; // do nothing. - case TExecutorBootLogic::OpResultComplete: - return Active(ctx); - case TExecutorBootLogic::OpResultBroken: - BootLogic.Destroy(); - - if (auto logl = Logger->Log(ELnLev::Error)) { - logl << NFmt::Do(*this) << " Broken while booting"; - } - - return Broken(); - default: + Owner->ActivateExecutor(OwnerCtx()); + + UpdateCounters(ctx); +} + +void TExecutor::TranscriptBootOpResult(ui32 res, const TActorContext &ctx) { + switch (res) { + case TExecutorBootLogic::OpResultUnhandled: + return; // do nothing? + case TExecutorBootLogic::OpResultContinue: + return; // do nothing. + case TExecutorBootLogic::OpResultComplete: + return Active(ctx); + case TExecutorBootLogic::OpResultBroken: + BootLogic.Destroy(); + + if (auto logl = Logger->Log(ELnLev::Error)) { + logl << NFmt::Do(*this) << " Broken while booting"; + } + + return Broken(); + default: Y_FAIL("unknown boot result"); - } -} - + } +} + void TExecutor::TranscriptFollowerBootOpResult(ui32 res, const TActorContext &ctx) { - switch (res) { - case TExecutorBootLogic::OpResultUnhandled: - return; - case TExecutorBootLogic::OpResultContinue: - return; - case TExecutorBootLogic::OpResultComplete: + switch (res) { + case TExecutorBootLogic::OpResultUnhandled: + return; + case TExecutorBootLogic::OpResultContinue: + return; + case TExecutorBootLogic::OpResultComplete: return ActivateFollower(ctx); - case TExecutorBootLogic::OpResultBroken: - BootLogic.Destroy(); - if (auto logl = Logger->Log(ELnLev::Error)) { + case TExecutorBootLogic::OpResultBroken: + BootLogic.Destroy(); + if (auto logl = Logger->Log(ELnLev::Error)) { logl << NFmt::Do(*this) << " Broken while follower booting"; - } - return Broken(); - default: - Y_FAIL("unknown boot result"); - } -} - + } + return Broken(); + default: + Y_FAIL("unknown boot result"); + } +} + void TExecutor::PlanTransactionActivation() { - if (!CanExecuteTransaction()) - return; - + if (!CanExecuteTransaction()) + return; + const ui64 limitTxInFly = Scheme().Executor.LimitInFlyTx; - while (PendingQueue->Head() && (!limitTxInFly || (Stats->TxInFly - Stats->TxPending < limitTxInFly))) { + while (PendingQueue->Head() && (!limitTxInFly || (Stats->TxInFly - Stats->TxPending < limitTxInFly))) { TAutoPtr<TSeat> seat = PendingQueue->Pop(); LWTRACK(TransactionEnqueued, seat->Self->Orbit, seat->UniqID); ActivationQueue->Push(seat.Release()); ActivateTransactionWaiting++; - --Stats->TxPending; - } - + --Stats->TxPending; + } + while (ActivateTransactionInFlight < ActivateTransactionWaiting) { Send(SelfId(), new TEvPrivate::TEvActivateExecution()); ActivateTransactionInFlight++; - } -} - + } +} + void TExecutor::ActivateWaitingTransactions(TPrivatePageCache::TPage::TWaitQueuePtr waitPadsQueue) { - if (waitPadsQueue) { + if (waitPadsQueue) { bool haveTransactions = false; bool haveCompactionReads = false; while (TPrivatePageCacheWaitPad *waitPad = waitPadsQueue->Pop()) { @@ -501,20 +501,20 @@ void TExecutor::ActivateWaitingTransactions(TPrivatePageCache::TPage::TWaitQueue } else { Y_Fail("Unexpected wait pad triggered"); } - } + } if (haveTransactions) { PlanTransactionActivation(); } if (haveCompactionReads) { PlanCompactionReadActivation(); } - } -} - + } +} + void TExecutor::AddCachesOfBundle(const NTable::TPartView &partView) noexcept { auto *partStore = partView.As<NTable::TPartStore>(); - + { ui32 room = 0; @@ -564,29 +564,29 @@ void TExecutor::DropSingleCache(const TLogoBlobID &label) noexcept Counters->Simple()[TExecutorCounters::CACHE_PINNED_LOAD] = PrivatePageCache->GetStats().PinnedLoadSize; } -void TExecutor::TranslateCacheTouchesToSharedCache() { +void TExecutor::TranslateCacheTouchesToSharedCache() { auto touches = PrivatePageCache->GetPrepareSharedTouched(); - if (touches.empty()) - return; + if (touches.empty()) + return; Send(MakeSharedPageCacheId(), new NSharedCache::TEvTouch(std::move(touches))); -} +} -void TExecutor::RequestInMemPagesForDatabase() { +void TExecutor::RequestInMemPagesForDatabase() { const auto &scheme = Scheme(); - for (auto &sxpair : scheme.Tables) { + for (auto &sxpair : scheme.Tables) { // should be over page collection cache with already set inmem flags? if (scheme.CachePolicy(sxpair.first) == NTable::NPage::ECache::Ever) { auto subset = Database->Subset(sxpair.first, NTable::TEpoch::Max(), { } , { }); - + for (auto &partView: subset->Flatten) RequestInMemPagesForPartStore(sxpair.first, partView); - } - } -} - + } + } +} + TExecutorCaches TExecutor::CleanupState() { TExecutorCaches caches; - + if (BootLogic) { caches = BootLogic->DetachCaches(); } else { @@ -600,45 +600,45 @@ TExecutorCaches TExecutor::CleanupState() { } } - BootLogic.Destroy(); + BootLogic.Destroy(); PendingBlobQueue.Clear(); PostponedFollowerUpdates.clear(); PendingPartSwitches.clear(); ReadyPartSwitches = 0; Y_VERIFY(!LogicRedo); - Database.Destroy(); - Y_VERIFY(!GcLogic); + Database.Destroy(); + Y_VERIFY(!GcLogic); Y_VERIFY(!LogicAlter); - Y_VERIFY(!CompactionLogic); - BorrowLogic.Destroy(); - + Y_VERIFY(!CompactionLogic); + BorrowLogic.Destroy(); + return caches; -} - -void TExecutor::Boot(TEvTablet::TEvBoot::TPtr &ev, const TActorContext &ctx) { +} + +void TExecutor::Boot(TEvTablet::TEvBoot::TPtr &ev, const TActorContext &ctx) { if (Stats->IsFollower) { TabletCountersForgetTablet(Owner->TabletID(), Owner->TabletType(), Owner->Info()->TenantPathId, Stats->IsFollower, SelfId()); } - + RegisterTabletFlatProbes(); - Become(&TThis::StateBoot); - Stats->IsActive = false; + Become(&TThis::StateBoot); + Stats->IsActive = false; Stats->IsFollower = false; - - TEvTablet::TEvBoot *msg = ev->Get(); - Generation0 = msg->Generation; - Step0 = 0; + + TEvTablet::TEvBoot *msg = ev->Get(); + Generation0 = msg->Generation; + Step0 = 0; Launcher = msg->Launcher; Memory->SetProfiles(msg->ResourceProfiles); - - const ui64 maxBootBytesInFly = 12 * 1024 * 1024; - + + const ui64 maxBootBytesInFly = 12 * 1024 * 1024; + auto executorCaches = CleanupState(); - + BootLogic.Reset(new TExecutorBootLogic(this, SelfId(), Owner->Info(), maxBootBytesInFly)); - + ui64 totalBytes = 0; for (auto& kv : msg->GroupReadBytes) { totalBytes += kv.second; @@ -655,116 +655,116 @@ void TExecutor::Boot(TEvTablet::TEvBoot::TPtr &ev, const TActorContext &ctx) { std::move(msg->GroupReadOps))); const auto res = BootLogic->ReceiveBoot(ev, std::move(executorCaches)); - return TranscriptBootOpResult(res, ctx); -} - + return TranscriptBootOpResult(res, ctx); +} + void TExecutor::FollowerBoot(TEvTablet::TEvFBoot::TPtr &ev, const TActorContext &ctx) { - Y_VERIFY(CurrentStateFunc() == &TThis::StateInit + Y_VERIFY(CurrentStateFunc() == &TThis::StateInit || CurrentStateFunc() == &TThis::StateFollowerBoot || CurrentStateFunc() == &TThis::StateFollower); - + RegisterTabletFlatProbes(); Become(&TThis::StateFollowerBoot); - Stats->IsActive = false; + Stats->IsActive = false; Stats->IsFollower = true; - + TEvTablet::TEvFBoot *msg = ev->Get(); - Generation0 = msg->Generation; - Step0 = 0; - Launcher = msg->Launcher; + Generation0 = msg->Generation; + Step0 = 0; + Launcher = msg->Launcher; Memory->SetProfiles(msg->ResourceProfiles); FollowerId = msg->FollowerID; - - const ui64 maxBootBytesInFly = 12 * 1024 * 1024; - + + const ui64 maxBootBytesInFly = 12 * 1024 * 1024; + auto executorCaches = CleanupState(); - + BootLogic.Reset(new TExecutorBootLogic(this, SelfId(), Owner->Info(), maxBootBytesInFly)); const auto res = BootLogic->ReceiveFollowerBoot(ev, std::move(executorCaches)); return TranscriptFollowerBootOpResult(res, ctx); -} - -void TExecutor::Restored(TEvTablet::TEvRestored::TPtr &ev, const TActorContext &ctx) { +} + +void TExecutor::Restored(TEvTablet::TEvRestored::TPtr &ev, const TActorContext &ctx) { Y_VERIFY(CurrentStateFunc() == &TThis::StateBoot && BootLogic); - - TEvTablet::TEvRestored *msg = ev->Get(); + + TEvTablet::TEvRestored *msg = ev->Get(); Y_VERIFY(Generation() == msg->Generation); - + const TExecutorBootLogic::EOpResult res = BootLogic->ReceiveRestored(ev); - return TranscriptBootOpResult(res, ctx); -} - -void TExecutor::DetachTablet(const TActorContext &) { + return TranscriptBootOpResult(res, ctx); +} + +void TExecutor::DetachTablet(const TActorContext &) { TabletCountersForgetTablet(Owner->TabletID(), Owner->TabletType(), Owner->Info()->TenantPathId, Stats->IsFollower, SelfId()); return PassAway(); -} - +} + void TExecutor::FollowerUpdate(THolder<TEvTablet::TFUpdateBody> upd) { - if (BootLogic) { + if (BootLogic) { Y_VERIFY(CurrentStateFunc() == &TThis::StateFollowerBoot); PostponedFollowerUpdates.emplace_back(std::move(upd)); - } else if (PendingPartSwitches) { + } else if (PendingPartSwitches) { Y_VERIFY(CurrentStateFunc() == &TThis::StateFollower); PostponedFollowerUpdates.emplace_back(std::move(upd)); - } else { + } else { Y_VERIFY(CurrentStateFunc() == &TThis::StateFollower); Y_VERIFY(PostponedFollowerUpdates.empty()); ApplyFollowerUpdate(std::move(upd)); - } -} - + } +} + void TExecutor::FollowerAuxUpdate(TString upd) { - if (BootLogic) { + if (BootLogic) { Y_VERIFY(CurrentStateFunc() == &TThis::StateFollowerBoot); PostponedFollowerUpdates.emplace_back(new TEvTablet::TFUpdateBody(std::move(upd))); - } else if (PendingPartSwitches) { + } else if (PendingPartSwitches) { Y_VERIFY(CurrentStateFunc() == &TThis::StateFollower); PostponedFollowerUpdates.emplace_back(new TEvTablet::TFUpdateBody(std::move(upd))); - } else { + } else { Y_VERIFY(CurrentStateFunc() == &TThis::StateFollower); Y_VERIFY(PostponedFollowerUpdates.empty()); ApplyFollowerAuxUpdate(upd); - } -} - + } +} + void TExecutor::FollowerAttached() { HadFollowerAttached = true; NeedFollowerSnapshot = true; - - if (CurrentStateFunc() != &TThis::StateWork) - return; - + + if (CurrentStateFunc() != &TThis::StateWork) + return; + MakeLogSnapshot(); -} - +} + void TExecutor::FollowerSyncComplete() { - Y_VERIFY(CurrentStateFunc() == &TThis::StateWork || CurrentStateFunc() == &TThis::StateBoot); - if (GcLogic) + Y_VERIFY(CurrentStateFunc() == &TThis::StateWork || CurrentStateFunc() == &TThis::StateBoot); + if (GcLogic) GcLogic->FollowersSyncComplete(false); - else if (BootLogic) + else if (BootLogic) BootLogic->FollowersSyncComplete(); - else - Y_FAIL("must not happens"); -} - + else + Y_FAIL("must not happens"); +} + void TExecutor::FollowerGcApplied(ui32 step, TDuration followerSyncDelay) { - if (auto logl = Logger->Log(ELnLev::Debug)) { + if (auto logl = Logger->Log(ELnLev::Debug)) { logl << NFmt::Do(*this) << " switch applied on followers, step " << step; - } + } + + auto it = InFlyCompactionGcBarriers.find(step); + Y_VERIFY(it != InFlyCompactionGcBarriers.end()); + CheckCollectionBarrier(it->second); + InFlyCompactionGcBarriers.erase(it); - auto it = InFlyCompactionGcBarriers.find(step); - Y_VERIFY(it != InFlyCompactionGcBarriers.end()); - CheckCollectionBarrier(it->second); - InFlyCompactionGcBarriers.erase(it); - if (followerSyncDelay != TDuration::Max()) Counters->Percentile()[TExecutorCounters::TX_PERCENTILE_FOLLOWERSYNC_LATENCY].IncrementFor(followerSyncDelay.MicroSeconds()); -} - +} + void TExecutor::CheckCollectionBarrier(TIntrusivePtr<TBarrier> &barrier) { - if (barrier && barrier->RefCount() == 1) { + if (barrier && barrier->RefCount() == 1) { GcLogic->ReleaseBarrier(barrier->Step); if (BorrowLogic->SetGcBarrier(GcLogic->GetActiveGcBarrier())) { // N.B. PassAway may have already been called @@ -772,24 +772,24 @@ void TExecutor::CheckCollectionBarrier(TIntrusivePtr<TBarrier> &barrier) { Owner->CompletedLoansChanged(OwnerCtx()); } } - } - - barrier.Drop(); -} - + } + + barrier.Drop(); +} + void TExecutor::ApplyFollowerPostponedUpdates() { while (PostponedFollowerUpdates && !PendingPartSwitches) { THolder<TEvTablet::TFUpdateBody> upd = std::move(PostponedFollowerUpdates.front()); PostponedFollowerUpdates.pop_front(); - - if (upd->Step) { + + if (upd->Step) { ApplyFollowerUpdate(std::move(upd)); - } else { + } else { ApplyFollowerAuxUpdate(upd->AuxPayload); - } - } -} - + } + } +} + void TExecutor::ApplyFollowerUpdate(THolder<TEvTablet::TFUpdateBody> update) { if (update->Step <= Step0 || CommitManager) { Y_Fail( @@ -799,23 +799,23 @@ void TExecutor::ApplyFollowerUpdate(THolder<TEvTablet::TFUpdateBody> update) { Step0 = update->Step; - if (update->IsSnapshot) // do nothing over snapshot after initial one - return; - + if (update->IsSnapshot) // do nothing over snapshot after initial one + return; + TString schemeUpdate; TString dataUpdate; TStackVec<TString> partSwitches; - TStackVec<TLogoBlob> loanPartInfos; + TStackVec<TLogoBlob> loanPartInfos; TVector<NPageCollection::TMemGlob> annex; - - if (update->EmbeddedBody) { // we embed only regular updates - Y_VERIFY(update->References.empty()); - dataUpdate = update->EmbeddedBody; - } else { - for (auto &xpair : update->References) { - const TLogoBlobID &id = xpair.first; + + if (update->EmbeddedBody) { // we embed only regular updates + Y_VERIFY(update->References.empty()); + dataUpdate = update->EmbeddedBody; + } else { + for (auto &xpair : update->References) { + const TLogoBlobID &id = xpair.first; const TString &body = xpair.second; - + const NBoot::TCookie cookie(id.Cookie()); Y_VERIFY(cookie.Type() == NBoot::TCookie::EType::Log); @@ -827,34 +827,34 @@ void TExecutor::ApplyFollowerUpdate(THolder<TEvTablet::TFUpdateBody> update) { continue; } - switch (cookie.Index()) { + switch (cookie.Index()) { case NBoot::TCookie::EIdx::RedoLz4: - if (dataUpdate) - dataUpdate.append(body); - else - dataUpdate = body; - break; + if (dataUpdate) + dataUpdate.append(body); + else + dataUpdate = body; + break; case NBoot::TCookie::EIdx::Alter: - if (schemeUpdate) - schemeUpdate.append(body); - else - schemeUpdate = body; - break; + if (schemeUpdate) + schemeUpdate.append(body); + else + schemeUpdate = body; + break; case NBoot::TCookie::EIdx::TurnLz4: - partSwitches.push_back(body); - break; + partSwitches.push_back(body); + break; case NBoot::TCookie::EIdx::Loan: - loanPartInfos.push_back(TLogoBlob(id, body)); - break; + loanPartInfos.push_back(TLogoBlob(id, body)); + break; case NBoot::TCookie::EIdx::GCExt: - // ignore - break; - default: - Y_FAIL("unsupported blob kind"); - } - } - } - + // ignore + break; + default: + Y_FAIL("unsupported blob kind"); + } + } + } + if (schemeUpdate || dataUpdate || annex) { if (dataUpdate) dataUpdate = NPageCollection::TSlicer::Lz4()->Decode(dataUpdate); @@ -867,35 +867,35 @@ void TExecutor::ApplyFollowerUpdate(THolder<TEvTablet::TFUpdateBody> update) { ReadResourceProfile(); ReflectSchemeSettings(); } - } - - for (const TLogoBlob &loanQu : loanPartInfos) { + } + + for (const TLogoBlob &loanQu : loanPartInfos) { const TString uncompressed = NPageCollection::TSlicer::Lz4()->Decode(loanQu.Buffer); - + TProtoBox<NKikimrExecutorFlat::TBorrowedPart> proto(uncompressed); - + // for now follower borrowed info is not cleared. - // it's not problem as by design we expect limited number of loans + // it's not problem as by design we expect limited number of loans BorrowLogic->RestoreFollowerBorrowedInfo(loanQu.Id, proto); - } - - if (partSwitches) { + } + + if (partSwitches) { NKikimrExecutorFlat::TFollowerPartSwitchAux auxProto; - - if (update->AuxPayload) { + + if (update->AuxPayload) { const TString auxBody = NPageCollection::TSlicer::Lz4()->Decode(update->AuxPayload); - Y_VERIFY(auxProto.ParseFromString(auxBody)); + Y_VERIFY(auxProto.ParseFromString(auxBody)); Y_VERIFY(auxProto.BySwitchAuxSize() <= partSwitches.size()); - } - + } + bool hadPendingPartSwitches = bool(PendingPartSwitches); ui32 nextAuxIdx = 0; - for (ui32 idx : xrange(partSwitches.size())) { + for (ui32 idx : xrange(partSwitches.size())) { const TString uncompressed = NPageCollection::TSlicer::Lz4()->Decode(partSwitches[idx]); - + const TProtoBox<NKikimrExecutorFlat::TTablePartSwitch> proto(uncompressed); - + const NKikimrExecutorFlat::TFollowerPartSwitchAux::TBySwitch *aux = nullptr; if (proto.HasIntroducedParts() || proto.HasIntroducedTxStatus()) { Y_VERIFY(nextAuxIdx < auxProto.BySwitchAuxSize()); @@ -918,76 +918,76 @@ void TExecutor::ApplyFollowerUpdate(THolder<TEvTablet::TFUpdateBody> update) { } } } - } + } if (!hadPendingPartSwitches) { ApplyReadyPartSwitches(); // safe to apply switches right now } } else if (update->NeedFollowerGcAck) { Send(Owner->Tablet(), new TEvTablet::TEvFGcAck(Owner->TabletID(), Generation(), Step0)); - } -} - + } +} + void TExecutor::ApplyFollowerAuxUpdate(const TString &auxBody) { const TString aux = NPageCollection::TSlicer::Lz4()->Decode(auxBody); TProtoBox<NKikimrExecutorFlat::TFollowerAux> proto(aux); - + for (const auto &x : proto.GetPageCollectionsTouched()) { - const TLogoBlobID &metaId = LogoBlobIDFromLogoBlobID(x.GetMetaInfoId()); + const TLogoBlobID &metaId = LogoBlobIDFromLogoBlobID(x.GetMetaInfoId()); TPrivatePageCache::TInfo *collectionInfo = PrivatePageCache->Info(metaId); - if (!collectionInfo) - continue; - + if (!collectionInfo) + continue; + TVector<NTable::TPageId> pages; - for (ui32 pageId : x.GetTouchedPages()) { + for (ui32 pageId : x.GetTouchedPages()) { auto* page = collectionInfo->EnsurePage(pageId); switch (page->LoadState) { case TPrivatePageCache::TPage::LoadStateNo: pages.push_back(pageId); page->LoadState = TPrivatePageCache::TPage::LoadStateRequestedAsync; - break; + break; case TPrivatePageCache::TPage::LoadStateRequested: case TPrivatePageCache::TPage::LoadStateRequestedAsync: - break; + break; case TPrivatePageCache::TPage::LoadStateLoaded: PrivatePageCache->Touch(pageId, collectionInfo); - break; - default: - Y_FAIL("unknown ELoadState"); - } - } - + break; + default: + Y_FAIL("unknown ELoadState"); + } + } + if (auto logl = Logger->Log(ELnLev::Debug)) { logl << NFmt::Do(*this) << " refresh pageCollection " << metaId << " " << pages.size() << " pages of " << x.TouchedPagesSize(); } - + if (pages) { auto *req = new NPageCollection::TFetch(0, collectionInfo->PageCollection, std::move(pages)); RequestFromSharedCache(req, NBlockIO::EPriority::Bkgr, EPageCollectionRequest::CacheSync); - } - } + } + } if (proto.HasUserAuxUpdate()) Owner->OnLeaderUserAuxUpdate(std::move(proto.GetUserAuxUpdate())); -} - +} + void TExecutor::RequestFromSharedCache(TAutoPtr<NPageCollection::TFetch> fetch, NBlockIO::EPriority priority, EPageCollectionRequest requestCategory) -{ +{ Y_VERIFY(fetch->Pages.size() > 0, "Got TFetch req w/o any page"); Send(MakeSharedPageCacheId(), new NSharedCache::TEvRequest( priority, fetch, - SelfId()), - 0, (ui64)requestCategory); -} - + SelfId()), + 0, (ui64)requestCategory); +} + void TExecutor::AddFollowerPartSwitch( const NKikimrExecutorFlat::TTablePartSwitch &switchProto, const NKikimrExecutorFlat::TFollowerPartSwitchAux::TBySwitch *aux, @@ -995,7 +995,7 @@ void TExecutor::AddFollowerPartSwitch( { auto& partSwitch = PendingPartSwitches.emplace_back(); partSwitch.FollowerUpdateStep = updateStep; - partSwitch.TableId = switchProto.GetTableId(); + partSwitch.TableId = switchProto.GetTableId(); partSwitch.Step = step; if (switchProto.HasIntroducedParts() && switchProto.GetIntroducedParts().BundlesSize()) { @@ -1039,7 +1039,7 @@ void TExecutor::AddFollowerPartSwitch( } for (auto &x : switchProto.GetLeavingBundles()) - partSwitch.Leaving.push_back(LogoBlobIDFromLogoBlobID(x)); + partSwitch.Leaving.push_back(LogoBlobIDFromLogoBlobID(x)); for (auto &x : switchProto.GetLeavingTxStatus()) partSwitch.LeavingTxStatus.push_back(LogoBlobIDFromLogoBlobID(x)); @@ -1055,7 +1055,7 @@ void TExecutor::AddFollowerPartSwitch( move.SourceTable = x.GetSourceTable(); } } -} +} bool TExecutor::PrepareExternalPart(TPendingPartSwitch &partSwitch, NTable::TPartComponents &&pc) { Y_VERIFY(pc); @@ -1082,7 +1082,7 @@ bool TExecutor::PrepareExternalPart(TPendingPartSwitch &partSwitch, NTable::TPar } auto &bundle = partSwitch.NewBundles.emplace_back(std::move(pc)); - + return PrepareExternalPart(partSwitch, bundle); } @@ -1118,15 +1118,15 @@ bool TExecutor::PrepareExternalPart(TPendingPartSwitch &partSwitch, TPendingPart ++partSwitch.PendingLoads; return true; - } - + } + auto partView = stage->Loader.Result(); bundle.Stage.emplace<TPendingPartSwitch::TResultStage>(std::move(partView)); return false; } Y_FAIL("Unexpected PrepareExternalPart called"); -} +} bool TExecutor::PrepareExternalTxStatus( TPendingPartSwitch &partSwitch, @@ -1257,12 +1257,12 @@ void TExecutor::RequestInMemPagesForPartStore(ui32 tableId, const NTable::TPartV TPrivatePageCache::TInfo *info = PrivatePageCache->Info(req->PageCollection->Label()); for (ui32 pageId : req->Pages) PrivatePageCache->MarkSticky(pageId, info); - + RequestFromSharedCache(req, NBlockIO::EPriority::Bkgr, EPageCollectionRequest::CacheSync); - } -} - -void TExecutor::ApplyExternalPartSwitch(TPendingPartSwitch &partSwitch) { + } +} + +void TExecutor::ApplyExternalPartSwitch(TPendingPartSwitch &partSwitch) { TVector<NTable::TPartView> newParts; newParts.reserve(partSwitch.NewBundles.size()); for (auto &bundle : partSwitch.NewBundles) { @@ -1272,7 +1272,7 @@ void TExecutor::ApplyExternalPartSwitch(TPendingPartSwitch &partSwitch) { RequestInMemPagesForPartStore(partSwitch.TableId, stage->PartView); newParts.push_back(std::move(stage->PartView)); } - + TVector<TIntrusiveConstPtr<NTable::TColdPart>> newColdParts = std::move(partSwitch.NewColdParts); TVector<TIntrusiveConstPtr<NTable::TTxStatusPart>> newTxStatus; @@ -1314,26 +1314,26 @@ void TExecutor::ApplyExternalPartSwitch(TPendingPartSwitch &partSwitch) { } if (partSwitch.FollowerUpdateStep) { - auto subset = Database->Subset(partSwitch.TableId, partSwitch.Leaving, partSwitch.Head); - - if (partSwitch.Head != subset->Head) { + auto subset = Database->Subset(partSwitch.TableId, partSwitch.Leaving, partSwitch.Head); + + if (partSwitch.Head != subset->Head) { Y_FAIL("Follower table epoch head has diverged from leader"); - } else if (*subset && !subset->IsStickedToHead()) { + } else if (*subset && !subset->IsStickedToHead()) { Y_FAIL("Follower table replace subset isn't sticked to head"); - } - + } + Y_VERIFY(newColdParts.empty(), "Unexpected cold part at a follower"); Database->Replace(partSwitch.TableId, std::move(newParts), *subset); Database->ReplaceTxStatus(partSwitch.TableId, std::move(newTxStatus), *subset); for (auto &gone : subset->Flatten) DropCachesOfBundle(*gone); - + Send(Owner->Tablet(), new TEvTablet::TEvFGcAck(Owner->TabletID(), Generation(), partSwitch.FollowerUpdateStep)); - } else { + } else { for (auto &partView : newParts) { Database->Merge(partSwitch.TableId, partView); - + if (CompactionLogic) { CompactionLogic->BorrowedPart(partSwitch.TableId, std::move(partView)); } @@ -1348,7 +1348,7 @@ void TExecutor::ApplyExternalPartSwitch(TPendingPartSwitch &partSwitch) { for (auto &txStatus : newTxStatus) { Database->Merge(partSwitch.TableId, txStatus); } - } + } if (partSwitch.Moves) { struct TMoveState { @@ -1393,30 +1393,30 @@ void TExecutor::ApplyExternalPartSwitch(TPendingPartSwitch &partSwitch) { } } } -} - -bool TExecutor::CanExecuteTransaction() const { +} + +bool TExecutor::CanExecuteTransaction() const { return Stats->IsActive && (Stats->IsFollower || PendingPartSwitches.empty()) && !BrokenTransaction; -} - +} + void TExecutor::Execute(TAutoPtr<ITransaction> self, const TActorContext &ctx) { Y_VERIFY(ActivationQueue, "attempt to execute transaction before activation"); - + TAutoPtr<TSeat> seat = new TSeat(++TransactionUniqCounter, self); LWTRACK(TransactionBegin, seat->Self->Orbit, seat->UniqID, Owner->TabletID(), TypeName(*seat->Self)); - ++Stats->TxInFly; - Counters->Simple()[TExecutorCounters::DB_TX_IN_FLY] = Stats->TxInFly; + ++Stats->TxInFly; + Counters->Simple()[TExecutorCounters::DB_TX_IN_FLY] = Stats->TxInFly; Counters->Cumulative()[TExecutorCounters::TX_COUNT_ALL].Increment(1); //Deprecated Counters->Cumulative()[TExecutorCounters::TX_QUEUED].Increment(1); - + if (auto logl = Logger->Log(ELnLev::Debug)) { logl << NFmt::Do(*this) << " " << NFmt::Do(*seat) << " queued, type " << NFmt::Do(*seat->Self); } - + ui64 staticRemain = Memory->RemainedStatic(*seat); // Submit resource broker task if there is no enough memory to start @@ -1434,34 +1434,34 @@ void TExecutor::Execute(TAutoPtr<ITransaction> self, const TActorContext &ctx) { Memory->AllocStatic(*seat, Memory->Profile->GetInitialTxMemory()); - if (!CanExecuteTransaction() + if (!CanExecuteTransaction() || Scheme().Executor.LimitInFlyTx && Stats->TxInFly > Scheme().Executor.LimitInFlyTx) - { + { LWTRACK(TransactionPending, seat->Self->Orbit, seat->UniqID, CanExecuteTransaction() ? "tx limit reached" : "transactions paused"); PendingQueue->Push(seat.Release()); - ++Stats->TxPending; + ++Stats->TxPending; return; - } - + } + if (ActiveTransaction || ActivateTransactionWaiting) { LWTRACK(TransactionEnqueued, seat->Self->Orbit, seat->UniqID); ActivationQueue->Push(seat.Release()); ActivateTransactionWaiting++; PlanTransactionActivation(); - return; - } - + return; + } + ExecuteTransaction(seat, ctx); -} - +} + void TExecutor::ExecuteTransaction(TAutoPtr<TSeat> seat, const TActorContext &ctx) { Y_VERIFY_DEBUG(!ActiveTransaction); - - ActiveTransaction = true; + + ActiveTransaction = true; ++seat->Retries; - - THPTimer cpuTimer; + + THPTimer cpuTimer; TPageCollectionTxEnv env(*PrivatePageCache); @@ -1473,12 +1473,12 @@ void TExecutor::ExecuteTransaction(TAutoPtr<TSeat> seat, const TActorContext &ct const bool done = seat->Self->Execute(txc, ctx.MakeFor(OwnerActorId)); LWTRACK(TransactionExecuteEnd, seat->Self->Orbit, seat->UniqID, done); seat->CPUExecTime += cpuTimer.PassedReset(); - + if (done && !Stats->IsFollower) { /* possible rw commit */ for (auto one: env.MakeSnap) Database->TxSnapTable(one.first /* table */); } - + bool failed = false; TString failureReason; if (done && (failed = !Database->ValidateCommit(failureReason))) { @@ -1531,33 +1531,33 @@ void TExecutor::ExecuteTransaction(TAutoPtr<TSeat> seat, const TActorContext &ct Y_VERIFY(!seat->RequestedMemory); seat->OnCommitted = std::move(txc.OnCommitted_); CommitTransactionLog(seat, env, prod.Change, cpuTimer, ctx); - } else { + } else { Y_VERIFY(!seat->CapturedMemory); PostponeTransaction(seat, env, prod.Change, cpuTimer, ctx); - } - - ActiveTransaction = false; + } + + ActiveTransaction = false; PlanTransactionActivation(); -} - +} + void TExecutor::UnpinTransactionPages(TSeat &seat) { for (auto &xinfoid : seat.Pinned) { if (TPrivatePageCache::TInfo *info = PrivatePageCache->Info(xinfoid.first)) { - for (auto &x : xinfoid.second) { - ui32 pageId = x.first; + for (auto &x : xinfoid.second) { + ui32 pageId = x.first; TPrivatePageCachePinPad *pad = x.second.Get(); - x.second.Reset(); + x.second.Reset(); PrivatePageCache->Unpin(pageId, pad, info); - } - } - } + } + } + } seat.Pinned.clear(); seat.MemoryTouched = 0; - + Counters->Simple()[TExecutorCounters::CACHE_PINNED_SET] = PrivatePageCache->GetStats().PinnedSetSize; Counters->Simple()[TExecutorCounters::CACHE_PINNED_LOAD] = PrivatePageCache->GetStats().PinnedLoadSize; -} - +} + void TExecutor::ReleaseTxData(TSeat &seat, ui64 requested, const TActorContext &ctx) { if (auto logl = Logger->Log(ELnLev::Debug)) @@ -1581,10 +1581,10 @@ void TExecutor::PostponeTransaction(TAutoPtr<TSeat> seat, TPageCollectionTxEnv & if (!env.ToLoad && !seat->RequestedMemory) { Y_Fail(NFmt::Do(*this) << " " << NFmt::Do(*seat) << " type " << NFmt::Do(*seat->Self) << " postoned w/o demands"); - } - + } + TTxType txType = seat->Self->GetTxType(); - + ui32 touchedPages = 0; ui32 touchedBytes = 0; ui32 newPinnedPages = 0; @@ -1592,42 +1592,42 @@ void TExecutor::PostponeTransaction(TAutoPtr<TSeat> seat, TPageCollectionTxEnv & ui32 loadPages = 0; ui64 loadBytes = 0; ui64 prevTouched = seat->MemoryTouched; - - // must pin new entries + + // must pin new entries for (auto &xpair : env.Touches) { TPrivatePageCache::TInfo *pageCollectionInfo = xpair.first; auto &pinned = seat->Pinned[pageCollectionInfo->Id]; for (auto &x : xpair.second) { - // would insert only if first seen + // would insert only if first seen if (pinned.insert(std::make_pair(x, PrivatePageCache->Pin(x, pageCollectionInfo))).second) { ++newPinnedPages; seat->MemoryTouched += pageCollectionInfo->GetPage(x)->Size; - } - } + } + } touchedPages += xpair.second.size(); - } - + } + touchedBytes = seat->MemoryTouched - prevTouched; prevTouched = seat->MemoryTouched; for (auto &xpair : env.ToLoad) { TPrivatePageCache::TInfo *pageCollectionInfo = xpair.first; auto &pinned = seat->Pinned[pageCollectionInfo->Id]; - - for (auto &x : xpair.second) { + + for (auto &x : xpair.second) { if (pinned.insert(std::make_pair(x, PrivatePageCache->Pin(x, pageCollectionInfo))).second) { ++newPinnedPages; seat->MemoryTouched += pageCollectionInfo->GetPage(x)->Size; - } - } - } - + } + } + } + if (seat->AttachedMemory) Memory->AttachMemory(*seat); - + const ui64 requestedMemory = std::exchange(seat->RequestedMemory, 0); seat->CurrentTxDataLimit += requestedMemory; - + if (auto logl = Logger->Log(ELnLev::Debug)) { logl << NFmt::Do(*this) << " " << NFmt::Do(*seat) @@ -1652,7 +1652,7 @@ void TExecutor::PostponeTransaction(TAutoPtr<TSeat> seat, TPageCollectionTxEnv & seat->TerminationReason = ETerminationReason::MemoryLimitExceeded; CommitTransactionLog(seat, env, change, bookkeepingTimer, ctx); - return; + return; } else if (totalMemory > seat->CurrentMemoryLimit) { // We usually try to at least double allocated memory. But it's OK to use less @@ -1686,8 +1686,8 @@ void TExecutor::PostponeTransaction(TAutoPtr<TSeat> seat, TPageCollectionTxEnv & // todo: counters return; } - } - + } + // If memory was allocated and there is nothing to load // then tx may be re-activated. if (!env.ToLoad) { @@ -1702,7 +1702,7 @@ void TExecutor::PostponeTransaction(TAutoPtr<TSeat> seat, TPageCollectionTxEnv & auto padHolder = MakeHolder<TTransactionWaitPad>(std::move(seat)); auto *const pad = padHolder.Get(); TransactionWaitPads[pad] = std::move(padHolder); - + for (auto &xpair : env.ToLoad) { TPrivatePageCache::TInfo *pageCollectionInfo = xpair.first; @@ -1710,20 +1710,20 @@ void TExecutor::PostponeTransaction(TAutoPtr<TSeat> seat, TPageCollectionTxEnv & pages.reserve(xpair.second.size()); waitPages += xpair.second.size(); - for (auto &x : xpair.second) { + for (auto &x : xpair.second) { pages.push_back(x); - } - + } + const std::pair<ui32, ui64> toLoad = PrivatePageCache->Load(pages, pad, pageCollectionInfo); - if (toLoad.first) { + if (toLoad.first) { auto *req = new NPageCollection::TFetch(0, pageCollectionInfo->PageCollection, std::move(pages)); loadPages += toLoad.first; loadBytes += toLoad.second; RequestFromSharedCache(req, NBlockIO::EPriority::Fast, EPageCollectionRequest::Cache); - } - } - + } + } + if (auto logl = Logger->Log(ELnLev::Debug)) { logl << NFmt::Do(*this) << " " << NFmt::Do(*pad->Seat) << " postponed" @@ -1731,7 +1731,7 @@ void TExecutor::PostponeTransaction(TAutoPtr<TSeat> seat, TPageCollectionTxEnv & << "{" << waitPages << " wait, " << loadPages << " load}" << ", freshly touched " << newPinnedPages << " pages"; } - + pad->Seat->CPUBookkeepingTime += bookkeepingTimer.PassedReset(); Counters->Cumulative()[TExecutorCounters::TX_POSTPONED].Increment(1); @@ -1749,42 +1749,42 @@ void TExecutor::PostponeTransaction(TAutoPtr<TSeat> seat, TPageCollectionTxEnv & AppTxCounters->TxCumulative(txType, COUNTER_TT_LOADED_BLOCKS).Increment(loadPages); AppTxCounters->TxCumulative(txType, COUNTER_TT_BYTES_READ).Increment(loadBytes); } - + Counters->Simple()[TExecutorCounters::CACHE_PINNED_SET] = PrivatePageCache->GetStats().PinnedSetSize; Counters->Simple()[TExecutorCounters::CACHE_PINNED_LOAD] = PrivatePageCache->GetStats().PinnedLoadSize; -} - +} + void TExecutor::CommitTransactionLog(TAutoPtr<TSeat> seat, TPageCollectionTxEnv &env, TAutoPtr<NTable::TChange> change, THPTimer &bookkeepingTimer, const TActorContext &ctx) { const bool isReadOnly = !(change->HasAny() || env.HasChanges()); const bool isTerminated = seat->TerminationReason != ETerminationReason::None; const TTxType txType = seat->Self->GetTxType(); - - ui64 touchedBlocks = 0; + + ui64 touchedBlocks = 0; for (auto &xpair : env.Touches) { TPrivatePageCache::TInfo *pageCollectionInfo = xpair.first; touchedBlocks += xpair.second.size(); for (ui32 blockId : xpair.second) PrivatePageCache->Touch(blockId, pageCollectionInfo); - } - Counters->Percentile()[TExecutorCounters::TX_PERCENTILE_TOUCHED_BLOCKS].IncrementFor(touchedBlocks); + } + Counters->Percentile()[TExecutorCounters::TX_PERCENTILE_TOUCHED_BLOCKS].IncrementFor(touchedBlocks); if (AppTxCounters && txType != UnknownTxType) AppTxCounters->TxCumulative(txType, COUNTER_TT_TOUCHED_BLOCKS).Increment(touchedBlocks); - + if (seat->Retries == 1) { Counters->Cumulative()[TExecutorCounters::TX_CACHE_HITS].Increment(touchedBlocks); } UnpinTransactionPages(*seat); Memory->ReleaseMemory(*seat); - + const double currentBookkeepingTime = seat->CPUBookkeepingTime; const double currentExecTime = seat->CPUExecTime; - + if (isTerminated) { if (Stats->IsFollower) { --Stats->TxInFly; - Counters->Simple()[TExecutorCounters::DB_TX_IN_FLY] = Stats->TxInFly; + Counters->Simple()[TExecutorCounters::DB_TX_IN_FLY] = Stats->TxInFly; seat->Self->Terminate(seat->TerminationReason, OwnerCtx()); } else if (LogicRedo->TerminateTransaction(seat, ctx, OwnerActorId)) { --Stats->TxInFly; @@ -1792,19 +1792,19 @@ void TExecutor::CommitTransactionLog(TAutoPtr<TSeat> seat, TPageCollectionTxEnv } } else if (isReadOnly) { if (Stats->IsFollower) { - // todo: extract completion counters from txloglogic - --Stats->TxInFly; - Counters->Simple()[TExecutorCounters::DB_TX_IN_FLY] = Stats->TxInFly; + // todo: extract completion counters from txloglogic + --Stats->TxInFly; + Counters->Simple()[TExecutorCounters::DB_TX_IN_FLY] = Stats->TxInFly; CompleteRoTransaction(seat, OwnerCtx(), Counters.Get(), AppTxCounters); } else if (LogicRedo->CommitROTransaction(seat, OwnerCtx())) { - --Stats->TxInFly; - Counters->Simple()[TExecutorCounters::DB_TX_IN_FLY] = Stats->TxInFly; - } - } else { + --Stats->TxInFly; + Counters->Simple()[TExecutorCounters::DB_TX_IN_FLY] = Stats->TxInFly; + } + } else { Y_VERIFY(!Stats->IsFollower); - + const bool allowBatching = Scheme().Executor.AllowLogBatching; - const bool force = !allowBatching + const bool force = !allowBatching || change->Scheme || change->Annex /* Required for replication to followers */ || change->RemovedRowVersions /* Required for replication to followers */ @@ -1814,12 +1814,12 @@ void TExecutor::CommitTransactionLog(TAutoPtr<TSeat> seat, TPageCollectionTxEnv || env.LoanTxStatus || env.LoanConfirmation || env.BorrowUpdates; - + auto commitResult = LogicRedo->CommitRWTransaction(seat, *change, force); - + Y_VERIFY(!force || commitResult.Commit); auto *commit = commitResult.Commit.Get(); // could be nullptr - + Y_VERIFY(env.MakeSnap.size() == change->Snapshots.size()); for (auto seq: xrange(env.MakeSnap.size())) { @@ -1917,15 +1917,15 @@ void TExecutor::CommitTransactionLog(TAutoPtr<TSeat> seat, TPageCollectionTxEnv ReleaseScanLocks(std::move(snapshot->Barrier), *snapshot->Subset); } LogicRedo->CutLog(change->Deleted[num], edge, commit->GcDelta); - } + } if (auto garbage = std::move(change->Garbage)) { commit->WaitFollowerGcAck = true; // as we could collect some page collections - + for (auto &subset: garbage) { ui64 total = 0; TDeque<NTable::NFwd::TSieve> sieve(subset->Flatten.size() + 1); - + for (auto seq: xrange(subset->Flatten.size())) { sieve[seq] = { subset->Flatten[seq]->Blobs, @@ -1953,9 +1953,9 @@ void TExecutor::CommitTransactionLog(TAutoPtr<TSeat> seat, TPageCollectionTxEnv TIntrusivePtr<TBarrier> barrier(new TBarrier(commit->Step)); Y_VERIFY(InFlyCompactionGcBarriers.emplace(commit->Step, barrier).second); - GcLogic->HoldBarrier(barrier->Step); - } - + GcLogic->HoldBarrier(barrier->Step); + } + NKikimrExecutorFlat::TFollowerPartSwitchAux aux; if (auto *snap = env.DropSnap.Get()) { @@ -1976,7 +1976,7 @@ void TExecutor::CommitTransactionLog(TAutoPtr<TSeat> seat, TPageCollectionTxEnv for (auto &bundle: result.Bundles) BorrowLogic->BorrowBundle(bundle.first, bundle.second, commit); - + if (result.Moved) { for (const auto& [src, dst] : result.Moved) { auto srcSubset = Database->Subset(src, snap->SnapContext->Impl->Edge(src).Head, { }, { }); @@ -2083,25 +2083,25 @@ void TExecutor::CommitTransactionLog(TAutoPtr<TSeat> seat, TPageCollectionTxEnv } InFlySnapCollectionBarriers.emplace(commit->Step, std::move(result.Barriers)); - } - + } + bool hadPendingPartSwitches = bool(PendingPartSwitches); aux.MutableBySwitchAux()->Reserve(aux.BySwitchAuxSize() + env.LoanBundle.size() + env.LoanTxStatus.size()); for (auto &loaned : env.LoanBundle) { auto& partSwitch = PendingPartSwitches.emplace_back(); - partSwitch.TableId = loaned->LocalTableId; + partSwitch.TableId = loaned->LocalTableId; partSwitch.Step = commit->Step; - + Y_VERIFY(loaned->PartComponents.PageCollectionComponents, "Loaned PartComponents without any page collections"); BorrowLogic->LoanBundle( loaned->PartComponents.PageCollectionComponents.front().LargeGlobId.Lead, *loaned, commit); - - { - NKikimrExecutorFlat::TTablePartSwitch proto; - - proto.SetTableId(partSwitch.TableId); + + { + NKikimrExecutorFlat::TTablePartSwitch proto; + + proto.SetTableId(partSwitch.TableId); { TGCBlobDelta dummy; /* this isn't real cut log operation */ @@ -2122,23 +2122,23 @@ void TExecutor::CommitTransactionLog(TAutoPtr<TSeat> seat, TPageCollectionTxEnv auto *snap = proto.MutableIntroducedParts(); auto *bySwitchAux = aux.AddBySwitchAux(); - + TPageCollectionProtoHelper::Snap(snap, loaned->PartComponents, partSwitch.TableId, CompactionLogic->BorrowedPartLevel()); TPageCollectionProtoHelper(true, false).Do(bySwitchAux->AddHotBundles(), loaned->PartComponents); - + auto body = proto.SerializeAsString(); auto glob = CommitManager->Turns.One(commit->Refs, std::move(body), true); LogoBlobIDFromLogoBlobID(glob.Logo, bySwitchAux->MutablePartSwitchRef()); - } - + } + PrepareExternalPart(partSwitch, std::move(loaned->PartComponents)); } for (auto &loaned : env.LoanTxStatus) { auto& partSwitch = PendingPartSwitches.emplace_back(); partSwitch.TableId = loaned->LocalTableId; partSwitch.Step = commit->Step; - + BorrowLogic->LoanTxStatus( loaned->DataId.Lead, *loaned, commit); @@ -2191,47 +2191,47 @@ void TExecutor::CommitTransactionLog(TAutoPtr<TSeat> seat, TPageCollectionTxEnv if (!hadPendingPartSwitches) { ApplyReadyPartSwitches(); // safe to apply switches right now - } - + } + if (aux.BySwitchAuxSize()) { commit->FollowerAux = NPageCollection::TSlicer::Lz4()->Encode(aux.SerializeAsString()); } - if (env.BorrowUpdates) { + if (env.BorrowUpdates) { commit->WaitFollowerGcAck = true; - for (auto &borrowUpdate : env.BorrowUpdates) { - BorrowLogic->UpdateBorrow( - borrowUpdate.first, - borrowUpdate.second, + for (auto &borrowUpdate : env.BorrowUpdates) { + BorrowLogic->UpdateBorrow( + borrowUpdate.first, + borrowUpdate.second, commit); - } - + } + TIntrusivePtr<TBarrier> barrier(new TBarrier(commit->Step)); Y_VERIFY(InFlyCompactionGcBarriers.emplace(commit->Step, barrier).second); - GcLogic->HoldBarrier(barrier->Step); - } - - if (env.LoanConfirmation) { + GcLogic->HoldBarrier(barrier->Step); + } + + if (env.LoanConfirmation) { commit->WaitFollowerGcAck = true; - for (auto &xupd : env.LoanConfirmation) { - BorrowLogic->ConfirmUpdateLoan( - xupd.first, - xupd.second.BorrowId, + for (auto &xupd : env.LoanConfirmation) { + BorrowLogic->ConfirmUpdateLoan( + xupd.first, + xupd.second.BorrowId, commit); - } + } TIntrusivePtr<TBarrier> barrier(new TBarrier(commit->Step)); Y_VERIFY(InFlyCompactionGcBarriers.emplace(commit->Step, barrier).second); - GcLogic->HoldBarrier(barrier->Step); - } - + GcLogic->HoldBarrier(barrier->Step); + } + if (commitResult.Commit) CommitManager->Commit(commitResult.Commit); - + for (auto &affectedTable : change->Affects) CompactionLogic->UpdateInMemStatsStep(affectedTable, 1, Database->GetTableMemSize(affectedTable)); - - if (commitResult.NeedFlush && !LogBatchFlushScheduled) { - LogBatchFlushScheduled = true; + + if (commitResult.NeedFlush && !LogBatchFlushScheduled) { + LogBatchFlushScheduled = true; auto delay = Scheme().Executor.LogFlushPeriod; if (LogFlushDelayOverrideUsec != -1) { @@ -2244,36 +2244,36 @@ void TExecutor::CommitTransactionLog(TAutoPtr<TSeat> seat, TPageCollectionTxEnv delay = Min(delay, TDuration::Seconds(59)); Schedule(delay, new TEvents::TEvFlushLog()); } - } - + } + if (NeedFollowerSnapshot || LogicSnap->MayFlush(false)) MakeLogSnapshot(); CompactionLogic->UpdateLogUsage(LogicRedo->GrabLogUsage()); - } - + } + if (!Stats->IsFollower && HadFollowerAttached && env.Touches) { NKikimrExecutorFlat::TFollowerAux proto; proto.MutablePageCollectionsTouched()->Reserve(env.Touches.size()); for (auto &xpair : env.Touches) { auto *px = proto.AddPageCollectionsTouched(); - LogoBlobIDFromLogoBlobID(xpair.first->Id, px->MutableMetaInfoId()); + LogoBlobIDFromLogoBlobID(xpair.first->Id, px->MutableMetaInfoId()); px->MutableTouchedPages()->Reserve(xpair.second.size()); for (ui32 blockId : xpair.second) - px->AddTouchedPages(blockId); - } - + px->AddTouchedPages(blockId); + } + auto coded = NPageCollection::TSlicer::Lz4()->Encode(proto.SerializeAsString()); - + Send(Owner->Tablet(), new TEvTablet::TEvAux(std::move(coded))); - } - - const ui64 bookkeepingTimeuS = ui64(1000000. * (currentBookkeepingTime + bookkeepingTimer.PassedReset())); - const ui64 execTimeuS = ui64(1000000. * currentExecTime); - + } + + const ui64 bookkeepingTimeuS = ui64(1000000. * (currentBookkeepingTime + bookkeepingTimer.PassedReset())); + const ui64 execTimeuS = ui64(1000000. * currentExecTime); + Counters->Cumulative()[TExecutorCounters::TX_FINISHED].Increment(1); - Counters->Percentile()[TExecutorCounters::TX_PERCENTILE_EXECUTE_CPUTIME].IncrementFor(execTimeuS); - Counters->Percentile()[TExecutorCounters::TX_PERCENTILE_BOOKKEEPING_CPUTIME].IncrementFor(bookkeepingTimeuS); + Counters->Percentile()[TExecutorCounters::TX_PERCENTILE_EXECUTE_CPUTIME].IncrementFor(execTimeuS); + Counters->Percentile()[TExecutorCounters::TX_PERCENTILE_BOOKKEEPING_CPUTIME].IncrementFor(bookkeepingTimeuS); Counters->Cumulative()[TExecutorCounters::CONSUMED_CPU].Increment(execTimeuS + bookkeepingTimeuS); if (AppTxCounters && txType != UnknownTxType) { AppTxCounters->TxCumulative(txType, COUNTER_TT_EXECUTE_CPUTIME).Increment(execTimeuS); @@ -2284,19 +2284,19 @@ void TExecutor::CommitTransactionLog(TAutoPtr<TSeat> seat, TPageCollectionTxEnv ResourceMetrics->CPU.Increment(bookkeepingTimeuS + execTimeuS, Time->Now()); ResourceMetrics->TryUpdate(ctx); } -} - +} + void TExecutor::MakeLogSnapshot() { if (!LogicSnap->MayFlush(true) || PendingPartSwitches) - return; - + return; + NeedFollowerSnapshot = false; - THPTimer makeLogSnapTimer; - + THPTimer makeLogSnapTimer; + LogicRedo->FlushBatchedLog(); - + auto commit = CommitManager->Begin(true, ECommit::Snap); - + NKikimrExecutorFlat::TLogSnapshot snap; snap.SetSerial(Database->Head(Max<ui32>()).Serial); @@ -2390,21 +2390,21 @@ void TExecutor::MakeLogSnapshot() { LogicSnap->MakeSnap(snap, *commit, Logger.Get()); CommitManager->Commit(commit); - + CompactionLogic->UpdateLogUsage(LogicRedo->GrabLogUsage()); - const ui64 makeLogSnapTimeuS = ui64(1000000. * makeLogSnapTimer.Passed()); - Counters->Percentile()[TExecutorCounters::TX_PERCENTILE_LOGSNAP_CPUTIME].IncrementFor(makeLogSnapTimeuS); -} - -void TExecutor::Handle(TEvPrivate::TEvActivateExecution::TPtr &ev, const TActorContext &ctx) { + const ui64 makeLogSnapTimeuS = ui64(1000000. * makeLogSnapTimer.Passed()); + Counters->Percentile()[TExecutorCounters::TX_PERCENTILE_LOGSNAP_CPUTIME].IncrementFor(makeLogSnapTimeuS); +} + +void TExecutor::Handle(TEvPrivate::TEvActivateExecution::TPtr &ev, const TActorContext &ctx) { Y_UNUSED(ev); Y_VERIFY(ActivateTransactionInFlight > 0); ActivateTransactionInFlight--; - - if (!CanExecuteTransaction()) - return; - + + if (!CanExecuteTransaction()) + return; + if (TAutoPtr<TSeat> seat = ActivationQueue->Pop()) { Y_VERIFY(ActivateTransactionWaiting > 0); ActivateTransactionWaiting--; @@ -2417,8 +2417,8 @@ void TExecutor::Handle(TEvPrivate::TEvActivateExecution::TPtr &ev, const TActorC // one transaction in queue. Y_VERIFY(ActivateTransactionWaiting == 0); } -} - +} + void TExecutor::Handle(TEvPrivate::TEvBrokenTransaction::TPtr &ev, const TActorContext &ctx) { Y_UNUSED(ev); Y_UNUSED(ctx); @@ -2436,38 +2436,38 @@ void TExecutor::Wakeup(TEvents::TEvWakeup::TPtr &ev, const TActorContext&) { } void TExecutor::Handle(TEvents::TEvFlushLog::TPtr &ev) { - Y_UNUSED(ev); + Y_UNUSED(ev); LogBatchFlushScheduled = false; LogicRedo->FlushBatchedLog(); CompactionLogic->UpdateLogUsage(LogicRedo->GrabLogUsage()); -} - +} + void TExecutor::Handle(NSharedCache::TEvRequest::TPtr &ev) { const auto priority = ev->Get()->Priority; TAutoPtr<NPageCollection::TFetch> msg = ev->Get()->Fetch; - + Y_VERIFY(msg->Pages, "empty page collection request, do not do it"); const TLogoBlobID &metaId = msg->PageCollection->Label(); TPrivatePageCache::TInfo *collectionInfo = PrivatePageCache->Info(metaId); - if (!collectionInfo) { + if (!collectionInfo) { auto *reply = new NSharedCache::TEvResult(std::move(msg->PageCollection), msg->Cookie, NKikimrProto::RACE); Send(ev->Sender, reply, 0, ev->Cookie); - return; - } - + return; + } + TVector<NSharedCache::TEvResult::TLoaded> cached; TVector<NTable::TPageId> left; - + for (auto &x : msg->Pages) { if (TSharedPageRef body = PrivatePageCache->LookupShared(x, collectionInfo)) { cached.emplace_back(x, body); - } else { + } else { left.push_back(x); - } - } - - if (cached) { + } + } + + if (cached) { if (auto logl = Logger->Log(ELnLev::Debug)) { logl << NFmt::Do(*this) << " cache hit for data request from: " @@ -2477,8 +2477,8 @@ void TExecutor::Handle(NSharedCache::TEvRequest::TPtr &ev) { auto *reply = new NSharedCache::TEvResult(msg->PageCollection, msg->Cookie, NKikimrProto::OK); reply->Loaded.swap(cached); Send(ev->Sender, reply, 0, ev->Cookie); - } - + } + if (left) { DoSwap(msg->Pages, left); @@ -2491,12 +2491,12 @@ void TExecutor::Handle(NSharedCache::TEvRequest::TPtr &ev) { auto *req = new NSharedCache::TEvRequest(priority, msg, SelfId()); TActorIdentity(ev->Sender).Send(MakeSharedPageCacheId(), req, 0, ev->Cookie); - } -} - + } +} + void TExecutor::Handle(NSharedCache::TEvResult::TPtr &ev) { const bool failed = (ev->Get()->Status != NKikimrProto::OK); - + if (auto logl = Logger->Log(failed ? ELnLev::Info : ELnLev::Debug)) { logl << NFmt::Do(*this) << " got result " << NFmt::Do(*ev->Get()) @@ -2506,34 +2506,34 @@ void TExecutor::Handle(NSharedCache::TEvResult::TPtr &ev) { switch (EPageCollectionRequest(ev->Cookie)) { case EPageCollectionRequest::Cache: case EPageCollectionRequest::CacheSync: - { + { auto *msg = ev->CastAsLocal<NSharedCache::TEvResult>(); TPrivatePageCache::TInfo *collectionInfo = PrivatePageCache->Info(msg->Origin->Label()); - if (!collectionInfo) // collection could be outdated - return; - + if (!collectionInfo) // collection could be outdated + return; + if (msg->Status != NKikimrProto::OK) { // collection is still active but we got bs error. no choice then die - if (auto logl = Logger->Log(ELnLev::Error)) { + if (auto logl = Logger->Log(ELnLev::Error)) { logl << NFmt::Do(*this) << " Broken on page collection request error " << NFmt::Do(*ev->Get()); - } - - if (msg->Status == NKikimrProto::NODATA) { - GetServiceCounters(AppData()->Counters, "tablets")->GetCounter("alerts_req_nodata", true)->Inc(); - } - - return Broken(); - } - + } + + if (msg->Status == NKikimrProto::NODATA) { + GetServiceCounters(AppData()->Counters, "tablets")->GetCounter("alerts_req_nodata", true)->Inc(); + } + + return Broken(); + } + for (auto& loaded : msg->Loaded) { TPrivatePageCache::TPage::TWaitQueuePtr transactionsToActivate = PrivatePageCache->ProvideBlock(std::move(loaded), collectionInfo); ActivateWaitingTransactions(transactionsToActivate); - } - } + } + } return; - + case EPageCollectionRequest::PendingInit: - { + { auto *msg = ev->CastAsLocal<NSharedCache::TEvResult>(); const auto *pageCollection = msg->Origin.Get(); @@ -2554,42 +2554,42 @@ void TExecutor::Handle(NSharedCache::TEvResult::TPtr &ev) { if (foundStage) break; } - - // nope. just ignore. + + // nope. just ignore. if (!foundStage) - return; - + return; + foundStage->Fetching = nullptr; if (msg->Status != NKikimrProto::OK) { - if (auto logl = Logger->Log(ELnLev::Error)) { - logl << NFmt::Do(*this) << " Broken while pending part init" << NFmt::Do(*ev->Get()); - } - - if (msg->Status == NKikimrProto::NODATA) { - GetServiceCounters(AppData()->Counters, "tablets")->GetCounter("alerts_pending_nodata", true)->Inc(); - } - - return Broken(); - } - + if (auto logl = Logger->Log(ELnLev::Error)) { + logl << NFmt::Do(*this) << " Broken while pending part init" << NFmt::Do(*ev->Get()); + } + + if (msg->Status == NKikimrProto::NODATA) { + GetServiceCounters(AppData()->Counters, "tablets")->GetCounter("alerts_pending_nodata", true)->Inc(); + } + + return Broken(); + } + foundStage->Loader.Save(msg->Cookie, msg->Loaded); foundSwitch->PendingLoads--; - + if (PrepareExternalPart(*foundSwitch, *foundBundle)) { // Waiting for more pages return; - } - + } + AdvancePendingPartSwitches(); - } - return; - - default: - break; - } -} - + } + return; + + default: + break; + } +} + void TExecutor::Handle(NSharedCache::TEvUpdated::TPtr &ev) { const auto *msg = ev->Get(); @@ -2605,24 +2605,24 @@ void TExecutor::Handle(NSharedCache::TEvUpdated::TPtr &ev) { } } -void TExecutor::Handle(TEvTablet::TEvCommitResult::TPtr &ev, const TActorContext &ctx) { - TEvTablet::TEvCommitResult *msg = ev->Get(); - - if (msg->Status != NKikimrProto::OK) { - if (auto logl = Logger->Log(ELnLev::Error)) { - logl << NFmt::Do(*this) << " Broken on commit error for step " << msg->Step; - } - return Broken(); - } - +void TExecutor::Handle(TEvTablet::TEvCommitResult::TPtr &ev, const TActorContext &ctx) { + TEvTablet::TEvCommitResult *msg = ev->Get(); + + if (msg->Status != NKikimrProto::OK) { + if (auto logl = Logger->Log(ELnLev::Error)) { + logl << NFmt::Do(*this) << " Broken on commit error for step " << msg->Step; + } + return Broken(); + } + Y_VERIFY(msg->Generation == Generation()); - const ui32 step = msg->Step; - - ActiveTransaction = true; - + const ui32 step = msg->Step; + + ActiveTransaction = true; + GcLogic->OnCommitLog(step, msg->ConfirmedOnSend, ctx); CommitManager->Confirm(step); - + const auto cookie = static_cast<ECommit>(ev->Cookie); if (auto logl = Logger->Log(ELnLev::Debug)) { @@ -2633,43 +2633,43 @@ void TExecutor::Handle(TEvTablet::TEvCommitResult::TPtr &ev, const TActorContext switch (cookie) { case ECommit::Redo: - { + { const ui64 confirmedTransactions = LogicRedo->Confirm(step, ctx, OwnerActorId); - Stats->TxInFly -= confirmedTransactions; - Counters->Simple()[TExecutorCounters::DB_TX_IN_FLY] = Stats->TxInFly; - - auto snapCollectionIt = InFlySnapCollectionBarriers.find(step); - if (snapCollectionIt != InFlySnapCollectionBarriers.end()) { - for (auto &x : snapCollectionIt->second) - CheckCollectionBarrier(x); - InFlySnapCollectionBarriers.erase(snapCollectionIt); - } - } - break; + Stats->TxInFly -= confirmedTransactions; + Counters->Simple()[TExecutorCounters::DB_TX_IN_FLY] = Stats->TxInFly; + + auto snapCollectionIt = InFlySnapCollectionBarriers.find(step); + if (snapCollectionIt != InFlySnapCollectionBarriers.end()) { + for (auto &x : snapCollectionIt->second) + CheckCollectionBarrier(x); + InFlySnapCollectionBarriers.erase(snapCollectionIt); + } + } + break; case ECommit::Snap: LogicSnap->Confirm(msg->Step); - + if (NeedFollowerSnapshot) MakeLogSnapshot(); - - break; + + break; case ECommit::Data: - { - auto it = InFlyCompactionGcBarriers.find(step); + { + auto it = InFlyCompactionGcBarriers.find(step); Y_VERIFY(it != InFlyCompactionGcBarriers.end()); // just check, real barrier release on follower gc ack - } - - // any action on snapshot commit? - break; + } + + // any action on snapshot commit? + break; case ECommit::Misc: - break; - default: + break; + default: Y_FAIL("unknown event cookie"); - } - + } + CheckYellow(std::move(msg->YellowMoveChannels), std::move(msg->YellowStopChannels)); - + ui64 totalBytes = 0; for (auto& kv : msg->GroupWrittenBytes) { totalBytes += kv.second; @@ -2685,16 +2685,16 @@ void TExecutor::Handle(TEvTablet::TEvCommitResult::TPtr &ev, const TActorContext std::move(msg->GroupWrittenBytes), std::move(msg->GroupWrittenOps))); - ActiveTransaction = false; + ActiveTransaction = false; PlanTransactionActivation(); -} - +} + void TExecutor::Handle(TEvBlobStorage::TEvCollectGarbageResult::TPtr &ev) { - GcLogic->OnCollectGarbageResult(ev); -} - + GcLogic->OnCollectGarbageResult(ev); +} + void TExecutor::Handle(TEvResourceBroker::TEvResourceAllocated::TPtr &ev) { - auto *msg = ev->Get(); + auto *msg = ev->Get(); if (!msg->Cookie.Get()) { // Generic broker is not using cookies Broker->OnResourceAllocated(msg->TaskId); @@ -2708,11 +2708,11 @@ void TExecutor::Handle(TEvResourceBroker::TEvResourceAllocated::TPtr &ev) { return StartSeat(msg->TaskId, cookie); case TResource::ESource::Scan: return StartScan(msg->TaskId, cookie); - default: - Y_FAIL("unexpected resource source"); - } -} - + default: + Y_FAIL("unexpected resource source"); + } +} + void TExecutor::StartSeat(ui64 task, TResource *cookie_) noexcept { auto *cookie = CheckedCast<TMemory::TCookie*>(cookie_); @@ -2725,14 +2725,14 @@ void TExecutor::StartSeat(ui64 task, TResource *cookie_) noexcept ActivationQueue->Push(seat.Release()); ActivateTransactionWaiting++; PlanTransactionActivation(); -} - +} + THolder<TScanSnapshot> TExecutor::PrepareScanSnapshot(ui32 table, const NTable::TCompactionParams *params, TRowVersion snapshot) { LogicRedo->FlushBatchedLog(); - + auto commit = CommitManager->Begin(true, ECommit::Misc); - + if (params && params->Edge.Head == NTable::TEpoch::Max()) { auto redo = Database->SnapshotToLog(table, { Generation(), commit->Step }); LogicRedo->MakeLogEntry(*commit, std::move(redo), { table }, true); @@ -2761,8 +2761,8 @@ THolder<TScanSnapshot> TExecutor::PrepareScanSnapshot(ui32 table, const NTable:: } else { // This grabs a volatile snapshot of the mutable table state subset = Database->ScanSnapshot(table, snapshot); - } - + } + for (auto &partView : subset->Flatten) PrivatePageCache->LockPageCollection(partView->Label); @@ -2831,14 +2831,14 @@ void TExecutor::UtilizeSubset(const NTable::TSubset &subset, const NTable::NFwd::TSeen &seen, THashSet<TLogoBlobID> reusedBundles, TLogCommit *commit) -{ +{ if (seen.Sieve.size() == subset.Flatten.size() + 1) { /* The last TSieve, if present, corresponds to external blobs of all compacted TMemTable tables, this pseudo NPage::TBlobs is generated by NFwd blobs tracer for this GC logic and may bypass borrow logic since TMemTable cannot be borrowed. */ - + seen.Sieve.back().MaterializeTo(commit->GcDelta.Deleted); } else if (seen.Sieve.size() != subset.Flatten.size()) { Y_FAIL("Got an unexpected TSieve items count after compaction"); @@ -2885,8 +2885,8 @@ void TExecutor::UtilizeSubset(const NTable::TSubset &subset, } Counters->Cumulative()[TExecutorCounters::DB_ELOBS_ITEMS_GONE].Increment(seen.Total - seen.Seen); -} - +} + void TExecutor::ReleaseScanLocks(TIntrusivePtr<TBarrier> barrier, const NTable::TSubset &subset) { CheckCollectionBarrier(barrier); @@ -2905,20 +2905,20 @@ void TExecutor::Handle(NOps::TEvScanStat::TPtr &ev, const TActorContext &ctx) { } } -void TExecutor::Handle(NOps::TEvResult::TPtr &ev) { +void TExecutor::Handle(NOps::TEvResult::TPtr &ev) { auto *msg = ev->Get(); const auto outcome = Scans->Release(msg->Serial, msg->Status, msg->Result); if (outcome.System) { /* System scans are used for compactions and specially handled */ - Handle(msg, CheckedCast<TProdCompact*>(msg->Result.Get()), outcome.Cancelled); + Handle(msg, CheckedCast<TProdCompact*>(msg->Result.Get()), outcome.Cancelled); } ReleaseScanLocks(std::move(msg->Barrier), *msg->Subset); } -void TExecutor::Handle(NOps::TEvResult *ops, TProdCompact *msg, bool cancelled) { - THPTimer partSwitchCpuTimer; +void TExecutor::Handle(NOps::TEvResult *ops, TProdCompact *msg, bool cancelled) { + THPTimer partSwitchCpuTimer; if (msg->Params->TaskId != 0) { // We have taken over this task, mark it as finished in the broker @@ -2927,7 +2927,7 @@ void TExecutor::Handle(NOps::TEvResult *ops, TProdCompact *msg, bool cancelled) } const ui32 tableId = msg->Params->Table; - + const bool abandoned = cancelled || !Scheme().GetTableInfo(tableId); TProdCompact::TResults results = std::move(msg->Results); @@ -2955,14 +2955,14 @@ void TExecutor::Handle(NOps::TEvResult *ops, TProdCompact *msg, bool cancelled) if (cancelled && Scheme().GetTableInfo(tableId)) { CompactionLogic->CancelledCompaction(ops->Serial, std::move(msg->Params)); } - return; + return; } else if (!msg->Success) { - if (auto logl = Logger->Log(ELnLev::Error)) { - logl << NFmt::Do(*this) << " Broken on compaction error"; - } - + if (auto logl = Logger->Log(ELnLev::Error)) { + logl << NFmt::Do(*this) << " Broken on compaction error"; + } + CheckYellow(std::move(msg->YellowMoveChannels), std::move(msg->YellowStopChannels), /* terminal */ true); - return Broken(); + return Broken(); } ActiveTransaction = true; @@ -2972,12 +2972,12 @@ void TExecutor::Handle(NOps::TEvResult *ops, TProdCompact *msg, bool cancelled) LogicRedo->FlushBatchedLog(); - // now apply effects - NKikimrExecutorFlat::TTablePartSwitch proto; - proto.SetTableId(tableId); - + // now apply effects + NKikimrExecutorFlat::TTablePartSwitch proto; + proto.SetTableId(tableId); + NKikimrExecutorFlat::TFollowerPartSwitchAux aux; - + auto commit = CommitManager->Begin(true, ECommit::Data); commit->WaitFollowerGcAck = true; @@ -2989,8 +2989,8 @@ void TExecutor::Handle(NOps::TEvResult *ops, TProdCompact *msg, bool cancelled) // effectively a snapshot. Y_VERIFY(msg->Params->Edge.Head > NTable::TEpoch::Zero()); LogicRedo->CutLog(tableId, { snapStamp, ops->Subset->Head }, commit->GcDelta); - auto *sx = proto.MutableTableSnapshoted(); - sx->SetTable(tableId); + auto *sx = proto.MutableTableSnapshoted(); + sx->SetTable(tableId); sx->SetGeneration(ExpandGenStepPair(snapStamp).first); sx->SetStep(ExpandGenStepPair(snapStamp).second); sx->SetHead(ops->Subset->Head.ToProto()); @@ -3003,11 +3003,11 @@ void TExecutor::Handle(NOps::TEvResult *ops, TProdCompact *msg, bool cancelled) for (const auto &result : results) { const auto &newPart = result.Part; - + AddCachesOfBundle(newPart); - + auto *partStore = newPart.As<NTable::TPartStore>(); - + { /*_ enum all new blobs (include external) to gc logic */ partStore->SaveAllBlobIdsTo(commit->GcDelta.Created); @@ -3016,8 +3016,8 @@ void TExecutor::Handle(NOps::TEvResult *ops, TProdCompact *msg, bool cancelled) gcDiscovered.push_back(partStore->Blobs->Glob(seq).Logo); } } - } - + } + if (newTxStatus) { for (const auto &txStatus : newTxStatus) { auto *partStore = dynamic_cast<const NTable::TTxStatusPartStore*>(txStatus.Get()); @@ -3037,8 +3037,8 @@ void TExecutor::Handle(NOps::TEvResult *ops, TProdCompact *msg, bool cancelled) Y_VERIFY(ops->Trace->Seen + totalGrow == totalBlobs); Counters->Cumulative()[TExecutorCounters::DB_ELOBS_ITEMS_GROW].Increment(totalGrow); - } - + } + THashMap<TLogoBlobID, NKikimrExecutorFlat::TBundleChange*> bundleChanges; { /*_ Replace original subset with compacted results */ @@ -3160,15 +3160,15 @@ void TExecutor::Handle(NOps::TEvResult *ops, TProdCompact *msg, bool cancelled) { /*_ Finalize switch (turn) blob and attach it to commit */ auto body = proto.SerializeAsString(); auto glob = CommitManager->Turns.One(commit->Refs, std::move(body), true); - + if (bySwitchAux) LogoBlobIDFromLogoBlobID(glob.Logo, bySwitchAux->MutablePartSwitchRef()); } - + commit->FollowerAux = NPageCollection::TSlicer::Lz4()->Encode(aux.SerializeAsString()); - + Y_VERIFY(InFlyCompactionGcBarriers.emplace(commit->Step, ops->Barrier).second); - + CommitManager->Commit(commit); if (hadFrozen || logicResult.MemCompacted) @@ -3186,17 +3186,17 @@ void TExecutor::Handle(NOps::TEvResult *ops, TProdCompact *msg, bool cancelled) for (auto &snap : logicResult.CompleteSnapshots) { if (snap->Impl->Complete(tableId, ops->Barrier)) { auto snapIt = WaitingSnapshots.find(snap.Get()); - Y_VERIFY(snapIt != WaitingSnapshots.end()); - TIntrusivePtr<TTableSnapshotContext> snapCtxPtr = snapIt->second; - WaitingSnapshots.erase(snapIt); - - Owner->SnapshotComplete(snapCtxPtr, OwnerCtx()); - } - } - - Owner->CompactionComplete(tableId, OwnerCtx()); - - ActiveTransaction = false; + Y_VERIFY(snapIt != WaitingSnapshots.end()); + TIntrusivePtr<TTableSnapshotContext> snapCtxPtr = snapIt->second; + WaitingSnapshots.erase(snapIt); + + Owner->SnapshotComplete(snapCtxPtr, OwnerCtx()); + } + } + + Owner->CompactionComplete(tableId, OwnerCtx()); + + ActiveTransaction = false; if (LogicSnap->MayFlush(false)) { MakeLogSnapshot(); @@ -3224,10 +3224,10 @@ void TExecutor::UpdateUsedTabletMemory() { UsedTabletMemory += Owner->GetMemoryUsage(); } -void TExecutor::UpdateCounters(const TActorContext &ctx) { - TAutoPtr<TTabletCountersBase> executorCounters; - TAutoPtr<TTabletCountersBase> externalTabletCounters; - +void TExecutor::UpdateCounters(const TActorContext &ctx) { + TAutoPtr<TTabletCountersBase> executorCounters; + TAutoPtr<TTabletCountersBase> externalTabletCounters; + if (CounterEventsInFlight.RefCount() == 1) { UpdateUsedTabletMemory(); @@ -3245,8 +3245,8 @@ void TExecutor::UpdateCounters(const TActorContext &ctx) { Counters->Simple()[TExecutorCounters::CACHE_STAGING_SIZE].Set(CounterCacheStaging->Val()); Counters->Simple()[TExecutorCounters::CACHE_WARM_SIZE].Set(CounterCacheMemTable->Val()); Counters->Simple()[TExecutorCounters::USED_TABLET_MEMORY].Set(UsedTabletMemory); - } - + } + if (CommitManager) /* exists only on leader, mostly storage usage data */ { auto redo = LogicRedo->LogStats(); Counters->Simple()[TExecutorCounters::LOG_REDO_COUNT].Set(redo.Items); @@ -3333,17 +3333,17 @@ void TExecutor::UpdateCounters(const TActorContext &ctx) { Counters->Simple()[TExecutorCounters::CONSUMED_MEMORY].Set(memorySize); } } - + if (AppCounters) { externalTabletCounters = AppCounters->MakeDiffForAggr(*AppCountersBaseline); AppCounters->RememberCurrentStateAsBaseline(*AppCountersBaseline); } - + // tablet id + tablet type ui64 tabletId = Owner->TabletID(); auto tabletType = Owner->TabletType(); auto tenantPathId = Owner->Info()->TenantPathId; - + TActorId countersAggregator = MakeTabletCountersAggregatorID(SelfId().NodeId(), Stats->IsFollower); Send(countersAggregator, new TEvTabletCounters::TEvTabletAddCounters( CounterEventsInFlight, tabletId, tabletType, tenantPathId, executorCounters, externalTabletCounters)); @@ -3353,8 +3353,8 @@ void TExecutor::UpdateCounters(const TActorContext &ctx) { } } Schedule(TDuration::Seconds(15), new TEvPrivate::TEvUpdateCounters()); -} - +} + float TExecutor::GetRejectProbability() const { // Limit number of in-flight TXs // TODO: make configurable @@ -3534,32 +3534,32 @@ bool TExecutor::CompactTables() { } } -STFUNC(TExecutor::StateInit) { +STFUNC(TExecutor::StateInit) { Y_UNUSED(ev); Y_UNUSED(ctx); Y_FAIL("must be no events before boot processing"); -} - -STFUNC(TExecutor::StateBoot) { +} + +STFUNC(TExecutor::StateBoot) { Y_VERIFY(BootLogic); - switch (ev->GetTypeRewrite()) { + switch (ev->GetTypeRewrite()) { // N.B. must work during follower promotion to leader HFunc(TEvPrivate::TEvActivateExecution, Handle); HFunc(TEvPrivate::TEvBrokenTransaction, Handle); HFunc(TEvents::TEvWakeup, Wakeup); hFunc(TEvResourceBroker::TEvResourceAllocated, Handle); - default: + default: return TranscriptBootOpResult(BootLogic->Receive(*ev), ctx); - } -} - -STFUNC(TExecutor::StateWork) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvPrivate::TEvActivateExecution, Handle); + } +} + +STFUNC(TExecutor::StateWork) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvPrivate::TEvActivateExecution, Handle); HFunc(TEvPrivate::TEvBrokenTransaction, Handle); HFunc(TEvPrivate::TEvActivateCompactionRead, Handle); HFunc(TEvPrivate::TEvActivateCompactionChanges, Handle); - CFunc(TEvPrivate::EvUpdateCounters, UpdateCounters); + CFunc(TEvPrivate::EvUpdateCounters, UpdateCounters); cFunc(TEvPrivate::EvCheckYellow, UpdateYellow); cFunc(TEvPrivate::EvUpdateCompactions, UpdateCompactions); HFunc(TEvents::TEvWakeup, Wakeup); @@ -3567,27 +3567,27 @@ STFUNC(TExecutor::StateWork) { hFunc(NSharedCache::TEvRequest, Handle); hFunc(NSharedCache::TEvResult, Handle); hFunc(NSharedCache::TEvUpdated, Handle); - HFunc(TEvTablet::TEvCommitResult, Handle); + HFunc(TEvTablet::TEvCommitResult, Handle); hFunc(TEvTablet::TEvCheckBlobstorageStatusResult, Handle); hFunc(TEvBlobStorage::TEvCollectGarbageResult, Handle); HFunc(TEvBlobStorage::TEvGetResult, Handle); hFunc(TEvResourceBroker::TEvResourceAllocated, Handle); HFunc(NOps::TEvScanStat, Handle); - hFunc(NOps::TEvResult, Handle); + hFunc(NOps::TEvResult, Handle); HFunc(NBlockIO::TEvStat, Handle); - default: - break; - } - - TranslateCacheTouchesToSharedCache(); -} - + default: + break; + } + + TranslateCacheTouchesToSharedCache(); +} + STFUNC(TExecutor::StateFollower) { - Y_UNUSED(ctx); - switch (ev->GetTypeRewrite()) { - HFunc(TEvPrivate::TEvActivateExecution, Handle); + Y_UNUSED(ctx); + switch (ev->GetTypeRewrite()) { + HFunc(TEvPrivate::TEvActivateExecution, Handle); HFunc(TEvPrivate::TEvBrokenTransaction, Handle); - CFunc(TEvPrivate::EvUpdateCounters, UpdateCounters); + CFunc(TEvPrivate::EvUpdateCounters, UpdateCounters); HFunc(TEvents::TEvWakeup, Wakeup); hFunc(NSharedCache::TEvResult, Handle); hFunc(NSharedCache::TEvUpdated, Handle); @@ -3596,26 +3596,26 @@ STFUNC(TExecutor::StateFollower) { HFunc(NOps::TEvScanStat, Handle); hFunc(NOps::TEvResult, Handle); HFunc(NBlockIO::TEvStat, Handle); - default: - break; - } - - TranslateCacheTouchesToSharedCache(); -} - + default: + break; + } + + TranslateCacheTouchesToSharedCache(); +} + STFUNC(TExecutor::StateFollowerBoot) { - Y_VERIFY(BootLogic); - switch (ev->GetTypeRewrite()) { + Y_VERIFY(BootLogic); + switch (ev->GetTypeRewrite()) { // N.B. must handle activities started before resync HFunc(TEvPrivate::TEvActivateExecution, Handle); HFunc(TEvPrivate::TEvBrokenTransaction, Handle); HFunc(TEvents::TEvWakeup, Wakeup); hFunc(TEvResourceBroker::TEvResourceAllocated, Handle); - default: + default: return TranscriptFollowerBootOpResult(BootLogic->Receive(*ev), ctx); - } -} - + } +} + THashMap<TLogoBlobID, TVector<ui64>> TExecutor::GetBorrowedParts() const { if (BorrowLogic) { return BorrowLogic->GetBorrowedParts(); @@ -3624,13 +3624,13 @@ THashMap<TLogoBlobID, TVector<ui64>> TExecutor::GetBorrowedParts() const { return { }; } -const TExecutorStats& TExecutor::GetStats() const { - return *Stats; -} - +const TExecutorStats& TExecutor::GetStats() const { + return *Stats; +} + void TExecutor::RenderHtmlCounters(NMon::TEvRemoteHttpInfo::TPtr &ev) const { - TStringStream str; - + TStringStream str; + if (Database) { HTML(str) { str << "<style>"; @@ -3638,32 +3638,32 @@ void TExecutor::RenderHtmlCounters(NMon::TEvRemoteHttpInfo::TPtr &ev) const { str << "table.metrics td { text-align: right; padding-right: 10px; }"; str << "table.metrics td:nth-child(3) { text-align: left; }"; str << "</style>"; - if (Counters) { + if (Counters) { H3() {str << "Executor counters";} - Counters->OutputHtml(str); - } - - if (AppCounters) { + Counters->OutputHtml(str); + } + + if (AppCounters) { H3() {str << "App counters";} - AppCounters->OutputHtml(str); - } + AppCounters->OutputHtml(str); + } if (ResourceMetrics) { str << NMetrics::AsHTML(*ResourceMetrics); } } - } else { + } else { HTML(str) {str << "loading...";} // todo: populate from bootlogic - } - + } + Send(ev->Sender, new NMon::TEvRemoteHttpInfoRes(str.Str())); -} - +} + void TExecutor::RenderHtmlPage(NMon::TEvRemoteHttpInfo::TPtr &ev) const { auto cgi = ev->Get()->Cgi(); - TStringStream str; + TStringStream str; const NScheme::TTypeRegistry& tr = *AppData()->TypeRegistry; - + if (cgi.Has("force_compaction")) { bool ok; bool allTables = false; @@ -3756,8 +3756,8 @@ void TExecutor::RenderHtmlPage(NMon::TEvRemoteHttpInfo::TPtr &ev) const { } } } - } - + } + H3() {str << "Storage:";} DIV_CLASS("row") {str << "Bytes pinned in cache: " << PrivatePageCache->GetStats().PinnedSetSize << Endl; } DIV_CLASS("row") {str << "Bytes pinned to load: " << PrivatePageCache->GetStats().PinnedLoadSize << Endl; } @@ -3766,9 +3766,9 @@ void TExecutor::RenderHtmlPage(NMon::TEvRemoteHttpInfo::TPtr &ev) const { DIV_CLASS("row") {str << "used tablet memory: " << UsedTabletMemory; } Memory->DumpStateToHTML(str); - if (CompactionLogic) + if (CompactionLogic) CompactionLogic->OutputHtml(str, *scheme, cgi); - + H3() {str << "Page collection cache:";} DIV_CLASS("row") {str << "fresh bytes: " << CounterCacheFresh->Val(); } DIV_CLASS("row") {str << "staging bytes: " << CounterCacheStaging->Val(); } @@ -3779,10 +3779,10 @@ void TExecutor::RenderHtmlPage(NMon::TEvRemoteHttpInfo::TPtr &ev) const { DIV_CLASS("row") {str << "Total bytes exclusive to local cache: " << PrivatePageCache->GetStats().TotalExclusive; } DIV_CLASS("row") {str << "Total bytes in transit to shared cache: " << PrivatePageCache->GetStats().TotalSharedPending; } DIV_CLASS("row") {str << "Total bytes marked as sticky: " << PrivatePageCache->GetStats().TotalSticky; } - - if (GcLogic) { + + if (GcLogic) { H3() {str << "Gc logic:";} - auto gcInfo = GcLogic->IntrospectStateSize(); + auto gcInfo = GcLogic->IntrospectStateSize(); DIV_CLASS("row") {str << "uncommited entries: " << gcInfo.UncommitedEntries;} DIV_CLASS("row") {str << "uncommited blob ids: " << gcInfo.UncommitedBlobIds; } DIV_CLASS("row") {str << "uncommited entries bytes: " << gcInfo.UncommitedEntriesBytes;} @@ -3791,37 +3791,37 @@ void TExecutor::RenderHtmlPage(NMon::TEvRemoteHttpInfo::TPtr &ev) const { DIV_CLASS("row") {str << "commited blob ids left: " << gcInfo.CommitedBlobIdsLeft;} DIV_CLASS("row") {str << "commited entries bytes: " << gcInfo.CommitedEntriesBytes; } DIV_CLASS("row") {str << "active collect barriers: " << gcInfo.BarriersSetSize; } - } - - if (BorrowLogic) { + } + + if (BorrowLogic) { H3() {str << "Borrow logic:";} - BorrowLogic->OutputHtml(str); - } + BorrowLogic->OutputHtml(str); + } } - - } else { + + } else { HTML(str) {str << "loading...";} // todo: populate from bootlogic - } - + } + Send(ev->Sender, new NMon::TEvRemoteHttpInfoRes(str.Str())); -} - +} + const NTable::TScheme& TExecutor::Scheme() const noexcept { Y_VERIFY_DEBUG(Database); return Database->GetScheme(); -} - -void TExecutor::RegisterExternalTabletCounters(TAutoPtr<TTabletCountersBase> appCounters) { - AppCounters = appCounters; +} + +void TExecutor::RegisterExternalTabletCounters(TAutoPtr<TTabletCountersBase> appCounters) { + AppCounters = appCounters; AppCountersBaseline = MakeHolder<TTabletCountersBase>(); - AppCounters->RememberCurrentStateAsBaseline(*AppCountersBaseline); + AppCounters->RememberCurrentStateAsBaseline(*AppCountersBaseline); if (LogicRedo) { - AppTxCounters = dynamic_cast<TTabletCountersWithTxTypes*>(AppCounters.Get()); + AppTxCounters = dynamic_cast<TTabletCountersWithTxTypes*>(AppCounters.Get()); LogicRedo->InstallCounters(Counters.Get(), AppTxCounters); - } -} - + } +} + void TExecutor::GetTabletCounters(TEvTablet::TEvGetCounters::TPtr &ev) { TAutoPtr<TEvTablet::TEvGetCountersResponse> response = new TEvTablet::TEvGetCountersResponse(); Counters->OutputProto(*response->Record.MutableTabletCounters()->MutableExecutorCounters()); @@ -3856,8 +3856,8 @@ void TExecutor::ReadResourceProfile() { } } -TString TExecutor::CheckBorrowConsistency() { - THashSet<TLogoBlobID> knownBundles; +TString TExecutor::CheckBorrowConsistency() { + THashSet<TLogoBlobID> knownBundles; for (auto& kv : Scheme().Tables) { const ui32 tableId = kv.first; Database->EnumerateTableParts(tableId, @@ -3869,16 +3869,16 @@ TString TExecutor::CheckBorrowConsistency() { knownBundles.insert(part->Label); }); } - return BorrowLogic->DebugCheckBorrowConsistency(knownBundles); -} - + return BorrowLogic->DebugCheckBorrowConsistency(knownBundles); +} + TTransactionWaitPad::TTransactionWaitPad(THolder<TSeat> seat) : Seat(std::move(seat)) -{} +{} TTransactionWaitPad::~TTransactionWaitPad() -{} - +{} + // ICompactionBackend implementation ui64 TExecutor::OwnerTabletId() const diff --git a/ydb/core/tablet_flat/flat_executor.h b/ydb/core/tablet_flat/flat_executor.h index 55e6adc241..df08b3a338 100644 --- a/ydb/core/tablet_flat/flat_executor.h +++ b/ydb/core/tablet_flat/flat_executor.h @@ -1,9 +1,9 @@ -#pragma once -#include "defs.h" -#include "tablet_flat_executor.h" -#include "flat_database.h" +#pragma once +#include "defs.h" +#include "tablet_flat_executor.h" +#include "flat_database.h" #include "flat_dbase_change.h" -#include "flat_sausagecache.h" +#include "flat_sausagecache.h" #include "flat_part_store.h" #include "flat_part_outset.h" #include "flat_part_loader.h" @@ -15,7 +15,7 @@ #include "flat_exec_read.h" #include "flat_executor_misc.h" #include "flat_executor_compaction_logic.h" -#include "flat_executor_gclogic.h" +#include "flat_executor_gclogic.h" #include "flat_bio_events.h" #include "flat_bio_stats.h" #include "flat_fwd_sieve.h" @@ -32,27 +32,27 @@ #include <library/cpp/monlib/dynamic_counters/counters.h> -#include <util/system/hp_timer.h> -#include <util/thread/singleton.h> - +#include <util/system/hp_timer.h> +#include <util/thread/singleton.h> + #include <optional> #include <variant> -namespace NKikimr { +namespace NKikimr { namespace NTable { class TLoader; } -namespace NTabletFlatExecutor { - +namespace NTabletFlatExecutor { + class TLogicSnap; -class TExecutorBootLogic; +class TExecutorBootLogic; class TLogicRedo; class TLogicAlter; class TLogicSnap; -class TExecutorBorrowLogic; -class TExecutorCounters; +class TExecutorBorrowLogic; +class TExecutorCounters; class TCommitManager; class TScans; class TMemory; @@ -62,8 +62,8 @@ struct TPageCollectionTxEnv; struct TProdCompact; struct TProdBackup; struct TSeat; - -struct TPendingPartSwitch { + +struct TPendingPartSwitch { struct TLargeGlobLoader { size_t Index; NPageCollection::TLargeGlobId LargeGlobId; @@ -251,9 +251,9 @@ struct TPendingPartSwitch { using TPendingBlobs = THashMultiMap<TLogoBlobID, TBlobWaiter>; - ui32 TableId = 0; + ui32 TableId = 0; ui32 Step = 0; - + TList<TNewBundle> NewBundles; TList<TNewTxStatus> NewTxStatus; TVector<TIntrusiveConstPtr<NTable::TColdPart>> NewColdParts; @@ -266,7 +266,7 @@ struct TPendingPartSwitch { TVector<TLogoBlobID> LeavingTxStatus; TVector<TBundleMove> Moves; NTable::TEpoch Head = NTable::TEpoch::Zero(); - + ui32 FollowerUpdateStep = 0; bool AddPendingBlob(const TLogoBlobID& id, TBlobWaiter waiter) { @@ -275,21 +275,21 @@ struct TPendingPartSwitch { PendingBlobs.emplace_direct(ctx, id, std::move(waiter)); return newBlob; } -}; - +}; + enum class EPageCollectionRequest : ui64 { - Undefined = 0, - Cache = 1, - CacheSync, - PendingInit, - BootLogic, -}; - -struct TExecutorStatsImpl : public TExecutorStats { - TInstant YellowLastChecked; + Undefined = 0, + Cache = 1, + CacheSync, + PendingInit, + BootLogic, +}; + +struct TExecutorStatsImpl : public TExecutorStats { + TInstant YellowLastChecked; ui64 PacksMetaBytes = 0; /* Memory occupied by NPageCollection::TMeta */ -}; - +}; + struct TTransactionWaitPad : public TPrivatePageCacheWaitPad { THolder<TSeat> Seat; @@ -323,43 +323,43 @@ class TExecutor friend class TExecutorCompactionLogic; class TTxExecutorDbMon; - static constexpr ui64 PostponeTransactionMemThreshold = 250*1024*1024; - - struct TEvPrivate { - enum EEv { - EvActivateExecution = EventSpaceBegin(TKikimrEvents::ES_PRIVATE), - EvUpdateCounters, - EvCheckYellow, + static constexpr ui64 PostponeTransactionMemThreshold = 250*1024*1024; + + struct TEvPrivate { + enum EEv { + EvActivateExecution = EventSpaceBegin(TKikimrEvents::ES_PRIVATE), + EvUpdateCounters, + EvCheckYellow, EvUpdateCompactions, EvActivateCompactionRead, EvActivateCompactionChanges, EvBrokenTransaction, - - EvEnd - }; - - static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_PRIVATE), "enum range overrun"); - - struct TEvActivateExecution : public TEventLocal<TEvActivateExecution, EvActivateExecution> {}; - struct TEvUpdateCounters : public TEventLocal<TEvUpdateCounters, EvUpdateCounters> {}; - struct TEvCheckYellow : public TEventLocal<TEvCheckYellow, EvCheckYellow> {}; + + EvEnd + }; + + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_PRIVATE), "enum range overrun"); + + struct TEvActivateExecution : public TEventLocal<TEvActivateExecution, EvActivateExecution> {}; + struct TEvUpdateCounters : public TEventLocal<TEvUpdateCounters, EvUpdateCounters> {}; + struct TEvCheckYellow : public TEventLocal<TEvCheckYellow, EvCheckYellow> {}; struct TEvUpdateCompactions : public TEventLocal<TEvUpdateCompactions, EvUpdateCompactions> {}; struct TEvActivateCompactionRead : public TEventLocal<TEvActivateCompactionRead, EvActivateCompactionRead> {}; struct TEvActivateCompactionChanges : public TEventLocal<TEvActivateCompactionChanges, EvActivateCompactionChanges> {}; struct TEvBrokenTransaction : public TEventLocal<TEvBrokenTransaction, EvBrokenTransaction> {}; - }; - + }; + const TIntrusivePtr<ITimeProvider> Time = nullptr; NFlatExecutorSetup::ITablet * Owner; const TActorId OwnerActorId; TAutoPtr<NUtil::ILogger> Logger; - + ui32 FollowerId = 0; using TActivationQueue = TOneOneQueueInplace<TSeat *, 64>; THolder<TActivationQueue, TActivationQueue::TPtrCleanDestructor> ActivationQueue; - THolder<TActivationQueue, TActivationQueue::TPtrCleanDestructor> PendingQueue; - + THolder<TActivationQueue, TActivationQueue::TPtrCleanDestructor> PendingQueue; + THashMap<ui64, TCompactionReadState> CompactionReads; TDeque<ui64> CompactionReadQueue; bool CompactionReadActivating = false; @@ -368,27 +368,27 @@ class TExecutor TMap<TSeat*, TAutoPtr<TSeat>> PostponedTransactions; THashMap<ui64, THolder<TScanSnapshot>> ScanSnapshots; ui64 ScanSnapshotId = 1; - + bool ActiveTransaction = false; bool BrokenTransaction = false; ui32 ActivateTransactionWaiting = 0; ui32 ActivateTransactionInFlight = 0; - + using TWaitingSnaps = THashMap<TTableSnapshotContext *, TIntrusivePtr<TTableSnapshotContext>>; const TIntrusivePtr<TIdEmitter> Emitter; TAutoPtr<TBroker> Broker; - TWaitingSnaps WaitingSnapshots; - - THolder<TExecutorBootLogic> BootLogic; + TWaitingSnaps WaitingSnapshots; + + THolder<TExecutorBootLogic> BootLogic; THolder<TPrivatePageCache> PrivatePageCache; THolder<TExecutorCounters> Counters; THolder<TTabletCountersBase> AppCounters; THolder<TTabletCountersBase> CountersBaseline; THolder<TTabletCountersBase> AppCountersBaseline; THolder<NMetrics::TResourceMetrics> ResourceMetrics; - + TAutoPtr<NTable::TDatabase> Database; TAutoPtr<TCommitManager> CommitManager; @@ -400,51 +400,51 @@ class TExecutor THolder<TExecutorGCLogic> GcLogic; THolder<TCompactionLogic> CompactionLogic; THolder<TExecutorBorrowLogic> BorrowLogic; - + TLoadBlobQueue PendingBlobQueue; - // Used control number of in flight events to the counter aggregator + // Used control number of in flight events to the counter aggregator TIntrusivePtr<TEvTabletCounters::TInFlightCookie> CounterEventsInFlight; - + TTabletCountersWithTxTypes* AppTxCounters = nullptr; TActorId Launcher; THashMap<TPrivatePageCacheWaitPad*, THolder<TTransactionWaitPad>> TransactionWaitPads; THashMap<TPrivatePageCacheWaitPad*, THolder<TCompactionReadWaitPad>> CompactionReadWaitPads; - + ui64 TransactionUniqCounter = 0; ui64 CompactionReadUniqCounter = 0; - + bool LogBatchFlushScheduled = false; bool HadFollowerAttached = false; bool NeedFollowerSnapshot = false; - - TCacheCacheConfig::TCounterPtr CounterCacheFresh; + + TCacheCacheConfig::TCounterPtr CounterCacheFresh; TCacheCacheConfig::TCounterPtr CounterCacheMemTable; - TCacheCacheConfig::TCounterPtr CounterCacheStaging; - + TCacheCacheConfig::TCounterPtr CounterCacheStaging; + THashMap<ui32, TIntrusivePtr<TBarrier>> InFlyCompactionGcBarriers; TDeque<THolder<TEvTablet::TFUpdateBody>> PostponedFollowerUpdates; THashMap<ui32, TVector<TIntrusivePtr<TBarrier>>> InFlySnapCollectionBarriers; - + THolder<TExecutorStatsImpl> Stats; bool HasYellowCheckInFly = false; - + TDeque<TPendingPartSwitch> PendingPartSwitches; size_t ReadyPartSwitches = 0; - + ui64 UsedTabletMemory = 0; - TActorContext OwnerCtx() const; - + TActorContext OwnerCtx() const; + TControlWrapper LogFlushDelayOverrideUsec; ui64 Stamp() const noexcept; void Registered(TActorSystem*, const TActorId&) override; void PassAway() override; - void Broken(); - void Active(const TActorContext &ctx); + void Broken(); + void Active(const TActorContext &ctx); void ActivateFollower(const TActorContext &ctx); void RecreatePageCollectionsCache() noexcept; void ReflectSchemeSettings() noexcept; @@ -461,11 +461,11 @@ class TExecutor void OnBlobLoaded(const TLogoBlobID& id, TString body, uintptr_t cookie) override; void AdvancePendingPartSwitches(); bool ApplyReadyPartSwitches(); - + TExecutorCaches CleanupState(); - bool CanExecuteTransaction() const; - - void TranscriptBootOpResult(ui32 res, const TActorContext &ctx); + bool CanExecuteTransaction() const; + + void TranscriptBootOpResult(ui32 res, const TActorContext &ctx); void TranscriptFollowerBootOpResult(ui32 res, const TActorContext &ctx); void ExecuteTransaction(TAutoPtr<TSeat> seat, const TActorContext &ctx); void CommitTransactionLog(TAutoPtr<TSeat>, TPageCollectionTxEnv&, TAutoPtr<NTable::TChange>, @@ -481,8 +481,8 @@ class TExecutor void DropCachesOfBundle(const NTable::TPart &part) noexcept; void DropSingleCache(const TLogoBlobID&) noexcept; - void TranslateCacheTouchesToSharedCache(); - void RequestInMemPagesForDatabase(); + void TranslateCacheTouchesToSharedCache(); + void RequestInMemPagesForDatabase(); void RequestInMemPagesForPartStore(ui32 tableId, const NTable::TPartView &partView); void RequestFromSharedCache(TAutoPtr<NPageCollection::TFetch> fetch, NBlockIO::EPriority way, EPageCollectionRequest requestCategory); @@ -493,17 +493,17 @@ class TExecutor void StartScan(ui64 task, TResource*) noexcept; void StartSeat(ui64 task, TResource*) noexcept; void PostponedScanCleared(NResourceBroker::TEvResourceBroker::TEvResourceAllocated *msg, const TActorContext &ctx); - + void ApplyFollowerUpdate(THolder<TEvTablet::TFUpdateBody> update); void ApplyFollowerAuxUpdate(const TString &auxBody); void ApplyFollowerPostponedUpdates(); void AddFollowerPartSwitch(const NKikimrExecutorFlat::TTablePartSwitch &switchProto, const NKikimrExecutorFlat::TFollowerPartSwitchAux::TBySwitch *aux, ui32 updateStep, ui32 step); - void ApplyExternalPartSwitch(TPendingPartSwitch &partSwitch); - + void ApplyExternalPartSwitch(TPendingPartSwitch &partSwitch); + void Wakeup(TEvents::TEvWakeup::TPtr &ev, const TActorContext &ctx); - void Handle(TEvTablet::TEvCommitResult::TPtr &ev, const TActorContext &ctx); - void Handle(TEvPrivate::TEvActivateExecution::TPtr &ev, const TActorContext &ctx); + void Handle(TEvTablet::TEvCommitResult::TPtr &ev, const TActorContext &ctx); + void Handle(TEvPrivate::TEvActivateExecution::TPtr &ev, const TActorContext &ctx); void Handle(TEvPrivate::TEvBrokenTransaction::TPtr &ev, const TActorContext &ctx); void Handle(TEvents::TEvFlushLog::TPtr &ev); void Handle(TEvBlobStorage::TEvCollectGarbageResult::TPtr&); @@ -512,19 +512,19 @@ class TExecutor void Handle(NSharedCache::TEvUpdated::TPtr &ev); void Handle(NResourceBroker::TEvResourceBroker::TEvResourceAllocated::TPtr&); void Handle(NOps::TEvScanStat::TPtr &ev, const TActorContext &ctx); - void Handle(NOps::TEvResult::TPtr &ev); + void Handle(NOps::TEvResult::TPtr &ev); void Handle(NBlockIO::TEvStat::TPtr &ev, const TActorContext &ctx); - void Handle(NOps::TEvResult *ops, TProdCompact *msg, bool cancelled); + void Handle(NOps::TEvResult *ops, TProdCompact *msg, bool cancelled); void Handle(TEvBlobStorage::TEvGetResult::TPtr&, const TActorContext&); void UpdateUsedTabletMemory(); - void UpdateCounters(const TActorContext &ctx); + void UpdateCounters(const TActorContext &ctx); void UpdateYellow(); void UpdateCompactions(); void Handle(TEvTablet::TEvCheckBlobstorageStatusResult::TPtr &ev); void ReadResourceProfile(); - TString CheckBorrowConsistency(); + TString CheckBorrowConsistency(); // ICompactionBackend API @@ -560,7 +560,7 @@ class TExecutor const NTable::TCompactionChanges& changes, NKikimrSchemeOp::ECompactionStrategy strategy); -public: +public: void Describe(IOutputStream &out) const noexcept override { out @@ -569,14 +569,14 @@ public: << ":" << Generation() << ":" << Step() << "}"; } - // IExecutor interface - void Boot(TEvTablet::TEvBoot::TPtr &ev, const TActorContext &ctx) override; - void Restored(TEvTablet::TEvRestored::TPtr &ev, const TActorContext &ctx) override; - void DetachTablet(const TActorContext &ctx) override; + // IExecutor interface + void Boot(TEvTablet::TEvBoot::TPtr &ev, const TActorContext &ctx) override; + void Restored(TEvTablet::TEvRestored::TPtr &ev, const TActorContext &ctx) override; + void DetachTablet(const TActorContext &ctx) override; void Execute(TAutoPtr<ITransaction> transaction, const TActorContext &ctx) override; - + TString BorrowSnapshot(ui32 tableId, const TTableSnapshotContext& snap, TRawVals from, TRawVals to, ui64 loaner) const override; - + ui64 MakeScanSnapshot(ui32 table) override; void DropScanSnapshot(ui64 snapId) override; ui64 QueueScan(ui32 tableId, TAutoPtr<NTable::IScan> scan, ui64 cookie, const TScanOptions& options) override; @@ -594,43 +594,43 @@ public: void FollowerBoot(TEvTablet::TEvFBoot::TPtr &ev, const TActorContext &ctx) override; void FollowerUpdate(THolder<TEvTablet::TFUpdateBody> update) override; void FollowerAuxUpdate(TString upd) override; - + void RenderHtmlPage(NMon::TEvRemoteHttpInfo::TPtr &ev) const override; void RenderHtmlCounters(NMon::TEvRemoteHttpInfo::TPtr &ev) const override; void RenderHtmlDb(NMon::TEvRemoteHttpInfo::TPtr &ev, const TActorContext &ctx) const override; void GetTabletCounters(TEvTablet::TEvGetCounters::TPtr &ev) override; - + void UpdateConfig(TEvTablet::TEvUpdateConfig::TPtr &ev) override; void SendUserAuxUpdateToFollowers(TString upd, const TActorContext &ctx) override; THashMap<TLogoBlobID, TVector<ui64>> GetBorrowedParts() const override; - const TExecutorStats& GetStats() const override; + const TExecutorStats& GetStats() const override; NMetrics::TResourceMetrics* GetResourceMetrics() const override; - + void RegisterExternalTabletCounters(TAutoPtr<TTabletCountersBase> appCounters) override; - + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::FLAT_EXECUTOR; } TExecutor(NFlatExecutorSetup::ITablet *owner, const TActorId& ownerActorId); - ~TExecutor(); - - STFUNC(StateInit); - STFUNC(StateBoot); - STFUNC(StateWork); + ~TExecutor(); + + STFUNC(StateInit); + STFUNC(StateBoot); + STFUNC(StateWork); STFUNC(StateFollowerBoot); STFUNC(StateFollower); - - // database interface + + // database interface const NTable::TScheme& Scheme() const noexcept override; - ui64 TabletId() const { return Owner->TabletID(); } + ui64 TabletId() const { return Owner->TabletID(); } float GetRejectProbability() const override; TActorId GetLauncher() const { return Launcher; } -}; - -}} +}; + +}} diff --git a/ydb/core/tablet_flat/flat_executor.proto b/ydb/core/tablet_flat/flat_executor.proto index cff11fd06b..7758812187 100644 --- a/ydb/core/tablet_flat/flat_executor.proto +++ b/ydb/core/tablet_flat/flat_executor.proto @@ -1,10 +1,10 @@ import "ydb/core/protos/base.proto"; import "ydb/core/protos/tablet.proto"; import "ydb/core/protos/flat_scheme_op.proto"; - -package NKikimrExecutorFlat; -option java_package = "ru.yandex.kikimr.proto"; - + +package NKikimrExecutorFlat; +option java_package = "ru.yandex.kikimr.proto"; + message TLargeGlobId { // This is the correct way of doing for what StorageInfo is now used. @@ -88,61 +88,61 @@ message TEvolution { required uint32 Head = 2; } -message TLogTableSnap { - optional uint32 Table = 1; +message TLogTableSnap { + optional uint32 Table = 1; repeated NKikimrProto.TLogoBlobID DbPartMetaInfoBody = 2; // Legacy, replaced with Bundles optional uint32 Legacy0_ = 3; optional uint32 Legacy1_ = 4; optional uint32 Legacy2_ = 5; optional uint32 Legacy3_ = 6; - - optional uint32 CompactionLevel = 7; + + optional uint32 CompactionLevel = 7; repeated TBundle Bundles = 8; -} - +} + message TLogTxStatusSnap { optional uint32 Table = 1; repeated TTxStatus TxStatus = 2; } -message TLogMemSnap { - optional uint32 Table = 1; - optional uint32 Generation = 2; - optional uint32 Step = 3; +message TLogMemSnap { + optional uint32 Table = 1; + optional uint32 Generation = 2; + optional uint32 Step = 3; optional int64 Head = 4; -} - -message TGcChannelBarrierInfo { - optional uint32 Channel = 1; - optional uint32 SetToGeneration = 2; - optional uint32 SetToStep = 3; -} - -message TEmbeddedLogBody { - optional uint32 Generation = 1; - optional uint32 Step = 2; - optional bytes Body = 3; -} - -message TBorrowedList { - optional uint64 Who = 1; - repeated NKikimrProto.TLogoBlobID What = 2; -} - -message TBorrowedPart { +} + +message TGcChannelBarrierInfo { + optional uint32 Channel = 1; + optional uint32 SetToGeneration = 2; + optional uint32 SetToStep = 3; +} + +message TEmbeddedLogBody { + optional uint32 Generation = 1; + optional uint32 Step = 2; + optional bytes Body = 3; +} + +message TBorrowedList { + optional uint64 Who = 1; + repeated NKikimrProto.TLogoBlobID What = 2; +} + +message TBorrowedPart { optional NKikimrProto.TLogoBlobID MetaId = 1; - repeated uint64 Loaners = 2; - repeated TBorrowedList BorrowedList = 3; - repeated NKikimrProto.TLogoBlobID BorrowKeepList = 4; - - optional uint64 Lender = 10; - repeated NKikimrTabletBase.TTabletStorageInfo StorageInfo = 11; - optional bool LoanCollected = 12; - repeated NKikimrProto.TLogoBlobID LoanKeepList = 13; -} - + repeated uint64 Loaners = 2; + repeated TBorrowedList BorrowedList = 3; + repeated NKikimrProto.TLogoBlobID BorrowKeepList = 4; + + optional uint64 Lender = 10; + repeated NKikimrTabletBase.TTabletStorageInfo StorageInfo = 11; + optional bool LoanCollected = 12; + repeated NKikimrProto.TLogoBlobID LoanKeepList = 13; +} + message TSnapWaste { optional uint64 Since = 1; // Stamp of waste accounting age optional uint64 Level = 2; // Total bytes keeping by tablet @@ -171,17 +171,17 @@ message TRowVersionState { repeated TRemovedRange RemovedRanges = 2; } -message TLogSnapshot { - repeated NKikimrProto.TLogoBlobID NonSnapLogBodies = 1; - repeated NKikimrProto.TLogoBlobID SchemeInfoBodies = 2; - repeated TLogTableSnap DbParts = 3; - repeated TEmbeddedLogBody EmbeddedLogBodies = 4; - repeated TLogMemSnap TableSnapshoted = 5; - repeated NKikimrProto.TLogoBlobID BorrowInfoIds = 6; - - repeated NKikimrProto.TLogoBlobID GcSnapDiscovered = 12; - repeated NKikimrProto.TLogoBlobID GcSnapLeft = 13; - repeated TGcChannelBarrierInfo GcBarrierInfo = 14; +message TLogSnapshot { + repeated NKikimrProto.TLogoBlobID NonSnapLogBodies = 1; + repeated NKikimrProto.TLogoBlobID SchemeInfoBodies = 2; + repeated TLogTableSnap DbParts = 3; + repeated TEmbeddedLogBody EmbeddedLogBodies = 4; + repeated TLogMemSnap TableSnapshoted = 5; + repeated NKikimrProto.TLogoBlobID BorrowInfoIds = 6; + + repeated NKikimrProto.TLogoBlobID GcSnapDiscovered = 12; + repeated NKikimrProto.TLogoBlobID GcSnapLeft = 13; + repeated TGcChannelBarrierInfo GcBarrierInfo = 14; optional bytes Legacy0_ = 15; optional TEvolution Version = 16; @@ -191,13 +191,13 @@ message TLogSnapshot { repeated TCompactionState CompactionStates = 19; repeated TRowVersionState RowVersionStates = 20; repeated TLogTxStatusSnap TxStatusParts = 21; -} - -message TTablePartSwitch { +} + +message TTablePartSwitch { optional TLogTableSnap IntroducedParts = 1; - optional TLogMemSnap TableSnapshoted = 2; - optional uint32 TableId = 3; - + optional TLogMemSnap TableSnapshoted = 2; + optional uint32 TableId = 3; + repeated NKikimrProto.TLogoBlobID LeavingBundles = 10; repeated TBundleChange ChangedBundles = 11; optional TCompactionState CompactionChanges = 12; @@ -207,43 +207,43 @@ message TTablePartSwitch { repeated NKikimrProto.TLogoBlobID LeavingTxStatus = 16; optional TLogTxStatusSnap IntroducedTxStatus = 17; -} - -message TExternalGcEntry { - repeated NKikimrProto.TLogoBlobID GcDiscovered = 1; - repeated NKikimrProto.TLogoBlobID GcLeft = 2; -} - +} + +message TExternalGcEntry { + repeated NKikimrProto.TLogoBlobID GcDiscovered = 1; + repeated NKikimrProto.TLogoBlobID GcLeft = 2; +} + message TFollowerPartSwitchAux { - message TBySwitch { - optional NKikimrProto.TLogoBlobID PartSwitchRef = 1; + message TBySwitch { + optional NKikimrProto.TLogoBlobID PartSwitchRef = 1; repeated TBundle HotBundles = 2; repeated TTxStatus HotTxStatus = 3; - } - - repeated TBySwitch BySwitchAux = 1; -} - + } + + repeated TBySwitch BySwitchAux = 1; +} + message TFollowerAux { message TTouchByPageCollection { - optional NKikimrProto.TLogoBlobID MetaInfoId = 1; - repeated uint32 TouchedPages = 2; - } - + optional NKikimrProto.TLogoBlobID MetaInfoId = 1; + repeated uint32 TouchedPages = 2; + } + repeated TTouchByPageCollection PageCollectionsTouched = 1; optional bytes UserAuxUpdate = 2; -} - -message TDatabaseBorrowPart { - message TPartInfo { +} + +message TDatabaseBorrowPart { + message TPartInfo { optional TBundle Bundle = 12; - repeated NKikimrTabletBase.TTabletStorageInfo StorageInfo = 11; - } - - optional uint64 LenderTablet = 1; - optional uint32 SourceTable = 2; - - repeated TPartInfo Parts = 3; + repeated NKikimrTabletBase.TTabletStorageInfo StorageInfo = 11; + } + + optional uint64 LenderTablet = 1; + optional uint32 SourceTable = 2; + + repeated TPartInfo Parts = 3; repeated TTxStatus TxStatusParts = 4; -} +} diff --git a/ydb/core/tablet_flat/flat_executor_bootlogic.cpp b/ydb/core/tablet_flat/flat_executor_bootlogic.cpp index e00012ffdd..cf72960f9c 100644 --- a/ydb/core/tablet_flat/flat_executor_bootlogic.cpp +++ b/ydb/core/tablet_flat/flat_executor_bootlogic.cpp @@ -1,4 +1,4 @@ -#include "flat_executor_bootlogic.h" +#include "flat_executor_bootlogic.h" #include "flat_boot_env.h" #include "flat_boot_blobs.h" #include "flat_boot_back.h" @@ -15,10 +15,10 @@ #include <ydb/core/base/appdata.h> #include <ydb/core/base/counters.h> #include <ydb/core/util/pb.h> - -namespace NKikimr { -namespace NTabletFlatExecutor { - + +namespace NKikimr { +namespace NTabletFlatExecutor { + NBoot::TLoadBlobs::TLoadBlobs(IStep *owner, NPageCollection::TLargeGlobId largeGlobId, ui64 cookie) : IStep(owner, NBoot::EStep::Blobs) , Cookie(cookie) @@ -32,20 +32,20 @@ TExecutorBootLogic::TExecutorBootLogic(IOps *ops, const TActorId &self, TTabletS : Ops(ops) , SelfId(self) , Info(info) - , GroupResolveCachedChannel(Max<ui32>()) - , GroupResolveCachedGeneration(Max<ui32>()) - , GroupResolveCachedGroup(Max<ui32>()) + , GroupResolveCachedChannel(Max<ui32>()) + , GroupResolveCachedGeneration(Max<ui32>()) + , GroupResolveCachedGroup(Max<ui32>()) { LoadBlobQueue.Config.MaxBytesInFly = maxBytesInFly; } -TExecutorBootLogic::~TExecutorBootLogic() +TExecutorBootLogic::~TExecutorBootLogic() { LoadBlobQueue.Clear(); Loads.clear(); EntriesToLoad.clear(); - + Steps->Execute(); /* should flush all jobs in internal queue */ Y_VERIFY(Steps->Alone(), "Bootlogic is still has pending IStep()s"); @@ -59,58 +59,58 @@ void TExecutorBootLogic::Describe(IOutputStream &out) const noexcept TExecutorBootLogic::EOpResult TExecutorBootLogic::ReceiveFollowerBoot( TEvTablet::TEvFBoot::TPtr &ev, TExecutorCaches &&caches) -{ +{ TEvTablet::TEvFBoot *msg = ev->Get(); PrepareEnv(true, msg->Generation, std::move(caches)); - - if (msg->DependencyGraph) { - Steps->Spawn<NBoot::TStages>(std::move(msg->DependencyGraph), nullptr); - } else { - auto *update = msg->Update.Get(); - Y_VERIFY(update->IsSnapshot); + + if (msg->DependencyGraph) { + Steps->Spawn<NBoot::TStages>(std::move(msg->DependencyGraph), nullptr); + } else { + auto *update = msg->Update.Get(); + Y_VERIFY(update->IsSnapshot); Y_VERIFY(!update->NeedFollowerGcAck); - - if (auto logl = Steps->Logger()->Log(ELnLev::Debug)) - logl + + if (auto logl = Steps->Logger()->Log(ELnLev::Debug)) + logl << NFmt::Do(State()) << " start follower from log" << " snapshot " << State().Generation << ":" << update->Step; - - TString body; - TVector<TLogoBlobID> logo; - logo.reserve(update->References.size()); - - for (const auto &blob : update->References) { - logo.emplace_back(blob.first); - body.append(blob.second); - } - + + TString body; + TVector<TLogoBlobID> logo; + logo.reserve(update->References.size()); + + for (const auto &blob : update->References) { + logo.emplace_back(blob.first); + body.append(blob.second); + } + const auto span = NPageCollection::TGroupBlobsByCookie(logo).Do(); const auto largeGlobId = NPageCollection::TGroupBlobsByCookie::ToLargeGlobId(span, GetBSGroupFor(logo[0])); - Y_VERIFY(span.size() == update->References.size()); - Y_VERIFY(TCookie(logo[0].Cookie()).Type() == TCookie::EType::Log); + Y_VERIFY(span.size() == update->References.size()); + Y_VERIFY(TCookie(logo[0].Cookie()).Type() == TCookie::EType::Log); Y_VERIFY(largeGlobId, "Cannot make TLargeGlobId for snapshot"); Steps->Spawn<NBoot::TStages>(nullptr, new NBoot::TBody{ largeGlobId, std::move(body) }); - } - - Steps->Execute(); - - return CheckCompletion(); -} - -TExecutorBootLogic::EOpResult TExecutorBootLogic::ReceiveBoot( - TEvTablet::TEvBoot::TPtr &ev, + } + + Steps->Execute(); + + return CheckCompletion(); +} + +TExecutorBootLogic::EOpResult TExecutorBootLogic::ReceiveBoot( + TEvTablet::TEvBoot::TPtr &ev, TExecutorCaches &&caches) -{ +{ PrepareEnv(false, ev->Get()->Generation, std::move(caches)); Steps->Spawn<NBoot::TStages>(std::move(ev->Get()->DependencyGraph), nullptr); - Steps->Execute(); - - return CheckCompletion(); -} - + Steps->Execute(); + + return CheckCompletion(); +} + void TExecutorBootLogic::PrepareEnv(bool follower, ui32 gen, TExecutorCaches caches) noexcept { BootStartTime = TAppData::TimeProvider->Now(); @@ -189,62 +189,62 @@ ui32 TExecutorBootLogic::GetBSGroupFor(const TLogoBlobID &logo) const { return info->GroupFor(logo.Channel(), logo.Generation()); } -ui32 TExecutorBootLogic::GetBSGroupID(ui32 channel, ui32 generation) { - if (generation != GroupResolveCachedGeneration || channel != GroupResolveCachedChannel) { - GroupResolveCachedChannel = channel; - GroupResolveCachedGeneration = generation; +ui32 TExecutorBootLogic::GetBSGroupID(ui32 channel, ui32 generation) { + if (generation != GroupResolveCachedGeneration || channel != GroupResolveCachedChannel) { + GroupResolveCachedChannel = channel; + GroupResolveCachedGeneration = generation; GroupResolveCachedGroup = Info->GroupFor(channel, generation); - } - - return GroupResolveCachedGroup; -} - + } + + return GroupResolveCachedGroup; +} + TExecutorBootLogic::EOpResult TExecutorBootLogic::CheckCompletion() { if (LoadBlobQueue.SendRequests(SelfId)) return OpResultContinue; - + Y_VERIFY(EntriesToLoad.empty()); - + if (Steps && !Steps->Alone()) return OpResultContinue; if (Loads) - return OpResultContinue; - + return OpResultContinue; + if (State().Follower || Restored) { if (auto logl = Steps->Logger()->Log(ELnLev::Info)) { auto spent = TAppData::TimeProvider->Now() - BootStartTime; - + logl << NFmt::Do(State()) << " booting completed" << ", took " << NFmt::TDelay(spent); } - return OpResultComplete; - } - - return OpResultContinue; -} - + return OpResultComplete; + } + + return OpResultContinue; +} + TExecutorBootLogic::EOpResult TExecutorBootLogic::ReceiveRestored(TEvTablet::TEvRestored::TPtr &ev) { Y_UNUSED(ev); - Restored = true; + Restored = true; return CheckCompletion(); -} - +} + void TExecutorBootLogic::OnBlobLoaded(const TLogoBlobID& id, TString body, uintptr_t cookie) { Y_UNUSED(cookie); auto it = EntriesToLoad.find(id); - + Y_VERIFY(it != EntriesToLoad.end(), "OnBlobLoaded with unexpected blob id %s", id.ToString().c_str()); - + auto entry = std::move(it->second); EntriesToLoad.erase(it); - + entry->Feed(id, std::move(body)); entry.Reset(); @@ -259,56 +259,56 @@ TExecutorBootLogic::EOpResult TExecutorBootLogic::Receive(::NActors::IEventHandl } else if (auto *msg = ev.CastAsLocal<NSharedCache::TEvResult>()) { if (EPageCollectionRequest(ev.Cookie) != EPageCollectionRequest::BootLogic) - return OpResultUnhandled; - + return OpResultUnhandled; + auto it = Loads.find(msg->Origin.Get()); if (it == Loads.end()) // could receive outdated results - return OpResultUnhandled; + return OpResultUnhandled; // Remove step from loads first (so HandleBio may request more pages) auto step = std::move(it->second); Loads.erase(it); - if (msg->Status == NKikimrProto::NODATA) { - GetServiceCounters(AppData()->Counters, "tablets")->GetCounter("alerts_boot_nodata", true)->Inc(); - } - + if (msg->Status == NKikimrProto::NODATA) { + GetServiceCounters(AppData()->Counters, "tablets")->GetCounter("alerts_boot_nodata", true)->Inc(); + } + if (!step->HandleBio(*msg)) - return OpResultBroken; - + return OpResultBroken; + step.Drop(); Steps->Execute(); } else { - return OpResultUnhandled; - } + return OpResultUnhandled; + } return CheckCompletion(); -} - +} + TAutoPtr<NBoot::TResult> TExecutorBootLogic::ExtractState() noexcept { Y_VERIFY(Result_->Database, "Looks like booting hasn't been done"); return Result_; -} - +} + void TExecutorBootLogic::Cancel() { -} - +} + void TExecutorBootLogic::FollowersSyncComplete() { Y_VERIFY(Result_); Y_VERIFY(Result().GcLogic); Result().GcLogic->FollowersSyncComplete(true); -} - +} + TExecutorCaches TExecutorBootLogic::DetachCaches() { if (Result_) { for (auto &x : Result().PageCaches) State().PageCaches[x->Id] = x; - } + } return TExecutorCaches{ .PageCaches = std::move(State().PageCaches), .TxStatusCaches = std::move(State().TxStatusCaches), }; -} - -}} - +} + +}} + diff --git a/ydb/core/tablet_flat/flat_executor_bootlogic.h b/ydb/core/tablet_flat/flat_executor_bootlogic.h index 662fe9835f..34edb2d6b4 100644 --- a/ydb/core/tablet_flat/flat_executor_bootlogic.h +++ b/ydb/core/tablet_flat/flat_executor_bootlogic.h @@ -1,13 +1,13 @@ -#pragma once -#include "defs.h" -#include "flat_executor.h" +#pragma once +#include "defs.h" +#include "flat_executor.h" #include "flat_boot_cookie.h" #include "flat_boot_util.h" #include "flat_load_blob_queue.h" - -namespace NKikimr { -namespace NTabletFlatExecutor { - + +namespace NKikimr { +namespace NTabletFlatExecutor { + class TCommitManager; namespace NBoot { @@ -53,46 +53,46 @@ class TExecutorBootLogic friend class NBoot::TAlter; friend class NBoot::TTurns; friend class NBoot::TSnap; -public: - enum EOpResult { - OpResultUnhandled, - OpResultContinue, - OpResultBroken, - OpResultComplete, - }; - -private: +public: + enum EOpResult { + OpResultUnhandled, + OpResultContinue, + OpResultBroken, + OpResultComplete, + }; + +private: using ELnLev = NUtil::ELnLev; using IOps = NActors::IActorOps; using TCookie = NBoot::TCookie; - -private: + +private: bool Restored = false; - + IOps * const Ops = nullptr; const TActorId SelfId; TAutoPtr<NBoot::TBack> State_; TAutoPtr<NBoot::TResult> Result_; TAutoPtr<NBoot::TRoot> Steps; - TInstant BootStartTime; - + TInstant BootStartTime; + const TIntrusiveConstPtr<TTabletStorageInfo> Info; - + TLoadBlobQueue LoadBlobQueue; - + THashMap<TLogoBlobID, TIntrusivePtr<NBoot::TLoadBlobs>> EntriesToLoad; THashMap<const NPageCollection::IPageCollection*, TIntrusivePtr<NBoot::IStep>> Loads; - - ui32 GroupResolveCachedChannel; - ui32 GroupResolveCachedGeneration; - ui32 GroupResolveCachedGroup; - + + ui32 GroupResolveCachedChannel; + ui32 GroupResolveCachedGeneration; + ui32 GroupResolveCachedGroup; + EOpResult CheckCompletion(); - + void PrepareEnv(bool follower, ui32 generation, TExecutorCaches caches) noexcept; ui32 GetBSGroupFor(const TLogoBlobID &logo) const; - ui32 GetBSGroupID(ui32 channel, ui32 generation); + ui32 GetBSGroupID(ui32 channel, ui32 generation); void LoadEntry(TIntrusivePtr<NBoot::TLoadBlobs>); NBoot::TSpawned LoadPages(NBoot::IStep*, TAutoPtr<NPageCollection::TFetch> req); @@ -101,22 +101,22 @@ private: inline NBoot::TResult& Result() const noexcept { return *Result_; } inline NBoot::TBack& State() const noexcept { return *State_; } -public: +public: TExecutorBootLogic(IOps*, const TActorId&, TTabletStorageInfo *info, ui64 maxBytesInFly); - ~TExecutorBootLogic(); - + ~TExecutorBootLogic(); + void Describe(IOutputStream&) const noexcept; EOpResult ReceiveBoot(TEvTablet::TEvBoot::TPtr &ev, TExecutorCaches &&caches); EOpResult ReceiveFollowerBoot(TEvTablet::TEvFBoot::TPtr &ev, TExecutorCaches &&caches); EOpResult ReceiveRestored(TEvTablet::TEvRestored::TPtr &ev); EOpResult Receive(::NActors::IEventHandle&); - + void FollowersSyncComplete(); void Cancel(); - + TAutoPtr<NBoot::TResult> ExtractState() noexcept; - + TExecutorCaches DetachCaches(); -}; - -}} +}; + +}} diff --git a/ydb/core/tablet_flat/flat_executor_borrowlogic.cpp b/ydb/core/tablet_flat/flat_executor_borrowlogic.cpp index 4a385f25a7..bd52264b10 100644 --- a/ydb/core/tablet_flat/flat_executor_borrowlogic.cpp +++ b/ydb/core/tablet_flat/flat_executor_borrowlogic.cpp @@ -1,85 +1,85 @@ -#include "flat_executor_borrowlogic.h" +#include "flat_executor_borrowlogic.h" #include "flat_bio_eggs.h" - + #include <library/cpp/monlib/service/pages/templates.h> -#include <util/generic/xrange.h> -#include <util/string/builder.h> - -namespace NKikimr { -namespace NTabletFlatExecutor { - +#include <util/generic/xrange.h> +#include <util/string/builder.h> + +namespace NKikimr { +namespace NTabletFlatExecutor { + TExecutorBorrowLogic::TExecutorBorrowLogic(TAutoPtr<NPageCollection::TSteppedCookieAllocator> cookies) : SelfTabletId(cookies ? cookies->Tablet : 0) , Cookies(cookies) , Slicer(1, Cookies.Get(), NBlockIO::BlockSize) - , HasFlag(false) -{} - -void TExecutorBorrowLogic::UpdateStorageInfo(TTabletStorageInfo *update) { - auto itpair = ReferencedStorageInfos.insert(std::make_pair(update->TabletID, update)); - if (!itpair.second) { - TIntrusivePtr<TTabletStorageInfo> &stored = itpair.first->second; - if (*stored < *update) - stored = update; - } -} - -void TExecutorBorrowLogic::FillBorrowProto( - const TLogoBlobID &metaId, - NKikimrExecutorFlat::TBorrowedPart &proto, - const TBorrowedPartInfo &storedInfo) -{ + , HasFlag(false) +{} + +void TExecutorBorrowLogic::UpdateStorageInfo(TTabletStorageInfo *update) { + auto itpair = ReferencedStorageInfos.insert(std::make_pair(update->TabletID, update)); + if (!itpair.second) { + TIntrusivePtr<TTabletStorageInfo> &stored = itpair.first->second; + if (*stored < *update) + stored = update; + } +} + +void TExecutorBorrowLogic::FillBorrowProto( + const TLogoBlobID &metaId, + NKikimrExecutorFlat::TBorrowedPart &proto, + const TBorrowedPartInfo &storedInfo) +{ LogoBlobIDFromLogoBlobID(metaId, proto.MutableMetaId()); - - if (storedInfo.BorrowInfo.FullBorrow) { - proto.MutableLoaners()->Reserve(storedInfo.BorrowInfo.FullBorrow.size()); - for (ui64 x : storedInfo.BorrowInfo.FullBorrow) - proto.AddLoaners(x); - } - - if (storedInfo.BorrowInfo.Keep) { - proto.MutableBorrowKeepList()->Reserve(storedInfo.BorrowInfo.Keep.size()); - for (const auto &x : storedInfo.BorrowInfo.Keep) - LogoBlobIDFromLogoBlobID(x, proto.AddBorrowKeepList()); - } - - // we don't fill borrowed list for now (as we don't keep referenced blobs) - - if (storedInfo.LoanInfo.Lender) { - proto.SetLender(storedInfo.LoanInfo.Lender); - + + if (storedInfo.BorrowInfo.FullBorrow) { + proto.MutableLoaners()->Reserve(storedInfo.BorrowInfo.FullBorrow.size()); + for (ui64 x : storedInfo.BorrowInfo.FullBorrow) + proto.AddLoaners(x); + } + + if (storedInfo.BorrowInfo.Keep) { + proto.MutableBorrowKeepList()->Reserve(storedInfo.BorrowInfo.Keep.size()); + for (const auto &x : storedInfo.BorrowInfo.Keep) + LogoBlobIDFromLogoBlobID(x, proto.AddBorrowKeepList()); + } + + // we don't fill borrowed list for now (as we don't keep referenced blobs) + + if (storedInfo.LoanInfo.Lender) { + proto.SetLender(storedInfo.LoanInfo.Lender); + if (auto *info = storedInfo.LoanInfo.StorageInfo.Get()) TabletStorageInfoToProto(*info, proto.AddStorageInfo()); - if (storedInfo.LoanInfo.Collected) { - proto.SetLoanCollected(true); - if (storedInfo.LoanInfo.Keep) { - proto.MutableLoanKeepList()->Reserve(storedInfo.LoanInfo.Keep.size()); - for (const auto &x : storedInfo.LoanInfo.Keep) - LogoBlobIDFromLogoBlobID(x, proto.AddLoanKeepList()); - } - } - } -} - + if (storedInfo.LoanInfo.Collected) { + proto.SetLoanCollected(true); + if (storedInfo.LoanInfo.Keep) { + proto.MutableLoanKeepList()->Reserve(storedInfo.LoanInfo.Keep.size()); + for (const auto &x : storedInfo.LoanInfo.Keep) + LogoBlobIDFromLogoBlobID(x, proto.AddLoanKeepList()); + } + } + } +} + void TExecutorBorrowLogic::StoreBorrowProto( - const TLogoBlobID &metaId, + const TLogoBlobID &metaId, TBorrowedPartInfo &info, TLogCommit *commit) -{ +{ Cookies->Switch(commit->Step, false /* could reuse step */); - NKikimrExecutorFlat::TBorrowedPart proto; + NKikimrExecutorFlat::TBorrowedPart proto; FillBorrowProto(metaId, proto, info); - + auto glob = Slicer.One(commit->Refs, proto.SerializeAsString(), true); commit->GcDelta.Created.push_back(glob.Logo); - + if (auto gone = std::exchange(info.BorrowBlobId, glob.Logo)) Garbage.push_back(gone); -} - +} + bool TExecutorBorrowLogic::BundlePartiallyCompacted( const NTable::IBundle &bundle, const NTable::NFwd::TSieve &sieve, @@ -119,18 +119,18 @@ bool TExecutorBorrowLogic::BundleCompacted( const NTable::IBundle &bundle, const NTable::NFwd::TSieve &sieve, TLogCommit *commit) -{ +{ const TLogoBlobID &metaId = bundle.BundleId(); - TBorrowedPartInfo *info = BorrowedInfo.FindPtr(metaId); - if (info == nullptr) - return true; - + TBorrowedPartInfo *info = BorrowedInfo.FindPtr(metaId); + if (info == nullptr) + return true; + // 1. if bundle borrowed - keep blobs non-collected - if (info->BorrowInfo.FullBorrow) { + if (info->BorrowInfo.FullBorrow) { Y_VERIFY(!info->BorrowInfo.HasKeep(bundle.BundleId()), "Trying to compact the same page collection twice"); - if (SelfTabletId == metaId.TabletID()) { + if (SelfTabletId == metaId.TabletID()) { sieve.MaterializeTo(info->BorrowInfo.Keep); bundle.SaveAllBlobIdsTo(info->BorrowInfo.Keep); @@ -139,23 +139,23 @@ bool TExecutorBorrowLogic::BundleCompacted( Y_VERIFY(end == info->BorrowInfo.Keep.end(), "Unexpected duplicates in compacted blobs"); KeepBytes += info->BorrowInfo.UpdateKeepBytes(); - } - } - - if (info->LoanInfo.Lender) { - info->LoanInfo.Collected = true; - } - + } + } + + if (info->LoanInfo.Lender) { + info->LoanInfo.Collected = true; + } + CheckLoanCompletion(metaId, *info, commit->Step); Y_VERIFY(commit->WaitFollowerGcAck); - - // must be loaned or borrowed (otherwise would be not on list) - // in this case - changes must be propagated to lender before cleanup + + // must be loaned or borrowed (otherwise would be not on list) + // in this case - changes must be propagated to lender before cleanup // in that case - loaner must detach from borrowed bundle and we must keep blobs non-collect awhile StoreBorrowProto(metaId, *info, commit); - return false; -} - + return false; +} + bool TExecutorBorrowLogic::BundleCompacted( const NTable::IBorrowBundle &bundle, TLogCommit *commit) @@ -222,15 +222,15 @@ void TExecutorBorrowLogic::BorrowBundle( const TLogoBlobID &bundleId, const TSet<ui64> &loaners, TLogCommit *commit) -{ +{ auto storedInfoItPair = BorrowedInfo.insert(std::make_pair(bundleId, TBorrowedPartInfo())); - HasFlag = true; - - TBorrowedPartInfo &storedInfo = storedInfoItPair.first->second; - + HasFlag = true; + + TBorrowedPartInfo &storedInfo = storedInfoItPair.first->second; + Y_VERIFY(!(storedInfo.LoanInfo.Lender && storedInfo.LoanInfo.Collected), "Sanity check: trying to borrow a compacted bundle"); - + // It is possible to borrow partially compacted bundles, in which case // keep list might not be empty. However, if bundle has been fully // compacted keep list would contain bundleId and it is possible @@ -238,37 +238,37 @@ void TExecutorBorrowLogic::BorrowBundle( Y_VERIFY(!storedInfo.BorrowInfo.HasKeep(bundleId), "Sanity check: trying to borrow a compacted bundle"); - auto &fullBorrow = storedInfo.BorrowInfo.FullBorrow; - fullBorrow.insert( // not replace as some borrows could exist - fullBorrow.end(), - loaners.begin(), - loaners.end()); - - Sort(fullBorrow); + auto &fullBorrow = storedInfo.BorrowInfo.FullBorrow; + fullBorrow.insert( // not replace as some borrows could exist + fullBorrow.end(), + loaners.begin(), + loaners.end()); + + Sort(fullBorrow); // !!HACK: Allow to borrow the same bundle multiple times //Y_VERIFY(std::adjacent_find(fullBorrow.begin(), fullBorrow.end()) == fullBorrow.end()); fullBorrow.erase(std::unique(fullBorrow.begin(), fullBorrow.end()), fullBorrow.end()); - + StoreBorrowProto(bundleId, storedInfo, commit); -} - +} + void TExecutorBorrowLogic::LoanBundle( const TLogoBlobID &bundleId, TPageCollectionTxEnv::TLoanBundle &loaned, TLogCommit *commit) -{ +{ auto storedInfoItPair = BorrowedInfo.insert(std::make_pair(bundleId, TBorrowedPartInfo())); Y_VERIFY(storedInfoItPair.second, "must not back-borrow parts at %" PRIu64 " part owner %" PRIu64 " existing loan from %" PRIu64 " new loan from %" PRIu64, SelfTabletId, bundleId.TabletID(), storedInfoItPair.first->second.LoanInfo.Lender, loaned.Lender); - HasFlag = true; - - TBorrowedPartInfo &storedInfo = storedInfoItPair.first->second; + HasFlag = true; + + TBorrowedPartInfo &storedInfo = storedInfoItPair.first->second; storedInfo.LoanInfo.Lender = loaned.Lender; - + StoreBorrowProto(bundleId, storedInfo, commit); -} - +} + void TExecutorBorrowLogic::LoanTxStatus( const TLogoBlobID &bundleId, TPageCollectionTxEnv::TLoanTxStatus &loaned, @@ -289,283 +289,283 @@ void TExecutorBorrowLogic::LoanTxStatus( void TExecutorBorrowLogic::SnapToLog(NKikimrExecutorFlat::TLogSnapshot &snap, TLogCommit &commit) { snap.MutableBorrowInfoIds()->Reserve(BorrowedInfo.size()); - for (auto &xpair : BorrowedInfo) + for (auto &xpair : BorrowedInfo) LogoBlobIDFromLogoBlobID(xpair.second.BorrowBlobId, snap.AddBorrowInfoIds()); - + commit.GcDelta.Deleted.insert( commit.GcDelta.Deleted.end(), Garbage.begin(), Garbage.end()); Garbage.clear(); -} - +} + const THashMap<TLogoBlobID, TCompactedPartLoans>* TExecutorBorrowLogic::GetCompactedLoansList() { - return &CompactedPartLoans; -} - -const bool* TExecutorBorrowLogic::GetHasFlag() { - return &HasFlag; -} - -bool TExecutorBorrowLogic::CheckLoanCompletion(const TLogoBlobID &metaId, TBorrowedPartInfo &storedInfo, ui32 step) { - if (metaId.TabletID() == SelfTabletId) // produced by ourselves, could not be loaned - return false; - - if (storedInfo.BorrowInfo.FullBorrow - || storedInfo.BorrowInfo.Keep - || !storedInfo.LoanInfo.Lender - || !storedInfo.LoanInfo.Collected) - return false; - - // zero to signal "from restore, apply right now - // for new changes wait for step commit - if (step == 0) { - auto &x = CompactedPartLoans[metaId]; - x.MetaInfoId = metaId; - x.Lender = storedInfo.LoanInfo.Lender; - } else { - if (PendingCompactedPartLoans.empty() || PendingCompactedPartLoans.back().BindStep != step) { - PendingCompactedPartLoans.emplace_back(); - auto &x = PendingCompactedPartLoans.back(); - x.BindStep = step; - } - PendingCompactedPartLoans.back().Parts.emplace_back(metaId, storedInfo.LoanInfo.Lender); - } - - return true; -} - -bool TExecutorBorrowLogic::SetGcBarrier(ui32 step) { - bool somethingChanged = false; - while (!PendingCompactedPartLoans.empty()) { - auto &x = PendingCompactedPartLoans.front(); - if (x.BindStep > step) - break; - - for (auto &compactedPart : x.Parts) - CompactedPartLoans.emplace(compactedPart.MetaInfoId, std::move(compactedPart)); - - somethingChanged = true; - PendingCompactedPartLoans.pop_front(); - } - - HasFlag = !BorrowedInfo.empty(); - return somethingChanged; -} - + return &CompactedPartLoans; +} + +const bool* TExecutorBorrowLogic::GetHasFlag() { + return &HasFlag; +} + +bool TExecutorBorrowLogic::CheckLoanCompletion(const TLogoBlobID &metaId, TBorrowedPartInfo &storedInfo, ui32 step) { + if (metaId.TabletID() == SelfTabletId) // produced by ourselves, could not be loaned + return false; + + if (storedInfo.BorrowInfo.FullBorrow + || storedInfo.BorrowInfo.Keep + || !storedInfo.LoanInfo.Lender + || !storedInfo.LoanInfo.Collected) + return false; + + // zero to signal "from restore, apply right now + // for new changes wait for step commit + if (step == 0) { + auto &x = CompactedPartLoans[metaId]; + x.MetaInfoId = metaId; + x.Lender = storedInfo.LoanInfo.Lender; + } else { + if (PendingCompactedPartLoans.empty() || PendingCompactedPartLoans.back().BindStep != step) { + PendingCompactedPartLoans.emplace_back(); + auto &x = PendingCompactedPartLoans.back(); + x.BindStep = step; + } + PendingCompactedPartLoans.back().Parts.emplace_back(metaId, storedInfo.LoanInfo.Lender); + } + + return true; +} + +bool TExecutorBorrowLogic::SetGcBarrier(ui32 step) { + bool somethingChanged = false; + while (!PendingCompactedPartLoans.empty()) { + auto &x = PendingCompactedPartLoans.front(); + if (x.BindStep > step) + break; + + for (auto &compactedPart : x.Parts) + CompactedPartLoans.emplace(compactedPart.MetaInfoId, std::move(compactedPart)); + + somethingChanged = true; + PendingCompactedPartLoans.pop_front(); + } + + HasFlag = !BorrowedInfo.empty(); + return somethingChanged; +} + void TExecutorBorrowLogic::UpdateBorrow( - const TLogoBlobID &metaInfoId, + const TLogoBlobID &metaInfoId, TPageCollectionTxEnv::TBorrowUpdate &borrowUpdate, TLogCommit *commit) -{ - auto storedInfoIt = BorrowedInfo.find(metaInfoId); - if (storedInfoIt == BorrowedInfo.end()) +{ + auto storedInfoIt = BorrowedInfo.find(metaInfoId); + if (storedInfoIt == BorrowedInfo.end()) return; - - bool smthChanged = false; - - TBorrowedPartInfo &storedInfo = storedInfoIt->second; - - for (auto &loaner : borrowUpdate.StoppedLoans) { - const auto it = std::find(storedInfo.BorrowInfo.FullBorrow.begin(), storedInfo.BorrowInfo.FullBorrow.end(), loaner); - if (it == storedInfo.BorrowInfo.FullBorrow.end()) - continue; - - smthChanged = true; - if (storedInfo.BorrowInfo.FullBorrow.size() == 1) { + + bool smthChanged = false; + + TBorrowedPartInfo &storedInfo = storedInfoIt->second; + + for (auto &loaner : borrowUpdate.StoppedLoans) { + const auto it = std::find(storedInfo.BorrowInfo.FullBorrow.begin(), storedInfo.BorrowInfo.FullBorrow.end(), loaner); + if (it == storedInfo.BorrowInfo.FullBorrow.end()) + continue; + + smthChanged = true; + if (storedInfo.BorrowInfo.FullBorrow.size() == 1) { TVector<ui64>().swap(storedInfo.BorrowInfo.FullBorrow); - if (storedInfo.BorrowInfo.Keep) { + if (storedInfo.BorrowInfo.Keep) { commit->GcDelta.Deleted.insert( commit->GcDelta.Deleted.end(), - storedInfo.BorrowInfo.Keep.begin(), - storedInfo.BorrowInfo.Keep.end()); + storedInfo.BorrowInfo.Keep.begin(), + storedInfo.BorrowInfo.Keep.end()); TVector<TLogoBlobID>().swap(storedInfo.BorrowInfo.Keep); KeepBytes += storedInfo.BorrowInfo.UpdateKeepBytes(); - } - } else { - *it = storedInfo.BorrowInfo.FullBorrow.back(); - storedInfo.BorrowInfo.FullBorrow.crop(storedInfo.BorrowInfo.FullBorrow.size() - 1); - } - } - - if (!smthChanged) // if nothing changes - nothing to change + } + } else { + *it = storedInfo.BorrowInfo.FullBorrow.back(); + storedInfo.BorrowInfo.FullBorrow.crop(storedInfo.BorrowInfo.FullBorrow.size() - 1); + } + } + + if (!smthChanged) // if nothing changes - nothing to change return; - - if (metaInfoId.TabletID() == SelfTabletId) { - // could not be loaned, so if complete - could be erased + + if (metaInfoId.TabletID() == SelfTabletId) { + // could not be loaned, so if complete - could be erased StoreBorrowProto(metaInfoId, storedInfo, commit); - - if (storedInfo.BorrowInfo.FullBorrow.empty()) { + + if (storedInfo.BorrowInfo.FullBorrow.empty()) { Garbage.push_back(storedInfo.BorrowBlobId); - BorrowedInfo.erase(storedInfoIt); - HasFlag = !BorrowedInfo.empty(); - } - } else { - // if not local - must be loaned + BorrowedInfo.erase(storedInfoIt); + HasFlag = !BorrowedInfo.empty(); + } + } else { + // if not local - must be loaned CheckLoanCompletion(metaInfoId, storedInfo, commit->Step); StoreBorrowProto(metaInfoId, storedInfo, commit); Y_VERIFY(commit->WaitFollowerGcAck); - } -} - + } +} + void TExecutorBorrowLogic::ConfirmUpdateLoan( - const TLogoBlobID &metaInfoId, - const TLogoBlobID &borrowId, + const TLogoBlobID &metaInfoId, + const TLogoBlobID &borrowId, TLogCommit *commit) -{ - auto storedInfoIt = BorrowedInfo.find(metaInfoId); - if (storedInfoIt == BorrowedInfo.end()) +{ + auto storedInfoIt = BorrowedInfo.find(metaInfoId); + if (storedInfoIt == BorrowedInfo.end()) return; - - Y_UNUSED(borrowId); - - TBorrowedPartInfo &storedInfo = storedInfoIt->second; - - //if (storedInfo.BorrowBlobId != borrowId) + + Y_UNUSED(borrowId); + + TBorrowedPartInfo &storedInfo = storedInfoIt->second; + + //if (storedInfo.BorrowBlobId != borrowId) // return; - - //if (storedInfo.LoanInfo.Lender == 0) // already confirmed, nothing to update + + //if (storedInfo.LoanInfo.Lender == 0) // already confirmed, nothing to update // return; - - Y_VERIFY(storedInfo.LoanInfo.Collected, "must not stop loan for non-collected parts"); - Y_VERIFY(!storedInfo.BorrowInfo.FullBorrow, "must not stop loan for borrowed parts"); - - // todo: merge - in such case we could loan part from different lenders. - // so naive approach would not work - - storedInfo.LoanInfo.Lender = 0; + + Y_VERIFY(storedInfo.LoanInfo.Collected, "must not stop loan for non-collected parts"); + Y_VERIFY(!storedInfo.BorrowInfo.FullBorrow, "must not stop loan for borrowed parts"); + + // todo: merge - in such case we could loan part from different lenders. + // so naive approach would not work + + storedInfo.LoanInfo.Lender = 0; StoreBorrowProto(metaInfoId, storedInfo, commit); - + Garbage.push_back(storedInfo.BorrowBlobId); - BorrowedInfo.erase(storedInfoIt); - CompactedPartLoans.erase(metaInfoId); - - HasFlag = !BorrowedInfo.empty(); -} - + BorrowedInfo.erase(storedInfoIt); + CompactedPartLoans.erase(metaInfoId); + + HasFlag = !BorrowedInfo.empty(); +} + void TExecutorBorrowLogic::RestoreFollowerBorrowedInfo(const TLogoBlobID &blobId, const NKikimrExecutorFlat::TBorrowedPart &proto) { - Y_UNUSED(blobId); + Y_UNUSED(blobId); const TLogoBlobID metaInfoId = LogoBlobIDFromLogoBlobID(proto.GetMetaId()); - - if (proto.HasLender()) { - auto storedInfoItPair = BorrowedInfo.insert(std::make_pair(metaInfoId, TBorrowedPartInfo())); - TBorrowedPartInfo &storedInfo = storedInfoItPair.first->second; - - storedInfo.LoanInfo.Lender = proto.GetLender(); + + if (proto.HasLender()) { + auto storedInfoItPair = BorrowedInfo.insert(std::make_pair(metaInfoId, TBorrowedPartInfo())); + TBorrowedPartInfo &storedInfo = storedInfoItPair.first->second; + + storedInfo.LoanInfo.Lender = proto.GetLender(); if (proto.StorageInfoSize() > 0) { Y_VERIFY(proto.StorageInfoSize() == 1); storedInfo.LoanInfo.StorageInfo = TabletStorageInfoFromProto(proto.GetStorageInfo(0)); UpdateStorageInfo(storedInfo.LoanInfo.StorageInfo.Get()); } - } - - // as part switch could be pending - we could not drop info right now - // and in reality we never drop info until reloading - it's simpler to keep some (limited in number) deprecated infos -} - -void TExecutorBorrowLogic::RestoreBorrowedInfo(const TLogoBlobID &blobId, const NKikimrExecutorFlat::TBorrowedPart &proto) { + } + + // as part switch could be pending - we could not drop info right now + // and in reality we never drop info until reloading - it's simpler to keep some (limited in number) deprecated infos +} + +void TExecutorBorrowLogic::RestoreBorrowedInfo(const TLogoBlobID &blobId, const NKikimrExecutorFlat::TBorrowedPart &proto) { const TLogoBlobID metaInfoId = LogoBlobIDFromLogoBlobID(proto.GetMetaId()); - - auto storedInfoItPair = BorrowedInfo.insert(std::make_pair(metaInfoId, TBorrowedPartInfo())); - TBorrowedPartInfo &storedInfo = storedInfoItPair.first->second; - - if (!storedInfoItPair.second) { - Y_VERIFY(blobId > storedInfo.BorrowBlobId); + + auto storedInfoItPair = BorrowedInfo.insert(std::make_pair(metaInfoId, TBorrowedPartInfo())); + TBorrowedPartInfo &storedInfo = storedInfoItPair.first->second; + + if (!storedInfoItPair.second) { + Y_VERIFY(blobId > storedInfo.BorrowBlobId); Garbage.push_back(storedInfo.BorrowBlobId); KeepBytes -= storedInfo.BorrowInfo.KeepBytes; - storedInfo = TBorrowedPartInfo(); - } - - storedInfo.BorrowBlobId = blobId; - - if (proto.LoanersSize()) { - storedInfo.BorrowInfo.FullBorrow.insert( - storedInfo.BorrowInfo.FullBorrow.end(), - proto.GetLoaners().begin(), - proto.GetLoaners().end()); - } - - // we don't fill and use borrowed list for now - - if (proto.BorrowKeepListSize()) { - storedInfo.BorrowInfo.Keep.reserve(proto.BorrowKeepListSize()); - for (const auto &x : proto.GetBorrowKeepList()) - storedInfo.BorrowInfo.Keep.emplace_back(LogoBlobIDFromLogoBlobID(x)); + storedInfo = TBorrowedPartInfo(); + } + + storedInfo.BorrowBlobId = blobId; + + if (proto.LoanersSize()) { + storedInfo.BorrowInfo.FullBorrow.insert( + storedInfo.BorrowInfo.FullBorrow.end(), + proto.GetLoaners().begin(), + proto.GetLoaners().end()); + } + + // we don't fill and use borrowed list for now + + if (proto.BorrowKeepListSize()) { + storedInfo.BorrowInfo.Keep.reserve(proto.BorrowKeepListSize()); + for (const auto &x : proto.GetBorrowKeepList()) + storedInfo.BorrowInfo.Keep.emplace_back(LogoBlobIDFromLogoBlobID(x)); KeepBytes += storedInfo.BorrowInfo.UpdateKeepBytes(); - } - - if (proto.HasLender()) { - storedInfo.LoanInfo.Lender = proto.GetLender(); + } + + if (proto.HasLender()) { + storedInfo.LoanInfo.Lender = proto.GetLender(); if (proto.StorageInfoSize() > 0) { Y_VERIFY(proto.StorageInfoSize() == 1); storedInfo.LoanInfo.StorageInfo = TabletStorageInfoFromProto(proto.GetStorageInfo(0)); UpdateStorageInfo(storedInfo.LoanInfo.StorageInfo.Get()); } - } - - storedInfo.LoanInfo.Collected = proto.HasLoanCollected() && proto.GetLoanCollected(); - if (proto.LoanKeepListSize()) { - storedInfo.LoanInfo.Keep.reserve(proto.LoanKeepListSize()); - for (const auto &x : proto.GetLoanKeepList()) - storedInfo.LoanInfo.Keep.emplace_back(LogoBlobIDFromLogoBlobID(x)); - } - - if (!storedInfo.BorrowInfo.FullBorrow - // todo: partial borrow - && !storedInfo.LoanInfo.Lender) - { + } + + storedInfo.LoanInfo.Collected = proto.HasLoanCollected() && proto.GetLoanCollected(); + if (proto.LoanKeepListSize()) { + storedInfo.LoanInfo.Keep.reserve(proto.LoanKeepListSize()); + for (const auto &x : proto.GetLoanKeepList()) + storedInfo.LoanInfo.Keep.emplace_back(LogoBlobIDFromLogoBlobID(x)); + } + + if (!storedInfo.BorrowInfo.FullBorrow + // todo: partial borrow + && !storedInfo.LoanInfo.Lender) + { Garbage.push_back(storedInfo.BorrowBlobId); - BorrowedInfo.erase(storedInfoItPair.first); - CompactedPartLoans.erase(metaInfoId); - } else { - CheckLoanCompletion(metaInfoId, storedInfo, 0); - } - - HasFlag = !BorrowedInfo.empty(); -} - + BorrowedInfo.erase(storedInfoItPair.first); + CompactedPartLoans.erase(metaInfoId); + } else { + CheckLoanCompletion(metaInfoId, storedInfo, 0); + } + + HasFlag = !BorrowedInfo.empty(); +} + void TExecutorBorrowLogic::OutputHtml(IOutputStream &out) { HTML(out) { H4() {out << "Borrowed parts";} PRE() { - for (const auto &xpair : BorrowedInfo) { - if (xpair.second.BorrowInfo.FullBorrow) { - out << xpair.first << ":"; - for (ui64 targetTablet : xpair.second.BorrowInfo.FullBorrow) - out << " " << targetTablet; - out << Endl; - } - } + for (const auto &xpair : BorrowedInfo) { + if (xpair.second.BorrowInfo.FullBorrow) { + out << xpair.first << ":"; + for (ui64 targetTablet : xpair.second.BorrowInfo.FullBorrow) + out << " " << targetTablet; + out << Endl; + } + } } - + H4() {out << "Loaned parts";} PRE() { - for (const auto &xpair : BorrowedInfo) { - if (xpair.second.LoanInfo.Lender) - out << xpair.first << ": " << xpair.second.LoanInfo.Lender; - if (xpair.second.LoanInfo.Collected) - out << " - collected"; - out << Endl; - } + for (const auto &xpair : BorrowedInfo) { + if (xpair.second.LoanInfo.Lender) + out << xpair.first << ": " << xpair.second.LoanInfo.Lender; + if (xpair.second.LoanInfo.Collected) + out << " - collected"; + out << Endl; + } } } -} - -TString TExecutorBorrowLogic::DebugCheckBorrowConsistency(THashSet<TLogoBlobID> &knownBundles) { - TStringBuilder out; - // every non-collected bundle must be known - - for (const auto &xpair : BorrowedInfo) { +} + +TString TExecutorBorrowLogic::DebugCheckBorrowConsistency(THashSet<TLogoBlobID> &knownBundles) { + TStringBuilder out; + // every non-collected bundle must be known + + for (const auto &xpair : BorrowedInfo) { bool collected; - if (xpair.second.LoanInfo.Lender) { + if (xpair.second.LoanInfo.Lender) { collected = xpair.second.LoanInfo.Collected; } else if (xpair.second.BorrowInfo.FullBorrow) { collected = xpair.second.BorrowInfo.HasKeep(xpair.first); } else { out << xpair.first << ": neither borrowed nor loaned. "; continue; - } + } if (collected) { if (knownBundles.contains(xpair.first)) @@ -574,12 +574,12 @@ TString TExecutorBorrowLogic::DebugCheckBorrowConsistency(THashSet<TLogoBlobID> if (!knownBundles.contains(xpair.first)) out << xpair.first << ": non-collected bundle not present in database. "; } - } - - // must be no foreign bundles not tracked by borrow logic - return out; -} - + } + + // must be no foreign bundles not tracked by borrow logic + return out; +} + THashMap<TLogoBlobID, TVector<ui64>> TExecutorBorrowLogic::GetBorrowedParts() const { THashMap<TLogoBlobID, TVector<ui64>> result; for (const auto &xpair : BorrowedInfo) { @@ -593,4 +593,4 @@ THashMap<TLogoBlobID, TVector<ui64>> TExecutorBorrowLogic::GetBorrowedParts() co return result; } -}} +}} diff --git a/ydb/core/tablet_flat/flat_executor_borrowlogic.h b/ydb/core/tablet_flat/flat_executor_borrowlogic.h index a4a8c14a67..5d990b49dc 100644 --- a/ydb/core/tablet_flat/flat_executor_borrowlogic.h +++ b/ydb/core/tablet_flat/flat_executor_borrowlogic.h @@ -1,28 +1,28 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include "flat_fwd_sieve.h" #include "flat_exec_commit.h" #include "flat_executor_tx_env.h" #include "flat_sausage_slicer.h" #include <ydb/core/tablet_flat/flat_executor.pb.h> - -namespace NKikimr { -namespace NTabletFlatExecutor { - -class TExecutorBorrowLogic { - const ui64 SelfTabletId; + +namespace NKikimr { +namespace NTabletFlatExecutor { + +class TExecutorBorrowLogic { + const ui64 SelfTabletId; TAutoPtr<NPageCollection::TSteppedCookieAllocator> Cookies; NPageCollection::TSlicer Slicer; ui64 KeepBytes = 0; - - struct TBorrowedPartInfo { - TLogoBlobID BorrowBlobId; - - struct { // out + + struct TBorrowedPartInfo { + TLogoBlobID BorrowBlobId; + + struct { // out TVector<ui64> FullBorrow; TVector<TLogoBlobID> Keep; ui64 KeepBytes = 0; - + bool HasKeep(const TLogoBlobID &blob) const noexcept { return std::find(Keep.begin(), Keep.end(), blob) != Keep.end(); @@ -36,94 +36,94 @@ class TExecutorBorrowLogic { return KeepBytes - oldKeepBytes; } - // todo: per-borrower keep lists - } BorrowInfo; - - struct { // in - ui64 Lender = 0; - TIntrusivePtr<TTabletStorageInfo> StorageInfo; // todo: must be list with info for every referenced tablet - - bool Collected = false; + // todo: per-borrower keep lists + } BorrowInfo; + + struct { // in + ui64 Lender = 0; + TIntrusivePtr<TTabletStorageInfo> StorageInfo; // todo: must be list with info for every referenced tablet + + bool Collected = false; TVector<TLogoBlobID> Keep; - } LoanInfo; - }; - - struct TCompactedPart { - ui32 BindStep = Max<ui32>(); - TVector<TCompactedPartLoans> Parts; - }; - + } LoanInfo; + }; + + struct TCompactedPart { + ui32 BindStep = Max<ui32>(); + TVector<TCompactedPartLoans> Parts; + }; + THashMap<TLogoBlobID, TBorrowedPartInfo> BorrowedInfo; TDeque<TLogoBlobID> Garbage; - + THashMap<TLogoBlobID, TCompactedPartLoans> CompactedPartLoans; - TDeque<TCompactedPart> PendingCompactedPartLoans; - - bool HasFlag; - + TDeque<TCompactedPart> PendingCompactedPartLoans; + + bool HasFlag; + THashMap<ui64, TIntrusivePtr<TTabletStorageInfo>> ReferencedStorageInfos; - - void UpdateStorageInfo(TTabletStorageInfo *update); - - void FillBorrowProto( - const TLogoBlobID &metaId, - NKikimrExecutorFlat::TBorrowedPart &proto, - const TBorrowedPartInfo &storedInfo); - + + void UpdateStorageInfo(TTabletStorageInfo *update); + + void FillBorrowProto( + const TLogoBlobID &metaId, + NKikimrExecutorFlat::TBorrowedPart &proto, + const TBorrowedPartInfo &storedInfo); + void StoreBorrowProto( - const TLogoBlobID &metaId, - TBorrowedPartInfo &storedInfo, + const TLogoBlobID &metaId, + TBorrowedPartInfo &storedInfo, TLogCommit *commit); - - bool CheckLoanCompletion(const TLogoBlobID &metaId, TBorrowedPartInfo &storedInfo, ui32 step); - -public: + + bool CheckLoanCompletion(const TLogoBlobID &metaId, TBorrowedPartInfo &storedInfo, ui32 step); + +public: TExecutorBorrowLogic(TAutoPtr<NPageCollection::TSteppedCookieAllocator>); - - TTabletStorageInfo* StorageInfoFor(const TLogoBlobID &blobId) { - auto it = ReferencedStorageInfos.find(blobId.TabletID()); - if (it != ReferencedStorageInfos.end()) - return it->second.Get(); - else - return nullptr; - } - + + TTabletStorageInfo* StorageInfoFor(const TLogoBlobID &blobId) { + auto it = ReferencedStorageInfos.find(blobId.TabletID()); + if (it != ReferencedStorageInfos.end()) + return it->second.Get(); + else + return nullptr; + } + ui64 GetKeepBytes() const { return KeepBytes; } - // called on lender at moment of sharing part + // called on lender at moment of sharing part void BorrowBundle( const TLogoBlobID &bundleId, const TSet<ui64> &loaners, TLogCommit *commit); - - // called on loaner at moment of attaching part + + // called on loaner at moment of attaching part void LoanBundle( const TLogoBlobID &bundleId, TPageCollectionTxEnv::TLoanBundle &loaned, TLogCommit *commit); - + // called on loaner at moment of attaching part void LoanTxStatus( const TLogoBlobID &bundleId, TPageCollectionTxEnv::TLoanTxStatus &loaned, TLogCommit *commit); - // called on lender + // called on lender void UpdateBorrow( const TLogoBlobID &bundleId, TPageCollectionTxEnv::TBorrowUpdate &borrowUpdate, TLogCommit *commit); - - // confirmation for loaner + + // confirmation for loaner void ConfirmUpdateLoan( const TLogoBlobID &bundleId, - const TLogoBlobID &borrowId, + const TLogoBlobID &borrowId, TLogCommit *commit); - + void SnapToLog(NKikimrExecutorFlat::TLogSnapshot&, TLogCommit&); - + // returns true if sieve blobs could be collected // returning false means those blobs are still in use bool BundlePartiallyCompacted( @@ -131,13 +131,13 @@ public: const NTable::NFwd::TSieve &sieve, TLogCommit *commit); - // returns true if part blobs could be collected - // returning false means part is still in use + // returns true if part blobs could be collected + // returning false means part is still in use bool BundleCompacted( const NTable::IBundle &bundle, const NTable::NFwd::TSieve &sieve, TLogCommit *commit); - + // returns true if bundle blobs could be collected // returns false when part is still in use bool BundleCompacted( @@ -150,24 +150,24 @@ public: const TLogoBlobID &bundleId, TLogCommit *commit); - // returns true if smth moved to CompactedPartLoands so we need to signal for user tablet - bool SetGcBarrier(ui32 step); - + // returns true if smth moved to CompactedPartLoands so we need to signal for user tablet + bool SetGcBarrier(ui32 step); + const THashMap<TLogoBlobID, TCompactedPartLoans>* GetCompactedLoansList(); - const bool* GetHasFlag(); - - // on bootstrap - void RestoreBorrowedInfo(const TLogoBlobID &blobId, const NKikimrExecutorFlat::TBorrowedPart &proto); - + const bool* GetHasFlag(); + + // on bootstrap + void RestoreBorrowedInfo(const TLogoBlobID &blobId, const NKikimrExecutorFlat::TBorrowedPart &proto); + // for followers void RestoreFollowerBorrowedInfo(const TLogoBlobID &blobId, const NKikimrExecutorFlat::TBorrowedPart &proto); - - // for monitoring + + // for monitoring void OutputHtml(IOutputStream &out); - TString DebugCheckBorrowConsistency(THashSet<TLogoBlobID> &knownBundles); + TString DebugCheckBorrowConsistency(THashSet<TLogoBlobID> &knownBundles); // for cleanup THashMap<TLogoBlobID, TVector<ui64>> GetBorrowedParts() const; -}; - -}} +}; + +}} diff --git a/ydb/core/tablet_flat/flat_executor_compaction_logic.cpp b/ydb/core/tablet_flat/flat_executor_compaction_logic.cpp index 70756363fa..3d699e8f87 100644 --- a/ydb/core/tablet_flat/flat_executor_compaction_logic.cpp +++ b/ydb/core/tablet_flat/flat_executor_compaction_logic.cpp @@ -6,17 +6,17 @@ #include <ydb/core/base/appdata.h> #include <library/cpp/monlib/service/pages/templates.h> -#include <util/generic/cast.h> - +#include <util/generic/cast.h> + namespace NKikimr { namespace NTabletFlatExecutor { -TCompactionLogicState::TSnapRequest::~TSnapRequest() -{} - -TCompactionLogicState::TTableInfo::~TTableInfo() -{} - +TCompactionLogicState::TSnapRequest::~TSnapRequest() +{} + +TCompactionLogicState::TTableInfo::~TTableInfo() +{} + TCompactionLogic::TCompactionLogic(NUtil::ILogger *logger, NTable::IResourceBroker *broker, NTable::ICompactionBackend *backend, @@ -28,11 +28,11 @@ TCompactionLogic::TCompactionLogic(NUtil::ILogger *logger, , Time(TAppData::TimeProvider.Get()) , State(state) , TaskNameSuffix(taskNameSuffix) -{} - -TCompactionLogic::~TCompactionLogic() -{} - +{} + +TCompactionLogic::~TCompactionLogic() +{} + void TCompactionLogic::Start() { auto result = ReflectSchemeChanges(); Y_VERIFY(!result.StrategyChanges); @@ -42,7 +42,7 @@ void TCompactionLogic::Start() { void TCompactionLogic::Stop() { for (auto &kv : State->Tables) { StopTable(kv.second); - } + } State->Tables.clear(); } @@ -105,25 +105,25 @@ TVector<TTableCompactionChanges> TCompactionLogic::ApplyChanges() } void TCompactionLogic::PrepareTableSnapshot(ui32 table, NTable::TSnapEdge edge, TTableSnapshotContext *snapContext) { - TCompactionLogicState::TTableInfo *tableInfo = State->Tables.FindPtr(table); - Y_VERIFY_DEBUG(tableInfo); - TCompactionLogicState::TInMem &inMem = tableInfo->InMem; - + TCompactionLogicState::TTableInfo *tableInfo = State->Tables.FindPtr(table); + Y_VERIFY_DEBUG(tableInfo); + TCompactionLogicState::TInMem &inMem = tableInfo->InMem; + Y_VERIFY(edge.TxStamp != Max<ui64>(), "TxStamp of snapshot is undefined"); - + tableInfo->SnapRequests.emplace_back(TCompactionLogicState::TSnapRequest(edge, snapContext)); - switch (inMem.State) { + switch (inMem.State) { case ECompactionState::Free: SubmitCompactionTask(table, 0, tableInfo->Policy->SnapshotResourceBrokerTask, tableInfo->Policy->DefaultTaskPriority, inMem.CompactionTask); inMem.State = ECompactionState::SnapshotPending; - break; + break; case ECompactionState::Pending: inMem.State = ECompactionState::SnapshotPending; - break; + break; case ECompactionState::PendingBackground: // Replace background compaction with regular snapshot task. UpdateCompactionTask(tableInfo->Policy->SnapshotResourceBrokerTask, @@ -131,11 +131,11 @@ void TCompactionLogic::PrepareTableSnapshot(ui32 table, NTable::TSnapEdge edge, inMem.CompactionTask); inMem.State = ECompactionState::SnapshotPending; break; - default: - break; - } -} - + default: + break; + } +} + bool TCompactionLogic::PrepareForceCompaction() { bool ok = true; for (auto &it : State->Tables) { @@ -460,11 +460,11 @@ void TCompactionLogic::UpdateLogUsage(const NRedo::TUsage &usage) bool TCompactionLogic::BeginMemTableCompaction(ui64 taskId, ui32 tableId) { - TCompactionLogicState::TTableInfo *tableInfo = State->Tables.FindPtr(tableId); + TCompactionLogicState::TTableInfo *tableInfo = State->Tables.FindPtr(tableId); Y_VERIFY(tableInfo, "Unexpected BeginMemTableCompaction(%" PRIu64 ", %" PRIu32 ") for a dropped table", taskId, tableId); - + TCompactionLogicState::TInMem &inMem = tableInfo->InMem; Y_VERIFY(taskId == inMem.CompactionTask.TaskId); @@ -477,7 +477,7 @@ bool TCompactionLogic::BeginMemTableCompaction(ui64 taskId, ui32 tableId) inMem.State = ECompactionState::Compaction; edge.Head = NTable::TEpoch::Max(); break; - + case ECompactionState::SnapshotPending: inMem.CompactingSteps = inMem.Steps; inMem.State = ECompactionState::SnapshotCompaction; @@ -522,22 +522,22 @@ TCompactionLogic::HandleCompaction( const ui32 tableId = params->Table; const auto edge = params->Edge; - TCompactionLogicState::TTableInfo *tableInfo = State->Tables.FindPtr(tableId); + TCompactionLogicState::TTableInfo *tableInfo = State->Tables.FindPtr(tableId); Y_VERIFY(tableInfo, "Unexpected CompleteCompaction for a dropped table"); - + if (compactionId == tableInfo->InMem.CompactionTask.CompactionId) { TCompactionLogicState::TInMem &inMem = tableInfo->InMem; Y_VERIFY(params->TaskId == inMem.CompactionTask.TaskId); - switch (inMem.State) { + switch (inMem.State) { case ECompactionState::Compaction: inMem.Steps -= std::exchange(inMem.CompactingSteps, 0); inMem.State = ECompactionState::Free; inMem.CompactionTask.TaskId = 0; inMem.CompactionTask.CompactionId = 0; - break; + break; case ECompactionState::SnapshotCompaction: - Y_VERIFY(tableInfo->SnapRequests); + Y_VERIFY(tableInfo->SnapRequests); Y_VERIFY(edge == tableInfo->SnapRequests.front().Edge); if (ret) { ret->CompleteSnapshots.push_back(tableInfo->SnapRequests.front().Context); @@ -547,11 +547,11 @@ TCompactionLogic::HandleCompaction( inMem.State = ECompactionState::Free; inMem.CompactionTask.TaskId = 0; inMem.CompactionTask.CompactionId = 0; - break; - default: + break; + default: Y_FAIL("must not happens, state=%d", (int)inMem.State); - } - + } + if (tableInfo->ForcedCompactionState == EForcedCompactionState::CompactingMem) { tableInfo->ForcedCompactionState = EForcedCompactionState::None; } @@ -569,7 +569,7 @@ TCompactionLogic::HandleCompaction( tableInfo->Policy->DefaultTaskPriority, inMem.CompactionTask); inMem.State = ECompactionState::Pending; - } + } if (ret) { // Signal we need UpdateInMemStats call @@ -578,7 +578,7 @@ TCompactionLogic::HandleCompaction( // Maybe schedule another compaction CheckInMemStats(tableId); } - } + } if (tableInfo->ForcedCompactionState == EForcedCompactionState::None) { if (tableInfo->ForcedCompactionQueued) { @@ -617,9 +617,9 @@ TCompactionLogic::CancelledCompaction( void TCompactionLogic::BorrowedPart(ui32 tableId, NTable::TPartView partView) { auto *tableInfo = State->Tables.FindPtr(tableId); - Y_VERIFY(tableInfo); + Y_VERIFY(tableInfo); tableInfo->Strategy->PartMerged(std::move(partView), 255); -} +} void TCompactionLogic::BorrowedPart(ui32 tableId, TIntrusiveConstPtr<NTable::TColdPart> part) { auto *tableInfo = State->Tables.FindPtr(tableId); @@ -629,8 +629,8 @@ void TCompactionLogic::BorrowedPart(ui32 tableId, TIntrusiveConstPtr<NTable::TCo ui32 TCompactionLogic::BorrowedPartLevel() { return 255; -} - +} + TTableCompactionChanges TCompactionLogic::RemovedParts(ui32 tableId, TArrayRef<const TLogoBlobID> parts) { auto *tableInfo = State->Tables.FindPtr(tableId); Y_VERIFY(tableInfo); @@ -738,12 +738,12 @@ ui64 TCompactionLogic::GetBackingSize(ui64 ownerTabletId) const { void TCompactionLogic::OutputHtml(IOutputStream &out, const NTable::TScheme &scheme, const TCgiParameters& cgi) { HTML(out) { - for (const auto &xtable : State->Tables) { + for (const auto &xtable : State->Tables) { H4() {out << scheme.GetTableInfo(xtable.first)->Name;} - + DIV_CLASS("row") { out - << "InMem Size: " << xtable.second.InMem.EstimatedSize - << ", Changes: " << xtable.second.InMem.Steps + << "InMem Size: " << xtable.second.InMem.EstimatedSize + << ", Changes: " << xtable.second.InMem.Steps << ", Compaction state: " << xtable.second.InMem.State << ", Backing size: " << xtable.second.Strategy->GetBackingSize() << ", Log overhead size: " << xtable.second.InMem.LogOverheadSize @@ -761,10 +761,10 @@ void TCompactionLogic::OutputHtml(IOutputStream &out, const NTable::TScheme &sch << ") submitted " << xtable.second.InMem.CompactionTask.SubmissionTimestamp.ToStringLocal(); } } - + xtable.second.Strategy->OutputHtml(out); - } + } } -} - +} + }} diff --git a/ydb/core/tablet_flat/flat_executor_compaction_logic.h b/ydb/core/tablet_flat/flat_executor_compaction_logic.h index e64964235e..b85a13a19e 100644 --- a/ydb/core/tablet_flat/flat_executor_compaction_logic.h +++ b/ydb/core/tablet_flat/flat_executor_compaction_logic.h @@ -1,6 +1,6 @@ #pragma once -#include "defs.h" -#include "tablet_flat_executor.h" +#include "defs.h" +#include "tablet_flat_executor.h" #include "flat_executor_misc.h" #include "flat_store_bundle.h" #include "flat_exec_broker.h" @@ -18,7 +18,7 @@ namespace NTable{ namespace NTabletFlatExecutor { class TTableSnapshotContext; - + using TCompactionPolicy = NLocalDb::TCompactionPolicy; enum class EForceCompaction { @@ -43,7 +43,7 @@ enum class EForcedCompactionState { CompactingMem, }; -struct TCompactionLogicState { +struct TCompactionLogicState { struct TCompactionTask { ui64 TaskId = 0; ui32 Priority = 0; @@ -51,7 +51,7 @@ struct TCompactionLogicState { ui64 CompactionId = 0; }; - struct TInMem { + struct TInMem { ui64 EstimatedSize = 0; ui32 Steps = 0; ui32 CompactingSteps = 0; @@ -60,35 +60,35 @@ struct TCompactionLogicState { ui64 LogOverheadCount = 0; ui64 LogOverheadSize = 0; float OverloadFactor = 0.0; - }; - - struct TSnapRequest { + }; + + struct TSnapRequest { const NTable::TSnapEdge Edge; TIntrusivePtr<TTableSnapshotContext> Context; - + TSnapRequest(NTable::TSnapEdge edge, TTableSnapshotContext *context) : Edge(edge) - , Context(context) - {} - - ~TSnapRequest(); - }; - - struct TTableInfo { + , Context(context) + {} + + ~TSnapRequest(); + }; + + struct TTableInfo { ui32 TableId = Max<ui32>(); - TInMem InMem; + TInMem InMem; // This identifies currently active strategy type // The default value is used as a marker for uninitialized strategies NKikimrSchemeOp::ECompactionStrategy StrategyType = NKikimrSchemeOp::CompactionStrategyUnset; THolder<NTable::ICompactionStrategy> Strategy; - + TDeque<TSnapRequest> SnapRequests; - + TIntrusiveConstPtr<TCompactionPolicy> Policy; - + EForcedCompactionState ForcedCompactionState = EForcedCompactionState::None; bool ForcedCompactionQueued = false; @@ -102,7 +102,7 @@ struct TCompactionLogicState { TTableInfo() = default; - ~TTableInfo(); + ~TTableInfo(); ui32 ComputeBackgroundPriority(const TCompactionLogicState::TCompactionTask &task, const TCompactionPolicy::TBackgroundPolicy &policy, @@ -131,13 +131,13 @@ struct TCompactionLogicState { class TFlatTableScan; -struct TTableCompactionResult { +struct TTableCompactionResult { NTable::TCompactionChanges Changes; NKikimrSchemeOp::ECompactionStrategy Strategy; TVector<TIntrusivePtr<TTableSnapshotContext>> CompleteSnapshots; bool MemCompacted = false; -}; - +}; + struct TTableCompactionChanges { ui32 Table; NTable::TCompactionChanges Changes; @@ -153,14 +153,14 @@ struct TReflectSchemeChangesResult { TVector<TStrategyChange> StrategyChanges; }; -class TCompactionLogic { +class TCompactionLogic { NUtil::ILogger * const Logger; NTable::IResourceBroker * const Broker; NTable::ICompactionBackend * const Backend; ITimeProvider * const Time = nullptr; - TAutoPtr<TCompactionLogicState> State; + TAutoPtr<TCompactionLogicState> State; TString TaskNameSuffix; - + // Update background compaction task when priority changes // at least by 5% (1/20 of current value). static constexpr ui32 PRIORITY_UPDATE_FACTOR = 20; @@ -192,7 +192,7 @@ public: NTable::ICompactionBackend*, TAutoPtr<TCompactionLogicState>, TString taskSuffix = { }); - ~TCompactionLogic(); + ~TCompactionLogic(); void Start(); void Stop(); @@ -206,9 +206,9 @@ public: void RequestChanges(ui32 tableId); TVector<TTableCompactionChanges> ApplyChanges(); - // + // void PrepareTableSnapshot(ui32 table, NTable::TSnapEdge edge, TTableSnapshotContext *snapContext); - + // Force compaction support // See slightly simlified state diagram: jing.yandex-team.ru/files/eivanov89/ForcedCompactionPath.png // or img/ForcedCompactionQueue.drawio @@ -225,7 +225,7 @@ public: float GetOverloadFactor() const; ui64 GetBackingSize() const; ui64 GetBackingSize(ui64 ownerTabletId) const; - + TTableCompactionResult CompleteCompaction( ui64 compactionId, THolder<NTable::TCompactionParams> params, @@ -238,7 +238,7 @@ public: void BorrowedPart(ui32 tableId, NTable::TPartView partView); void BorrowedPart(ui32 tableId, TIntrusiveConstPtr<NTable::TColdPart> part); ui32 BorrowedPartLevel(); - + TTableCompactionChanges RemovedParts(ui32 tableId, TArrayRef<const TLogoBlobID> parts); void OutputHtml(IOutputStream &out, const NTable::TScheme &scheme, const TCgiParameters& cgi); diff --git a/ydb/core/tablet_flat/flat_executor_counters.cpp b/ydb/core/tablet_flat/flat_executor_counters.cpp index 471476c69e..ddecce5206 100644 --- a/ydb/core/tablet_flat/flat_executor_counters.cpp +++ b/ydb/core/tablet_flat/flat_executor_counters.cpp @@ -1,31 +1,31 @@ -#include "flat_executor_counters.h" - -namespace NKikimr { -namespace NTabletFlatExecutor { - -#define FLAT_EXECUTOR_LATENCY_RANGES(XX) \ - XX(0, "<200 us") \ - XX(200, "200-500 us") \ - XX(500, "0.5-1 ms") \ - XX(1000, "1-5 ms") \ - XX(5000, "5-20 ms") \ - XX(20000, "20-50 ms") \ - XX(50000, "50-200 ms") \ - XX(200000, "0.2-0.5 s") \ - XX(500000, "0.5-1 s") \ - XX(1000000, "1-4 s") \ - XX(40000000, "4-10 s") \ - XX(100000000, "10-30 s") \ - XX(300000000, "> 30s") - -#define FLAT_EXECUTOR_TOUCHED_BLOCKS(XX) \ - XX(0, "0 || 1") \ - XX(2, "2-10") \ - XX(10, "10-50") \ - XX(50, "50-200") \ - XX(200, "200-1000") \ - XX(1000, ">1000") - +#include "flat_executor_counters.h" + +namespace NKikimr { +namespace NTabletFlatExecutor { + +#define FLAT_EXECUTOR_LATENCY_RANGES(XX) \ + XX(0, "<200 us") \ + XX(200, "200-500 us") \ + XX(500, "0.5-1 ms") \ + XX(1000, "1-5 ms") \ + XX(5000, "5-20 ms") \ + XX(20000, "20-50 ms") \ + XX(50000, "50-200 ms") \ + XX(200000, "0.2-0.5 s") \ + XX(500000, "0.5-1 s") \ + XX(1000000, "1-4 s") \ + XX(40000000, "4-10 s") \ + XX(100000000, "10-30 s") \ + XX(300000000, "> 30s") + +#define FLAT_EXECUTOR_TOUCHED_BLOCKS(XX) \ + XX(0, "0 || 1") \ + XX(2, "2-10") \ + XX(10, "10-50") \ + XX(50, "50-200") \ + XX(200, "200-1000") \ + XX(1000, ">1000") + #define FLAT_EXECUTOR_DATA_SIZE(XX) \ XX(0ULL, "0") \ XX(1ULL, "10240") \ @@ -65,22 +65,22 @@ namespace NTabletFlatExecutor { XX(800000, "90%") \ XX(900000, "100%") -const char* TExecutorCounters::SimpleCounterNames[TExecutorCounters::SIMPLE_COUNTER_SIZE] = - {FLAT_EXECUTOR_SIMPLE_COUNTERS_MAP(COUNTER_TEXT_ARRAY)}; -const char* TExecutorCounters::CumulativeCounterNames[TExecutorCounters::CUMULATIVE_COUNTER_SIZE] = - {FLAT_EXECUTOR_CUMULATIVE_COUNTERS_MAP(COUNTER_TEXT_ARRAY)}; -const char* TExecutorCounters::PercentileCounterNames[TExecutorCounters::PERCENTILE_COUNTER_SIZE] = - {FLAT_EXECUTOR_PERCENTILE_COUNTERS_MAP(COUNTER_TEXT_ARRAY)}; - -TExecutorCounters::TExecutorCounters() - : TTabletCountersBase(SIMPLE_COUNTER_SIZE, CUMULATIVE_COUNTER_SIZE, PERCENTILE_COUNTER_SIZE, SimpleCounterNames, CumulativeCounterNames, PercentileCounterNames) -{ - static TTabletPercentileCounter::TRangeDef txLatencyConfig[] = { FLAT_EXECUTOR_LATENCY_RANGES(COUNTER_PERCENTILE_CONFIG_ARRAY) }; - static TTabletPercentileCounter::TRangeDef txTouchedConfig[] = { FLAT_EXECUTOR_TOUCHED_BLOCKS(COUNTER_PERCENTILE_CONFIG_ARRAY) }; +const char* TExecutorCounters::SimpleCounterNames[TExecutorCounters::SIMPLE_COUNTER_SIZE] = + {FLAT_EXECUTOR_SIMPLE_COUNTERS_MAP(COUNTER_TEXT_ARRAY)}; +const char* TExecutorCounters::CumulativeCounterNames[TExecutorCounters::CUMULATIVE_COUNTER_SIZE] = + {FLAT_EXECUTOR_CUMULATIVE_COUNTERS_MAP(COUNTER_TEXT_ARRAY)}; +const char* TExecutorCounters::PercentileCounterNames[TExecutorCounters::PERCENTILE_COUNTER_SIZE] = + {FLAT_EXECUTOR_PERCENTILE_COUNTERS_MAP(COUNTER_TEXT_ARRAY)}; + +TExecutorCounters::TExecutorCounters() + : TTabletCountersBase(SIMPLE_COUNTER_SIZE, CUMULATIVE_COUNTER_SIZE, PERCENTILE_COUNTER_SIZE, SimpleCounterNames, CumulativeCounterNames, PercentileCounterNames) +{ + static TTabletPercentileCounter::TRangeDef txLatencyConfig[] = { FLAT_EXECUTOR_LATENCY_RANGES(COUNTER_PERCENTILE_CONFIG_ARRAY) }; + static TTabletPercentileCounter::TRangeDef txTouchedConfig[] = { FLAT_EXECUTOR_TOUCHED_BLOCKS(COUNTER_PERCENTILE_CONFIG_ARRAY) }; static TTabletPercentileCounter::TRangeDef txDataSize[] = { FLAT_EXECUTOR_DATA_SIZE(COUNTER_PERCENTILE_CONFIG_ARRAY) }; static TTabletPercentileCounter::TRangeDef txDataRate[] = { FLAT_EXECUTOR_DATA_RATE(COUNTER_PERCENTILE_CONFIG_ARRAY) }; static TTabletPercentileCounter::TRangeDef txConsumedCpu[] = { FLAT_EXECUTOR_CONSUMED_CPU_RANGES(COUNTER_PERCENTILE_CONFIG_ARRAY) }; - + Percentile()[TX_PERCENTILE_LATENCY_RO].Initialize(txLatencyConfig, false); Percentile()[TX_PERCENTILE_LATENCY_RW].Initialize(txLatencyConfig, false); Percentile()[TX_PERCENTILE_LATENCY_COMMIT].Initialize(txLatencyConfig, false); @@ -95,6 +95,6 @@ TExecutorCounters::TExecutorCounters() Percentile()[TX_PERCENTILE_TABLET_BYTES_WRITTEN].Initialize(txDataRate, false); Percentile()[TX_PERCENTILE_CONSUMED_CPU].Initialize(txConsumedCpu, false); Percentile()[TX_PERCENTILE_FOLLOWERSYNC_LATENCY].Initialize(txLatencyConfig, false); -} - -}} +} + +}} diff --git a/ydb/core/tablet_flat/flat_executor_counters.h b/ydb/core/tablet_flat/flat_executor_counters.h index b4eb041987..f100bc48a0 100644 --- a/ydb/core/tablet_flat/flat_executor_counters.h +++ b/ydb/core/tablet_flat/flat_executor_counters.h @@ -1,11 +1,11 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include <ydb/core/tablet/tablet_counters.h> - -namespace NKikimr { -namespace NTabletFlatExecutor { - -#define FLAT_EXECUTOR_SIMPLE_COUNTERS_MAP(XX) \ + +namespace NKikimr { +namespace NTabletFlatExecutor { + +#define FLAT_EXECUTOR_SIMPLE_COUNTERS_MAP(XX) \ XX(DB_TX_IN_FLY, "ExecutorTxInFly") \ XX(LOG_REDO_COUNT, "LogRedoItems") \ XX(LOG_REDO_MEMORY, "LogRedoMemory") \ @@ -47,7 +47,7 @@ namespace NTabletFlatExecutor { XX(CACHE_FRESH_SIZE, "CacheFreshSize") \ XX(CACHE_STAGING_SIZE, "CacheStagingSize") \ XX(CACHE_WARM_SIZE, "CacheMemTableSize") \ - XX(CACHE_PINNED_SET, "CachePinned") \ + XX(CACHE_PINNED_SET, "CachePinned") \ XX(CACHE_PINNED_LOAD, "CachePinnedLoad") \ XX(CACHE_TOTAL_COLLECTIONS, "CacheTotalCollections") \ XX(CACHE_TOTAL_SHARED_BODY, "CacheTotalSharedBody") \ @@ -61,8 +61,8 @@ namespace NTabletFlatExecutor { XX(CONSUMED_STORAGE, "ConsumedStorage") \ XX(CONSUMED_MEMORY, "ConsumedMemory") \ XX(COMPACTION_READ_IN_FLY, "CompactionReadInFly") \ - -#define FLAT_EXECUTOR_CUMULATIVE_COUNTERS_MAP(XX) \ + +#define FLAT_EXECUTOR_CUMULATIVE_COUNTERS_MAP(XX) \ XX(LOG_COMMITS, "LogCommits") \ XX(LOG_WRITTEN, "LogWritten") \ XX(LOG_EMBEDDED, "LogEmbedded" ) \ @@ -80,7 +80,7 @@ namespace NTabletFlatExecutor { XX(DB_ELOBS_ITEMS_GONE, "DbELargeObjsItemsGone") \ XX(DB_REDO_WRITTEN_BYTES, "DbRedoWrittenBytes") \ XX(DB_ANNEX_WRITTEN_BYTES, "DbAnnexWrittenBytes") \ - XX(TX_COUNT_ALL, "Tx(all)") \ + XX(TX_COUNT_ALL, "Tx(all)") \ XX(TX_QUEUED, "TxQueued") \ XX(TX_RETRIED, "TxRetried") \ XX(TX_FINISHED, "TxFinished") \ @@ -89,8 +89,8 @@ namespace NTabletFlatExecutor { XX(TX_MEM_CAPTURES, "TxMemoryCaptures") \ XX(TX_MEM_ATTACHES, "TxMemoryAttaches") \ XX(TX_DATA_RELEASES, "TxDataReleases") \ - XX(TX_RO_COMPLETED, "Tx(ro complete)") \ - XX(TX_RW_COMPLETED, "Tx(rw complete)") \ + XX(TX_RO_COMPLETED, "Tx(ro complete)") \ + XX(TX_RW_COMPLETED, "Tx(rw complete)") \ XX(TX_TERMINATED, "Tx(terminated)") \ XX(TX_CHARGE_WEEDED, "TxKeyChargeWeeded") \ XX(TX_CHARGE_SIEVED, "TxKeyChargeSieved") \ @@ -100,10 +100,10 @@ namespace NTabletFlatExecutor { XX(TX_BYTES_READ, "TxReadBytes") \ XX(TX_CACHE_HITS, "TxPageCacheHits") \ XX(TX_CACHE_MISSES, "TxPageCacheMisses") \ - XX(GC_DISCOVERED, "GcBlobsDiscovered") \ - XX(GC_DISCARDED, "GcBlobsDiscarded") \ - XX(GC_FORGOTTEN, "GcBlobsForgotten") \ - XX(GC_KEEPSET, "GcKeepFlagsSet") \ + XX(GC_DISCOVERED, "GcBlobsDiscovered") \ + XX(GC_DISCARDED, "GcBlobsDiscarded") \ + XX(GC_FORGOTTEN, "GcBlobsForgotten") \ + XX(GC_KEEPSET, "GcKeepFlagsSet") \ XX(GC_NOTKEEPSET, "GcNotKeepFlagsSet") \ XX(CONSUMED_CPU, "ConsumedCPU") \ XX(COMPACTION_READ_POSTPONED, "CompactionReadPostponed") \ @@ -111,44 +111,44 @@ namespace NTabletFlatExecutor { XX(COMPACTION_READ_CACHE_MISSES, "CompactionReadCacheMisses") \ XX(COMPACTION_READ_LOAD_BYTES, "CompactionReadLoadBytes") \ XX(COMPACTION_READ_LOAD_PAGES, "CompactionReadLoadPages") \ - -#define FLAT_EXECUTOR_PERCENTILE_COUNTERS_MAP(XX) \ - XX(TX_PERCENTILE_LATENCY_RO, "TxRoLatency") \ - XX(TX_PERCENTILE_LATENCY_RW, "TxRwLatency") \ - XX(TX_PERCENTILE_LATENCY_COMMIT, "TxCommitLatency") \ - XX(TX_PERCENTILE_EXECUTE_CPUTIME, "TxExecuteCPUTime") \ - XX(TX_PERCENTILE_BOOKKEEPING_CPUTIME, "TxBookkeepingCPUTime") \ - XX(TX_PERCENTILE_COMMITED_CPUTIME, "TxCommitedCPUTime") \ - XX(TX_PERCENTILE_LOGSNAP_CPUTIME, "LogSnapCPUTime") \ - XX(TX_PERCENTILE_PARTSWITCH_CPUTIME, "PartSwitchCPUTime") \ + +#define FLAT_EXECUTOR_PERCENTILE_COUNTERS_MAP(XX) \ + XX(TX_PERCENTILE_LATENCY_RO, "TxRoLatency") \ + XX(TX_PERCENTILE_LATENCY_RW, "TxRwLatency") \ + XX(TX_PERCENTILE_LATENCY_COMMIT, "TxCommitLatency") \ + XX(TX_PERCENTILE_EXECUTE_CPUTIME, "TxExecuteCPUTime") \ + XX(TX_PERCENTILE_BOOKKEEPING_CPUTIME, "TxBookkeepingCPUTime") \ + XX(TX_PERCENTILE_COMMITED_CPUTIME, "TxCommitedCPUTime") \ + XX(TX_PERCENTILE_LOGSNAP_CPUTIME, "LogSnapCPUTime") \ + XX(TX_PERCENTILE_PARTSWITCH_CPUTIME, "PartSwitchCPUTime") \ XX(TX_PERCENTILE_TOUCHED_BLOCKS, "TouchedBlocks") \ XX(TX_PERCENTILE_DB_DATA_BYTES, "HIST(DbDataBytes)") \ XX(TX_PERCENTILE_TABLET_BYTES_WRITTEN, "HIST(TabletBytesWritten)") \ XX(TX_PERCENTILE_TABLET_BYTES_READ, "HIST(TabletBytesRead)") \ XX(TX_PERCENTILE_CONSUMED_CPU, "HIST(ConsumedCPU)") \ XX(TX_PERCENTILE_FOLLOWERSYNC_LATENCY, "FollowerSyncLatency") - -class TExecutorCounters : public TTabletCountersBase { -public: - enum ESimpleCounter { - FLAT_EXECUTOR_SIMPLE_COUNTERS_MAP(ENUM_VALUE_GEN_NO_VALUE) - SIMPLE_COUNTER_SIZE - }; - static const char* SimpleCounterNames[SIMPLE_COUNTER_SIZE]; - - enum ECumulativeCounter { - FLAT_EXECUTOR_CUMULATIVE_COUNTERS_MAP(ENUM_VALUE_GEN_NO_VALUE) - CUMULATIVE_COUNTER_SIZE - }; - static const char* CumulativeCounterNames[CUMULATIVE_COUNTER_SIZE]; - - enum EPercentileCounter { - FLAT_EXECUTOR_PERCENTILE_COUNTERS_MAP(ENUM_VALUE_GEN_NO_VALUE) - PERCENTILE_COUNTER_SIZE - }; - static const char* PercentileCounterNames[PERCENTILE_COUNTER_SIZE]; - - TExecutorCounters(); -}; - -}} + +class TExecutorCounters : public TTabletCountersBase { +public: + enum ESimpleCounter { + FLAT_EXECUTOR_SIMPLE_COUNTERS_MAP(ENUM_VALUE_GEN_NO_VALUE) + SIMPLE_COUNTER_SIZE + }; + static const char* SimpleCounterNames[SIMPLE_COUNTER_SIZE]; + + enum ECumulativeCounter { + FLAT_EXECUTOR_CUMULATIVE_COUNTERS_MAP(ENUM_VALUE_GEN_NO_VALUE) + CUMULATIVE_COUNTER_SIZE + }; + static const char* CumulativeCounterNames[CUMULATIVE_COUNTER_SIZE]; + + enum EPercentileCounter { + FLAT_EXECUTOR_PERCENTILE_COUNTERS_MAP(ENUM_VALUE_GEN_NO_VALUE) + PERCENTILE_COUNTER_SIZE + }; + static const char* PercentileCounterNames[PERCENTILE_COUNTER_SIZE]; + + TExecutorCounters(); +}; + +}} diff --git a/ydb/core/tablet_flat/flat_executor_gclogic.cpp b/ydb/core/tablet_flat/flat_executor_gclogic.cpp index adc84409ac..bded66353e 100644 --- a/ydb/core/tablet_flat/flat_executor_gclogic.cpp +++ b/ydb/core/tablet_flat/flat_executor_gclogic.cpp @@ -13,7 +13,7 @@ TExecutorGCLogic::TExecutorGCLogic(TIntrusiveConstPtr<TTabletStorageInfo> info, , SnapshotStep(0) , PrevSnapshotStep(0) , ConfirmedOnSendStep(0) - , AllowGarbageCollection(false) + , AllowGarbageCollection(false) { } @@ -21,44 +21,44 @@ void TExecutorGCLogic::WriteToLog(TLogCommit &commit) { TGCTime time(Generation, commit.Step); TGCLogEntry& uncommittedDelta = UncommittedDeltaLog[time]; uncommittedDelta.Time = time; - - const ui32 gcEntriesInBatch = 250000; // ~7mb rawsize - + + const ui32 gcEntriesInBatch = 250000; // ~7mb rawsize + Cookies->Switch(commit.Step, true /* require step switch */); - + const ui32 gcGrowSize = commit.GcDelta.Created.size(); const ui32 gcLeftSize = commit.GcDelta.Deleted.size(); if (commit.Type == ECommit::Snap || gcGrowSize + gcLeftSize < gcEntriesInBatch) { uncommittedDelta.Delta = commit.GcDelta; /* preserve for embedding */ - } else { - ui32 placedDiscovered = 0; - ui32 placedLeft = 0; - + } else { + ui32 placedDiscovered = 0; + ui32 placedLeft = 0; + uncommittedDelta.Delta = std::exchange(commit.GcDelta, { }); while (placedDiscovered < gcGrowSize || placedLeft < gcLeftSize) { NKikimrExecutorFlat::TExternalGcEntry proto; - ui32 leftInBatch = gcEntriesInBatch; + ui32 leftInBatch = gcEntriesInBatch; if (placedDiscovered < gcGrowSize) { const ui32 toMove = Min(leftInBatch, gcGrowSize - placedDiscovered); auto it = uncommittedDelta.Delta.Created.begin() + placedDiscovered; - LogoBlobIDRepatedFromLogoBlobIDVector(proto.MutableGcDiscovered(), it, it + toMove); - placedDiscovered += toMove; - leftInBatch -= toMove; - } - - if (leftInBatch && placedLeft < gcLeftSize) { - const ui32 toMove = Min(leftInBatch, gcLeftSize - placedLeft); + LogoBlobIDRepatedFromLogoBlobIDVector(proto.MutableGcDiscovered(), it, it + toMove); + placedDiscovered += toMove; + leftInBatch -= toMove; + } + + if (leftInBatch && placedLeft < gcLeftSize) { + const ui32 toMove = Min(leftInBatch, gcLeftSize - placedLeft); auto it = uncommittedDelta.Delta.Deleted.begin() + placedLeft; - LogoBlobIDRepatedFromLogoBlobIDVector(proto.MutableGcLeft(), it, it + toMove); - placedLeft += toMove; - } - + LogoBlobIDRepatedFromLogoBlobIDVector(proto.MutableGcLeft(), it, it + toMove); + placedLeft += toMove; + } + Slicer.One(commit.Refs, proto.SerializeAsString(), true); - } - } + } + } } TGCLogEntry TExecutorGCLogic::SnapshotLog(ui32 step) { @@ -71,12 +71,12 @@ TGCLogEntry TExecutorGCLogic::SnapshotLog(ui32 step) { TExecutorGCLogic::MergeVectors(snapshot.Delta.Deleted, le.second.Deleted); } } - - for (const auto &it : UncommittedDeltaLog) { + + for (const auto &it : UncommittedDeltaLog) { TExecutorGCLogic::MergeVectors(snapshot.Delta.Created, it.second.Delta.Created); TExecutorGCLogic::MergeVectors(snapshot.Delta.Deleted, it.second.Delta.Deleted); - } - + } + PrevSnapshotStep = SnapshotStep; SnapshotStep = step; return snapshot; @@ -94,15 +94,15 @@ void TExecutorGCLogic::SnapToLog(NKikimrExecutorFlat::TLogSnapshot &snap, ui32 s gcSnapLeft->Reserve(gcLogEntry.Delta.Deleted.size()); for (const TLogoBlobID &x : gcLogEntry.Delta.Deleted) LogoBlobIDFromLogoBlobID(x, gcSnapLeft->Add()); - - for (const auto &chIt : ChannelInfo) { - if (chIt.second.CommitedGcBarrier) { + + for (const auto &chIt : ChannelInfo) { + if (chIt.second.CommitedGcBarrier) { auto *x = snap.AddGcBarrierInfo(); - x->SetChannel(chIt.first); - x->SetSetToGeneration(chIt.second.CommitedGcBarrier.Generation); - x->SetSetToStep(chIt.second.CommitedGcBarrier.Step); - } - } + x->SetChannel(chIt.first); + x->SetSetToGeneration(chIt.second.CommitedGcBarrier.Generation); + x->SetSetToStep(chIt.second.CommitedGcBarrier.Step); + } + } } void TExecutorGCLogic::OnCommitLog(ui32 step, ui32 confirmedOnSend, const TActorContext& ctx) { @@ -134,64 +134,64 @@ void TExecutorGCLogic::ApplyLogEntry(TGCLogEntry& entry) { void TExecutorGCLogic::ApplyLogSnapshot(TGCLogEntry &snapshot, const TVector<std::pair<ui32, ui64>> &barriers) { ApplyLogEntry(snapshot); - for (auto &xpair : barriers) { - const ui32 channel = xpair.first; - const std::pair<ui32, ui32> barrier = ExpandGenStepPair(xpair.second); - ChannelInfo[channel].CommitedGcBarrier = {barrier.first, barrier.second}; - } + for (auto &xpair : barriers) { + const ui32 channel = xpair.first; + const std::pair<ui32, ui32> barrier = ExpandGenStepPair(xpair.second); + ChannelInfo[channel].CommitedGcBarrier = {barrier.first, barrier.second}; + } } -void TExecutorGCLogic::HoldBarrier(ui32 step) { - Y_VERIFY(true == HoldBarriersSet.insert(TGCTime(Generation, step)).second); +void TExecutorGCLogic::HoldBarrier(ui32 step) { + Y_VERIFY(true == HoldBarriersSet.insert(TGCTime(Generation, step)).second); } void TExecutorGCLogic::ReleaseBarrier(ui32 step) { - Y_VERIFY(1 == HoldBarriersSet.erase(TGCTime(Generation, step))); + Y_VERIFY(1 == HoldBarriersSet.erase(TGCTime(Generation, step))); +} + +ui32 TExecutorGCLogic::GetActiveGcBarrier() { + if (HoldBarriersSet.empty()) + return Max<ui32>(); + return HoldBarriersSet.begin()->Step; } -ui32 TExecutorGCLogic::GetActiveGcBarrier() { - if (HoldBarriersSet.empty()) - return Max<ui32>(); - return HoldBarriersSet.begin()->Step; -} - void TExecutorGCLogic::FollowersSyncComplete(bool isBoot) { - Y_UNUSED(isBoot); - AllowGarbageCollection = true; -} - + Y_UNUSED(isBoot); + AllowGarbageCollection = true; +} + void TExecutorGCLogic::ApplyDelta(TGCTime time, TGCBlobDelta &delta) { for (const TLogoBlobID &blobId : delta.Created) { - auto &channel = ChannelInfo[blobId.Channel()]; - TGCTime gcTime(blobId.Generation(), blobId.Step()); + auto &channel = ChannelInfo[blobId.Channel()]; + TGCTime gcTime(blobId.Generation(), blobId.Step()); Y_VERIFY(channel.KnownGcBarrier < gcTime); channel.CommittedDelta[gcTime].Created.push_back(blobId); } - + for (const TLogoBlobID &blobId : delta.Deleted) { - auto &channel = ChannelInfo[blobId.Channel()]; + auto &channel = ChannelInfo[blobId.Channel()]; channel.CommittedDelta[time].Deleted.push_back(blobId); - } + } } void TExecutorGCLogic::SendCollectGarbage(const TActorContext& ctx) { - if (!AllowGarbageCollection) - return; - - const TGCTime uncommittedTime(UncommittedDeltaLog.empty() ? TGCTime::Infinity() : UncommittedDeltaLog.begin()->first); + if (!AllowGarbageCollection) + return; + + const TGCTime uncommittedTime(UncommittedDeltaLog.empty() ? TGCTime::Infinity() : UncommittedDeltaLog.begin()->first); const TGCTime uncommitedSnap(Generation, ConfirmedOnSendStep >= SnapshotStep ? SnapshotStep : PrevSnapshotStep); - const TGCTime minBarrier = HoldBarriersSet.empty() ? TGCTime::Infinity() : *HoldBarriersSet.begin(); - - const TGCTime minTime = std::min(uncommittedTime, std::min(uncommitedSnap, minBarrier)); - + const TGCTime minBarrier = HoldBarriersSet.empty() ? TGCTime::Infinity() : *HoldBarriersSet.begin(); + + const TGCTime minTime = std::min(uncommittedTime, std::min(uncommitedSnap, minBarrier)); + for (auto it = ChannelInfo.begin(); it != ChannelInfo.end(); ++it) { - it->second.SendCollectGarbage(minTime, TabletStorageInfo.Get(), it->first, Generation, ctx); + it->second.SendCollectGarbage(minTime, TabletStorageInfo.Get(), it->first, Generation, ctx); } } TExecutorGCLogic::TChannelInfo::TChannelInfo() - : GcCounter(1) - , GcWaitFor(0) + : GcCounter(1) + , GcWaitFor(0) { } @@ -219,68 +219,68 @@ void TExecutorGCLogic::MergeVectors(THolder<TVector<TLogoBlobID>>& destination, void DeduplicateGCKeepVectors(TVector<TLogoBlobID> *keep, TVector<TLogoBlobID> *doNotKeep, ui32 barrierGen, ui32 barrierStep) { if (keep && doNotKeep && !keep->empty() && !doNotKeep->empty()) { - // vectors must be sorted! - + // vectors must be sorted! + TVector<TLogoBlobID>::const_iterator keepIt = keep->begin(); TVector<TLogoBlobID>::const_iterator keepEnd = keep->end(); TVector<TLogoBlobID>::const_iterator notIt = doNotKeep->begin(); TVector<TLogoBlobID>::const_iterator notEnd = doNotKeep->end(); TVector<TLogoBlobID>::iterator keepIns = keep->begin(); TVector<TLogoBlobID>::iterator notIns = doNotKeep->begin(); - - bool keepModified = false; - bool notKeepModified = false; - - for (;;) { - if (keepIt == keepEnd) { - if (notKeepModified && notIt != notEnd) { - const ui64 toCopy = notEnd - notIt; - MemMove(&*notIns, &*notIt, toCopy); - notIns += toCopy; - } - break; - } - - if (notIt == notEnd) { - if (keepModified && keepIt != keepEnd) { - const ui64 toCopy = keepEnd - keepIt; - MemMove(&*keepIns, &*keepIt, toCopy); - keepIns += toCopy; - } - break; - } - - if (*keepIt < *notIt) { - if (keepModified) - *keepIns = *keepIt; - ++keepIns; - ++keepIt; - } else if (*notIt < *keepIt) { - if (notKeepModified) - *notIns = *notIt; - ++notIns; - ++notIt; - } else { - // we discard keep mark anycase and - // could eleminate donotkeep mark if seen both events in live tail - if (keepIt->Generation() != barrierGen || keepIt->Step() <= barrierStep) { - if (notKeepModified) - *notIns = *notIt; - ++notIns; - } else { - notKeepModified = true; - } - - keepModified = true; - ++keepIt; - ++notIt; - } - } - - if (keepModified) - keep->erase(keepIns, keepEnd); - if (notKeepModified) - doNotKeep->erase(notIns, notEnd); + + bool keepModified = false; + bool notKeepModified = false; + + for (;;) { + if (keepIt == keepEnd) { + if (notKeepModified && notIt != notEnd) { + const ui64 toCopy = notEnd - notIt; + MemMove(&*notIns, &*notIt, toCopy); + notIns += toCopy; + } + break; + } + + if (notIt == notEnd) { + if (keepModified && keepIt != keepEnd) { + const ui64 toCopy = keepEnd - keepIt; + MemMove(&*keepIns, &*keepIt, toCopy); + keepIns += toCopy; + } + break; + } + + if (*keepIt < *notIt) { + if (keepModified) + *keepIns = *keepIt; + ++keepIns; + ++keepIt; + } else if (*notIt < *keepIt) { + if (notKeepModified) + *notIns = *notIt; + ++notIns; + ++notIt; + } else { + // we discard keep mark anycase and + // could eleminate donotkeep mark if seen both events in live tail + if (keepIt->Generation() != barrierGen || keepIt->Step() <= barrierStep) { + if (notKeepModified) + *notIns = *notIt; + ++notIns; + } else { + notKeepModified = true; + } + + keepModified = true; + ++keepIt; + ++notIt; + } + } + + if (keepModified) + keep->erase(keepIns, keepEnd); + if (notKeepModified) + doNotKeep->erase(notIns, notEnd); } } @@ -292,28 +292,28 @@ TVector<TLogoBlobID>* TExecutorGCLogic::CreateVector(const TVector<TLogoBlobID>& } } -TExecutorGCLogic::TIntrospection TExecutorGCLogic::IntrospectStateSize() const { - TIntrospection ret; - - for (auto &xpair : UncommittedDeltaLog) { - ++ret.UncommitedEntries; +TExecutorGCLogic::TIntrospection TExecutorGCLogic::IntrospectStateSize() const { + TIntrospection ret; + + for (auto &xpair : UncommittedDeltaLog) { + ++ret.UncommitedEntries; ret.UncommitedBlobIds += xpair.second.Delta.Created.size() + xpair.second.Delta.Deleted.size(); - } - ret.UncommitedEntriesBytes += ret.UncommitedBlobIds * sizeof(TLogoBlobID) + 96; - ret.BarriersSetSize += HoldBarriersSet.size(); - - for (auto xchannelp : ChannelInfo) { - for (auto &xpair : xchannelp.second.CommittedDelta) { - ++ret.CommitedEntries; + } + ret.UncommitedEntriesBytes += ret.UncommitedBlobIds * sizeof(TLogoBlobID) + 96; + ret.BarriersSetSize += HoldBarriersSet.size(); + + for (auto xchannelp : ChannelInfo) { + for (auto &xpair : xchannelp.second.CommittedDelta) { + ++ret.CommitedEntries; ret.CommitedBlobIdsKnown += xpair.second.Created.size(); ret.CommitedBlobIdsLeft += xpair.second.Deleted.size(); - } - ret.CommitedEntriesBytes += sizeof(TLogoBlobID) *(ret.CommitedBlobIdsKnown + ret.CommitedBlobIdsLeft) + 96; - } - - return ret; -} - + } + ret.CommitedEntriesBytes += sizeof(TLogoBlobID) *(ret.CommitedBlobIdsKnown + ret.CommitedBlobIdsLeft) + 96; + } + + return ret; +} + namespace { void ValidateGCVector(ui64 tabletId, ui32 channel, const char* name, const TVector<TLogoBlobID>& vec) { for (size_t i = 0; i < vec.size(); ++i) { @@ -332,136 +332,136 @@ namespace { } } -void TExecutorGCLogic::TChannelInfo::SendCollectGarbageEntry( - const TActorContext &ctx, +void TExecutorGCLogic::TChannelInfo::SendCollectGarbageEntry( + const TActorContext &ctx, TVector<TLogoBlobID> &&keep, TVector<TLogoBlobID> &¬Keep, - ui64 tabletid, ui32 channel, ui32 bsgroup, ui32 generation) -{ + ui64 tabletid, ui32 channel, ui32 bsgroup, ui32 generation) +{ ValidateGCVector(tabletid, channel, "Keep", keep); ValidateGCVector(tabletid, channel, "DoNotKeep", notKeep); - THolder<TEvBlobStorage::TEvCollectGarbage> ev = + THolder<TEvBlobStorage::TEvCollectGarbage> ev = MakeHolder<TEvBlobStorage::TEvCollectGarbage>( - tabletid, - generation, GcCounter, - channel, true, - KnownGcBarrier.Generation, KnownGcBarrier.Step, + tabletid, + generation, GcCounter, + channel, true, + KnownGcBarrier.Generation, KnownGcBarrier.Step, keep.empty() ? nullptr : new TVector<TLogoBlobID>(std::move(keep)), notKeep.empty() ? nullptr : new TVector<TLogoBlobID>(std::move(notKeep)), - TInstant::Max(), - true); - GcCounter += ev->PerGenerationCounterStepSize(); - SendToBSProxy(ctx, bsgroup, ev.Release()); - ++GcWaitFor; -} - + TInstant::Max(), + true); + GcCounter += ev->PerGenerationCounterStepSize(); + SendToBSProxy(ctx, bsgroup, ev.Release()); + ++GcWaitFor; +} + void TExecutorGCLogic::TChannelInfo::SendCollectGarbage(TGCTime uncommittedTime, const TTabletStorageInfo *tabletStorageInfo, ui32 channel, ui32 generation, const TActorContext& ctx) { - if (GcWaitFor > 0) + if (GcWaitFor > 0) return; - + TVector<TLogoBlobID> keep; TVector<TLogoBlobID> notKeep; - - TGCTime collectBarrier; - - for (auto it = CommittedDelta.begin(), end = CommittedDelta.end(); it != end; ++it) { - if (it->first < uncommittedTime) { + + TGCTime collectBarrier; + + for (auto it = CommittedDelta.begin(), end = CommittedDelta.end(); it != end; ++it) { + if (it->first < uncommittedTime) { keep.insert(keep.end(), it->second.Created.begin(), it->second.Created.end()); notKeep.insert(notKeep.end(), it->second.Deleted.begin(), it->second.Deleted.end()); - collectBarrier = it->first; + collectBarrier = it->first; } else break; } - + // The first barrier of gen:0 (zero entry) is special TGCTime zeroTime{ generation, 0 }; if (KnownGcBarrier < zeroTime && collectBarrier < zeroTime && zeroTime <= uncommittedTime) { collectBarrier = zeroTime; } - if (collectBarrier) { + if (collectBarrier) { Sort(keep); Sort(notKeep); - + DeduplicateGCKeepVectors(&keep, ¬Keep, generation, KnownGcBarrier.Step); - - CollectSent = collectBarrier; - KnownGcBarrier = collectBarrier; - - const auto *channelInfo = tabletStorageInfo->ChannelInfo(channel); + + CollectSent = collectBarrier; + KnownGcBarrier = collectBarrier; + + const auto *channelInfo = tabletStorageInfo->ChannelInfo(channel); Y_VERIFY(channelInfo); - - - const ui32 lastCommitedGcBarrier = CommitedGcBarrier.Generation; + + + const ui32 lastCommitedGcBarrier = CommitedGcBarrier.Generation; const ui32 firstFlagGen = std::min<ui32>(keep.empty() ? Max<ui32>() : keep.front().Generation(), notKeep.empty() ? Max<ui32>() : notKeep.front().Generation()); - const auto *latestEntry = channelInfo->LatestEntry(); - - if (lastCommitedGcBarrier >= latestEntry->FromGeneration && firstFlagGen >= latestEntry->FromGeneration) { - // normal case, commit gc info for last entry only + const auto *latestEntry = channelInfo->LatestEntry(); + + if (lastCommitedGcBarrier >= latestEntry->FromGeneration && firstFlagGen >= latestEntry->FromGeneration) { + // normal case, commit gc info for last entry only SendCollectGarbageEntry(ctx, std::move(keep), std::move(notKeep), tabletStorageInfo->TabletID, channel, latestEntry->GroupID, generation); - } else { - // bloated case - spread among different groups + } else { + // bloated case - spread among different groups TMap<ui32, std::pair<TVector<TLogoBlobID>, TVector<TLogoBlobID>>> affectedGroups; - - { // mark every actual generation for update - auto xit = UpperBound(channelInfo->History.begin(), channelInfo->History.end(), lastCommitedGcBarrier, TTabletChannelInfo::THistoryEntry::TCmp()); + + { // mark every actual generation for update + auto xit = UpperBound(channelInfo->History.begin(), channelInfo->History.end(), lastCommitedGcBarrier, TTabletChannelInfo::THistoryEntry::TCmp()); if (xit != channelInfo->History.begin()) { --xit; } for (; xit != channelInfo->History.end(); ++xit) - affectedGroups[xit->GroupID]; - } - - ui32 activeGen = Max<ui32>(); - ui32 activeGroup = Max<ui32>(); + affectedGroups[xit->GroupID]; + } + + ui32 activeGen = Max<ui32>(); + ui32 activeGroup = Max<ui32>(); TVector<TLogoBlobID> *vec = nullptr; - + for (const auto &blobId : keep) { - if (activeGen != blobId.Generation()) { - activeGen = blobId.Generation(); - activeGroup = channelInfo->GroupForGeneration(blobId.Generation()); - vec = &affectedGroups[activeGroup].first; - } - - vec->push_back(blobId); - } - - activeGen = Max<ui32>(); - activeGroup = Max<ui32>(); - vec = nullptr; - + if (activeGen != blobId.Generation()) { + activeGen = blobId.Generation(); + activeGroup = channelInfo->GroupForGeneration(blobId.Generation()); + vec = &affectedGroups[activeGroup].first; + } + + vec->push_back(blobId); + } + + activeGen = Max<ui32>(); + activeGroup = Max<ui32>(); + vec = nullptr; + for (const auto &blobId : notKeep) { - if (activeGen != blobId.Generation()) { - activeGen = blobId.Generation(); - activeGroup = channelInfo->GroupForGeneration(blobId.Generation()); - vec = &affectedGroups[activeGroup].second; - } - - vec->push_back(blobId); - } - - for (auto &xpair : affectedGroups) { - SendCollectGarbageEntry(ctx, std::move(xpair.second.first), std::move(xpair.second.second), tabletStorageInfo->TabletID, channel, xpair.first, generation); - } - } + if (activeGen != blobId.Generation()) { + activeGen = blobId.Generation(); + activeGroup = channelInfo->GroupForGeneration(blobId.Generation()); + vec = &affectedGroups[activeGroup].second; + } + + vec->push_back(blobId); + } + + for (auto &xpair : affectedGroups) { + SendCollectGarbageEntry(ctx, std::move(xpair.second.first), std::move(xpair.second.second), tabletStorageInfo->TabletID, channel, xpair.first, generation); + } + } } } void TExecutorGCLogic::TChannelInfo::OnCollectGarbageSuccess() { - if (--GcWaitFor || !CollectSent) - return; - + if (--GcWaitFor || !CollectSent) + return; + auto it = CommittedDelta.upper_bound(CollectSent); if (it != CommittedDelta.begin()) { CommittedDelta.erase(CommittedDelta.begin(), it); } - + CollectSent.Clear(); - CommitedGcBarrier = KnownGcBarrier; + CommitedGcBarrier = KnownGcBarrier; } void TExecutorGCLogic::TChannelInfo::OnCollectGarbageFailure() { CollectSent.Clear(); - --GcWaitFor; + --GcWaitFor; } } diff --git a/ydb/core/tablet_flat/flat_executor_gclogic.h b/ydb/core/tablet_flat/flat_executor_gclogic.h index ba6d071f4c..9c1fa568a2 100644 --- a/ydb/core/tablet_flat/flat_executor_gclogic.h +++ b/ydb/core/tablet_flat/flat_executor_gclogic.h @@ -1,5 +1,5 @@ #pragma once -#include "defs.h" +#include "defs.h" #include "flat_sausage_slicer.h" #include "flat_exec_commit.h" #include <util/generic/vector.h> @@ -22,8 +22,8 @@ struct TGCTime { inline bool Valid() const { return Generation != 0 || Step != 0; } inline void Clear() { Generation = Step = 0; } static TGCTime Infinity() { return TGCTime(std::numeric_limits<ui32>::max(), std::numeric_limits<ui32>::max()); } - - explicit operator bool() const noexcept { return Valid(); } + + explicit operator bool() const noexcept { return Valid(); } }; struct TGCLogEntry { @@ -42,37 +42,37 @@ public: TGCLogEntry SnapshotLog(ui32 step); void SnapToLog(NKikimrExecutorFlat::TLogSnapshot &logSnapshot, ui32 step); void OnCommitLog(ui32 step, ui32 confirmedOnSend, const TActorContext &ctx); // notification about log commit - could send GC to blob storage - void OnCollectGarbageResult(TEvBlobStorage::TEvCollectGarbageResult::TPtr& ev); // notification on any garbage collection results + void OnCollectGarbageResult(TEvBlobStorage::TEvCollectGarbageResult::TPtr& ev); // notification on any garbage collection results void ApplyLogEntry(TGCLogEntry &entry); // apply one log entry, used during recovery and also from WriteToLog void ApplyLogSnapshot(TGCLogEntry &snapshot, const TVector<std::pair<ui32, ui64>> &barriers); - void HoldBarrier(ui32 step); // holds GC on no more than this step for channels specified + void HoldBarrier(ui32 step); // holds GC on no more than this step for channels specified void ReleaseBarrier(ui32 step); - ui32 GetActiveGcBarrier(); + ui32 GetActiveGcBarrier(); void FollowersSyncComplete(bool isBoot); - - struct TIntrospection { - ui64 UncommitedEntries; - ui64 UncommitedBlobIds; - ui64 UncommitedEntriesBytes; - ui64 CommitedEntries; - ui64 CommitedBlobIdsKnown; - ui64 CommitedBlobIdsLeft; - ui64 CommitedEntriesBytes; - ui64 BarriersSetSize; - - TIntrospection() - : UncommitedEntries(0) - , UncommitedBlobIds(0) - , UncommitedEntriesBytes(0) - , CommitedEntries(0) - , CommitedBlobIdsKnown(0) - , CommitedBlobIdsLeft(0) - , CommitedEntriesBytes(0) - , BarriersSetSize(0) - {} - }; - - TIntrospection IntrospectStateSize() const; + + struct TIntrospection { + ui64 UncommitedEntries; + ui64 UncommitedBlobIds; + ui64 UncommitedEntriesBytes; + ui64 CommitedEntries; + ui64 CommitedBlobIdsKnown; + ui64 CommitedBlobIdsLeft; + ui64 CommitedEntriesBytes; + ui64 BarriersSetSize; + + TIntrospection() + : UncommitedEntries(0) + , UncommitedBlobIds(0) + , UncommitedEntriesBytes(0) + , CommitedEntries(0) + , CommitedBlobIdsKnown(0) + , CommitedBlobIdsLeft(0) + , CommitedEntriesBytes(0) + , BarriersSetSize(0) + {} + }; + + TIntrospection IntrospectStateSize() const; protected: const TIntrusiveConstPtr<TTabletStorageInfo> TabletStorageInfo; const TAutoPtr<NPageCollection::TSteppedCookieAllocator> Cookies; @@ -82,10 +82,10 @@ protected: struct TChannelInfo { TMap<TGCTime, TGCBlobDelta> CommittedDelta; // we don't really need per-step map, what we really need is distinction b/w sent and not-yet-sent idsets TGCTime CollectSent; - TGCTime KnownGcBarrier; - TGCTime CommitedGcBarrier; - ui32 GcCounter; - ui32 GcWaitFor; + TGCTime KnownGcBarrier; + TGCTime CommitedGcBarrier; + ui32 GcCounter; + ui32 GcWaitFor; inline TChannelInfo(); void ApplyDelta(TGCTime time, TGCBlobDelta &delta); @@ -99,11 +99,11 @@ protected: ui32 PrevSnapshotStep; ui32 ConfirmedOnSendStep; THashMap<ui32, TChannelInfo> ChannelInfo; - TMap<TGCTime, TGCLogEntry> UncommittedDeltaLog; - TSet<TGCTime> HoldBarriersSet; + TMap<TGCTime, TGCLogEntry> UncommittedDeltaLog; + TSet<TGCTime> HoldBarriersSet; + + bool AllowGarbageCollection; - bool AllowGarbageCollection; - void ApplyDelta(TGCTime time, TGCBlobDelta &delta); void SendCollectGarbage(const TActorContext& executor); static inline void MergeVectors(THolder<TVector<TLogoBlobID>>& destination, const TVector<TLogoBlobID>& source); @@ -112,6 +112,6 @@ protected: }; void DeduplicateGCKeepVectors(TVector<TLogoBlobID> *keep, TVector<TLogoBlobID> *doNotKeep, ui32 barrierGen, ui32 barrierStep); - + } } diff --git a/ydb/core/tablet_flat/flat_executor_gclogic_ut.cpp b/ydb/core/tablet_flat/flat_executor_gclogic_ut.cpp index a21d9e7343..8c0c5ac6f0 100644 --- a/ydb/core/tablet_flat/flat_executor_gclogic_ut.cpp +++ b/ydb/core/tablet_flat/flat_executor_gclogic_ut.cpp @@ -6,111 +6,111 @@ namespace NTabletFlatExecutor { Y_UNIT_TEST_SUITE(TFlatTableExecutorGC) { bool TestDeduplication(TVector<TLogoBlobID> keep, TVector<TLogoBlobID> dontkeep, ui32 gen, ui32 step, TVector<TLogoBlobID> expectKeep, TVector<TLogoBlobID> expectnot) { - DeduplicateGCKeepVectors(&keep, &dontkeep, gen, step); - return (keep == expectKeep) && (dontkeep == expectnot); - } - + DeduplicateGCKeepVectors(&keep, &dontkeep, gen, step); + return (keep == expectKeep) && (dontkeep == expectnot); + } + Y_UNIT_TEST(TestGCVectorDeduplicaton) { - UNIT_ASSERT(TestDeduplication( - { - TLogoBlobID(1, 1, 1, 1, 0, 0), - TLogoBlobID(1, 1, 2, 1, 0, 0), - TLogoBlobID(1, 1, 3, 1, 0, 0), - TLogoBlobID(1, 1, 4, 1, 0, 0), - TLogoBlobID(1, 1, 5, 1, 0, 0), - TLogoBlobID(1, 1, 6, 1, 0, 0), - }, - { - TLogoBlobID(1, 1, 1, 1, 0, 0), - TLogoBlobID(1, 1, 2, 1, 0, 0), - TLogoBlobID(1, 1, 2, 1, 0, 1), - TLogoBlobID(1, 1, 6, 1, 0, 0), - }, - 0, 0, - { - TLogoBlobID(1, 1, 3, 1, 0, 0), - TLogoBlobID(1, 1, 4, 1, 0, 0), - TLogoBlobID(1, 1, 5, 1, 0, 0), - }, - { - TLogoBlobID(1, 1, 1, 1, 0, 0), - TLogoBlobID(1, 1, 2, 1, 0, 0), - TLogoBlobID(1, 1, 2, 1, 0, 1), - TLogoBlobID(1, 1, 6, 1, 0, 0), - } - )); - - - UNIT_ASSERT(TestDeduplication( - { - TLogoBlobID(1, 1, 1, 1, 0, 0), - TLogoBlobID(1, 1, 2, 1, 0, 0), - TLogoBlobID(1, 1, 3, 1, 0, 0), - TLogoBlobID(1, 1, 4, 1, 0, 0), - TLogoBlobID(1, 1, 5, 1, 0, 0), - TLogoBlobID(1, 1, 6, 1, 0, 0), - }, - { - TLogoBlobID(1, 1, 1, 1, 0, 0), - TLogoBlobID(1, 1, 2, 1, 0, 0), - TLogoBlobID(1, 1, 2, 1, 0, 1), - TLogoBlobID(1, 1, 6, 1, 0, 0), - }, - 1, 0, - { - TLogoBlobID(1, 1, 3, 1, 0, 0), - TLogoBlobID(1, 1, 4, 1, 0, 0), - TLogoBlobID(1, 1, 5, 1, 0, 0), - }, - { - TLogoBlobID(1, 1, 2, 1, 0, 1), - } - )); - - UNIT_ASSERT(TestDeduplication( - { - TLogoBlobID(1, 1, 1, 1, 0, 0), - TLogoBlobID(1, 1, 2, 1, 0, 0), - TLogoBlobID(1, 1, 3, 1, 0, 0), - TLogoBlobID(1, 1, 4, 1, 0, 0), - TLogoBlobID(1, 1, 5, 1, 0, 0), - TLogoBlobID(1, 1, 6, 1, 0, 0), - }, - { - TLogoBlobID(1, 1, 1, 1, 0, 0), - TLogoBlobID(1, 1, 2, 1, 0, 0), - TLogoBlobID(1, 1, 2, 1, 0, 1), - TLogoBlobID(1, 1, 6, 1, 0, 0), - }, - 1, 3, - { - TLogoBlobID(1, 1, 3, 1, 0, 0), - TLogoBlobID(1, 1, 4, 1, 0, 0), - TLogoBlobID(1, 1, 5, 1, 0, 0), - }, - { - TLogoBlobID(1, 1, 1, 1, 0, 0), - TLogoBlobID(1, 1, 2, 1, 0, 0), - TLogoBlobID(1, 1, 2, 1, 0, 1), - } - )); - - UNIT_ASSERT(TestDeduplication( - { - TLogoBlobID(1, 1, 1, 1, 0, 0), - }, - { - TLogoBlobID(1, 1, 2, 1, 0, 0), - }, - 0, 0, - { - TLogoBlobID(1, 1, 1, 1, 0, 0), - }, - { - TLogoBlobID(1, 1, 2, 1, 0, 0), - } - )); - } + UNIT_ASSERT(TestDeduplication( + { + TLogoBlobID(1, 1, 1, 1, 0, 0), + TLogoBlobID(1, 1, 2, 1, 0, 0), + TLogoBlobID(1, 1, 3, 1, 0, 0), + TLogoBlobID(1, 1, 4, 1, 0, 0), + TLogoBlobID(1, 1, 5, 1, 0, 0), + TLogoBlobID(1, 1, 6, 1, 0, 0), + }, + { + TLogoBlobID(1, 1, 1, 1, 0, 0), + TLogoBlobID(1, 1, 2, 1, 0, 0), + TLogoBlobID(1, 1, 2, 1, 0, 1), + TLogoBlobID(1, 1, 6, 1, 0, 0), + }, + 0, 0, + { + TLogoBlobID(1, 1, 3, 1, 0, 0), + TLogoBlobID(1, 1, 4, 1, 0, 0), + TLogoBlobID(1, 1, 5, 1, 0, 0), + }, + { + TLogoBlobID(1, 1, 1, 1, 0, 0), + TLogoBlobID(1, 1, 2, 1, 0, 0), + TLogoBlobID(1, 1, 2, 1, 0, 1), + TLogoBlobID(1, 1, 6, 1, 0, 0), + } + )); + + + UNIT_ASSERT(TestDeduplication( + { + TLogoBlobID(1, 1, 1, 1, 0, 0), + TLogoBlobID(1, 1, 2, 1, 0, 0), + TLogoBlobID(1, 1, 3, 1, 0, 0), + TLogoBlobID(1, 1, 4, 1, 0, 0), + TLogoBlobID(1, 1, 5, 1, 0, 0), + TLogoBlobID(1, 1, 6, 1, 0, 0), + }, + { + TLogoBlobID(1, 1, 1, 1, 0, 0), + TLogoBlobID(1, 1, 2, 1, 0, 0), + TLogoBlobID(1, 1, 2, 1, 0, 1), + TLogoBlobID(1, 1, 6, 1, 0, 0), + }, + 1, 0, + { + TLogoBlobID(1, 1, 3, 1, 0, 0), + TLogoBlobID(1, 1, 4, 1, 0, 0), + TLogoBlobID(1, 1, 5, 1, 0, 0), + }, + { + TLogoBlobID(1, 1, 2, 1, 0, 1), + } + )); + + UNIT_ASSERT(TestDeduplication( + { + TLogoBlobID(1, 1, 1, 1, 0, 0), + TLogoBlobID(1, 1, 2, 1, 0, 0), + TLogoBlobID(1, 1, 3, 1, 0, 0), + TLogoBlobID(1, 1, 4, 1, 0, 0), + TLogoBlobID(1, 1, 5, 1, 0, 0), + TLogoBlobID(1, 1, 6, 1, 0, 0), + }, + { + TLogoBlobID(1, 1, 1, 1, 0, 0), + TLogoBlobID(1, 1, 2, 1, 0, 0), + TLogoBlobID(1, 1, 2, 1, 0, 1), + TLogoBlobID(1, 1, 6, 1, 0, 0), + }, + 1, 3, + { + TLogoBlobID(1, 1, 3, 1, 0, 0), + TLogoBlobID(1, 1, 4, 1, 0, 0), + TLogoBlobID(1, 1, 5, 1, 0, 0), + }, + { + TLogoBlobID(1, 1, 1, 1, 0, 0), + TLogoBlobID(1, 1, 2, 1, 0, 0), + TLogoBlobID(1, 1, 2, 1, 0, 1), + } + )); + + UNIT_ASSERT(TestDeduplication( + { + TLogoBlobID(1, 1, 1, 1, 0, 0), + }, + { + TLogoBlobID(1, 1, 2, 1, 0, 0), + }, + 0, 0, + { + TLogoBlobID(1, 1, 1, 1, 0, 0), + }, + { + TLogoBlobID(1, 1, 2, 1, 0, 0), + } + )); + } } } diff --git a/ydb/core/tablet_flat/flat_executor_snapshot.h b/ydb/core/tablet_flat/flat_executor_snapshot.h index 54a39f204d..fae02f7fc8 100644 --- a/ydb/core/tablet_flat/flat_executor_snapshot.h +++ b/ydb/core/tablet_flat/flat_executor_snapshot.h @@ -53,7 +53,7 @@ namespace NTabletFlatExecutor { { Get(table, EReady::Done); Holds.Step = Min(Holds.Step, step); - Holds.Bundles[bundle].insert(loaner); + Holds.Bundles[bundle].insert(loaner); } void Moved(ui32 src, ui32 dst) diff --git a/ydb/core/tablet_flat/flat_executor_txloglogic.cpp b/ydb/core/tablet_flat/flat_executor_txloglogic.cpp index f373103f76..df59ddc245 100644 --- a/ydb/core/tablet_flat/flat_executor_txloglogic.cpp +++ b/ydb/core/tablet_flat/flat_executor_txloglogic.cpp @@ -1,4 +1,4 @@ -#include "flat_executor_txloglogic.h" +#include "flat_executor_txloglogic.h" #include "flat_executor_counters.h" #include "flat_exec_seat.h" #include "flat_exec_commit_mgr.h" @@ -10,41 +10,41 @@ #include <ydb/core/tablet_flat/flat_executor.pb.h> #include <util/system/sanitizers.h> -namespace NKikimr { -namespace NTabletFlatExecutor { - +namespace NKikimr { +namespace NTabletFlatExecutor { + LWTRACE_USING(TABLET_FLAT_PROVIDER) -const static ui64 MaxSizeToEmbedInLog = 2048; +const static ui64 MaxSizeToEmbedInLog = 2048; const static ui64 MaxBytesToBatch = 2 * 1024 * 1024; const static ui64 MaxItemsToBatch = 64; - + TLogicRedo::TCompletionEntry::TCompletionEntry(TAutoPtr<TSeat> seat, ui32 step) - : Step(step) + : Step(step) , InFlyRWTransaction(seat) -{} - +{} + TLogicRedo::TLogicRedo(TAutoPtr<NPageCollection::TSteppedCookieAllocator> cookies, TCommitManager *commitManager, TAutoPtr<NRedo::TQueue> queue) : CommitManager(commitManager) , Cookies(cookies) , Batch(new NRedo::TBatch) , Queue(queue) , Slicer(1, Cookies.Get(), NBlockIO::BlockSize) -{} - +{} + TLogicRedo::~TLogicRedo() -{} - +{} + void TLogicRedo::Describe(IOutputStream &out) const noexcept { return Queue->Describe(out); } void TLogicRedo::InstallCounters(TExecutorCounters *counters, TTabletCountersWithTxTypes *appTxCounters) { - Counters = counters; + Counters = counters; AppTxCounters = appTxCounters; -} - +} + NRedo::TStats TLogicRedo::LogStats() const noexcept { return { Queue->Items, Queue->Memory, Queue->LargeGlobIdsBytes }; @@ -71,54 +71,54 @@ bool TLogicRedo::TerminateTransaction(TAutoPtr<TSeat> seat, const TActorContext } void CompleteRoTransaction(TAutoPtr<TSeat> seat, const TActorContext &ownerCtx, TExecutorCounters *counters, TTabletCountersWithTxTypes *appTxCounters ) { - const TTxType txType = seat->Self->GetTxType(); + const TTxType txType = seat->Self->GetTxType(); - const ui64 latencyus = ui64(1000000. * seat->LatencyTimer.Passed()); - counters->Percentile()[TExecutorCounters::TX_PERCENTILE_LATENCY_RO].IncrementFor(latencyus); - - THPTimer completeTimer; + const ui64 latencyus = ui64(1000000. * seat->LatencyTimer.Passed()); + counters->Percentile()[TExecutorCounters::TX_PERCENTILE_LATENCY_RO].IncrementFor(latencyus); + + THPTimer completeTimer; LWTRACK(TransactionCompleteBegin, seat->Self->Orbit, seat->UniqID); seat->Complete(ownerCtx); LWTRACK(TransactionCompleteEnd, seat->Self->Orbit, seat->UniqID); - + const ui64 completeTimeus = ui64(1000000. * completeTimer.Passed()); - counters->Cumulative()[TExecutorCounters::TX_RO_COMPLETED].Increment(1); - if (appTxCounters && txType != UnknownTxType) - appTxCounters->TxCumulative(txType, COUNTER_TT_RO_COMPLETED).Increment(1); - counters->Percentile()[TExecutorCounters::TX_PERCENTILE_COMMITED_CPUTIME].IncrementFor(completeTimeus); + counters->Cumulative()[TExecutorCounters::TX_RO_COMPLETED].Increment(1); + if (appTxCounters && txType != UnknownTxType) + appTxCounters->TxCumulative(txType, COUNTER_TT_RO_COMPLETED).Increment(1); + counters->Percentile()[TExecutorCounters::TX_PERCENTILE_COMMITED_CPUTIME].IncrementFor(completeTimeus); counters->Cumulative()[TExecutorCounters::CONSUMED_CPU].Increment(completeTimeus); - if (appTxCounters && txType != UnknownTxType) - appTxCounters->TxCumulative(txType, COUNTER_TT_COMMITED_CPUTIME).Increment(completeTimeus); -} - + if (appTxCounters && txType != UnknownTxType) + appTxCounters->TxCumulative(txType, COUNTER_TT_COMMITED_CPUTIME).Increment(completeTimeus); +} + bool TLogicRedo::CommitROTransaction(TAutoPtr<TSeat> seat, const TActorContext &ownerCtx) { - if (CompletionQueue.empty()) { - CompleteRoTransaction(seat, ownerCtx, Counters, AppTxCounters); - return true; - } else { + if (CompletionQueue.empty()) { + CompleteRoTransaction(seat, ownerCtx, Counters, AppTxCounters); + return true; + } else { LWTRACK(TransactionReadOnlyWait, seat->Self->Orbit, seat->UniqID, CompletionQueue.back().Step); CompletionQueue.back().WaitingROTransactions.push_back(seat); - return false; - } -} - + return false; + } +} + void TLogicRedo::FlushBatchedLog() { if (TAutoPtr<TLogCommit> commit = Batch->Commit) { auto affects = Batch->Affects(); MakeLogEntry(*commit, Batch->Flush(), affects, true); CommitManager->Commit(commit); - } - + } + Y_VERIFY(Batch->Commit == nullptr, "Batch still has acquired commit"); -} - +} + TLogicRedo::TCommitRWTransactionResult TLogicRedo::CommitRWTransaction( TAutoPtr<TSeat> seat, NTable::TChange &change, bool force) { seat->CommitTimer.Reset(); - + Y_VERIFY(force || !(change.Scheme || change.Annex)); const TTxType txType = seat->Self->GetTxType(); @@ -143,15 +143,15 @@ TLogicRedo::TCommitRWTransactionResult TLogicRedo::CommitRWTransaction( if (force || MaxItemsToBatch < 2 || change.Redo.size() > MaxBytesToBatch) { FlushBatchedLog(); - + auto commit = CommitManager->Begin(true, ECommit::Redo); - + commit->PushTx(seat.Get()); CompletionQueue.push_back({ seat, commit->Step }); MakeLogEntry(*commit, std::move(change.Redo), change.Affects, !force); const auto was = commit->GcDelta.Created.size(); - + for (auto &one: change.Annex) { if (one.GId.Logo.Step() != commit->Step) { Y_Fail( @@ -172,30 +172,30 @@ TLogicRedo::TCommitRWTransactionResult TLogicRedo::CommitRWTransaction( Y_VERIFY(was + change.Annex.size() == commit->GcDelta.Created.size()); return { commit, false }; - } else { + } else { if (Batch->Bytes + change.Redo.size() > MaxBytesToBatch) FlushBatchedLog(); - + if (!Batch->Commit) Batch->Commit = CommitManager->Begin(false, ECommit::Redo); - + Batch->Commit->PushTx(seat.Get()); CompletionQueue.push_back({ seat, Batch->Commit->Step }); - + Batch->Add(std::move(change.Redo), change.Affects); if (Batch->Bodies.size() >= MaxItemsToBatch) FlushBatchedLog(); return { nullptr, bool(Batch->Commit) }; - } -} - + } +} + void TLogicRedo::MakeLogEntry(TLogCommit &commit, TString redo, TArrayRef<const ui32> affects, bool embed) { if (redo) { NSan::CheckMemIsInitialized(redo.data(), redo.size()); - + Cookies->Switch(commit.Step, true /* require step switch */); auto coded = NPageCollection::TSlicer::Lz4()->Encode(redo); @@ -211,59 +211,59 @@ void TLogicRedo::MakeLogEntry(TLogCommit &commit, TString redo, TArrayRef<const Queue->Push({ Cookies->Gen, commit.Step }, affects, largeGlobId); } - } -} - + } +} + ui64 TLogicRedo::Confirm(ui32 step, const TActorContext &ctx, const TActorId &ownerId) { - Y_VERIFY(!CompletionQueue.empty(), "t: %" PRIu64 - " non-expected confirmation %" PRIu32 + Y_VERIFY(!CompletionQueue.empty(), "t: %" PRIu64 + " non-expected confirmation %" PRIu32 ", prev %" PRIu32, Cookies->Tablet, step, PrevConfirmedStep); - - Y_VERIFY(CompletionQueue[0].Step == step, "t: %" PRIu64 - " inconsistent confirmation head: %" PRIu32 - ", step: %" PRIu32 - ", queue size: %" PRISZT - ", prev confimed: %" PRIu32 + + Y_VERIFY(CompletionQueue[0].Step == step, "t: %" PRIu64 + " inconsistent confirmation head: %" PRIu32 + ", step: %" PRIu32 + ", queue size: %" PRISZT + ", prev confimed: %" PRIu32 , Cookies->Tablet, CompletionQueue[0].Step, step, CompletionQueue.size(), PrevConfirmedStep); - - PrevConfirmedStep = step; - - const TActorContext ownerCtx = ctx.MakeFor(ownerId); - ui64 confirmedTransactions = 0; - do { - TCompletionEntry &entry = CompletionQueue[0]; + + PrevConfirmedStep = step; + + const TActorContext ownerCtx = ctx.MakeFor(ownerId); + ui64 confirmedTransactions = 0; + do { + TCompletionEntry &entry = CompletionQueue[0]; auto &seat = entry.InFlyRWTransaction; - + const TTxType txType = seat->Self->GetTxType(); const ui64 commitLatencyus = ui64(1000000. * seat->CommitTimer.Passed()); const ui64 latencyus = ui64(1000000. * seat->LatencyTimer.Passed()); - Counters->Percentile()[TExecutorCounters::TX_PERCENTILE_LATENCY_COMMIT].IncrementFor(commitLatencyus); - Counters->Percentile()[TExecutorCounters::TX_PERCENTILE_LATENCY_RW].IncrementFor(latencyus); - - ++confirmedTransactions; - THPTimer completeTimer; + Counters->Percentile()[TExecutorCounters::TX_PERCENTILE_LATENCY_COMMIT].IncrementFor(commitLatencyus); + Counters->Percentile()[TExecutorCounters::TX_PERCENTILE_LATENCY_RW].IncrementFor(latencyus); + + ++confirmedTransactions; + THPTimer completeTimer; LWTRACK(TransactionCompleteBegin, seat->Self->Orbit, seat->UniqID); entry.InFlyRWTransaction->Complete(ownerCtx); LWTRACK(TransactionCompleteEnd, seat->Self->Orbit, seat->UniqID); - + const ui64 completeTimeus = ui64(1000000. * completeTimer.Passed()); - Counters->Cumulative()[TExecutorCounters::TX_RW_COMPLETED].Increment(1); - if (AppTxCounters && txType != UnknownTxType) - AppTxCounters->TxCumulative(txType, COUNTER_TT_RW_COMPLETED).Increment(1); - Counters->Percentile()[TExecutorCounters::TX_PERCENTILE_COMMITED_CPUTIME].IncrementFor(completeTimeus); + Counters->Cumulative()[TExecutorCounters::TX_RW_COMPLETED].Increment(1); + if (AppTxCounters && txType != UnknownTxType) + AppTxCounters->TxCumulative(txType, COUNTER_TT_RW_COMPLETED).Increment(1); + Counters->Percentile()[TExecutorCounters::TX_PERCENTILE_COMMITED_CPUTIME].IncrementFor(completeTimeus); Counters->Cumulative()[TExecutorCounters::CONSUMED_CPU].Increment(completeTimeus); - if (AppTxCounters && txType != UnknownTxType) - AppTxCounters->TxCumulative(txType, COUNTER_TT_COMMITED_CPUTIME).Increment(completeTimeus); - - for (auto &x : entry.WaitingROTransactions) { - ++confirmedTransactions; - CompleteRoTransaction(x, ownerCtx, Counters, AppTxCounters); - } - + if (AppTxCounters && txType != UnknownTxType) + AppTxCounters->TxCumulative(txType, COUNTER_TT_COMMITED_CPUTIME).Increment(completeTimeus); + + for (auto &x : entry.WaitingROTransactions) { + ++confirmedTransactions; + CompleteRoTransaction(x, ownerCtx, Counters, AppTxCounters); + } + for (auto &x : entry.WaitingTerminatedTransactions) { const TTxType roTxType = x->Self->GetTxType(); - x->Self->Terminate(x->TerminationReason, ownerCtx); + x->Self->Terminate(x->TerminationReason, ownerCtx); Counters->Cumulative()[TExecutorCounters::TX_TERMINATED].Increment(1); if (AppTxCounters && roTxType != UnknownTxType) @@ -272,31 +272,31 @@ ui64 TLogicRedo::Confirm(ui32 step, const TActorContext &ctx, const TActorId &ow ++confirmedTransactions; } - CompletionQueue.pop_front(); - } while (!CompletionQueue.empty() && CompletionQueue[0].Step == step); - - return confirmedTransactions; -} - + CompletionQueue.pop_front(); + } while (!CompletionQueue.empty() && CompletionQueue[0].Step == step); + + return confirmedTransactions; +} + void TLogicRedo::SnapToLog(NKikimrExecutorFlat::TLogSnapshot &snap) { Y_VERIFY(Batch->Commit == nullptr); - + Queue->Flush(snap); - + for (auto &xpair : Queue->Edges) { auto genstep = ExpandGenStepPair(xpair.second.TxStamp); auto *x = snap.AddTableSnapshoted(); - x->SetTable(xpair.first); - x->SetGeneration(genstep.first); - x->SetStep(genstep.second); + x->SetTable(xpair.first); + x->SetGeneration(genstep.first); + x->SetStep(genstep.second); x->SetHead(xpair.second.Head.ToProto()); - } -} - + } +} + void TLogicRedo::CutLog(ui32 table, NTable::TSnapEdge edge, TGCBlobDelta &gc) { Queue->Cut(table, edge, gc); -} - -}} +} + +}} diff --git a/ydb/core/tablet_flat/flat_executor_txloglogic.h b/ydb/core/tablet_flat/flat_executor_txloglogic.h index 9e6421e164..1272c4f947 100644 --- a/ydb/core/tablet_flat/flat_executor_txloglogic.h +++ b/ydb/core/tablet_flat/flat_executor_txloglogic.h @@ -1,5 +1,5 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include "flat_sausage_grind.h" #include "flat_sausage_slicer.h" #include "flat_dbase_change.h" @@ -10,10 +10,10 @@ #include "logic_redo_eggs.h" #include <ydb/core/tablet_flat/flat_executor.pb.h> #include <ydb/core/tablet/tablet_counters_protobuf.h> - -namespace NKikimr { -namespace NTabletFlatExecutor { - + +namespace NKikimr { +namespace NTabletFlatExecutor { + class TCommitManager; namespace NRedo { @@ -30,33 +30,33 @@ class TLogicRedo { TAutoPtr<NRedo::TBatch> Batch; TAutoPtr<NRedo::TQueue> Queue; NPageCollection::TSlicer Slicer; - + TExecutorCounters *Counters = nullptr; TTabletCountersWithTxTypes *AppTxCounters = nullptr; - struct TCompletionEntry { - ui32 Step; - + struct TCompletionEntry { + ui32 Step; + /* vvvv argh.... */ TAutoPtr<TSeat> InFlyRWTransaction; TVector<TAutoPtr<TSeat>> WaitingROTransactions; TVector<TAutoPtr<TSeat>> WaitingTerminatedTransactions; TCompletionEntry(TAutoPtr<TSeat> seat, ui32 step); - }; - + }; + TDeque<TCompletionEntry> CompletionQueue; // would be graph once data-dependencies implemented ui32 PrevConfirmedStep = 0; - -public: - struct TCommitRWTransactionResult { + +public: + struct TCommitRWTransactionResult { TAutoPtr<TLogCommit> Commit; - bool NeedFlush; - }; - + bool NeedFlush; + }; + TLogicRedo(TAutoPtr<NPageCollection::TSteppedCookieAllocator>, TCommitManager*, TAutoPtr<NRedo::TQueue>); ~TLogicRedo(); - + void Describe(IOutputStream &out) const noexcept; void InstallCounters(TExecutorCounters *counters, TTabletCountersWithTxTypes* appTxCounters); bool TerminateTransaction(TAutoPtr<TSeat>, const TActorContext &ctx, const TActorId &ownerId); @@ -64,15 +64,15 @@ public: TCommitRWTransactionResult CommitRWTransaction(TAutoPtr<TSeat> seat, NTable::TChange &change, bool force); void MakeLogEntry(TLogCommit&, TString redo, TArrayRef<const ui32> affects, bool embed); void FlushBatchedLog(); - + ui64 Confirm(ui32 step, const TActorContext &ctx, const TActorId &ownerId); - + void CutLog(ui32 table, NTable::TSnapEdge, TGCBlobDelta&); void SnapToLog(NKikimrExecutorFlat::TLogSnapshot&); NRedo::TStats LogStats() const noexcept; TArrayRef<const NRedo::TUsage> GrabLogUsage() const noexcept; -}; - +}; + void CompleteRoTransaction(TAutoPtr<TSeat>, const TActorContext &ownerCtx, TExecutorCounters *counters, TTabletCountersWithTxTypes *appTxCounters); - -}} + +}} diff --git a/ydb/core/tablet_flat/flat_sausagecache.cpp b/ydb/core/tablet_flat/flat_sausagecache.cpp index 5ba65c2f5a..4d396e8f75 100644 --- a/ydb/core/tablet_flat/flat_sausagecache.cpp +++ b/ydb/core/tablet_flat/flat_sausagecache.cpp @@ -1,28 +1,28 @@ -#include "flat_sausagecache.h" -#include <util/generic/xrange.h> - -namespace NKikimr { -namespace NTabletFlatExecutor { - +#include "flat_sausagecache.h" +#include <util/generic/xrange.h> + +namespace NKikimr { +namespace NTabletFlatExecutor { + TPrivatePageCache::TPage::TPage(ui32 size, ui32 pageId, TInfo* info) - : LoadState(LoadStateNo) - , CacheGeneration(TCacheCacheConfig::CacheGenNone) + : LoadState(LoadStateNo) + , CacheGeneration(TCacheCacheConfig::CacheGenNone) , Sticky(false) , SharedPending(false) , Padding(0) - , Size(size) - , Id(pageId) + , Size(size) + , Id(pageId) , Info(info) -{} - +{} + TPrivatePageCache::TInfo::TInfo(TIntrusiveConstPtr<NPageCollection::IPageCollection> pageCollection) : Id(pageCollection->Label()) , PageCollection(std::move(pageCollection)) , Users(0) -{ +{ PageMap.resize(PageCollection->Total()); -} - +} + TPrivatePageCache::TInfo::TInfo(const TInfo &info) : Id(info.Id) , PageCollection(info.PageCollection) @@ -44,15 +44,15 @@ TPrivatePageCache::TInfo::TInfo(const TInfo &info) TPrivatePageCache::TPrivatePageCache(const TCacheCacheConfig &cacheConfig, bool prepareForSharedCache) : Cache(cacheConfig) - , PrepareForSharedCache(prepareForSharedCache) -{ -} - + , PrepareForSharedCache(prepareForSharedCache) +{ +} + void TPrivatePageCache::RegisterPageCollection(TIntrusivePtr<TInfo> info) { auto itpair = PageCollections.insert(decltype(PageCollections)::value_type(info->Id, info)); Y_VERIFY(itpair.second, "double registration of page collection is forbidden. logic flaw?"); ++Stats.TotalCollections; - + TPage* evicted = nullptr; for (const auto& kv : info->PageMap) { @@ -60,7 +60,7 @@ void TPrivatePageCache::RegisterPageCollection(TIntrusivePtr<TInfo> info) { Y_VERIFY_DEBUG(page); if (page->LoadState == TPage::LoadStateLoaded && !page->Sticky) { evicted = TPage::Join(evicted, Cache.Touch(page)); - } + } if (page->SharedBody) Stats.TotalSharedBody += page->Size; if (page->PinnedBody) @@ -69,49 +69,49 @@ void TPrivatePageCache::RegisterPageCollection(TIntrusivePtr<TInfo> info) { Stats.TotalExclusive += page->Size; if (page->Sticky) Stats.TotalSticky += page->Size; - } + } Evict(evicted); ++info->Users; -} - +} + TPrivatePageCache::TPage::TWaitQueuePtr TPrivatePageCache::ForgetPageCollection(TLogoBlobID id) { - // todo: amortize destruction cost (how?) + // todo: amortize destruction cost (how?) auto it = PageCollections.find(id); Y_VERIFY(it != PageCollections.end(), "trying to forget unknown page collection. logic flaw?"); TIntrusivePtr<TInfo> info = it->second; - - TPage::TWaitQueuePtr ret; + + TPage::TWaitQueuePtr ret; for (const auto& kv : info->PageMap) { auto* page = kv.second.Get(); Y_VERIFY_DEBUG(page); if (page->LoadState == TPage::LoadStateRequested) { while (TPrivatePageCacheWaitPad *x = page->WaitQueue->Pop()) { - if (0 == x->Dec()) { - if (!ret) + if (0 == x->Dec()) { + if (!ret) ret = new TPrivatePageCache::TPage::TWaitQueue; - ret->Push(x); - } - } + ret->Push(x); + } + } page->WaitQueue.Destroy(); } - + if (page->PinPad) { page->PinPad.Drop(); Stats.PinnedSetSize -= page->Size; if (page->LoadState != TPage::LoadStateLoaded) Stats.PinnedLoadSize -= page->Size; - } - } - + } + } + UnlockPageCollection(id); - - return ret; -} - + + return ret; +} + void TPrivatePageCache::LockPageCollection(TLogoBlobID id) { auto it = PageCollections.find(id); Y_VERIFY(it != PageCollections.end(), "trying to lock unknown page collection. logic flaw?"); @@ -158,36 +158,36 @@ bool TPrivatePageCache::UnlockPageCollection(TLogoBlobID id) { } THashMap<TLogoBlobID, THashMap<ui32, TSharedData>> TPrivatePageCache::GetPrepareSharedTouched() { - return std::move(ToTouchShared); -} - + return std::move(ToTouchShared); +} + TPrivatePageCache::TInfo* TPrivatePageCache::Info(TLogoBlobID id) { auto *x = PageCollections.FindPtr(id); - if (x) - return x->Get(); - else - return nullptr; -} - + if (x) + return x->Get(); + else + return nullptr; +} + void TPrivatePageCache::Touch(TPage *page) { if (!page->Sticky) { - switch (page->LoadState) { - case TPage::LoadStateNo: - return; - case TPage::LoadStateLoaded: - case TPage::LoadStateRequested: - case TPage::LoadStateRequestedAsync: - return Evict(Cache.Touch(page)); - } - } -} - + switch (page->LoadState) { + case TPage::LoadStateNo: + return; + case TPage::LoadStateLoaded: + case TPage::LoadStateRequested: + case TPage::LoadStateRequestedAsync: + return Evict(Cache.Touch(page)); + } + } +} + void TPrivatePageCache::Touch(ui32 pageId, TInfo *info) { if (auto* page = info->GetPage(pageId)) { Touch(page); } -} - +} + void TPrivatePageCache::MarkSticky(ui32 pageId, TInfo *collectionInfo) { TPage *page = collectionInfo->EnsurePage(pageId); if (Y_LIKELY(!page->Sticky)) { @@ -202,39 +202,39 @@ void TPrivatePageCache::MarkSticky(ui32 pageId, TInfo *collectionInfo) { page->CacheGeneration = TCacheCacheConfig::CacheGenNone; } } -} - +} + TIntrusivePtr<TPrivatePageCachePinPad> TPrivatePageCache::Pin(ui32 pageId, TInfo *info) { TPage *page = info->EnsurePage(pageId); - if (!page->PinPad) { + if (!page->PinPad) { page->PinPad = new TPrivatePageCachePinPad(); Stats.PinnedSetSize += page->Size; - + // N.B. it's ok not to call Touch here, because pinned pages don't have // to be part of the cache even when they are loaded. Restore(page); - if (page->LoadState != TPage::LoadStateLoaded) + if (page->LoadState != TPage::LoadStateLoaded) Stats.PinnedLoadSize += page->Size; - } - - return page->PinPad; -} - + } + + return page->PinPad; +} + void TPrivatePageCache::Unpin(ui32 pageId, TPrivatePageCachePinPad *pad, TInfo *info) { TPage *page = info->GetPage(pageId); if (page && page->PinPad.Get() == pad) { - if (page->PinPad.RefCount() == 1) { - page->PinPad.Drop(); + if (page->PinPad.RefCount() == 1) { + page->PinPad.Drop(); Stats.PinnedSetSize -= page->Size; - if (page->LoadState != TPage::LoadStateLoaded) + if (page->LoadState != TPage::LoadStateLoaded) Stats.PinnedLoadSize -= page->Size; - + if (page->CacheGeneration != TCacheCacheConfig::CacheGenNone || page->Sticky) - return; + return; - if (page->LoadState == TPage::LoadStateLoaded) { - page->LoadState = TPage::LoadStateNo; + if (page->LoadState == TPage::LoadStateLoaded) { + page->LoadState = TPage::LoadStateNo; if (!page->SharedPending) { if (Y_LIKELY(page->PinnedBody)) { Stats.TotalPinnedBody -= page->Size; @@ -245,55 +245,55 @@ void TPrivatePageCache::Unpin(ui32 pageId, TPrivatePageCachePinPad *pad, TInfo * } } page->SharedBody.UnUse(); - } - } - } -} - + } + } + } +} + std::pair<ui32, ui64> TPrivatePageCache::Load(TVector<ui32> &pages, TPrivatePageCacheWaitPad *waitPad, TInfo *info) { - ui32 blocksToRequest = 0; - ui64 bytesToRequest = 0; - + ui32 blocksToRequest = 0; + ui64 bytesToRequest = 0; + auto it = pages.begin(); auto end = pages.end(); - while (it != end) { + while (it != end) { TPage *page = info->EnsurePage(*it); - switch (page->LoadState) { - case TPage::LoadStateNo: + switch (page->LoadState) { + case TPage::LoadStateNo: Y_VERIFY_DEBUG(!page->SharedPending, "Trying to load a page that may be restored"); [[fallthrough]]; - case TPage::LoadStateRequestedAsync: - page->LoadState = TPage::LoadStateRequested; + case TPage::LoadStateRequestedAsync: + page->LoadState = TPage::LoadStateRequested; bytesToRequest += page->Size; - + Y_VERIFY(!page->WaitQueue); page->WaitQueue = new TPage::TWaitQueue(); page->WaitQueue->Push(waitPad); waitPad->Inc(); - - ++blocksToRequest; - ++it; - break; - case TPage::LoadStateLoaded: + + ++blocksToRequest; + ++it; + break; + case TPage::LoadStateLoaded: Y_FAIL("must not request already loaded pages"); - case TPage::LoadStateRequested: + case TPage::LoadStateRequested: if (!page->WaitQueue) page->WaitQueue = new TPage::TWaitQueue(); - + page->WaitQueue->Push(waitPad); waitPad->Inc(); - - --end; - if (end != it) - *it = *end; - break; - } - } + + --end; + if (end != it) + *it = *end; + break; + } + } pages.erase(end, pages.end()); - return std::make_pair(blocksToRequest, bytesToRequest); -} - + return std::make_pair(blocksToRequest, bytesToRequest); +} + bool TPrivatePageCache::Restore(TPage *page) { if (page->LoadState == TPage::LoadStateNo && page->SharedPending) { page->LoadState = TPage::LoadStateLoaded; @@ -305,20 +305,20 @@ bool TPrivatePageCache::Restore(TPage *page) { if (Y_LIKELY(!page->PinnedBody)) Stats.TotalPinnedBody += page->Size; page->PinnedBody = TPinnedPageRef(page->SharedBody).GetData(); - page->LoadState = TPage::LoadStateLoaded; + page->LoadState = TPage::LoadStateLoaded; return true; } - + page->SharedBody.Drop(); Stats.TotalSharedBody -= page->Size; if (Y_UNLIKELY(page->PinnedBody)) { Stats.TotalExclusive += page->Size; } - } + } return false; } - + const TSharedData* TPrivatePageCache::Lookup(ui32 pageId, TInfo *info) { TPage *page = info->GetPage(pageId); if (!page) @@ -329,8 +329,8 @@ const TSharedData* TPrivatePageCache::Lookup(ui32 pageId, TInfo *info) { } return page->GetBody(); -} - +} + TSharedPageRef TPrivatePageCache::LookupShared(ui32 pageId, TInfo *info) { TPage *page = info->GetPage(pageId); if (!page) @@ -345,13 +345,13 @@ TSharedPageRef TPrivatePageCache::LookupShared(ui32 pageId, TInfo *info) { TPrivatePageCache::TPage::TWaitQueuePtr TPrivatePageCache::ProvideBlock( NSharedCache::TEvResult::TLoaded&& loaded, TInfo *info) -{ +{ Y_VERIFY_DEBUG(loaded.Page && loaded.Page.IsUsed()); TPage *page = info->EnsurePage(loaded.PageId); - - if (page->LoadState != TPage::LoadStateLoaded && page->PinPad) + + if (page->LoadState != TPage::LoadStateLoaded && page->PinPad) Stats.PinnedLoadSize -= page->Size; - + if (Y_UNLIKELY(page->SharedBody)) Stats.TotalSharedBody -= page->Size; if (Y_UNLIKELY(page->PinnedBody)) @@ -360,66 +360,66 @@ TPrivatePageCache::TPage::TWaitQueuePtr TPrivatePageCache::ProvideBlock( Stats.TotalExclusive -= page->Size; if (Y_UNLIKELY(page->SharedPending)) Stats.TotalSharedPending -= page->Size; - + // N.B. we must be careful not to accidentally drop the sticky bit page->Fill(std::move(loaded.Page), page->Sticky); Stats.TotalSharedBody += page->Size; Stats.TotalPinnedBody += page->Size; - TPage::TWaitQueuePtr ret; - if (page->WaitQueue) { + TPage::TWaitQueuePtr ret; + if (page->WaitQueue) { while (TPrivatePageCacheWaitPad *x = page->WaitQueue->Pop()) { - if (0 == x->Dec()) { - if (!ret) - ret = new TPage::TWaitQueue(); - ret->Push(x); - } - } - page->WaitQueue.Destroy(); - } - - if (page->CacheGeneration == TCacheCacheConfig::CacheGenNone + if (0 == x->Dec()) { + if (!ret) + ret = new TPage::TWaitQueue(); + ret->Push(x); + } + } + page->WaitQueue.Destroy(); + } + + if (page->CacheGeneration == TCacheCacheConfig::CacheGenNone && !page->Sticky && !page->PinPad) - { // should be cache refresh by provided profile + { // should be cache refresh by provided profile Touch(page); - } - - return ret; -} - + } + + return ret; +} + void TPrivatePageCache::UpdateCacheSize(ui64 cacheSize) { - Cache.UpdateCacheSize(cacheSize); -} - + Cache.UpdateCacheSize(cacheSize); +} + THashMap<TLogoBlobID, TIntrusivePtr<TPrivatePageCache::TInfo>> TPrivatePageCache::DetachPrivatePageCache() { THashMap<TLogoBlobID, TIntrusivePtr<TPrivatePageCache::TInfo>> ret; - + for (const auto &xpair : PageCollections) { TIntrusivePtr<TInfo> info(new TInfo(*xpair.second)); - ret.insert(std::make_pair(xpair.first, info)); - } - - return ret; -} - + ret.insert(std::make_pair(xpair.first, info)); + } + + return ret; +} + void TPrivatePageCache::Evict(TPage *pages) { - if (pages == nullptr) - return; - - TPage *page = pages; - for (;;) { - Y_VERIFY(page->CacheGeneration == TCacheCacheConfig::CacheGenEvicted, "evicting non-evicted page with gen %" PRIu32, (ui32)page->CacheGeneration); - page->CacheGeneration = TCacheCacheConfig::CacheGenNone; - + if (pages == nullptr) + return; + + TPage *page = pages; + for (;;) { + Y_VERIFY(page->CacheGeneration == TCacheCacheConfig::CacheGenEvicted, "evicting non-evicted page with gen %" PRIu32, (ui32)page->CacheGeneration); + page->CacheGeneration = TCacheCacheConfig::CacheGenNone; + Y_VERIFY(!page->Sticky, "Unexpected sticky page evicted from cache"); - switch (page->LoadState) { - case TPage::LoadStateNo: - case TPage::LoadStateRequested: - case TPage::LoadStateRequestedAsync: - break; - case TPage::LoadStateLoaded: + switch (page->LoadState) { + case TPage::LoadStateNo: + case TPage::LoadStateRequested: + case TPage::LoadStateRequestedAsync: + break; + case TPage::LoadStateLoaded: if (PrepareForSharedCache) { auto &x = ToTouchShared[page->Info->Id][page->Id]; if (!page->SharedPending && !page->SharedBody && page->PinnedBody) { @@ -428,9 +428,9 @@ void TPrivatePageCache::Evict(TPage *pages) { Stats.TotalSharedPending += page->Size; page->SharedPending = true; x = page->PinnedBody; - } + } } - + if (!page->PinPad) { page->LoadState = TPage::LoadStateNo; if (!page->SharedPending) { @@ -441,16 +441,16 @@ void TPrivatePageCache::Evict(TPage *pages) { } page->PinnedBody = { }; } - } + } page->SharedBody.UnUse(); - } - - break; - default: + } + + break; + default: Y_FAIL("unknown load state"); - } - - TPage *next = page->Next()->Node(); + } + + TPage *next = page->Next()->Node(); if (page != next) { page->Unlink(); } @@ -468,10 +468,10 @@ void TPrivatePageCache::Evict(TPage *pages) { } if (page == next) - break; - - page = next; - } -} - -}} + break; + + page = next; + } +} + +}} diff --git a/ydb/core/tablet_flat/flat_sausagecache.h b/ydb/core/tablet_flat/flat_sausagecache.h index 8f4de229b3..ac040eb017 100644 --- a/ydb/core/tablet_flat/flat_sausagecache.h +++ b/ydb/core/tablet_flat/flat_sausagecache.h @@ -1,25 +1,25 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include "flat_sausage_gut.h" #include "flat_sausage_fetch.h" #include "shared_handle.h" #include "shared_cache_events.h" #include <ydb/core/util/cache_cache.h> #include <ydb/core/util/page_map.h> - -namespace NKikimr { -namespace NTabletFlatExecutor { - + +namespace NKikimr { +namespace NTabletFlatExecutor { + struct TPrivatePageCachePinPad : public TAtomicRefCount<TPrivatePageCachePinPad> { // no internal state }; - + struct TPrivatePageCacheWaitPad : public TExplicitSimpleCounter { // no internal state -}; - +}; + class TPrivatePageCache { -public: +public: struct TInfo; struct TStats { @@ -33,33 +33,33 @@ public: ui64 PinnedLoadSize = 0; // number of bytes pinned by transactions (which are currently being loaded) }; - struct TPage : public TIntrusiveListItem<TPage> { + struct TPage : public TIntrusiveListItem<TPage> { using TWaitQueue = TOneOneQueueInplace<TPrivatePageCacheWaitPad *, 64>; - using TWaitQueuePtr = TAutoPtr<TWaitQueue, TWaitQueue::TCleanDestructor>; - - enum ELoadState { - LoadStateNo, - LoadStateLoaded, - LoadStateRequested, - LoadStateRequestedAsync, - }; - - ui64 LoadState : 2; - ui64 CacheGeneration : 3; + using TWaitQueuePtr = TAutoPtr<TWaitQueue, TWaitQueue::TCleanDestructor>; + + enum ELoadState { + LoadStateNo, + LoadStateLoaded, + LoadStateRequested, + LoadStateRequestedAsync, + }; + + ui64 LoadState : 2; + ui64 CacheGeneration : 3; ui64 Sticky : 1; ui64 SharedPending : 1; ui64 Padding : 1; - const ui64 Size : 24; - const ui64 Id : 32; - + const ui64 Size : 24; + const ui64 Id : 32; + TInfo* const Info; TIntrusivePtr<TPrivatePageCachePinPad> PinPad; - TWaitQueuePtr WaitQueue; + TWaitQueuePtr WaitQueue; TSharedPageRef SharedBody; TSharedData PinnedBody; - + TPage(ui32 size, ui32 pageId, TInfo* info); - + TPage(const TPage&) = delete; TPage(TPage&&) = delete; @@ -122,13 +122,13 @@ public: return a; } - struct TWeight { - static ui64 Get(TPage *x) { - return x->Size; - } - }; - }; - + struct TWeight { + static ui64 Get(TPage *x) { + return x->Size; + } + }; + }; + struct TInfo : public TThrRefBase { ui32 Total() const noexcept { return PageMap.size(); @@ -225,32 +225,32 @@ public: } } - const TLogoBlobID Id; + const TLogoBlobID Id; const TIntrusiveConstPtr<NPageCollection::IPageCollection> PageCollection; TPageMap<THolder<TPage>> PageMap; ui64 Users; - + explicit TInfo(TIntrusiveConstPtr<NPageCollection::IPageCollection> pack); TInfo(const TInfo &info); - }; - -public: + }; + +public: TPrivatePageCache(const TCacheCacheConfig &cacheConfig, bool prepareForSharedCache = true); - + void RegisterPageCollection(TIntrusivePtr<TInfo> info); TPage::TWaitQueuePtr ForgetPageCollection(TLogoBlobID id); - + void LockPageCollection(TLogoBlobID id); // Return true for page collections removed after unlock. bool UnlockPageCollection(TLogoBlobID id); - TInfo* Info(TLogoBlobID id); - - void Touch(ui32 page, TInfo *collectionInfo); + TInfo* Info(TLogoBlobID id); + + void Touch(ui32 page, TInfo *collectionInfo); TIntrusivePtr<TPrivatePageCachePinPad> Pin(ui32 page, TInfo *collectionInfo); void Unpin(ui32 page, TPrivatePageCachePinPad *pad, TInfo *collectionInfo); void MarkSticky(ui32 pageId, TInfo *collectionInfo); - + const TStats& GetStats() const { return Stats; } void UpdateSharedBody(TInfo *collectionInfo, ui32 pageId, TSharedPageRef shared) noexcept { @@ -262,25 +262,25 @@ public: } std::pair<ui32, ui64> Load(TVector<ui32> &pages, TPrivatePageCacheWaitPad *waitPad, TInfo *info); // blocks to load, bytes to load - + const TSharedData* Lookup(ui32 page, TInfo *collection); TSharedPageRef LookupShared(ui32 page, TInfo *collection); TPage::TWaitQueuePtr ProvideBlock(NSharedCache::TEvResult::TLoaded&& loaded, TInfo *collectionInfo); - - void UpdateCacheSize(ui64 cacheSize); + + void UpdateCacheSize(ui64 cacheSize); THashMap<TLogoBlobID, TIntrusivePtr<TInfo>> DetachPrivatePageCache(); THashMap<TLogoBlobID, THashMap<ui32, TSharedData>> GetPrepareSharedTouched(); -private: +private: THashMap<TLogoBlobID, TIntrusivePtr<TInfo>> PageCollections; THashMap<TLogoBlobID, THashMap<ui32, TSharedData>> ToTouchShared; - + TStats Stats; - TCacheCache<TPage, TPage::TWeight> Cache; - bool PrepareForSharedCache; - + TCacheCache<TPage, TPage::TWeight> Cache; + bool PrepareForSharedCache; + bool Restore(TPage *page); - void Touch(TPage *page); - void Evict(TPage *pages); -}; - -}} + void Touch(TPage *page); + void Evict(TPage *pages); +}; + +}} diff --git a/ydb/core/tablet_flat/flat_scan_actor.h b/ydb/core/tablet_flat/flat_scan_actor.h index 379abfcff0..5cbf2797a0 100644 --- a/ydb/core/tablet_flat/flat_scan_actor.h +++ b/ydb/core/tablet_flat/flat_scan_actor.h @@ -628,13 +628,13 @@ namespace NOps { if (auto logl = Logger->Log(lvl)) logl << NFmt::Do(*this) << " " << NFmt::Do(msg); - if (msg.Status != NKikimrProto::OK) { - if (msg.Status == NKikimrProto::NODATA) { - GetServiceCounters(AppData()->Counters, "tablets")->GetCounter("alerts_scan_nodata", true)->Inc(); - } - + if (msg.Status != NKikimrProto::OK) { + if (msg.Status == NKikimrProto::NODATA) { + GetServiceCounters(AppData()->Counters, "tablets")->GetCounter("alerts_scan_nodata", true)->Inc(); + } + return Terminate(EAbort::Host); - } + } // TODO: would want to postpone pinning until usage TVector<NPageCollection::TLoadedPage> pinned(Reserve(msg.Loaded.size())); diff --git a/ydb/core/tablet_flat/flat_store_hotdog.cpp b/ydb/core/tablet_flat/flat_store_hotdog.cpp index 49f35fe51f..42a062cadf 100644 --- a/ydb/core/tablet_flat/flat_store_hotdog.cpp +++ b/ydb/core/tablet_flat/flat_store_hotdog.cpp @@ -30,19 +30,19 @@ void TPageCollectionProtoHelper::Snap(NKikimrExecutorFlat::TLogTableSnap *snap, void TPageCollectionProtoHelper::Snap(NKikimrExecutorFlat::TLogTableSnap *snap, const TPartComponents &pc, ui32 table, ui32 level) { - snap->SetTable(table); - snap->SetCompactionLevel(level); - + snap->SetTable(table); + snap->SetCompactionLevel(level); + TPageCollectionProtoHelper(false, false).Do(snap->AddBundles(), pc); -} - +} + void TPageCollectionProtoHelper::Do(TBundle *bundle, const TPartComponents &pc) { bundle->MutablePageCollections()->Reserve(pc.PageCollectionComponents.size()); - + for (auto &one : pc.PageCollectionComponents) Bundle(bundle->AddPageCollections(), one.LargeGlobId, one.Packet.Get(), one.Sticky); - + if (auto &legacy = pc.Legacy) bundle->SetLegacy(legacy); @@ -50,8 +50,8 @@ void TPageCollectionProtoHelper::Do(TBundle *bundle, const TPartComponents &pc) bundle->SetOpaque(opaque); bundle->SetEpoch(pc.GetEpoch().ToProto()); -} - +} + void TPageCollectionProtoHelper::Do(TBundle *bundle, const NTable::TPartView &partView) { Y_VERIFY(partView, "Cannot make bundle dump from empty NTable::TPartView"); @@ -119,7 +119,7 @@ void TPageCollectionProtoHelper::Bundle(NKikimrExecutorFlat::TPageCollection *pa pages.emplace_back(pageId, *body); } else { Y_FAIL("index and page collection pages must be kept inmemory"); - } + } } } diff --git a/ydb/core/tablet_flat/flat_store_hotdog.h b/ydb/core/tablet_flat/flat_store_hotdog.h index a3430d9587..1a2953bf40 100644 --- a/ydb/core/tablet_flat/flat_store_hotdog.h +++ b/ydb/core/tablet_flat/flat_store_hotdog.h @@ -39,14 +39,14 @@ namespace NTabletFlatExecutor { static void Snap(NKikimrExecutorFlat::TLogTableSnap *snap, const TPartComponents &pc, ui32 table, ui32 level); static void Snap(NKikimrExecutorFlat::TLogTableSnap *snap, const TPartView &partView, ui32 table, ui32 level); static void Snap(NKikimrExecutorFlat::TLogTableSnap *snap, const TIntrusiveConstPtr<TColdPart> &part, ui32 table, ui32 level); - + void Do(TBundle *bundle, const TPartView &partView); void Do(TBundle *bundle, const TIntrusiveConstPtr<TColdPart> &part); void Do(TBundle *bundle, const TPartComponents &pc); - + static TPartComponents MakePageCollectionComponents(const TBundle &proto, bool unsplit = false); - private: + private: void Bundle(NKikimrExecutorFlat::TPageCollection *pageCollectionProto, const TPrivatePageCache::TInfo &cache); void Bundle( NKikimrExecutorFlat::TPageCollection *pageCollectionProto, diff --git a/ydb/core/tablet_flat/flat_table.cpp b/ydb/core/tablet_flat/flat_table.cpp index a50371e341..686a404268 100644 --- a/ydb/core/tablet_flat/flat_table.cpp +++ b/ydb/core/tablet_flat/flat_table.cpp @@ -1,4 +1,4 @@ -#include "flat_table.h" +#include "flat_table.h" #include "flat_row_celled.h" #include "flat_row_remap.h" #include "flat_bloom_hash.h" @@ -10,12 +10,12 @@ #include "flat_range_cache.h" #include "flat_util_misc.h" #include "util_fmt_abort.h" - + #include <ydb/core/util/yverify_stream.h> -namespace NKikimr { +namespace NKikimr { namespace NTable { - + TTable::TTable(TEpoch epoch) : Epoch(epoch) { } TTable::~TTable() { } @@ -57,7 +57,7 @@ TIntrusiveConstPtr<TRowScheme> TTable::GetScheme() const noexcept TAutoPtr<TSubset> TTable::Subset(TArrayRef<const TLogoBlobID> bundle, TEpoch head) { head = Min(head, Epoch); - + TAutoPtr<TSubset> subset = new TSubset(head, Scheme); if (head > TEpoch::Zero()) { @@ -71,8 +71,8 @@ TAutoPtr<TSubset> TTable::Subset(TArrayRef<const TLogoBlobID> bundle, TEpoch hea subset->TxStatus.emplace_back(pr.second); } } - } - + } + subset->Flatten.reserve(bundle.size()); for (const TLogoBlobID &token : bundle) { if (auto* c = ColdParts.FindPtr(token)) { @@ -83,17 +83,17 @@ TAutoPtr<TSubset> TTable::Subset(TArrayRef<const TLogoBlobID> bundle, TEpoch hea Y_VERIFY_S(p, "Cannot find part " << token); subset->Flatten.push_back(*p); } - + subset->CommittedTransactions = CommittedTransactions; subset->RemovedTransactions = RemovedTransactions; return subset; -} - +} + TAutoPtr<TSubset> TTable::Subset(TEpoch head) const noexcept { head = Min(head, Epoch); - + TAutoPtr<TSubset> subset = new TSubset(head, Scheme); for (const auto &it : TxStatus) { @@ -213,7 +213,7 @@ void TTable::Replace(TArrayRef<const TPartView> partViews, const TSubset &subset for (auto &memTable : subset.Frozen) { const auto found = Frozen.erase(memTable.MemTable); - + Y_VERIFY(found == 1, "Got an unknown TMemTable table in TSubset"); NUtil::SubSafe(Stat_.FrozenWaste, memTable->GetWastedMem()); @@ -230,12 +230,12 @@ void TTable::Replace(TArrayRef<const TPartView> partViews, const TSubset &subset checkNewTransactions.insert(txId); } } - } - + } + for (auto &part : subset.Flatten) { Y_VERIFY(part.Slices && *part.Slices, "Got an empty TPart subset in TSubset"); - + auto it = Flatten.find(part->Label); Y_VERIFY(it != Flatten.end(), "Got an unknown TPart table in TSubset"); auto& existing = it->second; @@ -320,8 +320,8 @@ void TTable::Replace(TArrayRef<const TPartView> partViews, const TSubset &subset ProcessCheckTransactions(); ErasedKeysCache.Reset(); -} - +} + void TTable::ReplaceTxStatus(TArrayRef<const TIntrusiveConstPtr<TTxStatusPart>> newTxStatus, const TSubset &subset) noexcept { for (auto &part : subset.TxStatus) { @@ -1012,4 +1012,4 @@ TPartStats& TPartStats::operator-=(const TPartStats& rhs) return *this; } -}} +}} diff --git a/ydb/core/tablet_flat/flat_table.h b/ydb/core/tablet_flat/flat_table.h index 3642538ea4..a1fdeb9709 100644 --- a/ydb/core/tablet_flat/flat_table.h +++ b/ydb/core/tablet_flat/flat_table.h @@ -1,6 +1,6 @@ -#pragma once -#include "defs.h" -#include "flat_update_op.h" +#pragma once +#include "defs.h" +#include "flat_update_op.h" #include "flat_dbase_scheme.h" #include "flat_mem_warm.h" #include "flat_iterator.h" @@ -15,7 +15,7 @@ #include "flat_table_misc.h" #include "flat_sausage_solid.h" #include "util_basics.h" - + #include <ydb/core/scheme/scheme_tablecell.h> #include <library/cpp/containers/stack_vector/stack_vec.h> @@ -24,17 +24,17 @@ #include <util/generic/hash.h> #include <util/generic/ptr.h> -namespace NKikimr { +namespace NKikimr { namespace NTable { - + class TTableEpochs; class TKeyRangeCache; class TTable: public TAtomicRefCount<TTable> { -public: +public: using TOpsRef = TArrayRef<const TUpdateOp>; using TMemGlob = NPageCollection::TMemGlob; - + struct TStat { /*_ In memory (~memtable) data statistics */ @@ -135,9 +135,9 @@ public: IPages* env, ui64 flg, ui64 itemsLimit, ui64 bytesLimit, EDirection direction, TRowVersion snapshot) const; - + void Update(ERowOp, TRawVals key, TOpsRef, TArrayRef<TMemGlob> apart, TRowVersion rowVersion); - + void UpdateTx(ERowOp, TRawVals key, TOpsRef, TArrayRef<TMemGlob> apart, ui64 txId); void CommitTx(ui64 txId, TRowVersion rowVersion); void RemoveTx(ui64 txId); diff --git a/ydb/core/tablet_flat/flat_table_part.h b/ydb/core/tablet_flat/flat_table_part.h index 8da0885e61..aa555c515b 100644 --- a/ydb/core/tablet_flat/flat_table_part.h +++ b/ydb/core/tablet_flat/flat_table_part.h @@ -1,6 +1,6 @@ -#pragma once +#pragma once -#include "defs.h" +#include "defs.h" #include "flat_part_scheme.h" #include "flat_page_index.h" #include "flat_page_data.h" @@ -11,11 +11,11 @@ #include "flat_page_txidstat.h" #include "flat_page_txstatus.h" #include "util_basics.h" - -namespace NKikimr { + +namespace NKikimr { namespace NTable { struct IPages; - + /** * Cold parts are parts that don't have any metadata loaded into memory, * so we don't know much about them. Concrete implementations should diff --git a/ydb/core/tablet_flat/flat_update_op.h b/ydb/core/tablet_flat/flat_update_op.h index cbf629b1d7..9d7cb269ef 100644 --- a/ydb/core/tablet_flat/flat_update_op.h +++ b/ydb/core/tablet_flat/flat_update_op.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "flat_row_eggs.h" #include "flat_row_column.h" @@ -6,9 +6,9 @@ #include <ydb/core/scheme_types/scheme_raw_type_value.h> #include <util/string/printf.h> -namespace NKikimr { +namespace NKikimr { namespace NTable { - + inline const char* EOpToStr(const ECellOp op) { switch (op) { case ECellOp::Empty: @@ -26,13 +26,13 @@ namespace NTable { struct TUpdateOp { TUpdateOp() = default; - + TUpdateOp(TTag tag, TCellOp op, TRawTypeValue value) : Tag(tag) , Op(op) , Value(value) { - + } TArrayRef<const char> AsRef() const noexcept diff --git a/ydb/core/tablet_flat/protos/flat_table_part.proto b/ydb/core/tablet_flat/protos/flat_table_part.proto index 5723be79c2..61fa39e957 100644 --- a/ydb/core/tablet_flat/protos/flat_table_part.proto +++ b/ydb/core/tablet_flat/protos/flat_table_part.proto @@ -45,7 +45,7 @@ message TStat { message TRoot { // NTable::TPart page collection metablob optional int64 Epoch = 2; - optional uint64 Bytes = 3; // Actual raw data pages size in part + optional uint64 Bytes = 3; // Actual raw data pages size in part optional uint64 Coded = 4; // Observable (encoded) data pages size optional TEvol Evol = 6; optional TStat Stat = 7; // Some stats collected on compaction diff --git a/ydb/core/tablet_flat/shared_sausagecache.cpp b/ydb/core/tablet_flat/shared_sausagecache.cpp index 16368bdf56..c60c30202b 100644 --- a/ydb/core/tablet_flat/shared_sausagecache.cpp +++ b/ydb/core/tablet_flat/shared_sausagecache.cpp @@ -1,4 +1,4 @@ -#include "shared_sausagecache.h" +#include "shared_sausagecache.h" #include "shared_cache_events.h" #include "flat_bio_events.h" #include "flat_bio_actor.h" @@ -9,8 +9,8 @@ #include <library/cpp/actors/core/hfunc.h> #include <library/cpp/containers/stack_vector/stack_vec.h> #include <util/generic/set.h> - -namespace NKikimr { + +namespace NKikimr { TSharedPageCacheCounters::TSharedPageCacheCounters(const TIntrusivePtr<NMonitoring::TDynamicCounters> &group) : ActivePages(group->GetCounter("ActivePages")) @@ -30,53 +30,53 @@ TSharedPageCacheCounters::TSharedPageCacheCounters(const TIntrusivePtr<NMonitori } namespace NKikimr { -namespace NTabletFlatExecutor { - -static bool Satisfies(NLog::EPriority priority = NLog::PRI_DEBUG) { - if (NLog::TSettings *settings = TlsActivationContext->LoggerSettings()) - return settings->Satisfies(priority, NKikimrServices::TABLET_SAUSAGECACHE); - else - return false; -} - +namespace NTabletFlatExecutor { + +static bool Satisfies(NLog::EPriority priority = NLog::PRI_DEBUG) { + if (NLog::TSettings *settings = TlsActivationContext->LoggerSettings()) + return settings->Satisfies(priority, NKikimrServices::TABLET_SAUSAGECACHE); + else + return false; +} + class TSharedPageCache : public TActor<TSharedPageCache> { TIntrusiveConstPtr<TSharedPageCacheConfig> Config; - + using ELnLev = NUtil::ELnLev; using TBlocks = TVector<NSharedCache::TEvResult::TLoaded>; - enum EPageState { - PageStateNo, - PageStateLoaded, - PageStateRequested, - PageStateRequestedAsync, - PageStatePending, + enum EPageState { + PageStateNo, + PageStateLoaded, + PageStateRequested, + PageStateRequestedAsync, + PageStatePending, PageStateEvicted, - }; - + }; + struct TCollection; struct TPage : public TSharedPageHandle , public TIntrusiveListItem<TPage> { - ui64 State : 4; - ui64 CacheGeneration : 3; - ui64 InMemory : 1; - ui64 Size : 24; + ui64 State : 4; + ui64 CacheGeneration : 3; + ui64 InMemory : 1; + ui64 Size : 24; const ui64 PageId : 32; - + TCollection* Collection; - + TPage(ui32 pageId, TCollection* collection) - : State(PageStateNo) - , CacheGeneration(TCacheCacheConfig::CacheGenNone) - , InMemory(false) - , Size(0) + : State(PageStateNo) + , CacheGeneration(TCacheCacheConfig::CacheGenNone) + , InMemory(false) + , Size(0) , PageId(pageId) , Collection(collection) - {} - + {} + bool HasMissingBody() const { switch (State) { case PageStateNo: @@ -96,13 +96,13 @@ class TSharedPageCache : public TActor<TSharedPageCache> { State = PageStateLoaded; } - struct TWeight { - static ui64 Get(TPage *x) { + struct TWeight { + static ui64 Get(TPage *x) { return sizeof(TPage) + (x->State == PageStateLoaded ? x->Size : 0); - } - }; - }; - + } + }; + }; + struct TRequest : public TSimpleRefCount<TRequest> { TRequest(TIntrusiveConstPtr<NPageCollection::IPageCollection> pageCollection) : Label(pageCollection->Label()) @@ -116,59 +116,59 @@ class TSharedPageCache : public TActor<TSharedPageCache> { TActorId Owner; /* receiver of NBlockIO::TEvStat*/ NBlockIO::EPriority Priority; TIntrusiveConstPtr<NPageCollection::IPageCollection> PageCollection; - ui64 EventCookie = 0; - ui64 RequestCookie = 0; - ui64 PendingBlocks = 0; + ui64 EventCookie = 0; + ui64 RequestCookie = 0; + ui64 PendingBlocks = 0; TBlocks ReadyBlocks; TDeque<ui32> PagesToRequest; - }; - - struct TExpectant { + }; + + struct TExpectant { TDeque<std::pair<TIntrusivePtr<TRequest>, ui32>> SourceRequests; // waiting request, index in ready blocks for page - }; - - struct TCollection { + }; + + struct TCollection { TLogoBlobID MetaId; TSet<TActorId> Owners; TPageMap<TIntrusivePtr<TPage>> PageMap; TMap<ui32, TExpectant> Expectants; TDeque<ui32> DroppedPages; - }; - + }; + struct TCollectionsOwner { THashSet<TCollection*> Collections; }; - struct TRequestQueue { - struct TPagesToRequest : public TIntrusiveListItem<TPagesToRequest> { + struct TRequestQueue { + struct TPagesToRequest : public TIntrusiveListItem<TPagesToRequest> { TIntrusivePtr<TRequest> Request; - }; - - struct TByActorRequest { - TIntrusiveList<TPagesToRequest> Listed; + }; + + struct TByActorRequest { + TIntrusiveList<TPagesToRequest> Listed; THashMap<TLogoBlobID, TDeque<TPagesToRequest>> Index; - }; - + }; + TMap<TActorId, TByActorRequest> Requests; - - i64 Limit = 0; - i64 InFly = 0; - + + i64 Limit = 0; + i64 InFly = 0; + TActorId NextToRequest; - }; - + }; + TIntrusivePtr<TSharedPageGCList> GCList = new TSharedPageGCList; TActorId Owner; TAutoPtr<NUtil::ILogger> Logger; THashMap<TLogoBlobID, TCollection> Collections; THashMap<TActorId, TCollectionsOwner> CollectionsOwners; - - TRequestQueue AsyncRequests; - TRequestQueue ScanRequests; - - TCacheCache<TPage, TPage::TWeight> Cache; - + + TRequestQueue AsyncRequests; + TRequestQueue ScanRequests; + + TCacheCache<TPage, TPage::TWeight> Cache; + TControlWrapper SizeOverride; ui64 StatBioReqs = 0; @@ -187,7 +187,7 @@ class TSharedPageCache : public TActor<TSharedPageCache> { sys->AppData<TAppData>()->Icb->RegisterSharedControl(SizeOverride, Config->CacheName + "_Size"); } - void TakePoison() + void TakePoison() { if (auto logl = Logger->Log(ELnLev::Info)) { logl @@ -203,7 +203,7 @@ class TSharedPageCache : public TActor<TSharedPageCache> { } TCollection& AttachCollection(const TLogoBlobID &metaId, const NPageCollection::IPageCollection &pageCollection, const TActorId &owner) { - TCollection &collection = Collections[metaId]; + TCollection &collection = Collections[metaId]; if (!collection.MetaId) { Y_VERIFY(metaId); collection.MetaId = metaId; @@ -214,11 +214,11 @@ class TSharedPageCache : public TActor<TSharedPageCache> { "Page collection %s changed number of pages from %" PRISZT " to %" PRIu32 " by %s", metaId.ToString().c_str(), collection.PageMap.size(), pageCollection.Total(), owner.ToString().c_str()); } - + if (collection.Owners.insert(owner).second) { CollectionsOwners[owner].Collections.insert(&collection); } - + return collection; } @@ -243,15 +243,15 @@ class TSharedPageCache : public TActor<TSharedPageCache> { TCollection &collection = AttachCollection(metaId, pageCollection, msg->Owner); - TStackVec<std::pair<ui32, ui32>> pendingPages; // pageId, reqIdx - ui32 pagesToLoad = 0; + TStackVec<std::pair<ui32, ui32>> pendingPages; // pageId, reqIdx + ui32 pagesToLoad = 0; TBlocks readyBlocks; readyBlocks.reserve(msg->Fetch->Pages.size()); TVector<ui32> pagesToWait; - if (logsat) + if (logsat) pagesToWait.reserve(msg->Fetch->Pages.size()); - + TRequestQueue *queue = nullptr; switch (msg->Priority) { case NBlockIO::EPriority::None: @@ -265,7 +265,7 @@ class TSharedPageCache : public TActor<TSharedPageCache> { queue = &ScanRequests; break; } - + for (const ui32 reqIdx : xrange(msg->Fetch->Pages.size())) { const ui32 pageId = msg->Fetch->Pages[reqIdx]; Y_VERIFY(pageId < collection.PageMap.size(), @@ -276,47 +276,47 @@ class TSharedPageCache : public TActor<TSharedPageCache> { Y_VERIFY(collection.PageMap.emplace(pageId, (page = new TPage(pageId, &collection)))); page->Size = pageCollection.Page(pageId).Size; } - + if (Config->Counters) { ++*Config->Counters->RequestedPages; *Config->Counters->RequestedBytes += page->Size; } - switch (page->State) { + switch (page->State) { case PageStateEvicted: Y_VERIFY(page->Use()); // still in PageMap, guaranteed to be alive page->State = PageStateLoaded; RemovePassivePage(page); AddActivePage(page); [[fallthrough]]; - case PageStateLoaded: + case PageStateLoaded: StatHitPages += 1; StatHitBytes += page->Size; readyBlocks.emplace_back(pageId, TSharedPageRef::MakeUsed(page, GCList)); - if (logsat) - pagesToWait.emplace_back(pageId); + if (logsat) + pagesToWait.emplace_back(pageId); if (Config->Counters) { ++*Config->Counters->CacheHitPages; *Config->Counters->CacheHitBytes += page->Size; } Evict(Cache.Touch(page)); - break; - case PageStateNo: - ++pagesToLoad; + break; + case PageStateNo: + ++pagesToLoad; [[fallthrough]]; // AUTOGENERATED_FALLTHROUGH_FIXME - case PageStateRequested: - case PageStateRequestedAsync: - case PageStatePending: + case PageStateRequested: + case PageStateRequestedAsync: + case PageStatePending: if (Config->Counters) { ++*Config->Counters->CacheMissPages; *Config->Counters->CacheMissBytes += page->Size; } readyBlocks.emplace_back(pageId, TSharedPageRef()); - pendingPages.emplace_back(pageId, reqIdx); - break; - } - } - + pendingPages.emplace_back(pageId, reqIdx); + break; + } + } + auto waitingRequest = MakeIntrusive<TRequest>(std::move(msg->Fetch->PageCollection)); waitingRequest->Source = ev->Sender; @@ -326,70 +326,70 @@ class TSharedPageCache : public TActor<TSharedPageCache> { waitingRequest->RequestCookie = msg->Fetch->Cookie; waitingRequest->ReadyBlocks = std::move(readyBlocks); - if (pendingPages) { + if (pendingPages) { TVector<ui32> pagesToKeep; TVector<ui32> pagesToRequest; ui64 pagesToRequestBytes = 0; - pagesToRequest.reserve(pagesToLoad); - if (logsat) - pagesToWait.reserve(pendingPages.size() - pagesToLoad); - - TRequestQueue::TPagesToRequest *qpages = nullptr; - - if (queue) { - // register for loading regardless of pending state, to simplify actor deregister logic - // would be filtered on actual request + pagesToRequest.reserve(pagesToLoad); + if (logsat) + pagesToWait.reserve(pendingPages.size() - pagesToLoad); + + TRequestQueue::TPagesToRequest *qpages = nullptr; + + if (queue) { + // register for loading regardless of pending state, to simplify actor deregister logic + // would be filtered on actual request auto &owner = queue->Requests[msg->Owner]; - auto &list = owner.Index[metaId]; - - qpages = &list.emplace_back(); - + auto &list = owner.Index[metaId]; + + qpages = &list.emplace_back(); + qpages->Request = waitingRequest; - owner.Listed.PushBack(qpages); - } - - for (auto xpair : pendingPages) { - const ui32 pageId = xpair.first; - const ui32 reqIdx = xpair.second; - - collection.Expectants[pageId].SourceRequests.emplace_back(waitingRequest, reqIdx); - ++waitingRequest->PendingBlocks; + owner.Listed.PushBack(qpages); + } + + for (auto xpair : pendingPages) { + const ui32 pageId = xpair.first; + const ui32 reqIdx = xpair.second; + + collection.Expectants[pageId].SourceRequests.emplace_back(waitingRequest, reqIdx); + ++waitingRequest->PendingBlocks; auto* page = collection.PageMap[pageId].Get(); Y_VERIFY(page); - - if (qpages) + + if (qpages) qpages->Request->PagesToRequest.push_back(pageId); - - switch (page->State) { - case PageStateNo: - pagesToRequest.push_back(pageId); + + switch (page->State) { + case PageStateNo: + pagesToRequest.push_back(pageId); pagesToRequestBytes += page->Size; - - if (queue) - page->State = PageStatePending; - else - page->State = PageStateRequested; - - break; - case PageStateRequested: - if (logsat) - pagesToWait.emplace_back(pageId); - break; - case PageStateRequestedAsync: - case PageStatePending: - if (!queue) { - pagesToRequest.push_back(pageId); + + if (queue) + page->State = PageStatePending; + else + page->State = PageStateRequested; + + break; + case PageStateRequested: + if (logsat) + pagesToWait.emplace_back(pageId); + break; + case PageStateRequestedAsync: + case PageStatePending: + if (!queue) { + pagesToRequest.push_back(pageId); pagesToRequestBytes += page->Size; - page->State = PageStateRequested; - } else { - pagesToWait.emplace_back(pageId); - } - break; - default: - Y_FAIL("must not happens"); - } - } - + page->State = PageStateRequested; + } else { + pagesToWait.emplace_back(pageId); + } + break; + default: + Y_FAIL("must not happens"); + } + } + if (auto logl = Logger->Log(ELnLev::Debug)) { logl << "PageCollection " << metaId << " class " << waitingRequest->Priority @@ -397,143 +397,143 @@ class TSharedPageCache : public TActor<TSharedPageCache> { << " already requested " << pagesToWait << " to request " << pagesToRequest; } - - if (pagesToRequest) { - if (queue) { - RequestFromQueue(*queue); - } else { + + if (pagesToRequest) { + if (queue) { + RequestFromQueue(*queue); + } else { if (Config->Counters) { *Config->Counters->LoadInFlyPages += pagesToRequest.size(); *Config->Counters->LoadInFlyBytes += pagesToRequestBytes; } auto *fetch = new NPageCollection::TFetch(0, waitingRequest->PageCollection, std::move(pagesToRequest)); NBlockIO::Once(this, waitingRequest->Owner, 0, waitingRequest->Priority, fetch); - } - } - } else { + } + } + } else { if (auto logl = Logger->Log(ELnLev::Debug)) { logl << "PageCollection " << metaId << " class " << msg->Priority << " from cache " << msg->Fetch->Pages; } SendReadyBlocks(*waitingRequest); - } + } ProcessGCList(); - } - - void RequestFromQueue(TRequestQueue &queue) { - if (queue.Requests.empty()) - return; - + } + + void RequestFromQueue(TRequestQueue &queue) { + if (queue.Requests.empty()) + return; + TMap<TActorId, TRequestQueue::TByActorRequest>::iterator it; - if (queue.NextToRequest) { - it = queue.Requests.find(queue.NextToRequest); - if (it == queue.Requests.end()) - it = queue.Requests.begin(); - } else { - it = queue.Requests.begin(); - } - - while (queue.InFly <= queue.Limit) { // on limit == 0 would request pages one by one + if (queue.NextToRequest) { + it = queue.Requests.find(queue.NextToRequest); + if (it == queue.Requests.end()) + it = queue.Requests.begin(); + } else { + it = queue.Requests.begin(); + } + + while (queue.InFly <= queue.Limit) { // on limit == 0 would request pages one by one // request whole limit from one page collection for better locality (if possible) - // should be 'request from one logoblobid - auto &owner = it->second; - Y_VERIFY(!owner.Listed.Empty()); - - ui32 nthToRequest = 0; - ui32 nthToLoad = 0; - ui64 sizeToLoad = 0; - + // should be 'request from one logoblobid + auto &owner = it->second; + Y_VERIFY(!owner.Listed.Empty()); + + ui32 nthToRequest = 0; + ui32 nthToLoad = 0; + ui64 sizeToLoad = 0; + auto &wa = *owner.Listed.Front()->Request; - + if (wa.Source) { // is request already served? auto *collection = Collections.FindPtr(wa.Label); - Y_VERIFY(collection); - + Y_VERIFY(collection); + for (ui32 pageId : wa.PagesToRequest) { - ++nthToRequest; - + ++nthToRequest; + auto* page = collection->PageMap[pageId].Get(); - if (!page || page->State != PageStatePending) - continue; - - ++nthToLoad; + if (!page || page->State != PageStatePending) + continue; + + ++nthToLoad; queue.InFly += page->Size; sizeToLoad += page->Size; - if (queue.InFly > queue.Limit) - break; - } - - if (nthToRequest != 0) { - if (nthToLoad != 0) { + if (queue.InFly > queue.Limit) + break; + } + + if (nthToRequest != 0) { + if (nthToLoad != 0) { TVector<ui32> toLoad; - toLoad.reserve(nthToLoad); + toLoad.reserve(nthToLoad); for (ui32 pageId : wa.PagesToRequest) { auto* page = collection->PageMap[pageId].Get(); - if (!page || page->State != PageStatePending) - continue; - - toLoad.push_back(pageId); - page->State = PageStateRequestedAsync; - if (--nthToLoad == 0) - break; - } - + if (!page || page->State != PageStatePending) + continue; + + toLoad.push_back(pageId); + page->State = PageStateRequestedAsync; + if (--nthToLoad == 0) + break; + } + if (auto logl = Logger->Log(ELnLev::Debug)) { logl << "queue pageCollection " << wa.Label << " q: " << (&queue == &AsyncRequests ? "async" : "scan") << " pages " << toLoad; } - - // fetch cookie -> requested size; - // event cookie -> ptr to queue + + // fetch cookie -> requested size; + // event cookie -> ptr to queue auto *fetch = new NPageCollection::TFetch(sizeToLoad, wa.PageCollection, std::move(toLoad)); NBlockIO::Once(this, wa.Owner, (ui64)&queue, wa.Priority, fetch); - } - } - } - - // cleanup + } + } + } + + // cleanup if (!wa.Source || nthToRequest == wa.PagesToRequest.size()) { - { + { auto reqit = owner.Index.find(wa.Label); - Y_VERIFY(reqit != owner.Index.end()); - reqit->second.pop_front(); - - if (reqit->second.empty()) - owner.Index.erase(reqit); - } - - Y_VERIFY(bool(owner.Listed) == bool(owner.Index)); - - if (owner.Listed.Empty()) - it = queue.Requests.erase(it); - else - ++it; - } else { + Y_VERIFY(reqit != owner.Index.end()); + reqit->second.pop_front(); + + if (reqit->second.empty()) + owner.Index.erase(reqit); + } + + Y_VERIFY(bool(owner.Listed) == bool(owner.Index)); + + if (owner.Listed.Empty()) + it = queue.Requests.erase(it); + else + ++it; + } else { wa.PagesToRequest.erase(wa.PagesToRequest.begin(), wa.PagesToRequest.begin() + nthToRequest); - ++it; - } - - if (it == queue.Requests.end()) - it = queue.Requests.begin(); - - if (it == queue.Requests.end()) { + ++it; + } + + if (it == queue.Requests.end()) + it = queue.Requests.begin(); + + if (it == queue.Requests.end()) { queue.NextToRequest = TActorId(); - break; - } - - queue.NextToRequest = it->first; - } - } - + break; + } + + queue.NextToRequest = it->first; + } + } + void Handle(NSharedCache::TEvTouch::TPtr &ev) { NSharedCache::TEvTouch *msg = ev->Get(); THashMap<TLogoBlobID, NSharedCache::TEvUpdated::TActions> actions; - for (auto &xpair : msg->Touched) { - auto collectionIt = Collections.find(xpair.first); + for (auto &xpair : msg->Touched) { + auto collectionIt = Collections.find(xpair.first); if (collectionIt == Collections.end()) { for (auto &x : xpair.second) { if (x.second) { @@ -541,23 +541,23 @@ class TSharedPageCache : public TActor<TSharedPageCache> { x.second = { }; } } - continue; + continue; } auto &collection = collectionIt->second; - for (auto &x : xpair.second) { + for (auto &x : xpair.second) { const ui32 pageId = x.first; Y_VERIFY(pageId < collection.PageMap.size()); auto* page = collection.PageMap[pageId].Get(); - if (!page) { + if (!page) { if (x.second) { Y_VERIFY(collection.PageMap.emplace(pageId, (page = new TPage(pageId, &collection)))); page->Size = x.second.size(); } else { - continue; + continue; } - } + } Y_VERIFY(page); - + if (auto body = std::move(x.second)) { if (page->HasMissingBody()) { page->Initialize(std::move(body)); @@ -567,29 +567,29 @@ class TSharedPageCache : public TActor<TSharedPageCache> { auto ref = TSharedPageRef::MakeUsed(page, GCList); Y_VERIFY(ref.IsUsed(), "Unexpected failure to grab a cached page"); actions[xpair.first].Accepted[pageId] = std::move(ref); - } - - switch (page->State) { - case PageStateNo: + } + + switch (page->State) { + case PageStateNo: Y_FAIL("unexpected uninitialized page found"); - case PageStateRequested: - case PageStateRequestedAsync: - case PageStatePending: - break; + case PageStateRequested: + case PageStateRequestedAsync: + case PageStatePending: + break; case PageStateEvicted: Y_VERIFY(page->Use()); page->State = PageStateLoaded; RemovePassivePage(page); AddActivePage(page); [[fallthrough]]; - case PageStateLoaded: + case PageStateLoaded: Evict(Cache.Touch(page)); - break; - default: - Y_FAIL("unknown load state"); - } - } - } + break; + default: + Y_FAIL("unknown load state"); + } + } + } if (actions) { auto msg = MakeHolder<NSharedCache::TEvUpdated>(); @@ -598,14 +598,14 @@ class TSharedPageCache : public TActor<TSharedPageCache> { } ProcessGCList(); - } - + } + void Handle(NSharedCache::TEvUnregister::TPtr &ev) { - DropFromQueue(ScanRequests, ev->Sender); - DropFromQueue(AsyncRequests, ev->Sender); - - RequestFromQueue(AsyncRequests); - RequestFromQueue(ScanRequests); + DropFromQueue(ScanRequests, ev->Sender); + DropFromQueue(AsyncRequests, ev->Sender); + + RequestFromQueue(AsyncRequests); + RequestFromQueue(ScanRequests); auto ownerIt = CollectionsOwners.find(ev->Sender); if (ownerIt != CollectionsOwners.end()) { @@ -617,8 +617,8 @@ class TSharedPageCache : public TActor<TSharedPageCache> { } ProcessGCList(); - } - + } + void Handle(NSharedCache::TEvInvalidate::TPtr &ev) { const TLogoBlobID pageCollectionId = ev->Get()->PageCollectionId; auto collectionIt = Collections.find(pageCollectionId); @@ -627,11 +627,11 @@ class TSharedPageCache : public TActor<TSharedPageCache> { logl << "invalidate pageCollection " << pageCollectionId << (collectionIt == Collections.end() ? " unknown" : ""); - } - + } + if (collectionIt == Collections.end()) return; - + auto &collection = collectionIt->second; DropRequestsFor(ev->Sender, pageCollectionId); @@ -651,35 +651,35 @@ class TSharedPageCache : public TActor<TSharedPageCache> { } ProcessGCList(); - } - + } + void Handle(NBlockIO::TEvData::TPtr &ev) { auto *msg = ev->Get(); - - if (TRequestQueue *queue = (TRequestQueue *)ev->Cookie) { - Y_VERIFY(queue == &ScanRequests || queue == &AsyncRequests); - Y_VERIFY(queue->InFly >= (i64)msg->Cookie); - queue->InFly -= msg->Cookie; - RequestFromQueue(*queue); - } - + + if (TRequestQueue *queue = (TRequestQueue *)ev->Cookie) { + Y_VERIFY(queue == &ScanRequests || queue == &AsyncRequests); + Y_VERIFY(queue->InFly >= (i64)msg->Cookie); + queue->InFly -= msg->Cookie; + RequestFromQueue(*queue); + } + auto collectionIt = Collections.find(msg->Origin->Label()); - if (collectionIt == Collections.end()) - return; - + if (collectionIt == Collections.end()) + return; + if (msg->Status != NKikimrProto::OK) { DropCollection(collectionIt, msg->Status); - } else { - TCollection &collection = collectionIt->second; - for (auto &paged : msg->Blocks) { + } else { + TCollection &collection = collectionIt->second; + for (auto &paged : msg->Blocks) { StatMissPages += 1; StatMissBytes += paged.Data.size(); Y_VERIFY(paged.PageId < collection.PageMap.size()); auto* page = collection.PageMap[paged.PageId].Get(); if (!page || !page->HasMissingBody()) - continue; - + continue; + if (page->State == PageStateRequested && Config->Counters) { --*Config->Counters->LoadInFlyPages; *Config->Counters->LoadInFlyBytes -= page->Size; @@ -688,12 +688,12 @@ class TSharedPageCache : public TActor<TSharedPageCache> { page->Initialize(std::move(paged.Data)); BodyProvided(collection, paged.PageId, page); Evict(Cache.Touch(page)); - } + } } ProcessGCList(); - } - + } + void DropExpiredCollection(TCollection* collection) { if (!collection->Owners && !collection->Expectants && @@ -770,21 +770,21 @@ class TSharedPageCache : public TActor<TSharedPageCache> { void BodyProvided(TCollection &collection, ui32 pageId, TPage *page) { AddActivePage(page); - auto expectantIt = collection.Expectants.find(pageId); - if (expectantIt == collection.Expectants.end()) - return; - for (auto &xpair : expectantIt->second.SourceRequests) { - auto &r = xpair.first; - auto &rblock = r->ReadyBlocks[xpair.second]; + auto expectantIt = collection.Expectants.find(pageId); + if (expectantIt == collection.Expectants.end()) + return; + for (auto &xpair : expectantIt->second.SourceRequests) { + auto &r = xpair.first; + auto &rblock = r->ReadyBlocks[xpair.second]; Y_VERIFY(rblock.PageId == pageId); rblock.Page = TSharedPageRef::MakeUsed(page, GCList); - + if (--r->PendingBlocks == 0) SendReadyBlocks(*r); - } - collection.Expectants.erase(expectantIt); - } - + } + collection.Expectants.erase(expectantIt); + } + void SendReadyBlocks(TRequest &wa) { /* Do not hold my NPageCollection::IPageCollection, leave std::move(wa.PageCollection) */ @@ -798,25 +798,25 @@ class TSharedPageCache : public TActor<TSharedPageCache> { } void DropCollection(THashMap<TLogoBlobID, TCollection>::iterator collectionIt, NKikimrProto::EReplyStatus blobStorageError) { - // decline all pending requests - TCollection &collection = collectionIt->second; + // decline all pending requests + TCollection &collection = collectionIt->second; const TLogoBlobID &pageCollectionId = collectionIt->first; - + if (auto logl = Logger->Log(ELnLev::Debug)) logl << "droping pageCollection " << pageCollectionId; - - for (auto &expe : collection.Expectants) { - for (auto &xpair : expe.second.SourceRequests) { - auto &x = xpair.first; - if (!x->Source) - continue; - + + for (auto &expe : collection.Expectants) { + for (auto &xpair : expe.second.SourceRequests) { + auto &x = xpair.first; + if (!x->Source) + continue; + Send(x->Source, new NSharedCache::TEvResult(std::move(x->PageCollection), x->RequestCookie, blobStorageError), 0, x->EventCookie); x->Source = TActorId(); - } - } + } + } collection.Expectants.clear(); - + bool haveValidPages = false; size_t droppedPagesCount = 0; for (const auto &kv : collection.PageMap) { @@ -850,7 +850,7 @@ class TSharedPageCache : public TActor<TSharedPageCache> { page->Collection = nullptr; ++droppedPagesCount; } - + if (haveValidPages) { TVector<ui32> dropped(Reserve(droppedPagesCount)); for (const auto &kv : collection.PageMap) { @@ -865,7 +865,7 @@ class TSharedPageCache : public TActor<TSharedPageCache> { } else { collection.PageMap.clear(); } - + for (TActorId owner : collection.Owners) { DropRequestsFor(owner, pageCollectionId); } @@ -874,89 +874,89 @@ class TSharedPageCache : public TActor<TSharedPageCache> { // This collection no longer has anything useful Collections.erase(collectionIt); } - } - + } + void DropRequestsFor(TActorId owner, const TLogoBlobID &metaId) { DropFromQueue(ScanRequests, owner, metaId); DropFromQueue(AsyncRequests, owner, metaId); } void DropFromQueue(TRequestQueue &queue, TActorId ownerId, const TLogoBlobID &metaId) { - auto ownerIt = queue.Requests.find(ownerId); - if (ownerIt == queue.Requests.end()) - return; - auto &reqsByOwner = ownerIt->second; - auto reqsIt = reqsByOwner.Index.find(metaId); - if (reqsIt == reqsByOwner.Index.end()) - return; - - if (reqsByOwner.Index.size() == 1) { - queue.Requests.erase(ownerIt); - } else { - for (auto &x : reqsIt->second) - x.Unlink(); - reqsByOwner.Index.erase(reqsIt); - } - } - + auto ownerIt = queue.Requests.find(ownerId); + if (ownerIt == queue.Requests.end()) + return; + auto &reqsByOwner = ownerIt->second; + auto reqsIt = reqsByOwner.Index.find(metaId); + if (reqsIt == reqsByOwner.Index.end()) + return; + + if (reqsByOwner.Index.size() == 1) { + queue.Requests.erase(ownerIt); + } else { + for (auto &x : reqsIt->second) + x.Unlink(); + reqsByOwner.Index.erase(reqsIt); + } + } + void DropFromQueue(TRequestQueue &queue, TActorId ownerId) { - auto it = queue.Requests.find(ownerId); - if (it != queue.Requests.end()) { + auto it = queue.Requests.find(ownerId); + if (it != queue.Requests.end()) { if (auto logl = Logger->Log(ELnLev::Debug)) { logl << " drop from queue for " << ownerId << " pageCollections " << it->second.Index.size(); } - queue.Requests.erase(it); - } - } - + queue.Requests.erase(it); + } + } + void Evict(TPage *pages) { - if (pages == nullptr) - return; - TPage *page = pages; - for (;;) { - Y_VERIFY(page->CacheGeneration == TCacheCacheConfig::CacheGenEvicted); - page->CacheGeneration = TCacheCacheConfig::CacheGenNone; - - switch (page->State) { - case PageStateNo: + if (pages == nullptr) + return; + TPage *page = pages; + for (;;) { + Y_VERIFY(page->CacheGeneration == TCacheCacheConfig::CacheGenEvicted); + page->CacheGeneration = TCacheCacheConfig::CacheGenNone; + + switch (page->State) { + case PageStateNo: Y_FAIL("unexpected uninitialized page"); case PageStateEvicted: Y_FAIL("unexpected evicted page"); - case PageStateRequested: - case PageStateRequestedAsync: - case PageStatePending: - break; + case PageStateRequested: + case PageStateRequestedAsync: + case PageStatePending: + break; - case PageStateLoaded: + case PageStateLoaded: page->State = PageStateEvicted; RemoveActivePage(page); AddPassivePage(page); if (page->UnUse()) { GCList->PushGC(page); } - break; + break; - default: - Y_FAIL("unknown load state"); - } - - TPage *next = page->Next()->Node(); + default: + Y_FAIL("unknown load state"); + } + + TPage *next = page->Next()->Node(); if (page != next) { page->Unlink(); } if (page == next) - break; - - page = next; - } - } - + break; + + page = next; + } + } + void Handle(TEvSharedPageCache::TEvConfigure::TPtr& ev) { const auto* msg = ev->Get(); @@ -1005,20 +1005,20 @@ class TSharedPageCache : public TActor<TSharedPageCache> { } } -public: +public: TSharedPageCache(TSharedPageCacheConfig *config) - : TActor(&TThis::StateFunc) - , Config(config) - , Cache(*config->CacheConfig) + : TActor(&TThis::StateFunc) + , Config(config) + , Cache(*config->CacheConfig) , SizeOverride(config->CacheConfig->Limit, 1, Max<i64>()) - { - AsyncRequests.Limit = Config->TotalAsyncQueueInFlyLimit; - ScanRequests.Limit = Config->TotalScanQueueInFlyLimit; - } - - STFUNC(StateFunc) { - Y_UNUSED(ctx); - switch (ev->GetTypeRewrite()) { + { + AsyncRequests.Limit = Config->TotalAsyncQueueInFlyLimit; + ScanRequests.Limit = Config->TotalScanQueueInFlyLimit; + } + + STFUNC(StateFunc) { + Y_UNUSED(ctx); + switch (ev->GetTypeRewrite()) { hFunc(NSharedCache::TEvAttach, Handle); hFunc(NSharedCache::TEvRequest, Handle); hFunc(NSharedCache::TEvTouch, Handle); @@ -1027,29 +1027,29 @@ public: hFunc(NBlockIO::TEvData, Handle); hFunc(TEvSharedPageCache::TEvConfigure, Handle); cFunc(TEvents::TSystem::Wakeup, GCWakeup); - cFunc(TEvents::TSystem::PoisonPill, TakePoison); - } - } - + cFunc(TEvents::TSystem::PoisonPill, TakePoison); + } + } + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::SAUSAGE_CACHE; - } -}; - -} // NTabletFlatExecutor - + } +}; + +} // NTabletFlatExecutor + IActor* CreateSharedPageCache(TSharedPageCacheConfig *config) { return new NTabletFlatExecutor::TSharedPageCache(config); -} - -} - -template<> inline +} + +} + +template<> inline void Out<TVector<ui32>>(IOutputStream& o, const TVector<ui32> &vec) { - o << "[ "; - for (const auto &x : vec) - o << x << ' '; - o << "]"; -} - - + o << "[ "; + for (const auto &x : vec) + o << x << ' '; + o << "]"; +} + + diff --git a/ydb/core/tablet_flat/shared_sausagecache.h b/ydb/core/tablet_flat/shared_sausagecache.h index 73f873a2ba..f7afb2ee99 100644 --- a/ydb/core/tablet_flat/shared_sausagecache.h +++ b/ydb/core/tablet_flat/shared_sausagecache.h @@ -1,11 +1,11 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include <ydb/core/protos/shared_cache.pb.h> #include <ydb/core/util/cache_cache.h> #include <util/system/unaligned_mem.h> - -namespace NKikimr { - + +namespace NKikimr { + struct TEvSharedPageCache { enum EEv { EvBegin = EventSpaceBegin(TKikimrEvents::ES_FLAT_EXECUTOR) + 1536, @@ -40,19 +40,19 @@ struct TSharedPageCacheCounters final : public TAtomicRefCount<TSharedPageCacheC }; struct TSharedPageCacheConfig final : public TAtomicRefCount<TSharedPageCacheConfig> { - TIntrusivePtr<TCacheCacheConfig> CacheConfig; - ui64 TotalScanQueueInFlyLimit = 512 * 1024 * 1024; - ui64 TotalAsyncQueueInFlyLimit = 512 * 1024 * 1024; + TIntrusivePtr<TCacheCacheConfig> CacheConfig; + ui64 TotalScanQueueInFlyLimit = 512 * 1024 * 1024; + ui64 TotalAsyncQueueInFlyLimit = 512 * 1024 * 1024; TString CacheName = "SharedPageCache"; TIntrusivePtr<TSharedPageCacheCounters> Counters; -}; - +}; + IActor* CreateSharedPageCache(TSharedPageCacheConfig *config); - + inline TActorId MakeSharedPageCacheId(ui64 id = 0) { - char x[12] = { 's', 'h', 's', 'c' }; + char x[12] = { 's', 'h', 's', 'c' }; WriteUnaligned<ui64>((ui64*)(x+4), id); return TActorId(0, TStringBuf(x, 12)); -} - -} +} + +} diff --git a/ydb/core/tablet_flat/tablet_flat_executed.cpp b/ydb/core/tablet_flat/tablet_flat_executed.cpp index 756d0e35f7..4b3c15490c 100644 --- a/ydb/core/tablet_flat/tablet_flat_executed.cpp +++ b/ydb/core/tablet_flat/tablet_flat_executed.cpp @@ -1,93 +1,93 @@ -#include "tablet_flat_executed.h" +#include "tablet_flat_executed.h" #include "flat_executor.h" #include "flat_executor_counters.h" #include <ydb/core/base/appdata.h> #include <library/cpp/monlib/service/pages/templates.h> - -namespace NKikimr { -namespace NTabletFlatExecutor { - + +namespace NKikimr { +namespace NTabletFlatExecutor { + using IExecutor = NFlatExecutorSetup::IExecutor; TTabletExecutedFlat::TTabletExecutedFlat(TTabletStorageInfo *info, const TActorId &tablet, IMiniKQLFactory *factory) - : ITablet(info, tablet) + : ITablet(info, tablet) , Factory(factory) , Executor0(nullptr) - , StartTime0(TAppData::TimeProvider->Now()) -{} - + , StartTime0(TAppData::TimeProvider->Now()) +{} + IExecutor* TTabletExecutedFlat::CreateExecutor(const TActorContext &ctx) { - if (!Executor()) { + if (!Executor()) { IActor *executor = NFlatExecutorSetup::CreateExecutor(this, ctx.SelfID); const TActorId executorID = ctx.RegisterWithSameMailbox(executor); - Executor0 = dynamic_cast<TExecutor *>(executor); - Y_VERIFY(Executor0); - - ITablet::ExecutorActorID = executorID; - } - - return Executor(); -} - + Executor0 = dynamic_cast<TExecutor *>(executor); + Y_VERIFY(Executor0); + + ITablet::ExecutorActorID = executorID; + } + + return Executor(); +} + void TTabletExecutedFlat::Execute(TAutoPtr<ITransaction> transaction, const TActorContext &ctx) { - Y_UNUSED(ctx); - Execute(transaction); -} - + Y_UNUSED(ctx); + Execute(transaction); +} + void TTabletExecutedFlat::Execute(TAutoPtr<ITransaction> transaction) { if (transaction) - static_cast<TExecutor*>(Executor())->Execute(transaction, ExecutorCtx(*TlsActivationContext)); + static_cast<TExecutor*>(Executor())->Execute(transaction, ExecutorCtx(*TlsActivationContext)); } const NTable::TScheme& TTabletExecutedFlat::Scheme() const noexcept { return static_cast<TExecutor*>(Executor())->Scheme(); } -void TTabletExecutedFlat::Handle(TEvTablet::TEvBoot::TPtr &ev, const TActorContext &ctx) { +void TTabletExecutedFlat::Handle(TEvTablet::TEvBoot::TPtr &ev, const TActorContext &ctx) { // Notify sys tablet that leader supports graceful shutdown ctx.Send(Tablet(), new TEvTablet::TEvFeatures(TEvTablet::TEvFeatures::GracefulStop)); const auto& msg = *ev->Get(); UpdateTabletInfo(msg.TabletStorageInfo, msg.Launcher); - CreateExecutor(ctx)->Boot(ev, ExecutorCtx(ctx)); + CreateExecutor(ctx)->Boot(ev, ExecutorCtx(ctx)); TxCacheQuota = ev->Get()->TxCacheQuota; -} - -void TTabletExecutedFlat::Handle(TEvTablet::TEvRestored::TPtr &ev, const TActorContext &ctx) { - Executor()->Restored(ev, ExecutorCtx(ctx)); -} - +} + +void TTabletExecutedFlat::Handle(TEvTablet::TEvRestored::TPtr &ev, const TActorContext &ctx) { + Executor()->Restored(ev, ExecutorCtx(ctx)); +} + void TTabletExecutedFlat::Handle(TEvTablet::TEvFBoot::TPtr &ev, const TActorContext &ctx) { - UpdateTabletInfo(ev->Get()->TabletStorageInfo); + UpdateTabletInfo(ev->Get()->TabletStorageInfo); CreateExecutor(ctx)->FollowerBoot(ev, ExecutorCtx(ctx)); TxCacheQuota = ev->Get()->TxCacheQuota; -} - +} + void TTabletExecutedFlat::Handle(TEvTablet::TEvFUpdate::TPtr &ev) { Executor()->FollowerUpdate(std::move(ev->Get()->Update)); -} - +} + void TTabletExecutedFlat::Handle(TEvTablet::TEvFAuxUpdate::TPtr &ev) { Executor()->FollowerAuxUpdate(std::move(ev->Get()->AuxUpdate)); -} - +} + void TTabletExecutedFlat::Handle(TEvTablet::TEvNewFollowerAttached::TPtr &ev) { - Y_UNUSED(ev); - if (Executor()) + Y_UNUSED(ev); + if (Executor()) Executor()->FollowerAttached(); -} - +} + void TTabletExecutedFlat::Handle(TEvTablet::TEvFollowerSyncComplete::TPtr &ev) { - Y_UNUSED(ev); - if (Executor()) + Y_UNUSED(ev); + if (Executor()) Executor()->FollowerSyncComplete(); -} - +} + void TTabletExecutedFlat::Handle(TEvTablet::TEvFollowerGcApplied::TPtr &ev) { - auto *msg = ev->Get(); + auto *msg = ev->Get(); Executor()->FollowerGcApplied(msg->Step, msg->FollowerSyncDelay); -} - +} + void TTabletExecutedFlat::Handle(TEvTablet::TEvUpdateConfig::TPtr &ev) { if (Executor()) Executor()->UpdateConfig(ev); @@ -107,21 +107,21 @@ void TTabletExecutedFlat::HandleTabletStop(TEvTablet::TEvTabletStop::TPtr &ev, c } } -void TTabletExecutedFlat::HandleTabletDead(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext &ctx) { - if (Executor0) { - Executor0->DetachTablet(ExecutorCtx(ctx)); - Executor0 = nullptr; - } - - OnTabletDead(ev, ctx); -} - -void TTabletExecutedFlat::HandleLocalMKQL(TEvTablet::TEvLocalMKQL::TPtr &ev, const TActorContext &ctx) { +void TTabletExecutedFlat::HandleTabletDead(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext &ctx) { + if (Executor0) { + Executor0->DetachTablet(ExecutorCtx(ctx)); + Executor0 = nullptr; + } + + OnTabletDead(ev, ctx); +} + +void TTabletExecutedFlat::HandleLocalMKQL(TEvTablet::TEvLocalMKQL::TPtr &ev, const TActorContext &ctx) { Y_VERIFY(Factory, "Need IMiniKQLFactory to execute MKQL query"); Execute(Factory->Make(ev), ctx); -} - +} + void TTabletExecutedFlat::HandleLocalSchemeTx(TEvTablet::TEvLocalSchemeTx::TPtr &ev, const TActorContext &ctx) { Y_VERIFY(Factory, "Need IMiniKQLFactory to execute scheme query"); @@ -134,60 +134,60 @@ void TTabletExecutedFlat::HandleLocalReadColumns(TEvTablet::TEvLocalReadColumns: Execute(Factory->Make(ev), ctx); } -void TTabletExecutedFlat::SignalTabletActive(const TActorContext &ctx) { - ctx.Send(Tablet(), new TEvTablet::TEvTabletActive()); -} - -void TTabletExecutedFlat::DefaultSignalTabletActive(const TActorContext &ctx) { - SignalTabletActive(ctx); -} - -void TTabletExecutedFlat::Enqueue(STFUNC_SIG) { +void TTabletExecutedFlat::SignalTabletActive(const TActorContext &ctx) { + ctx.Send(Tablet(), new TEvTablet::TEvTabletActive()); +} + +void TTabletExecutedFlat::DefaultSignalTabletActive(const TActorContext &ctx) { + SignalTabletActive(ctx); +} + +void TTabletExecutedFlat::Enqueue(STFUNC_SIG) { Y_UNUSED(ev); Y_UNUSED(ctx); -} - -void TTabletExecutedFlat::ActivateExecutor(const TActorContext &ctx) { - DefaultSignalTabletActive(ctx); - OnActivateExecutor(ctx); -} - -void TTabletExecutedFlat::Detach(const TActorContext &ctx) { - Executor0 = nullptr; +} + +void TTabletExecutedFlat::ActivateExecutor(const TActorContext &ctx) { + DefaultSignalTabletActive(ctx); + OnActivateExecutor(ctx); +} + +void TTabletExecutedFlat::Detach(const TActorContext &ctx) { + Executor0 = nullptr; ctx.Send(Tablet(), new TEvents::TEvPoison()); - OnDetach(ctx); -} - -bool TTabletExecutedFlat::OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext &ctx) { - if (ev) { - TStringStream str; + OnDetach(ctx); +} + +bool TTabletExecutedFlat::OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext &ctx) { + if (ev) { + TStringStream str; HTML(str) {str << "nothing to see here...";} - ctx.Send(ev->Sender, new NMon::TEvRemoteHttpInfoRes(str.Str())); - } - return false; -} - -void TTabletExecutedFlat::RenderHtmlPage(NMon::TEvRemoteHttpInfo::TPtr &ev, const TActorContext &ctx) { - LOG_NOTICE_S(ctx, NKikimrServices::TABLET_EXECUTOR, "RenderHtmlPage for tablet " << TabletID()); - auto cgi = ev->Get()->Cgi(); - auto path = ev->Get()->PathInfo(); + ctx.Send(ev->Sender, new NMon::TEvRemoteHttpInfoRes(str.Str())); + } + return false; +} + +void TTabletExecutedFlat::RenderHtmlPage(NMon::TEvRemoteHttpInfo::TPtr &ev, const TActorContext &ctx) { + LOG_NOTICE_S(ctx, NKikimrServices::TABLET_EXECUTOR, "RenderHtmlPage for tablet " << TabletID()); + auto cgi = ev->Get()->Cgi(); + auto path = ev->Get()->PathInfo(); TString queryString = cgi.Print(); - - if (path == "/app") { - OnRenderAppHtmlPage(ev, ctx); - return; - } else if (path == "/executorInternals") { + + if (path == "/app") { + OnRenderAppHtmlPage(ev, ctx); + return; + } else if (path == "/executorInternals") { Executor()->RenderHtmlPage(ev); - return; - } else if (path == "/counters") { + return; + } else if (path == "/counters") { Executor()->RenderHtmlCounters(ev); - return; + return; } else if (path == "/db") { Executor()->RenderHtmlDb(ev, ExecutorCtx(ctx)); return; - } else { - const TDuration uptime = TAppData::TimeProvider->Now() - StartTime0; - TStringStream str; + } else { + const TDuration uptime = TAppData::TimeProvider->Now() - StartTime0; + TStringStream str; HTML(str) { DIV_CLASS("row") { DIV_CLASS("col-md-12") {str << "NodeID: " << ctx.SelfID.NodeId(); } @@ -196,7 +196,7 @@ void TTabletExecutedFlat::RenderHtmlPage(NMon::TEvRemoteHttpInfo::TPtr &ev, cons DIV_CLASS("col-md-12") {str << "Uptime: " << uptime.ToString(); } } DIV_CLASS("row") { - DIV_CLASS("col-md-12") {str << "Tablet type: " << TTabletTypes::TypeToStr((TTabletTypes::EType)TabletType()); } + DIV_CLASS("col-md-12") {str << "Tablet type: " << TTabletTypes::TypeToStr((TTabletTypes::EType)TabletType()); } } DIV_CLASS("row") { DIV_CLASS("col-md-12") {str << "Tablet id: " << TabletID() << (Executor()->GetStats().IsFollower ? " Follower" : " Leader"); } @@ -204,16 +204,16 @@ void TTabletExecutedFlat::RenderHtmlPage(NMon::TEvRemoteHttpInfo::TPtr &ev, cons DIV_CLASS("row") { DIV_CLASS("col-md-12") {str << "Tablet generation: " << Executor()->Generation();} } - DIV_CLASS("row") { - DIV_CLASS("col-md-12") { str << "Tenant id: " << Info()->TenantPathId; } - } - - if (OnRenderAppHtmlPage(nullptr, ctx)) { + DIV_CLASS("row") { + DIV_CLASS("col-md-12") { str << "Tenant id: " << Info()->TenantPathId; } + } + + if (OnRenderAppHtmlPage(nullptr, ctx)) { DIV_CLASS("row") { DIV_CLASS("col-md-12") {str << "<a href=\"tablets/app?" << queryString << "\">App</a>";} } - } - + } + DIV_CLASS("row") { DIV_CLASS("col-md-12") {str << "<a href=\"tablets/counters?" << queryString << "\">Counters</a>"; } } @@ -224,26 +224,26 @@ void TTabletExecutedFlat::RenderHtmlPage(NMon::TEvRemoteHttpInfo::TPtr &ev, cons DIV_CLASS("col-md-12") {str << "<a href=\"tablets?FollowerID=" << TabletID() << "\">Connect to follower</a>";} } DIV_CLASS("row") { - DIV_CLASS("col-md-12") {str << "<a href=\"tablets?SsId=" << TabletID() << "\">State Storage</a>";} + DIV_CLASS("col-md-12") {str << "<a href=\"tablets?SsId=" << TabletID() << "\">State Storage</a>";} } DIV_CLASS("row") { DIV_CLASS("col-md-12") {str << "<a href=\"tablets?KillTabletID=" << TabletID() << "\">Kill</a>";} } } - - ctx.Send(ev->Sender, new NMon::TEvRemoteHttpInfoRes(str.Str())); - return; - } -} - + + ctx.Send(ev->Sender, new NMon::TEvRemoteHttpInfoRes(str.Str())); + return; + } +} + void TTabletExecutedFlat::HandleGetCounters(TEvTablet::TEvGetCounters::TPtr &ev) { Executor()->GetTabletCounters(ev); } -bool TTabletExecutedFlat::HandleDefaultEvents(STFUNC_SIG) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvTablet::TEvBoot, Handle); - HFunc(TEvTablet::TEvRestored, Handle); +bool TTabletExecutedFlat::HandleDefaultEvents(STFUNC_SIG) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvTablet::TEvBoot, Handle); + HFunc(TEvTablet::TEvRestored, Handle); HFunc(TEvTablet::TEvFBoot, Handle); hFunc(TEvTablet::TEvFUpdate, Handle); hFunc(TEvTablet::TEvFAuxUpdate, Handle); @@ -251,35 +251,35 @@ bool TTabletExecutedFlat::HandleDefaultEvents(STFUNC_SIG) { hFunc(TEvTablet::TEvNewFollowerAttached, Handle); hFunc(TEvTablet::TEvFollowerSyncComplete, Handle); HFunc(TEvTablet::TEvTabletStop, HandleTabletStop); - HFunc(TEvTablet::TEvTabletDead, HandleTabletDead); - HFunc(TEvTablet::TEvLocalMKQL, HandleLocalMKQL); + HFunc(TEvTablet::TEvTabletDead, HandleTabletDead); + HFunc(TEvTablet::TEvLocalMKQL, HandleLocalMKQL); HFunc(TEvTablet::TEvLocalSchemeTx, HandleLocalSchemeTx); HFunc(TEvTablet::TEvLocalReadColumns, HandleLocalReadColumns); hFunc(TEvTablet::TEvGetCounters, HandleGetCounters); hFunc(TEvTablet::TEvUpdateConfig, Handle); - HFunc(NMon::TEvRemoteHttpInfo, RenderHtmlPage); - default: - return false; - } - return true; -} - + HFunc(NMon::TEvRemoteHttpInfo, RenderHtmlPage); + default: + return false; + } + return true; +} + void TTabletExecutedFlat::StateInitImpl(STFUNC_SIG) { switch (ev->GetTypeRewrite()) { - HFunc(TEvTablet::TEvBoot, Handle); + HFunc(TEvTablet::TEvBoot, Handle); HFunc(TEvTablet::TEvFBoot, Handle); hFunc(TEvTablet::TEvFUpdate, Handle); hFunc(TEvTablet::TEvFAuxUpdate, Handle); hFunc(TEvTablet::TEvFollowerGcApplied, Handle); - HFunc(TEvTablet::TEvRestored, Handle); + HFunc(TEvTablet::TEvRestored, Handle); HFunc(TEvTablet::TEvTabletStop, HandleTabletStop); - HFunc(TEvTablet::TEvTabletDead, HandleTabletDead); + HFunc(TEvTablet::TEvTabletDead, HandleTabletDead); hFunc(TEvTablet::TEvFollowerSyncComplete, Handle); hFunc(TEvTablet::TEvUpdateConfig, Handle); - HFunc(NMon::TEvRemoteHttpInfo, RenderHtmlPage); + HFunc(NMon::TEvRemoteHttpInfo, RenderHtmlPage); default: return Enqueue(ev, ctx); } } - -}} + +}} diff --git a/ydb/core/tablet_flat/tablet_flat_executed.h b/ydb/core/tablet_flat/tablet_flat_executed.h index be16c72333..117d7532bb 100644 --- a/ydb/core/tablet_flat/tablet_flat_executed.h +++ b/ydb/core/tablet_flat/tablet_flat_executed.h @@ -1,10 +1,10 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include "tablet_flat_executor.h" - -namespace NKikimr { -namespace NTabletFlatExecutor { - + +namespace NKikimr { +namespace NTabletFlatExecutor { + class TExecutor; struct IMiniKQLFactory { @@ -15,36 +15,36 @@ struct IMiniKQLFactory { virtual TAutoPtr<ITransaction> Make(TEvTablet::TEvLocalReadColumns::TPtr&) = 0; }; -class TTabletExecutedFlat : public NFlatExecutorSetup::ITablet { -protected: +class TTabletExecutedFlat : public NFlatExecutorSetup::ITablet { +protected: using IExecutor = NFlatExecutorSetup::IExecutor; TTabletExecutedFlat(TTabletStorageInfo *info, const TActorId &tablet, IMiniKQLFactory *factory); IExecutor* Executor() const { return Executor0; } const TInstant StartTime() const { return StartTime0; } - + void Execute(TAutoPtr<ITransaction> transaction, const TActorContext &ctx); void Execute(TAutoPtr<ITransaction> transaction); - + const NTable::TScheme& Scheme() const noexcept; - TActorContext ExecutorCtx(const TActivationContext &ctx) { + TActorContext ExecutorCtx(const TActivationContext &ctx) { return TActorContext(ctx.Mailbox, ctx.ExecutorThread, ctx.EventStart, ExecutorID()); - } - - virtual void OnActivateExecutor(const TActorContext &ctx) = 0; - virtual void OnDetach(const TActorContext &ctx) = 0; + } + + virtual void OnActivateExecutor(const TActorContext &ctx) = 0; + virtual void OnDetach(const TActorContext &ctx) = 0; virtual void OnTabletStop(TEvTablet::TEvTabletStop::TPtr &ev, const TActorContext &ctx); - virtual void OnTabletDead(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext &ctx) = 0; - virtual bool OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext &ctx); - - void SignalTabletActive(const TActorContext &ctx); - virtual void DefaultSignalTabletActive(const TActorContext &ctx); // must be overriden with empty body to postpone 'tablet active' notification - - virtual void Enqueue(STFUNC_SIG); - - void Handle(TEvTablet::TEvBoot::TPtr &ev, const TActorContext &ctx); - void Handle(TEvTablet::TEvRestored::TPtr &ev, const TActorContext &ctx); + virtual void OnTabletDead(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext &ctx) = 0; + virtual bool OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext &ctx); + + void SignalTabletActive(const TActorContext &ctx); + virtual void DefaultSignalTabletActive(const TActorContext &ctx); // must be overriden with empty body to postpone 'tablet active' notification + + virtual void Enqueue(STFUNC_SIG); + + void Handle(TEvTablet::TEvBoot::TPtr &ev, const TActorContext &ctx); + void Handle(TEvTablet::TEvRestored::TPtr &ev, const TActorContext &ctx); void Handle(TEvTablet::TEvFollowerSyncComplete::TPtr&); void Handle(TEvTablet::TEvFBoot::TPtr &ev, const TActorContext &ctx); void Handle(TEvTablet::TEvFUpdate::TPtr&); @@ -52,22 +52,22 @@ protected: void Handle(TEvTablet::TEvFollowerGcApplied::TPtr&); void Handle(TEvTablet::TEvNewFollowerAttached::TPtr&); void Handle(TEvTablet::TEvUpdateConfig::TPtr&); - + void HandleTabletStop(TEvTablet::TEvTabletStop::TPtr &ev, const TActorContext &ctx); - void HandleTabletDead(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext &ctx); - void HandleLocalMKQL(TEvTablet::TEvLocalMKQL::TPtr &ev, const TActorContext &ctx); + void HandleTabletDead(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext &ctx); + void HandleLocalMKQL(TEvTablet::TEvLocalMKQL::TPtr &ev, const TActorContext &ctx); void HandleLocalSchemeTx(TEvTablet::TEvLocalSchemeTx::TPtr &ev, const TActorContext &ctx); void HandleLocalReadColumns(TEvTablet::TEvLocalReadColumns::TPtr &ev, const TActorContext &ctx); void HandleGetCounters(TEvTablet::TEvGetCounters::TPtr &ev); - - STFUNC(StateInitImpl); - - void ActivateExecutor(const TActorContext &ctx) override; // executor is active after this point - void Detach(const TActorContext &ctx) override; // executor is dead after this point - - bool HandleDefaultEvents(STFUNC_SIG); + + STFUNC(StateInitImpl); + + void ActivateExecutor(const TActorContext &ctx) override; // executor is active after this point + void Detach(const TActorContext &ctx) override; // executor is dead after this point + + bool HandleDefaultEvents(STFUNC_SIG); virtual void RenderHtmlPage(NMon::TEvRemoteHttpInfo::TPtr&, const TActorContext &ctx); - + bool TryCaptureTxCache(ui64 size) { if (!TxCacheQuota) return false; @@ -77,19 +77,19 @@ protected: if (size) TxCacheQuota->ReleaseQuota(size); } - -private: + +private: IExecutor* CreateExecutor(const TActorContext &ctx); - + private: TAutoPtr<IMiniKQLFactory> Factory; IExecutor *Executor0; - TInstant StartTime0; + TInstant StartTime0; TSharedQuotaPtr TxCacheQuota; -}; - -}} +}; + +}} #define STFUNC_TABLET_INIT(NAME, HANDLERS) \ void NAME(STFUNC_SIG) { \ diff --git a/ydb/core/tablet_flat/tablet_flat_executor.cpp b/ydb/core/tablet_flat/tablet_flat_executor.cpp index 004e2cfa05..f69991ece9 100644 --- a/ydb/core/tablet_flat/tablet_flat_executor.cpp +++ b/ydb/core/tablet_flat/tablet_flat_executor.cpp @@ -1,29 +1,29 @@ -#include "tablet_flat_executor.h" -#include "flat_executor.h" - -namespace NKikimr { -namespace NTabletFlatExecutor { - -namespace NFlatExecutorSetup { +#include "tablet_flat_executor.h" +#include "flat_executor.h" + +namespace NKikimr { +namespace NTabletFlatExecutor { + +namespace NFlatExecutorSetup { IActor* CreateExecutor(ITablet *owner, const TActorId& ownerActorId) { return new TExecutor(owner, ownerActorId); - } - - void ITablet::SnapshotComplete(TIntrusivePtr<TTableSnapshotContext> snapContext, const TActorContext &ctx) { - Y_UNUSED(snapContext); - Y_UNUSED(ctx); - Y_FAIL("must be overriden if plan to use table snapshot completion"); - } - - void ITablet::CompactionComplete(ui32 tableId, const TActorContext &ctx) { - Y_UNUSED(tableId); - Y_UNUSED(ctx); - } - - void ITablet::CompletedLoansChanged(const TActorContext &ctx) { - Y_UNUSED(ctx); - } - + } + + void ITablet::SnapshotComplete(TIntrusivePtr<TTableSnapshotContext> snapContext, const TActorContext &ctx) { + Y_UNUSED(snapContext); + Y_UNUSED(ctx); + Y_FAIL("must be overriden if plan to use table snapshot completion"); + } + + void ITablet::CompactionComplete(ui32 tableId, const TActorContext &ctx) { + Y_UNUSED(tableId); + Y_UNUSED(ctx); + } + + void ITablet::CompletedLoansChanged(const TActorContext &ctx) { + Y_UNUSED(ctx); + } + void ITablet::ScanComplete(NTable::EAbort status, TAutoPtr<IDestructable> prod, ui64 cookie, const TActorContext &ctx) { Y_UNUSED(status); @@ -38,12 +38,12 @@ namespace NFlatExecutorSetup { } void ITablet::UpdateTabletInfo(TIntrusivePtr<TTabletStorageInfo> info, const TActorId& launcherID) { - if (info) - TabletInfo = info; + if (info) + TabletInfo = info; if (launcherID) LauncherActorID = launcherID; - } -} - -}} + } +} + +}} diff --git a/ydb/core/tablet_flat/tablet_flat_executor.h b/ydb/core/tablet_flat/tablet_flat_executor.h index 6ee8566f19..075ebce354 100644 --- a/ydb/core/tablet_flat/tablet_flat_executor.h +++ b/ydb/core/tablet_flat/tablet_flat_executor.h @@ -1,6 +1,6 @@ -#pragma once -#include "defs.h" - +#pragma once +#include "defs.h" + #include "flat_scan_iface.h" #include <ydb/core/base/tablet.h> @@ -9,37 +9,37 @@ #include <util/generic/maybe.h> #include <util/system/type_name.h> #include <util/generic/variant.h> - -//////////////////////////////////////////// -namespace NKikimr { -class TTabletCountersBase; - + +//////////////////////////////////////////// +namespace NKikimr { +class TTabletCountersBase; + namespace NTable { class TDatabase; class TScheme; } -namespace NTabletFlatExecutor { - -class TTransactionContext; -class TExecutor; +namespace NTabletFlatExecutor { + +class TTransactionContext; +class TExecutor; struct TPageCollectionTxEnv; -class TTableSnapshotContext : public TThrRefBase, TNonCopyable { - friend class TExecutor; +class TTableSnapshotContext : public TThrRefBase, TNonCopyable { + friend class TExecutor; friend struct TPageCollectionTxEnv; - - class TImpl; - THolder<TImpl> Impl; -public: - TTableSnapshotContext(); - virtual ~TTableSnapshotContext(); - virtual TConstArrayRef<ui32> TablesToSnapshot() const = 0; + + class TImpl; + THolder<TImpl> Impl; +public: + TTableSnapshotContext(); + virtual ~TTableSnapshotContext(); + virtual TConstArrayRef<ui32> TablesToSnapshot() const = 0; public: NTable::TSnapEdge Edge(ui32 table) const; -}; - +}; + class TMemoryGCToken : public TThrRefBase { public: TMemoryGCToken(ui64 size, ui64 taskId) @@ -103,14 +103,14 @@ struct IExecuting { }; class TTxMemoryProviderBase : TNonCopyable { -public: +public: TTxMemoryProviderBase(ui64 memoryLimit, ui64 taskId) : MemoryLimit(memoryLimit) , TaskId(taskId) , RequestedMemory(0) , NotEnoughMemoryCount(0) - {} - + {} + ~TTxMemoryProviderBase() {} ui64 GetMemoryLimit() const @@ -180,8 +180,8 @@ private: ui32 NotEnoughMemoryCount; TIntrusivePtr<TMemoryGCToken> MemoryGCToken; TAutoPtr<TMemoryToken> MemoryToken; -}; - +}; + class TTxMemoryProvider : public TTxMemoryProviderBase { public: TTxMemoryProvider(ui64 memoryLimit, ui64 taskId) @@ -226,17 +226,17 @@ private: TVector<std::function<void()>> OnCommitted_; }; -struct TCompactedPartLoans { - TLogoBlobID MetaInfoId; - ui64 Lender; - - TCompactedPartLoans() = default; - TCompactedPartLoans(const TLogoBlobID &metaId, ui64 lender) - : MetaInfoId(metaId) - , Lender(lender) - {} -}; - +struct TCompactedPartLoans { + TLogoBlobID MetaInfoId; + ui64 Lender; + + TCompactedPartLoans() = default; + TCompactedPartLoans(const TLogoBlobID &metaId, ui64 lender) + : MetaInfoId(metaId) + , Lender(lender) + {} +}; + struct TFinishedCompactionInfo { ui64 Edge = 0; TInstant FullCompactionTs; @@ -256,7 +256,7 @@ enum class ETerminationReason { class ITransaction : TNonCopyable { -public: +public: using TTransactionContext = NTabletFlatExecutor::TTransactionContext; ITransaction() = default; @@ -268,7 +268,7 @@ public: virtual ~ITransaction() = default; /// @return true if execution complete and transaction is ready for commit virtual bool Execute(TTransactionContext &txc, const TActorContext &ctx) = 0; - virtual void Complete(const TActorContext &ctx) = 0; + virtual void Complete(const TActorContext &ctx) = 0; virtual void Terminate(ETerminationReason reason, const TActorContext &/*ctx*/) { Y_FAIL("Unexpected transaction termination (reason %" PRIu32 ")", (ui32)reason); } @@ -282,8 +282,8 @@ public: public: NLWTrace::TOrbit Orbit; -}; - +}; + template<typename T> class TTransactionBase : public ITransaction { protected: @@ -302,16 +302,16 @@ public: { } }; -struct TExecutorStats { - bool IsActive = false; +struct TExecutorStats { + bool IsActive = false; bool IsFollower = false; bool IsAnyChannelYellowMove = false; bool IsAnyChannelYellowStop = false; - ui64 TxInFly = 0; - ui64 TxPending = 0; + ui64 TxInFly = 0; + ui64 TxPending = 0; const THashMap<TLogoBlobID, TCompactedPartLoans>* CompactedPartLoans = nullptr; - const bool* HasSharedBlobs = nullptr; - + const bool* HasSharedBlobs = nullptr; + TVector<ui32> YellowMoveChannels; TVector<ui32> YellowStopChannels; @@ -325,10 +325,10 @@ struct TExecutorStats { return it != YellowStopChannels.end() && *it == channel; } -protected: - virtual ~TExecutorStats() {} -}; - +protected: + virtual ~TExecutorStats() {} +}; + struct TScanOptions { enum class EReadPrio { Default, @@ -425,24 +425,24 @@ struct TScanOptions { } }; -namespace NFlatExecutorSetup { - struct ITablet : TNonCopyable { - virtual ~ITablet() {} - - virtual void ActivateExecutor(const TActorContext &ctx) = 0; - virtual void Detach(const TActorContext &ctx) = 0; - - TTabletStorageInfo* Info() const { return TabletInfo.Get(); } - ui64 TabletID() const { return TabletInfo->TabletID; } +namespace NFlatExecutorSetup { + struct ITablet : TNonCopyable { + virtual ~ITablet() {} + + virtual void ActivateExecutor(const TActorContext &ctx) = 0; + virtual void Detach(const TActorContext &ctx) = 0; + + TTabletStorageInfo* Info() const { return TabletInfo.Get(); } + ui64 TabletID() const { return TabletInfo->TabletID; } TTabletTypes::EType TabletType() const { return TabletInfo->TabletType; } const TActorId& Tablet() const { return TabletActorID; } const TActorId& ExecutorID() const { return ExecutorActorID; } const TActorId& LauncherID() const { return LauncherActorID; } - - virtual void SnapshotComplete(TIntrusivePtr<TTableSnapshotContext> snapContext, const TActorContext &ctx); // would be FAIL in default implementation - virtual void CompletedLoansChanged(const TActorContext &ctx); // would be no-op in default implementation - virtual void CompactionComplete(ui32 tableId, const TActorContext &ctx); // would be no-op in default implementation - + + virtual void SnapshotComplete(TIntrusivePtr<TTableSnapshotContext> snapContext, const TActorContext &ctx); // would be FAIL in default implementation + virtual void CompletedLoansChanged(const TActorContext &ctx); // would be no-op in default implementation + virtual void CompactionComplete(ui32 tableId, const TActorContext &ctx); // would be no-op in default implementation + virtual void ScanComplete(NTable::EAbort status, TAutoPtr<IDestructable> prod, ui64 cookie, const TActorContext &ctx); virtual bool ReassignChannelsEnabled() const; @@ -452,37 +452,37 @@ namespace NFlatExecutorSetup { virtual void OnLeaderUserAuxUpdate(TString) { /* default */ } - // create transaction? - protected: + // create transaction? + protected: ITablet(TTabletStorageInfo *info, const TActorId &tablet) - : TabletActorID(tablet) - , TabletInfo(info) - { + : TabletActorID(tablet) + , TabletInfo(info) + { Y_VERIFY(TTabletTypes::TYPE_INVALID != TabletInfo->TabletType); - } - + } + TActorId ExecutorActorID; TActorId TabletActorID; TActorId LauncherActorID; - + void UpdateTabletInfo(TIntrusivePtr<TTabletStorageInfo> info, const TActorId& launcherID = {}); - private: - TIntrusivePtr<TTabletStorageInfo> TabletInfo; - }; - - - //////////////////////////////////////////// - // tablet -> executor - struct IExecutor : TNonCopyable { - virtual ~IExecutor() {} - + private: + TIntrusivePtr<TTabletStorageInfo> TabletInfo; + }; + + + //////////////////////////////////////////// + // tablet -> executor + struct IExecutor : TNonCopyable { + virtual ~IExecutor() {} + // tablet assigned as leader, could begin loading - virtual void Boot(TEvTablet::TEvBoot::TPtr &ev, const TActorContext &ctx) = 0; + virtual void Boot(TEvTablet::TEvBoot::TPtr &ev, const TActorContext &ctx) = 0; // tablet generation restoration complete, tablet could act as leader - virtual void Restored(TEvTablet::TEvRestored::TPtr &ev, const TActorContext &ctx) = 0; - // die! - virtual void DetachTablet(const TActorContext &ctx) = 0; - + virtual void Restored(TEvTablet::TEvRestored::TPtr &ev, const TActorContext &ctx) = 0; + // die! + virtual void DetachTablet(const TActorContext &ctx) = 0; + // tablet assigned as follower (or follower connection refreshed), must begin loading virtual void FollowerBoot(TEvTablet::TEvFBoot::TPtr &ev, const TActorContext &ctx) = 0; // next follower incremental update @@ -493,9 +493,9 @@ namespace NFlatExecutorSetup { virtual void FollowerSyncComplete() = 0; // all followers had completed log with requested gc-barrier virtual void FollowerGcApplied(ui32 step, TDuration followerSyncDelay) = 0; - + virtual void Execute(TAutoPtr<ITransaction> transaction, const TActorContext &ctx) = 0; - + /* Make blob with data required for table bootstapping. Note: 1. Once non-trivial blob obtained and commited in tx all of its borrowed bundles have to be eventually released (see db). @@ -525,7 +525,7 @@ namespace NFlatExecutorSetup { virtual void RenderHtmlDb(NMon::TEvRemoteHttpInfo::TPtr &ev, const TActorContext &ctx) const = 0; virtual void RegisterExternalTabletCounters(TAutoPtr<TTabletCountersBase> appCounters) = 0; virtual void GetTabletCounters(TEvTablet::TEvGetCounters::TPtr&) = 0; - + virtual void UpdateConfig(TEvTablet::TEvUpdateConfig::TPtr&) = 0; virtual void SendUserAuxUpdateToFollowers(TString upd, const TActorContext &ctx) = 0; @@ -536,9 +536,9 @@ namespace NFlatExecutorSetup { // This method lets executor know about new yellow channels virtual void OnYellowChannels(TVector<ui32> yellowMoveChannels, TVector<ui32> yellowStopChannels) = 0; - virtual const TExecutorStats& GetStats() const = 0; + virtual const TExecutorStats& GetStats() const = 0; virtual NMetrics::TResourceMetrics* GetResourceMetrics() const = 0; - + /* This stange looking functionallity probably should be dropped */ virtual float GetRejectProbability() const = 0; @@ -546,21 +546,21 @@ namespace NFlatExecutorSetup { // Returns current database scheme (executor must be active) virtual const NTable::TScheme& Scheme() const noexcept = 0; - ui32 Generation() const { return Generation0; } - ui32 Step() const { return Step0; } - - protected: - // - IExecutor() - : Generation0(0) - , Step0(0) - {} - - ui32 Generation0; - ui32 Step0; - }; - + ui32 Generation() const { return Generation0; } + ui32 Step() const { return Step0; } + + protected: + // + IExecutor() + : Generation0(0) + , Step0(0) + {} + + ui32 Generation0; + ui32 Step0; + }; + IActor* CreateExecutor(ITablet *owner, const TActorId& ownerActorId); -}; - -}} // end of the NKikimr namespace +}; + +}} // end of the NKikimr namespace diff --git a/ydb/core/tablet_flat/test/libs/exec/runner.h b/ydb/core/tablet_flat/test/libs/exec/runner.h index 610af31463..3b58ab814b 100644 --- a/ydb/core/tablet_flat/test/libs/exec/runner.h +++ b/ydb/core/tablet_flat/test/libs/exec/runner.h @@ -137,9 +137,9 @@ namespace NFake { TIntrusivePtr<TStateStorageInfo> info(new TStateStorageInfo()); info->StateStorageGroup = 0; - info->NToSelect = 1; - info->Rings.resize(1); - info->Rings[0].Replicas.push_back(replica); + info->NToSelect = 1; + info->Rings.resize(1); + info->Rings[0].Replicas.push_back(replica); { auto *actor = CreateStateStorageReplica(info, 0); diff --git a/ydb/core/tablet_flat/test/libs/exec/ya.make b/ydb/core/tablet_flat/test/libs/exec/ya.make index 12a7b7acc4..7557219985 100644 --- a/ydb/core/tablet_flat/test/libs/exec/ya.make +++ b/ydb/core/tablet_flat/test/libs/exec/ya.make @@ -1,6 +1,6 @@ LIBRARY() -OWNER(g:kikimr) +OWNER(g:kikimr) SRCS() diff --git a/ydb/core/tablet_flat/test/libs/rows/ya.make b/ydb/core/tablet_flat/test/libs/rows/ya.make index 40f5d308f0..b8185eac60 100644 --- a/ydb/core/tablet_flat/test/libs/rows/ya.make +++ b/ydb/core/tablet_flat/test/libs/rows/ya.make @@ -1,6 +1,6 @@ LIBRARY() -OWNER(g:kikimr) +OWNER(g:kikimr) SRCS( all.cpp diff --git a/ydb/core/tablet_flat/test/libs/table/model/ya.make b/ydb/core/tablet_flat/test/libs/table/model/ya.make index 227adef063..dab9796656 100644 --- a/ydb/core/tablet_flat/test/libs/table/model/ya.make +++ b/ydb/core/tablet_flat/test/libs/table/model/ya.make @@ -1,6 +1,6 @@ LIBRARY() -OWNER(g:kikimr) +OWNER(g:kikimr) PEERDIR( ydb/core/tablet_flat/test/libs/rows diff --git a/ydb/core/tablet_flat/test/libs/table/ya.make b/ydb/core/tablet_flat/test/libs/table/ya.make index 6c50a6d86c..53d6ab494b 100644 --- a/ydb/core/tablet_flat/test/libs/table/ya.make +++ b/ydb/core/tablet_flat/test/libs/table/ya.make @@ -1,6 +1,6 @@ LIBRARY() -OWNER(g:kikimr) +OWNER(g:kikimr) SRCS( misc.cpp diff --git a/ydb/core/tablet_flat/test/tool/perf/ya.make b/ydb/core/tablet_flat/test/tool/perf/ya.make index c2de849f8c..dc0e8ca728 100644 --- a/ydb/core/tablet_flat/test/tool/perf/ya.make +++ b/ydb/core/tablet_flat/test/tool/perf/ya.make @@ -1,6 +1,6 @@ PROGRAM(table-perf) -OWNER(g:kikimr) +OWNER(g:kikimr) SRCS( colons.cpp diff --git a/ydb/core/tablet_flat/test/tool/surg/ya.make b/ydb/core/tablet_flat/test/tool/surg/ya.make index 7e74eec7bb..18495b00b9 100644 --- a/ydb/core/tablet_flat/test/tool/surg/ya.make +++ b/ydb/core/tablet_flat/test/tool/surg/ya.make @@ -1,6 +1,6 @@ PROGRAM() -OWNER(g:kikimr) +OWNER(g:kikimr) SRCS( main.cpp diff --git a/ydb/core/tablet_flat/test/tool/ya.make b/ydb/core/tablet_flat/test/tool/ya.make index fe5af5a304..e3f445cf0b 100644 --- a/ydb/core/tablet_flat/test/tool/ya.make +++ b/ydb/core/tablet_flat/test/tool/ya.make @@ -1,4 +1,4 @@ -OWNER(g:kikimr) +OWNER(g:kikimr) RECURSE( surg diff --git a/ydb/core/tablet_flat/ut/ya.make b/ydb/core/tablet_flat/ut/ya.make index 03471d21c2..fd66d04202 100644 --- a/ydb/core/tablet_flat/ut/ya.make +++ b/ydb/core/tablet_flat/ut/ya.make @@ -11,7 +11,7 @@ ELSE() SIZE(MEDIUM) ENDIF() -OWNER(g:kikimr) +OWNER(g:kikimr) SRCS( datetime_ut.cpp diff --git a/ydb/core/tablet_flat/ya.make b/ydb/core/tablet_flat/ya.make index ec84d93b3f..6b1226bf01 100644 --- a/ydb/core/tablet_flat/ya.make +++ b/ydb/core/tablet_flat/ya.make @@ -1,48 +1,48 @@ -LIBRARY() - -OWNER( - ddoarn +LIBRARY() + +OWNER( + ddoarn g:kikimr -) - -SRCS( - defs.h +) + +SRCS( + defs.h flat_boot_misc.cpp flat_comp.cpp flat_comp_create.cpp flat_comp_gen.cpp flat_comp_shard.cpp flat_cxx_database.h - flat_database.cpp - flat_database.h + flat_database.cpp + flat_database.h flat_dbase_scheme.cpp flat_dbase_apply.cpp flat_exec_broker.cpp flat_exec_commit.cpp flat_exec_commit_mgr.cpp flat_exec_seat.cpp - flat_executor.cpp - flat_executor.h - flat_executor_bootlogic.cpp - flat_executor_bootlogic.h - flat_executor_borrowlogic.cpp - flat_executor_borrowlogic.h + flat_executor.cpp + flat_executor.h + flat_executor_bootlogic.cpp + flat_executor_bootlogic.h + flat_executor_borrowlogic.cpp + flat_executor_borrowlogic.h flat_executor_compaction_logic.cpp flat_executor_compaction_logic.h - flat_executor_counters.cpp - flat_executor_counters.h + flat_executor_counters.cpp + flat_executor_counters.h flat_executor_db_mon.cpp flat_executor_gclogic.cpp flat_executor_gclogic.h flat_bio_actor.cpp flat_executor_snapshot.cpp - flat_executor_txloglogic.cpp - flat_executor_txloglogic.h - flat_iterator.h + flat_executor_txloglogic.cpp + flat_executor_txloglogic.h + flat_iterator.h flat_load_blob_queue.cpp flat_mem_warm.cpp - flat_sausagecache.cpp - flat_sausagecache.h + flat_sausagecache.cpp + flat_sausagecache.h flat_sausage_meta.cpp flat_page_label.cpp flat_part_dump.cpp @@ -58,23 +58,23 @@ SRCS( flat_stat_table.h flat_stat_table.cpp flat_store_hotdog.cpp - flat_table.cpp + flat_table.cpp flat_table.h - flat_table_part.cpp - flat_table_part.h + flat_table_part.cpp + flat_table_part.h flat_table_misc.cpp - flat_update_op.h + flat_update_op.h probes.cpp shared_handle.cpp - shared_sausagecache.cpp - shared_sausagecache.h - tablet_flat_executor.h - tablet_flat_executor.cpp - tablet_flat_executed.h - tablet_flat_executed.cpp - flat_executor.proto -) - + shared_sausagecache.cpp + shared_sausagecache.h + tablet_flat_executor.h + tablet_flat_executor.cpp + tablet_flat_executed.h + tablet_flat_executed.cpp + flat_executor.proto +) + GENERATE_ENUM_SERIALIZATION(flat_comp_gen.h) GENERATE_ENUM_SERIALIZATION(flat_comp_shard.h) @@ -91,7 +91,7 @@ IF (KIKIMR_TABLET_BORROW_WITHOUT_META) ) ENDIF() -PEERDIR( +PEERDIR( contrib/libs/protobuf library/cpp/containers/intrusive_rb_tree library/cpp/containers/stack_vector @@ -107,8 +107,8 @@ PEERDIR( ydb/library/binary_json ydb/library/dynumber ydb/library/mkql_proto/protos -) - +) + YQL_LAST_ABI_VERSION() END() diff --git a/ydb/core/testlib/actors/test_runtime_ut.cpp b/ydb/core/testlib/actors/test_runtime_ut.cpp index 2494ff74ca..fce7f19293 100644 --- a/ydb/core/testlib/actors/test_runtime_ut.cpp +++ b/ydb/core/testlib/actors/test_runtime_ut.cpp @@ -227,14 +227,14 @@ Y_UNIT_TEST_SUITE(TActorTest) { } Y_UNIT_TEST(TestSendAfterDelay) { - TMutex syncMutex; - + TMutex syncMutex; + class TMyActor : public TActor<TMyActor> { public: - TMyActor(TMutex *syncMutex) + TMyActor(TMutex *syncMutex) : TActor(&TMyActor::StateFunc) , CurrentTime(TInstant::MicroSeconds(0)) - , SyncMutex(syncMutex) + , SyncMutex(syncMutex) { } @@ -244,34 +244,34 @@ Y_UNIT_TEST_SUITE(TActorTest) { STFUNC(StateFunc) { - Y_VERIFY(SyncMutex); - + Y_VERIFY(SyncMutex); + auto sender = ev->Sender; auto selfID = ctx.SelfID; auto actorSystem = ctx.ExecutorThread.ActorSystem; - TMutex *syncMutex = SyncMutex; - + TMutex *syncMutex = SyncMutex; + SystemThreadFactory()->Run([=](){ - with_lock(*syncMutex) { - Sleep(TDuration::MilliSeconds(100)); - CurrentTime = actorSystem->Timestamp(); - actorSystem->Send(new IEventHandle(sender, selfID, new TEvents::TEvPong())); - } + with_lock(*syncMutex) { + Sleep(TDuration::MilliSeconds(100)); + CurrentTime = actorSystem->Timestamp(); + actorSystem->Send(new IEventHandle(sender, selfID, new TEvents::TEvPong())); + } }); - - SyncMutex = nullptr; + + SyncMutex = nullptr; } private: TInstant CurrentTime; - TMutex *SyncMutex; + TMutex *SyncMutex; }; TTestActorRuntime runtime; runtime.Initialize(MakeEgg()); try { TActorId sender = runtime.AllocateEdgeActor(); - auto myActor = new TMyActor(&syncMutex); + auto myActor = new TMyActor(&syncMutex); TActorId actorId = runtime.Register(myActor); runtime.Send(new IEventHandle(actorId, sender, new TEvents::TEvPing)); runtime.DispatchEvents(); @@ -287,8 +287,8 @@ Y_UNIT_TEST_SUITE(TActorTest) { Sleep(TDuration::MilliSeconds(1000)); throw; } - - with_lock(syncMutex) {} + + with_lock(syncMutex) {} } Y_UNIT_TEST(TestGetCtxTime) { diff --git a/ydb/core/testlib/basics/services.cpp b/ydb/core/testlib/basics/services.cpp index 54db83df82..b4585ad96c 100644 --- a/ydb/core/testlib/basics/services.cpp +++ b/ydb/core/testlib/basics/services.cpp @@ -155,26 +155,26 @@ namespace NPDisk { { TIntrusivePtr<TStateStorageInfo> info(new TStateStorageInfo()); info->StateStorageGroup = stateStorageGroup; - info->NToSelect = N; - info->Rings.resize(N); + info->NToSelect = N; + info->Rings.resize(N); for (size_t i = 0; i < N; ++i) { - info->Rings[i].Replicas.push_back(replicas[i]); + info->Rings[i].Replicas.push_back(replicas[i]); } return info; } static TActorId MakeBoardReplicaID( - const ui32 node, - const ui64 stateStorageGroup, - const ui32 replicaIndex - ) { - char x[12] = { 's', 's', 'b' }; - x[3] = (char)stateStorageGroup; - memcpy(x + 5, &replicaIndex, sizeof(ui32)); + const ui32 node, + const ui64 stateStorageGroup, + const ui32 replicaIndex + ) { + char x[12] = { 's', 's', 'b' }; + x[3] = (char)stateStorageGroup; + memcpy(x + 5, &replicaIndex, sizeof(ui32)); return TActorId(node, TStringBuf(x, 12)); - } - + } + void SetupStateStorage(TTestActorRuntime& runtime, ui32 nodeIndex, ui64 stateStorageGroup, bool firstNode) { const TActorId ssreplicas[3] = { @@ -184,11 +184,11 @@ namespace NPDisk { }; const TActorId breplicas[3] = { - MakeBoardReplicaID(runtime.GetNodeId(0), stateStorageGroup, 0), - MakeBoardReplicaID(runtime.GetNodeId(0), stateStorageGroup, 1), - MakeBoardReplicaID(runtime.GetNodeId(0), stateStorageGroup, 2), - }; - + MakeBoardReplicaID(runtime.GetNodeId(0), stateStorageGroup, 0), + MakeBoardReplicaID(runtime.GetNodeId(0), stateStorageGroup, 1), + MakeBoardReplicaID(runtime.GetNodeId(0), stateStorageGroup, 2), + }; + const TActorId sbreplicas[3] = { MakeSchemeBoardReplicaID(runtime.GetNodeId(0), stateStorageGroup, 0), MakeSchemeBoardReplicaID(runtime.GetNodeId(0), stateStorageGroup, 1), @@ -199,7 +199,7 @@ namespace NPDisk { auto ssInfo = GenerateStateStorageInfo(ssreplicas, stateStorageGroup); auto sbInfo = GenerateStateStorageInfo(sbreplicas, stateStorageGroup); - auto bInfo = GenerateStateStorageInfo(breplicas, stateStorageGroup); + auto bInfo = GenerateStateStorageInfo(breplicas, stateStorageGroup); if (!firstNode || nodeIndex == 0) { for (ui32 i = 0; i < 3; ++i) { @@ -207,13 +207,13 @@ namespace NPDisk { TActorSetupCmd(CreateStateStorageReplica(ssInfo.Get(), i), TMailboxType::Revolving, 0), nodeIndex); runtime.AddLocalService(sbreplicas[i], TActorSetupCmd(CreateSchemeBoardReplica(sbInfo.Get(), i), TMailboxType::Revolving, 0), nodeIndex); - runtime.AddLocalService(breplicas[i], - TActorSetupCmd(CreateStateStorageBoardReplica(bInfo.Get(), i), TMailboxType::Revolving, 0), nodeIndex); + runtime.AddLocalService(breplicas[i], + TActorSetupCmd(CreateStateStorageBoardReplica(bInfo.Get(), i), TMailboxType::Revolving, 0), nodeIndex); } } runtime.AddLocalService(ssproxy, - TActorSetupCmd(CreateStateStorageProxy(ssInfo.Get(), bInfo.Get(), sbInfo.Get()), TMailboxType::Revolving, 0), nodeIndex); + TActorSetupCmd(CreateStateStorageProxy(ssInfo.Get(), bInfo.Get(), sbInfo.Get()), TMailboxType::Revolving, 0), nodeIndex); } static void SetupStateStorageGroups(TTestActorRuntime& runtime, ui32 nodeIndex, TAppPrepare& app) diff --git a/ydb/core/testlib/fake_coordinator.cpp b/ydb/core/testlib/fake_coordinator.cpp index 53125d8c0d..0be35b3bcf 100644 --- a/ydb/core/testlib/fake_coordinator.cpp +++ b/ydb/core/testlib/fake_coordinator.cpp @@ -3,10 +3,10 @@ namespace NKikimr { - void BootFakeCoordinator(TTestActorRuntime& runtime, ui64 coordinatorId, TFakeCoordinator::TState::TPtr state) { + void BootFakeCoordinator(TTestActorRuntime& runtime, ui64 coordinatorId, TFakeCoordinator::TState::TPtr state) { CreateTestBootstrapper(runtime, CreateTestTabletInfo(coordinatorId, TTabletTypes::FLAT_TX_COORDINATOR), [=](const TActorId & tablet, TTabletStorageInfo* info) { - return new TFakeCoordinator(tablet, info, state); + return new TFakeCoordinator(tablet, info, state); }); { diff --git a/ydb/core/testlib/fake_coordinator.h b/ydb/core/testlib/fake_coordinator.h index 17b2e001f7..b3098d60a5 100644 --- a/ydb/core/testlib/fake_coordinator.h +++ b/ydb/core/testlib/fake_coordinator.h @@ -97,12 +97,12 @@ namespace NKikimr { State->TxIds.insert(std::make_pair(tx.GetTxId(), shards)); Cerr << "FAKE_COORDINATOR: Add transaction: " << tx.GetTxId() << " at step: " << State->CurrentStep << "\n"; for (ui64 shard : shards) { - auto evPlan = new TEvTxProcessing::TEvPlanStep(State->CurrentStep, 0, shard); - auto planTx = evPlan->Record.AddTransactions(); - planTx->SetCoordinator(TabletID()); - planTx->SetTxId(tx.GetTxId()); + auto evPlan = new TEvTxProcessing::TEvPlanStep(State->CurrentStep, 0, shard); + auto planTx = evPlan->Record.AddTransactions(); + planTx->SetCoordinator(TabletID()); + planTx->SetTxId(tx.GetTxId()); ActorIdToProto(ctx.SelfID, planTx->MutableAckTo()); - State->QueuedPlans[std::make_pair(shard, State->CurrentStep)].push_back(evPlan); + State->QueuedPlans[std::make_pair(shard, State->CurrentStep)].push_back(evPlan); } AdvancePlan(ctx); @@ -228,5 +228,5 @@ namespace NKikimr { TAutoPtr<NTabletPipe::IClientCache> Pipes; }; - void BootFakeCoordinator(TTestActorRuntime& runtime, ui64 tabletId, TFakeCoordinator::TState::TPtr state); + void BootFakeCoordinator(TTestActorRuntime& runtime, ui64 tabletId, TFakeCoordinator::TState::TPtr state); } diff --git a/ydb/core/testlib/tablet_flat_dummy.cpp b/ydb/core/testlib/tablet_flat_dummy.cpp index f95160b88c..1a9dca04a5 100644 --- a/ydb/core/testlib/tablet_flat_dummy.cpp +++ b/ydb/core/testlib/tablet_flat_dummy.cpp @@ -5,143 +5,143 @@ #include <ydb/core/engine/minikql/flat_local_tx_factory.h> #include <ydb/core/base/appdata.h> #include <library/cpp/actors/core/hfunc.h> - -namespace NKikimr { - + +namespace NKikimr { + namespace { class TDummyFlatTablet : public TActor<TDummyFlatTablet>, public NTabletFlatExecutor::TTabletExecutedFlat { - + struct Schema : NIceDb::Schema { - struct Snaps : Table<1> { - struct SourceTableId : Column<1, NScheme::NTypeIds::Uint32> {}; - struct DestinationTablet : Column<2, NScheme::NTypeIds::Uint64> {}; - struct Delivered : Column<3, NScheme::NTypeIds::Bool> {}; - - using TKey = TableKey<SourceTableId, DestinationTablet>; - using TColumns = TableColumns<SourceTableId, DestinationTablet, Delivered>; - }; - - struct t_by_ui64 : Table<32> { - struct key : Column<32, NScheme::NTypeIds::Uint64> {}; + struct Snaps : Table<1> { + struct SourceTableId : Column<1, NScheme::NTypeIds::Uint32> {}; + struct DestinationTablet : Column<2, NScheme::NTypeIds::Uint64> {}; + struct Delivered : Column<3, NScheme::NTypeIds::Bool> {}; + + using TKey = TableKey<SourceTableId, DestinationTablet>; + using TColumns = TableColumns<SourceTableId, DestinationTablet, Delivered>; + }; + + struct t_by_ui64 : Table<32> { + struct key : Column<32, NScheme::NTypeIds::Uint64> {}; struct v_bytes : Column<33, NScheme::NTypeIds::String4k> {}; - struct v_ui64 : Column<34, NScheme::NTypeIds::Uint64> {}; - - using TKey = TableKey<key>; - using TColumns = TableColumns<key, v_bytes, v_ui64>; - }; - - struct t_by_bytes : Table<33> { + struct v_ui64 : Column<34, NScheme::NTypeIds::Uint64> {}; + + using TKey = TableKey<key>; + using TColumns = TableColumns<key, v_bytes, v_ui64>; + }; + + struct t_by_bytes : Table<33> { struct key : Column<32, NScheme::NTypeIds::String4k> {}; struct v_bytes : Column<33, NScheme::NTypeIds::String4k> {}; - struct v_ui64 : Column<34, NScheme::NTypeIds::Uint64> {}; - - using TKey = TableKey<key>; - using TColumns = TableColumns<key, v_bytes, v_ui64>; - }; - - using TTables = SchemaTables<Snaps, t_by_ui64, t_by_bytes>; - }; - - struct TTxSchemeInit : public NTabletFlatExecutor::ITransaction { - TDummyFlatTablet * const Self; - - TTxSchemeInit(TDummyFlatTablet *self) - : Self(self) - {} - - bool Execute(TTransactionContext &txc, const TActorContext &ctx) override { - Y_UNUSED(ctx); + struct v_ui64 : Column<34, NScheme::NTypeIds::Uint64> {}; + + using TKey = TableKey<key>; + using TColumns = TableColumns<key, v_bytes, v_ui64>; + }; + + using TTables = SchemaTables<Snaps, t_by_ui64, t_by_bytes>; + }; + + struct TTxSchemeInit : public NTabletFlatExecutor::ITransaction { + TDummyFlatTablet * const Self; + + TTxSchemeInit(TDummyFlatTablet *self) + : Self(self) + {} + + bool Execute(TTransactionContext &txc, const TActorContext &ctx) override { + Y_UNUSED(ctx); NIceDb::TNiceDb(txc.DB).Materialize<Schema>(); - return true; - } - - void Complete(const TActorContext &ctx) override { - Self->Execute(new TTxInit(Self), ctx); - } - }; - - struct TTxInit : public NTabletFlatExecutor::ITransaction { - TDummyFlatTablet * const Self; - - TTxInit(TDummyFlatTablet *self) - : Self(self) - {} - - bool Execute(TTransactionContext &txc, const TActorContext &ctx) override { - Y_UNUSED(txc); + return true; + } + + void Complete(const TActorContext &ctx) override { + Self->Execute(new TTxInit(Self), ctx); + } + }; + + struct TTxInit : public NTabletFlatExecutor::ITransaction { + TDummyFlatTablet * const Self; + + TTxInit(TDummyFlatTablet *self) + : Self(self) + {} + + bool Execute(TTransactionContext &txc, const TActorContext &ctx) override { + Y_UNUSED(txc); Y_UNUSED(ctx); - return true; - } - - void Complete(const TActorContext &ctx) override { - Self->SignalTabletActive(ctx); - } - }; - - friend struct TTxSchemeInit; - friend struct TTxInit; - - void Handle(TEvents::TEvPoisonPill::TPtr &ev, const TActorContext &ctx) { + return true; + } + + void Complete(const TActorContext &ctx) override { + Self->SignalTabletActive(ctx); + } + }; + + friend struct TTxSchemeInit; + friend struct TTxInit; + + void Handle(TEvents::TEvPoisonPill::TPtr &ev, const TActorContext &ctx) { Y_UNUSED(ev); - Become(&TThis::StateBroken); - ctx.Send(Tablet(), new TEvents::TEvPoisonPill); - } - - void OnActivateExecutor(const TActorContext &ctx) override { - Become(&TThis::StateWork); + Become(&TThis::StateBroken); + ctx.Send(Tablet(), new TEvents::TEvPoisonPill); + } + + void OnActivateExecutor(const TActorContext &ctx) override { + Become(&TThis::StateWork); if (Executor()->GetStats().IsFollower) - SignalTabletActive(ctx); - else - Execute(new TTxSchemeInit(this), ctx); - } - + SignalTabletActive(ctx); + else + Execute(new TTxSchemeInit(this), ctx); + } + void OnDetach(const TActorContext &ctx) override { - Die(ctx); - } - + Die(ctx); + } + void OnTabletDead(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext &ctx) override { Y_UNUSED(ev); - Die(ctx); - } - - void DefaultSignalTabletActive(const TActorContext &ctx) override { + Die(ctx); + } + + void DefaultSignalTabletActive(const TActorContext &ctx) override { Y_UNUSED(ctx); - } - -public: + } + +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TEST_ACTOR_RUNTIME; } TDummyFlatTablet(const TActorId &tablet, TTabletStorageInfo *info) - : TActor(&TThis::StateInit) + : TActor(&TThis::StateInit) , TTabletExecutedFlat(info, tablet, new NMiniKQL::TMiniKQLFactory) - {} - - STFUNC(StateInit) { - StateInitImpl(ev, ctx); - } - - STFUNC(StateWork) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvents::TEvPoisonPill, Handle); - default: - HandleDefaultEvents(ev, ctx); - break; - } - } - - STFUNC(StateBroken) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvTablet::TEvTabletDead, HandleTabletDead) - } - } -}; - + {} + + STFUNC(StateInit) { + StateInitImpl(ev, ctx); + } + + STFUNC(StateWork) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvents::TEvPoisonPill, Handle); + default: + HandleDefaultEvents(ev, ctx); + break; + } + } + + STFUNC(StateBroken) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvTablet::TEvTabletDead, HandleTabletDead) + } + } +}; + } // namespace IActor* CreateFlatDummyTablet(const TActorId &tablet, TTabletStorageInfo *info) { - return new TDummyFlatTablet(tablet, info); - -}} + return new TDummyFlatTablet(tablet, info); + +}} diff --git a/ydb/core/testlib/tablet_helpers.cpp b/ydb/core/testlib/tablet_helpers.cpp index 90b589f8a2..a853040b93 100644 --- a/ydb/core/testlib/tablet_helpers.cpp +++ b/ydb/core/testlib/tablet_helpers.cpp @@ -570,8 +570,8 @@ namespace NKikimr { TActorId FollowerTablet(TTestActorRuntime &runtime, const TActorId &launcher, TTabletStorageInfo *info, std::function<IActor * (const TActorId &, TTabletStorageInfo *)> op) { return runtime.Register(CreateTabletFollower(launcher, info, new TTabletSetupInfo(op, TMailboxType::Simple, 0, TMailboxType::Simple, 0), 0, new TResourceProfiles)); - } - + } + TActorId ResolveTablet(TTestActorRuntime &runtime, ui64 tabletId, ui32 nodeIndex, bool sysTablet) { auto sender = runtime.AllocateEdgeActor(nodeIndex); runtime.Send(new IEventHandle(MakeTabletResolverID(), sender, @@ -1075,7 +1075,7 @@ namespace NKikimr { runtime.GrabEdgeEvent<TEvents::TEvWakeup>(handle); } - class TFakeHive : public TActor<TFakeHive>, public NTabletFlatExecutor::TTabletExecutedFlat { + class TFakeHive : public TActor<TFakeHive>, public NTabletFlatExecutor::TTabletExecutedFlat { public: static std::function<IActor* (const TActorId &, TTabletStorageInfo*)> DefaultGetTabletCreationFunc(ui32 type) { Y_UNUSED(type); diff --git a/ydb/core/testlib/tenant_runtime.cpp b/ydb/core/testlib/tenant_runtime.cpp index b9dd51a7b7..974cc166d0 100644 --- a/ydb/core/testlib/tenant_runtime.cpp +++ b/ydb/core/testlib/tenant_runtime.cpp @@ -822,7 +822,7 @@ void TTenantTestRuntime::Setup(bool createTenantPools) poolTypes["hdd-2"] = hddPool; poolTypes["hdd-3"] = hddPool; auto domainPtr = TDomainsInfo::TDomain::ConstructDomainWithExplicitTabletIds(domain.Name, i, domain.SchemeShardId, - i, i, TVector<ui32>{i}, + i, i, TVector<ui32>{i}, i, TVector<ui32>{i}, planResolution, TVector<ui64>{TDomainsInfo::MakeTxCoordinatorIDFixed(i, 1)}, diff --git a/ydb/core/testlib/test_client.cpp b/ydb/core/testlib/test_client.cpp index 846d412833..d4907c26f1 100644 --- a/ydb/core/testlib/test_client.cpp +++ b/ydb/core/testlib/test_client.cpp @@ -223,9 +223,9 @@ namespace Tests { } void TServer::SetupMessageBus(ui16 port, const TString &tracePath) { - if (port) { - Bus = NBus::CreateMessageQueue(NBus::TBusQueueConfig()); - if (tracePath) { + if (port) { + Bus = NBus::CreateMessageQueue(NBus::TBusQueueConfig()); + if (tracePath) { BusServer.Reset(NMsgBusProxy::CreateMsgBusTracingServer( Bus.Get(), BusServerSessionConfig, @@ -233,14 +233,14 @@ namespace Tests { Settings->PersQueueGetReadSessionsInfoWorkerFactory, port )); - } else { + } else { BusServer.Reset(NMsgBusProxy::CreateMsgBusServer( Bus.Get(), BusServerSessionConfig, Settings->PersQueueGetReadSessionsInfoWorkerFactory, port )); - } + } } } @@ -348,7 +348,7 @@ namespace Tests { planResolution = Settings->UseRealThreads ? 7 : 500; } auto domain = TDomainsInfo::TDomain::ConstructDomainWithExplicitTabletIds(Settings->DomainName, domainId, ChangeStateStorage(SchemeRoot, domainId), - domainId, domainId, TVector<ui32>{domainId}, + domainId, domainId, TVector<ui32>{domainId}, domainId, TVector<ui32>{domainId}, planResolution, TVector<ui64>{TDomainsInfo::MakeTxCoordinatorIDFixed(domainId, 1)}, @@ -649,7 +649,7 @@ namespace Tests { TActorId traceServiceId = Runtime->Register(traceService, nodeIdx, Runtime->GetAppData(nodeIdx).IOPoolId, TMailboxType::Simple, 0); Runtime->RegisterService(NMessageBusTracer::MakeMessageBusTraceServiceID(), traceServiceId, nodeIdx); } - } + } } { @@ -911,7 +911,7 @@ namespace Tests { ClientConfig.Ip = serverSetup.IpAddress; ClientConfig.Port = serverSetup.Port; - ClientConfig.BusSessionConfig.TotalTimeout = Max<int>() / 2; + ClientConfig.BusSessionConfig.TotalTimeout = Max<int>() / 2; ClientConfig.BusSessionConfig.ConnectTimeout = ConnectTimeoutMilliSeconds; ClientConfig.BusSessionConfig.NumRetries = 10; Client.reset(new NMsgBusProxy::TMsgBusClient(ClientConfig)); @@ -1322,13 +1322,13 @@ namespace Tests { NMsgBusProxy::EResponseStatus TClient::CreateTable(const TString& parent, const NKikimrSchemeOp::TTableDescription &table, TDuration timeout) { TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation()); - auto *op = request->Record.MutableTransaction()->MutableModifyScheme(); + auto *op = request->Record.MutableTransaction()->MutableModifyScheme(); op->SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpCreateTable); - op->SetWorkingDir(parent); - op->MutableCreateTable()->CopyFrom(table); + op->SetWorkingDir(parent); + op->MutableCreateTable()->CopyFrom(table); TAutoPtr<NBus::TBusMessage> reply; NBus::EMessageStatus status = SendAndWaitCompletion(request.Release(), reply, timeout); - UNIT_ASSERT_VALUES_EQUAL(status, NBus::MESSAGE_OK); + UNIT_ASSERT_VALUES_EQUAL(status, NBus::MESSAGE_OK); const NKikimrClient::TResponse &response = dynamic_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record; return (NMsgBusProxy::EResponseStatus)response.GetStatus(); } @@ -1410,8 +1410,8 @@ namespace Tests { bool parseOk = ::google::protobuf::TextFormat::ParseFromString(scheme, &table); UNIT_ASSERT(parseOk); return CreateTable(parent, table, timeout); - } - + } + NMsgBusProxy::EResponseStatus TClient::CreateKesus(const TString& parent, const TString& name) { auto* request = new NMsgBusProxy::TBusSchemeOperation(); auto* tx = request->Record.MutableTransaction()->MutableModifyScheme(); @@ -1811,25 +1811,25 @@ namespace Tests { } bool TClient::LocalQuery(const ui64 tabletId, const TString &pgmText, NKikimrMiniKQL::TResult& result) { - TAutoPtr<NMsgBusProxy::TBusTabletLocalMKQL> request = new NMsgBusProxy::TBusTabletLocalMKQL(); + TAutoPtr<NMsgBusProxy::TBusTabletLocalMKQL> request = new NMsgBusProxy::TBusTabletLocalMKQL(); request->Record.SetTabletID(ChangeStateStorage(tabletId, Domain)); request->Record.SetWithRetry(true); - auto *mkql = request->Record.MutableProgram(); - mkql->MutableProgram()->SetText(pgmText); - - TAutoPtr<NBus::TBusMessage> reply; + auto *mkql = request->Record.MutableProgram(); + mkql->MutableProgram()->SetText(pgmText); + + TAutoPtr<NBus::TBusMessage> reply; auto status = SyncCall(request, reply); UNIT_ASSERT_VALUES_EQUAL(status, NBus::MESSAGE_OK); - + const NKikimrClient::TResponse &response = dynamic_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record; UNIT_ASSERT_VALUES_EQUAL(response.GetStatus(), NMsgBusProxy::MSTATUS_OK); - - if (response.HasExecutionEngineEvaluatedResponse()) - result.CopyFrom(response.GetExecutionEngineEvaluatedResponse()); - + + if (response.HasExecutionEngineEvaluatedResponse()) + result.CopyFrom(response.GetExecutionEngineEvaluatedResponse()); + return response.GetExecutionEngineResponseStatus() == ui32(NMiniKQL::IEngineFlat::EStatus::Complete); - } - + } + bool TClient::LocalSchemeTx(const ui64 tabletId, const NTabletFlatScheme::TSchemeChanges& changes, bool dryRun, NTabletFlatScheme::TSchemeChanges& scheme, TString& err) { TAutoPtr<NMsgBusProxy::TBusTabletLocalSchemeTx> request = new NMsgBusProxy::TBusTabletLocalSchemeTx(); @@ -1859,35 +1859,35 @@ namespace Tests { } bool TClient::Compile(const TString &mkql, TString &compiled) { - TAutoPtr<NMsgBusProxy::TBusRequest> request = new NMsgBusProxy::TBusRequest(); + TAutoPtr<NMsgBusProxy::TBusRequest> request = new NMsgBusProxy::TBusRequest(); auto* mkqlTx = request->Record.MutableTransaction()->MutableMiniKQLTransaction(); mkqlTx->MutableProgram()->SetText(mkql); mkqlTx->SetFlatMKQL(true); - mkqlTx->SetMode(NKikimrTxUserProxy::TMiniKQLTransaction::COMPILE); - + mkqlTx->SetMode(NKikimrTxUserProxy::TMiniKQLTransaction::COMPILE); + TAutoPtr<NBus::TBusMessage> reply; NBus::EMessageStatus msgStatus = SyncCall(request, reply); UNIT_ASSERT_EQUAL(msgStatus, NBus::MESSAGE_OK); const NKikimrClient::TResponse &response = static_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record; - if (!response.HasMiniKQLCompileResults()) - return false; + if (!response.HasMiniKQLCompileResults()) + return false; - const auto &compileRes = response.GetMiniKQLCompileResults(); - if (compileRes.ProgramCompileErrorsSize()) { + const auto &compileRes = response.GetMiniKQLCompileResults(); + if (compileRes.ProgramCompileErrorsSize()) { NYql::TIssues issues; NYql::IssuesFromMessage(compileRes.GetProgramCompileErrors(), issues); TStringStream err; issues.PrintTo(err); Cerr << "error: " << err.Str() << Endl; - return false; - } - - compiled = compileRes.GetCompiledProgram(); - return true; - } - + return false; + } + + compiled = compileRes.GetCompiledProgram(); + return true; + } + ui32 TClient::FlatQueryRaw(const TString &query, TFlatQueryOptions& opts, NKikimrClient::TResponse& response, int retryCnt) { while (retryCnt--) { TAutoPtr<NMsgBusProxy::TBusRequest> request = new NMsgBusProxy::TBusRequest(); @@ -1897,7 +1897,7 @@ namespace Tests { mkqlTx->MutableProgram()->SetBin(query); else mkqlTx->MutableProgram()->SetText(query); - + if (opts.Params) mkqlTx->MutableParams()->SetText(opts.Params); mkqlTx->SetFlatMKQL(true); @@ -1908,7 +1908,7 @@ namespace Tests { TAutoPtr<NBus::TBusMessage> reply; NBus::EMessageStatus msgStatus = SyncCall(request, reply); UNIT_ASSERT_EQUAL(msgStatus, NBus::MESSAGE_OK); - + NMsgBusProxy::TBusResponse * ret = static_cast<NMsgBusProxy::TBusResponse *>(reply.Get()); ui32 responseStatus = ret->Record.GetStatus(); if (responseStatus == NMsgBusProxy::MSTATUS_NOTREADY || @@ -1919,11 +1919,11 @@ namespace Tests { response.Swap(&static_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record); break; } - + UNIT_ASSERT(retryCnt > 0); return response.GetStatus(); } - + bool TClient::FlatQuery(const TString &query, TFlatQueryOptions& opts, NKikimrMiniKQL::TResult &result, const NKikimrClient::TResponse& expectedResponse) { NKikimrClient::TResponse response; FlatQueryRaw(query, opts, response); @@ -1949,26 +1949,26 @@ namespace Tests { Cerr << response.GetUnresolvedKeys(i) << Endl; } } - if (response.HasMiniKQLCompileResults()) { - const auto &compileRes = response.GetMiniKQLCompileResults(); - if (compileRes.ProgramCompileErrorsSize()) { + if (response.HasMiniKQLCompileResults()) { + const auto &compileRes = response.GetMiniKQLCompileResults(); + if (compileRes.ProgramCompileErrorsSize()) { NYql::TIssues issues; NYql::IssuesFromMessage(compileRes.GetProgramCompileErrors(), issues); TStringStream err; issues.PrintTo(err); Cerr << "error: " << err.Str() << Endl; - } - if (compileRes.ParamsCompileErrorsSize()) { + } + if (compileRes.ParamsCompileErrorsSize()) { NYql::TIssues issues; NYql::IssuesFromMessage(compileRes.GetParamsCompileErrors(), issues); TStringStream err; issues.PrintTo(err); Cerr << "error: " << err.Str() << Endl; - } - } + } + } if (response.HasHadFollowerReads() && response.GetHadFollowerReads()) { Cerr << "had follower reads" << Endl; - } + } if (expectedResponse.HasStatus()) { UNIT_ASSERT_VALUES_EQUAL(response.GetStatus(), expectedResponse.GetStatus()); @@ -2003,8 +2003,8 @@ namespace Tests { bool TClient::FlatQuery(const TString& mkql, NKikimrMiniKQL::TResult& result) { TFlatQueryOptions opts; return FlatQuery(mkql, opts, result); - } - + } + TString TClient::SendTabletMonQuery(TTestActorRuntime* runtime, ui64 tabletId, TString query) { TActorId sender = runtime->AllocateEdgeActor(0); ForwardToTablet(*runtime, tabletId, sender, new NActors::NMon::TEvRemoteHttpInfo(query), 0); diff --git a/ydb/core/testlib/test_client.h b/ydb/core/testlib/test_client.h index fd8a5cc678..2064752ab4 100644 --- a/ydb/core/testlib/test_client.h +++ b/ydb/core/testlib/test_client.h @@ -44,8 +44,8 @@ namespace Tests { #endif const TDuration ITERATION_DURATION = TDuration::MilliSeconds(50); - constexpr const char* TestDomainName = "dc-1"; - const ui32 TestDomain = 1; + constexpr const char* TestDomainName = "dc-1"; + const ui32 TestDomain = 1; const ui64 DummyTablet1 = 0x840100; const ui64 DummyTablet2 = 0x840101; const ui64 Coordinator = 0x800001; diff --git a/ydb/core/tx/balance_coverage/balance_coverage_builder.h b/ydb/core/tx/balance_coverage/balance_coverage_builder.h index 555d1ae016..c14eaaadd6 100644 --- a/ydb/core/tx/balance_coverage/balance_coverage_builder.h +++ b/ydb/core/tx/balance_coverage/balance_coverage_builder.h @@ -1,37 +1,37 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include <ydb/core/protos/tx.pb.h> - -namespace NKikimr { - - class TBalanceCoverageBuilder : TNonCopyable { - public: - TBalanceCoverageBuilder(); - bool IsComplete() const; - /// returns false if result was already added - bool AddResult(const NKikimrTx::TBalanceTrackList& tracks); - - private: - struct TNode { - const ui64 Tablet; - bool HasResult; + +namespace NKikimr { + + class TBalanceCoverageBuilder : TNonCopyable { + public: + TBalanceCoverageBuilder(); + bool IsComplete() const; + /// returns false if result was already added + bool AddResult(const NKikimrTx::TBalanceTrackList& tracks); + + private: + struct TNode { + const ui64 Tablet; + bool HasResult; TVector<TAutoPtr<TNode>> Children; - - TNode(ui64 tablet) - : Tablet(tablet) - , HasResult(false) - { - } - }; - - bool AddToTree(const NKikimrTx::TBalanceTrack& track); - bool AddNode(TAutoPtr<TNode>& node, const NKikimrTx::TBalanceTrack& track, ui32 index); - bool CheckTree() const; - bool CheckNode(const TNode& node) const; - - private: - bool IsComplete0; - TAutoPtr<TNode> Root; - }; - -} + + TNode(ui64 tablet) + : Tablet(tablet) + , HasResult(false) + { + } + }; + + bool AddToTree(const NKikimrTx::TBalanceTrack& track); + bool AddNode(TAutoPtr<TNode>& node, const NKikimrTx::TBalanceTrack& track, ui32 index); + bool CheckTree() const; + bool CheckNode(const TNode& node) const; + + private: + bool IsComplete0; + TAutoPtr<TNode> Root; + }; + +} diff --git a/ydb/core/tx/balance_coverage/balance_coverage_builder_ut.cpp b/ydb/core/tx/balance_coverage/balance_coverage_builder_ut.cpp index 5eccc1f787..89a3b011ff 100644 --- a/ydb/core/tx/balance_coverage/balance_coverage_builder_ut.cpp +++ b/ydb/core/tx/balance_coverage/balance_coverage_builder_ut.cpp @@ -1,4 +1,4 @@ -#include "balance_coverage_builder.h" +#include "balance_coverage_builder.h" #include <library/cpp/testing/unittest/registar.h> namespace NKikimr { diff --git a/ydb/core/tx/coordinator/coordinator.h b/ydb/core/tx/coordinator/coordinator.h index b98d575a68..e7a76df3ce 100644 --- a/ydb/core/tx/coordinator/coordinator.h +++ b/ydb/core/tx/coordinator/coordinator.h @@ -1,115 +1,115 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include <ydb/core/tx/tx.h> #include <ydb/core/util/queue_oneone_inplace.h> -#include <util/generic/bitmap.h> -#include <util/generic/set.h> +#include <util/generic/bitmap.h> +#include <util/generic/set.h> #include <util/generic/hash.h> -#include <util/generic/map.h> +#include <util/generic/map.h> #include <util/generic/hash_set.h> - -namespace NKikimr { + +namespace NKikimr { namespace NFlatTxCoordinator { struct TMediatorStep; struct TMediatorConfirmations; struct TCoordinatorStepConfirmations; } } - + namespace NKikimr { IActor* CreateFlatTxCoordinator(const TActorId &tablet, TTabletStorageInfo *info); - -struct TEvTxCoordinator { - enum EEv { - EvCoordinatorStep = EventSpaceBegin(TKikimrEvents::ES_TX_COORDINATOR), - EvCoordinatorSync, - - EvCoordinatorStepResult = EvCoordinatorStep + 1 * 512, - EvCoordinatorSyncResult, - - EvMediatorQueueStep = EvCoordinatorStep + 2 * 512, - EvMediatorQueueRestart, - EvMediatorQueueStop, - EvMediatorQueueConfirmations, - - EvCoordinatorConfirmPlan = EvCoordinatorStep + 3 * 512, - - EvEnd - }; - + +struct TEvTxCoordinator { + enum EEv { + EvCoordinatorStep = EventSpaceBegin(TKikimrEvents::ES_TX_COORDINATOR), + EvCoordinatorSync, + + EvCoordinatorStepResult = EvCoordinatorStep + 1 * 512, + EvCoordinatorSyncResult, + + EvMediatorQueueStep = EvCoordinatorStep + 2 * 512, + EvMediatorQueueRestart, + EvMediatorQueueStop, + EvMediatorQueueConfirmations, + + EvCoordinatorConfirmPlan = EvCoordinatorStep + 3 * 512, + + EvEnd + }; + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_TX_COORDINATOR), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_TX_COORDINATOR)"); - - struct TEvCoordinatorStep : public TEventPB<TEvCoordinatorStep, NKikimrTx::TEvCoordinatorStep, EvCoordinatorStep> { - TEvCoordinatorStep() - {} - + + struct TEvCoordinatorStep : public TEventPB<TEvCoordinatorStep, NKikimrTx::TEvCoordinatorStep, EvCoordinatorStep> { + TEvCoordinatorStep() + {} + TEvCoordinatorStep(const NFlatTxCoordinator::TMediatorStep &mediatorStep, ui64 prevStep, ui64 mediatorId, ui64 coordinatorId, ui64 activeGeneration); - }; - - struct TEvCoordinatorStepResult : public TEventPB<TEvCoordinatorStep, NKikimrTx::TEvCoordinatorStepResult, EvCoordinatorStepResult> { - TEvCoordinatorStepResult() - {} - + }; + + struct TEvCoordinatorStepResult : public TEventPB<TEvCoordinatorStep, NKikimrTx::TEvCoordinatorStepResult, EvCoordinatorStepResult> { + TEvCoordinatorStepResult() + {} + TEvCoordinatorStepResult(NKikimrTx::TEvCoordinatorStepResult::EStatus status, ui64 step, ui64 completeStep, ui64 latestKnown, ui64 subjectiveTime, ui64 mediator, ui64 coordinator); - }; - - struct TEvCoordinatorSync : public TEventPB<TEvCoordinatorSync, NKikimrTx::TEvCoordinatorSync, EvCoordinatorSync> { - TEvCoordinatorSync() - {} - + }; + + struct TEvCoordinatorSync : public TEventPB<TEvCoordinatorSync, NKikimrTx::TEvCoordinatorSync, EvCoordinatorSync> { + TEvCoordinatorSync() + {} + TEvCoordinatorSync(ui64 cookie, ui64 mediator, ui64 coordinator); - }; - - struct TEvCoordinatorSyncResult : public TEventPB<TEvCoordinatorSyncResult, NKikimrTx::TEvCoordinatorSyncResult, EvCoordinatorSyncResult> { - - TEvCoordinatorSyncResult() - {} - + }; + + struct TEvCoordinatorSyncResult : public TEventPB<TEvCoordinatorSyncResult, NKikimrTx::TEvCoordinatorSyncResult, EvCoordinatorSyncResult> { + + TEvCoordinatorSyncResult() + {} + TEvCoordinatorSyncResult(NKikimrProto::EReplyStatus status, ui64 cookie); - + TEvCoordinatorSyncResult(ui64 cookie, ui64 completeStep, ui64 latestKnown, ui64 subjectiveTime, ui64 mediator, ui64 coordinator); - - }; - - // must be explicit queue? - struct TEvMediatorQueueStep : public TEventLocal<TEvMediatorQueueStep, EvMediatorQueueStep> { - const ui64 GenCookie; + + }; + + // must be explicit queue? + struct TEvMediatorQueueStep : public TEventLocal<TEvMediatorQueueStep, EvMediatorQueueStep> { + const ui64 GenCookie; TAutoPtr<NFlatTxCoordinator::TMediatorStep> Step; - + TEvMediatorQueueStep(ui64 genCookie, TAutoPtr<NFlatTxCoordinator::TMediatorStep> step); - }; - - struct TEvMediatorQueueRestart : public TEventLocal<TEvMediatorQueueRestart, EvMediatorQueueRestart> { - const ui64 MediatorId; - const ui64 StartFrom; - const ui64 GenCookie; - + }; + + struct TEvMediatorQueueRestart : public TEventLocal<TEvMediatorQueueRestart, EvMediatorQueueRestart> { + const ui64 MediatorId; + const ui64 StartFrom; + const ui64 GenCookie; + TEvMediatorQueueRestart(ui64 mediatorId, ui64 startFrom, ui64 genCookie); - }; - - struct TEvMediatorQueueStop : public TEventLocal<TEvMediatorQueueStop, EvMediatorQueueStop> { - const ui64 MediatorId; - + }; + + struct TEvMediatorQueueStop : public TEventLocal<TEvMediatorQueueStop, EvMediatorQueueStop> { + const ui64 MediatorId; + TEvMediatorQueueStop(ui64 mediatorId); - }; - - struct TEvMediatorQueueConfirmations : public TEventLocal<TEvMediatorQueueConfirmations, EvMediatorQueueConfirmations> { + }; + + struct TEvMediatorQueueConfirmations : public TEventLocal<TEvMediatorQueueConfirmations, EvMediatorQueueConfirmations> { TAutoPtr<NFlatTxCoordinator::TMediatorConfirmations> Confirmations; - + TEvMediatorQueueConfirmations(TAutoPtr<NFlatTxCoordinator::TMediatorConfirmations> &confirmations); - }; - - struct TEvCoordinatorConfirmPlan : public TEventLocal<TEvCoordinatorConfirmPlan, EvCoordinatorConfirmPlan> { + }; + + struct TEvCoordinatorConfirmPlan : public TEventLocal<TEvCoordinatorConfirmPlan, EvCoordinatorConfirmPlan> { TAutoPtr<NFlatTxCoordinator::TCoordinatorStepConfirmations> Confirmations; - + TEvCoordinatorConfirmPlan(TAutoPtr<NFlatTxCoordinator::TCoordinatorStepConfirmations> &confirmations); - }; - -}; - -} + }; + +}; + +} template<> inline void Out<NKikimrTx::TEvCoordinatorStepResult::EStatus>(IOutputStream& o, NKikimrTx::TEvCoordinatorStepResult::EStatus x) { diff --git a/ydb/core/tx/coordinator/coordinator__check.cpp b/ydb/core/tx/coordinator/coordinator__check.cpp index ced25533e1..345ce8d1dd 100644 --- a/ydb/core/tx/coordinator/coordinator__check.cpp +++ b/ydb/core/tx/coordinator/coordinator__check.cpp @@ -3,7 +3,7 @@ namespace NKikimr { namespace NFlatTxCoordinator { -ITransaction* TTxCoordinator::CreateTxConsistencyCheck() { +ITransaction* TTxCoordinator::CreateTxConsistencyCheck() { return new TTxConsistencyCheck(this); } diff --git a/ydb/core/tx/coordinator/coordinator__init.cpp b/ydb/core/tx/coordinator/coordinator__init.cpp index 84ce53c913..beb9975b42 100644 --- a/ydb/core/tx/coordinator/coordinator__init.cpp +++ b/ydb/core/tx/coordinator/coordinator__init.cpp @@ -135,7 +135,7 @@ struct TTxCoordinator::TTxInit : public TTransactionBase<TTxCoordinator> { } }; -ITransaction* TTxCoordinator::CreateTxInit() { +ITransaction* TTxCoordinator::CreateTxInit() { return new TTxCoordinator::TTxInit(this); } diff --git a/ydb/core/tx/coordinator/coordinator__mediators_confirmations.cpp b/ydb/core/tx/coordinator/coordinator__mediators_confirmations.cpp index daeb4e5cca..28a644503d 100644 --- a/ydb/core/tx/coordinator/coordinator__mediators_confirmations.cpp +++ b/ydb/core/tx/coordinator/coordinator__mediators_confirmations.cpp @@ -1,30 +1,30 @@ #include "coordinator_impl.h" #include <ydb/core/tablet_flat/flat_cxx_database.h> - + #include <util/generic/hash_set.h> -namespace NKikimr { +namespace NKikimr { namespace NFlatTxCoordinator { - + struct TTxCoordinator::TTxMediatorConfirmations : public TTransactionBase<TTxCoordinator> { - TAutoPtr<TMediatorConfirmations> Confirmations; - i64 CompleteTransactions; - - TTxMediatorConfirmations(TAutoPtr<TMediatorConfirmations> &confirmations, TSelf *coordinator) - : TBase(coordinator) - , Confirmations(confirmations) - , CompleteTransactions(0) - {} - + TAutoPtr<TMediatorConfirmations> Confirmations; + i64 CompleteTransactions; + + TTxMediatorConfirmations(TAutoPtr<TMediatorConfirmations> &confirmations, TSelf *coordinator) + : TBase(coordinator) + , Confirmations(confirmations) + , CompleteTransactions(0) + {} + TTxType GetTxType() const override { return TXTYPE_MEDIATOR_CONFIRMATIONS; } bool Execute(TTransactionContext &txc, const TActorContext &ctx) override { const TTabletId mediatorId = Confirmations->MediatorId; Y_UNUSED(ctx); - CompleteTransactions = 0; + CompleteTransactions = 0; NIceDb::TNiceDb db(txc.DB); - + ui64 internalTxGen = txc.Generation; ui64 internalTxStep = txc.Step; @@ -41,7 +41,7 @@ struct TTxCoordinator::TTxMediatorConfirmations : public TTransactionBase<TTxCoo } continue; } - + THashSet<TTabletId>& mediatorAffectedSet = txit->second.UnconfirmedAffectedSet[mediatorId]; for (const TTabletId affected : txidsx.second) { THashSet<TTabletId>::size_type result = mediatorAffectedSet.erase(affected); @@ -51,7 +51,7 @@ struct TTxCoordinator::TTxMediatorConfirmations : public TTransactionBase<TTxCoo << " gen:step " << internalTxGen << ":" << internalTxStep << " Confirmed transaction " << txid << " for mediator " << mediatorId << " tablet " << affected << " result=" << result); } - + if (mediatorAffectedSet.empty()) { FLOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR, "at tablet# " << Self->TabletID() @@ -59,7 +59,7 @@ struct TTxCoordinator::TTxMediatorConfirmations : public TTransactionBase<TTxCoo << " Mediator " << mediatorId << " confirmed finish of transaction " << txid); txit->second.UnconfirmedAffectedSet.erase(mediatorId); } - + if (txit->second.UnconfirmedAffectedSet.empty()) { // transaction finished FLOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR, "at tablet# " << Self->TabletID() @@ -68,23 +68,23 @@ struct TTxCoordinator::TTxMediatorConfirmations : public TTransactionBase<TTxCoo db.Table<Schema::Transaction>().Key(txid).Delete(); Self->Transactions.erase(txit); ++CompleteTransactions; - } + } } - + return true; - } - - void Complete(const TActorContext &ctx) override { - *Self->MonCounters.TxInFly -= CompleteTransactions; - Self->MonCounters.CurrentTxInFly -= CompleteTransactions; - + } + + void Complete(const TActorContext &ctx) override { + *Self->MonCounters.TxInFly -= CompleteTransactions; + Self->MonCounters.CurrentTxInFly -= CompleteTransactions; + Y_UNUSED(ctx); - } -}; - -ITransaction* TTxCoordinator::CreateTxMediatorConfirmations(TAutoPtr<TMediatorConfirmations> &confirmations) { - return new TTxMediatorConfirmations(confirmations, this); -} - -} -} + } +}; + +ITransaction* TTxCoordinator::CreateTxMediatorConfirmations(TAutoPtr<TMediatorConfirmations> &confirmations) { + return new TTxMediatorConfirmations(confirmations, this); +} + +} +} diff --git a/ydb/core/tx/coordinator/coordinator__monitoring.cpp b/ydb/core/tx/coordinator/coordinator__monitoring.cpp index 41b87af5ca..550c8ef281 100644 --- a/ydb/core/tx/coordinator/coordinator__monitoring.cpp +++ b/ydb/core/tx/coordinator/coordinator__monitoring.cpp @@ -33,7 +33,7 @@ struct TTxCoordinator::TTxMonitoring : public TTxCoordinator::TTxConsistencyChec } }; -ITransaction* TTxCoordinator::CreateTxMonitoring(NMon::TEvRemoteHttpInfo::TPtr& ev) { +ITransaction* TTxCoordinator::CreateTxMonitoring(NMon::TEvRemoteHttpInfo::TPtr& ev) { return new TTxMonitoring(this, ev->Sender); } diff --git a/ydb/core/tx/coordinator/coordinator__plan_step.cpp b/ydb/core/tx/coordinator/coordinator__plan_step.cpp index 000df7145a..c1fac2ffa5 100644 --- a/ydb/core/tx/coordinator/coordinator__plan_step.cpp +++ b/ydb/core/tx/coordinator/coordinator__plan_step.cpp @@ -1,10 +1,10 @@ #include "coordinator_impl.h" -#include <util/generic/hash_set.h> - -namespace NKikimr { +#include <util/generic/hash_set.h> + +namespace NKikimr { namespace NFlatTxCoordinator { - + struct TInFlyAccountant { NMonitoring::TDynamicCounters::TCounterPtr Counter; TInFlyAccountant(NMonitoring::TDynamicCounters::TCounterPtr counter) @@ -18,46 +18,46 @@ struct TInFlyAccountant { }; struct TTxCoordinator::TTxPlanStep : public TTransactionBase<TTxCoordinator> { - const ui64 PlanOnStep; - const bool Rapid; + const ui64 PlanOnStep; + const bool Rapid; TVector<TQueueType::TSlot> Slots; - + TMap<ui64, std::pair<ui64, bool *>> StepsToConfirm; - TAutoPtr<TCoordinatorStepConfirmations> ProxyPlanConfirmations; - - TInstant ExecStartMoment; - ui64 PlannedCounter; - ui64 DeclinedCounter; + TAutoPtr<TCoordinatorStepConfirmations> ProxyPlanConfirmations; + + TInstant ExecStartMoment; + ui64 PlannedCounter; + ui64 DeclinedCounter; TInFlyAccountant InFlyAccountant; - + TTxPlanStep(ui64 toPlan, TVector<TQueueType::TSlot> &slots, TSelf *coordinator, bool rapid) - : TBase(coordinator) - , PlanOnStep(toPlan) - , Rapid(rapid) - , PlannedCounter(0) - , DeclinedCounter(0) + : TBase(coordinator) + , PlanOnStep(toPlan) + , Rapid(rapid) + , PlannedCounter(0) + , DeclinedCounter(0) , InFlyAccountant(Self->MonCounters.StepsInFly) - { - Slots.swap(slots); - } - + { + Slots.swap(slots); + } + void Plan(TTransactionContext &txc, const TActorContext &ctx) { Y_UNUSED(txc); NIceDb::TNiceDb db(txc.DB); - ExecStartMoment = ctx.Now(); + ExecStartMoment = ctx.Now(); const bool lowDiskSpace = Self->Executor()->GetStats().IsAnyChannelYellowStop; - + THashSet<TTxId> newTransactions; TVector<TAutoPtr<TMediatorStep>> mediatorSteps; THashMap<TTabletId, TVector<TTabletId>> byMediatorAffected; - + // first fill every mediator with something (every mediator must receive step) const ui32 mediatorsSize = Self->Config.Mediators->List().size(); mediatorSteps.reserve(mediatorsSize); for (TTabletId mediatorId : Self->Config.Mediators->List()) { mediatorSteps.push_back(new TMediatorStep(mediatorId, PlanOnStep)); } - + // create mediator steps ProxyPlanConfirmations.Reset(new TCoordinatorStepConfirmations(PlanOnStep)); for (const auto &slot : Slots) { @@ -67,15 +67,15 @@ struct TTxCoordinator::TTxPlanStep : public TTransactionBase<TTxCoordinator> { for (auto &x : byMediatorAffected) { x.second.clear(); } - + const TTxId txId = proposal->TxId; Y_VERIFY(txId); - + Self->MonCounters.StepConsideredTx->Inc(); auto durationMs = (ExecStartMoment - proposal->AcceptMoment).MilliSeconds(); Self->MonCounters.LegacyTxFromReceiveToPlan.Add(durationMs); Self->MonCounters.TxFromReceiveToPlan->Collect(durationMs); - + if (proposal->MaxStep < PlanOnStep) { Self->MonCounters.StepOutdatedTx->Inc(); ProxyPlanConfirmations->Queue->Push(new TCoordinatorStepConfirmations::TEntry { @@ -86,7 +86,7 @@ struct TTxCoordinator::TTxPlanStep : public TTransactionBase<TTxCoordinator> { ++DeclinedCounter; continue; } - + // check is transactions already processed? if (newTransactions.insert(txId).second == false) { Self->MonCounters.StepPlannedDeclinedTx->Inc(); @@ -98,7 +98,7 @@ struct TTxCoordinator::TTxPlanStep : public TTransactionBase<TTxCoordinator> { ++DeclinedCounter; continue; } - + { auto it = Self->Transactions.find(txId); if (it != Self->Transactions.end()) { @@ -112,24 +112,24 @@ struct TTxCoordinator::TTxPlanStep : public TTransactionBase<TTxCoordinator> { continue; } } - + if (lowDiskSpace && !proposal->IgnoreLowDiskSpace) { - Self->MonCounters.StepDeclinedNoSpaceTx->Inc(); - ProxyPlanConfirmations->Queue->Push(new TCoordinatorStepConfirmations::TEntry{ - txId, - proposal->Proxy, - TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusDeclinedNoSpace, - 0 - }); - ++DeclinedCounter; - continue; - } - + Self->MonCounters.StepDeclinedNoSpaceTx->Inc(); + ProxyPlanConfirmations->Queue->Push(new TCoordinatorStepConfirmations::TEntry{ + txId, + proposal->Proxy, + TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusDeclinedNoSpace, + 0 + }); + ++DeclinedCounter; + continue; + } + // write transaction in body // todo: subtree insertion, moderator/body store { TTransaction& transaction = Self->Transactions[txId]; - + transaction.PlanOnStep = PlanOnStep; Y_VERIFY(!proposal->AffectedSet.empty()); for (const auto &txprop : proposal->AffectedSet) { @@ -138,27 +138,27 @@ struct TTxCoordinator::TTxPlanStep : public TTransactionBase<TTxCoordinator> { transaction.AffectedSet.insert(affectedTablet); transaction.UnconfirmedAffectedSet[mediatorId].insert(affectedTablet); - + byMediatorAffected[mediatorId].push_back(affectedTablet); } - + TVector<TTabletId> affectedSet(transaction.AffectedSet.begin(), transaction.AffectedSet.end()); - + db.Table<Schema::Transaction>().Key(txId).Update( NIceDb::TUpdate<Schema::Transaction::Plan>(PlanOnStep), NIceDb::TUpdate<Schema::Transaction::AffectedSet>(affectedSet)); FLOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR, "Transaction " << txId << " has been planned"); // todo: moderator, proxy } - + for (ui32 idx = 0; idx < mediatorsSize; ++idx) { TTabletId mediatorId = mediatorSteps[idx]->MediatorId; TVector<TTabletId> &affected = byMediatorAffected[mediatorId]; if (!affected.empty()) { - mediatorSteps[idx]->Transactions.push_back(TMediatorStep::TTx(txId, &affected.front(), affected.size(), 0)); + mediatorSteps[idx]->Transactions.push_back(TMediatorStep::TTx(txId, &affected.front(), affected.size(), 0)); } } - + newTransactions.insert(txId); ++PlannedCounter; @@ -170,10 +170,10 @@ struct TTxCoordinator::TTxPlanStep : public TTransactionBase<TTxCoordinator> { PlanOnStep } ); } } - + for (const TAutoPtr<TMediatorStep> &mp : mediatorSteps) { const ui64 mediatorId = mp->MediatorId; - + // write mediator entry for (const auto &tx : mp->Transactions) { for (TTabletId tablet : tx.PushToAffected) { @@ -181,7 +181,7 @@ struct TTxCoordinator::TTxPlanStep : public TTransactionBase<TTxCoordinator> { FLOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR, "Planned transaction " << tx.TxId << " for mediator " << mediatorId << " tablet " << tablet); } } - + TMediator& mediator = Self->Mediator(mediatorId, ctx); if (mediator.PushUpdates) { StepsToConfirm[mediatorId] = std::pair<ui64, bool *>(mediator.GenCookie, &mp->Confirmed); @@ -191,51 +191,51 @@ struct TTxCoordinator::TTxPlanStep : public TTransactionBase<TTxCoordinator> { } } db.Table<Schema::State>().Key(Schema::State::KeyLastPlanned).Update(NIceDb::TUpdate<Schema::State::StateValue>(PlanOnStep)); - } - + } + TTxType GetTxType() const override { return TXTYPE_STEP; } bool Execute(TTransactionContext &txc, const TActorContext &ctx) override { PlannedCounter = 0; DeclinedCounter = 0; - + Plan(txc, ctx); - + if (Rapid) Self->VolatileState.Queue.RapidFreeze = false; - + *Self->MonCounters.TxPlanned += PlannedCounter; *Self->MonCounters.TxInFly += PlannedCounter; Self->MonCounters.CurrentTxInFly += PlannedCounter; *Self->MonCounters.TxDeclined += DeclinedCounter; - + return true; - } - - void Complete(const TActorContext &ctx) override { + } + + void Complete(const TActorContext &ctx) override { auto durationMs = (ctx.Now() - ExecStartMoment).MilliSeconds(); Self->MonCounters.LegacyTxPlanLatency.Add(durationMs); Self->MonCounters.TxPlanLatency->Collect(durationMs); - - for (auto &cx : StepsToConfirm) { - const ui64 mediatorId = cx.first; - TMediator &mediator = Self->Mediator(mediatorId, ctx); - if (mediator.GenCookie == cx.second.first) { - *cx.second.second = true; - Self->SendMediatorStep(mediator, ctx); - } - } - - ctx.Send(ctx.SelfID, new TEvTxCoordinator::TEvCoordinatorConfirmPlan(ProxyPlanConfirmations)); + + for (auto &cx : StepsToConfirm) { + const ui64 mediatorId = cx.first; + TMediator &mediator = Self->Mediator(mediatorId, ctx); + if (mediator.GenCookie == cx.second.first) { + *cx.second.second = true; + Self->SendMediatorStep(mediator, ctx); + } + } + + ctx.Send(ctx.SelfID, new TEvTxCoordinator::TEvCoordinatorConfirmPlan(ProxyPlanConfirmations)); // uncomment this to enable consistency self-check //Self->Execute(Self->CreateTxConsistencyCheck(), ctx); - } -}; - -ITransaction* TTxCoordinator::CreateTxPlanStep(ui64 toStep, TVector<TQueueType::TSlot> &slots, bool rapid) { - return new TTxPlanStep(toStep, slots, this, rapid); -} - -} -} + } +}; + +ITransaction* TTxCoordinator::CreateTxPlanStep(ui64 toStep, TVector<TQueueType::TSlot> &slots, bool rapid) { + return new TTxPlanStep(toStep, slots, this, rapid); +} + +} +} diff --git a/ydb/core/tx/coordinator/coordinator__restart_mediator.cpp b/ydb/core/tx/coordinator/coordinator__restart_mediator.cpp index 3ac0c4a611..673115d22b 100644 --- a/ydb/core/tx/coordinator/coordinator__restart_mediator.cpp +++ b/ydb/core/tx/coordinator/coordinator__restart_mediator.cpp @@ -1,33 +1,33 @@ #include "coordinator_impl.h" - -namespace NKikimr { + +namespace NKikimr { namespace NFlatTxCoordinator { - + struct TTxCoordinator::TTxRestartMediatorQueue : public TTransactionBase<TTxCoordinator> { const TTabletId MediatorId; - const ui64 GenCookie; - + const ui64 GenCookie; + TVector<bool *> StepsToConfirm; - - TTxRestartMediatorQueue(ui64 mediatorId, ui64 genCookie, TSelf *coordinator) - : TBase(coordinator) - , MediatorId(mediatorId) - , GenCookie(genCookie) - {} - + + TTxRestartMediatorQueue(ui64 mediatorId, ui64 genCookie, TSelf *coordinator) + : TBase(coordinator) + , MediatorId(mediatorId) + , GenCookie(genCookie) + {} + TTxType GetTxType() const override { return TXTYPE_RESTART_MEDIATOR; } bool Execute(TTransactionContext &txc, const TActorContext &ctx) override { - TMediator &mediator = Self->Mediator(MediatorId, ctx); - if (mediator.GenCookie != GenCookie) - return true; - + TMediator &mediator = Self->Mediator(MediatorId, ctx); + if (mediator.GenCookie != GenCookie) + return true; + THashMap<TTxId,TVector<TTabletId>> pushToAffectedBuffer; TVector<TAutoPtr<TMediatorStep>> mediatorSteps; - + if (!Self->RestoreMediatorInfo(MediatorId, mediatorSteps, txc, pushToAffectedBuffer)) return false; - + for (const auto& it : pushToAffectedBuffer) { TTransaction& transaction = Self->Transactions[it.first]; THashSet<TTabletId>& unconfirmedAffectedSet = transaction.UnconfirmedAffectedSet[MediatorId]; @@ -39,60 +39,60 @@ struct TTxCoordinator::TTxRestartMediatorQueue : public TTransactionBase<TTxCoor it.first, affectedTabletId); } } - + for (const auto &mp : mediatorSteps) { StepsToConfirm.push_back(&mp->Confirmed); mediator.Queue->Push(mp.Release()); } - + mediator.PushUpdates = true; return true; - } - - void Complete(const TActorContext &ctx) override { - TMediator &mediator = Self->Mediator(MediatorId, ctx); - if (mediator.GenCookie != GenCookie) - return; - - for (bool *x : StepsToConfirm) - *x = true; - - Self->SendMediatorStep(mediator, ctx); - } -}; - -ITransaction* TTxCoordinator::CreateTxRestartMediatorQueue(TTabletId mediatorId, ui64 genCookie) { - return new TTxRestartMediatorQueue(mediatorId, genCookie, this); -} - + } + + void Complete(const TActorContext &ctx) override { + TMediator &mediator = Self->Mediator(MediatorId, ctx); + if (mediator.GenCookie != GenCookie) + return; + + for (bool *x : StepsToConfirm) + *x = true; + + Self->SendMediatorStep(mediator, ctx); + } +}; + +ITransaction* TTxCoordinator::CreateTxRestartMediatorQueue(TTabletId mediatorId, ui64 genCookie) { + return new TTxRestartMediatorQueue(mediatorId, genCookie, this); +} + bool TTxCoordinator::RestoreMediatorInfo(TTabletId mediatorId, TVector<TAutoPtr<TMediatorStep>> &planned, TTransactionContext &txc, /*TKeyBuilder &kb, */THashMap<TTxId,TVector<TTabletId>> &pushToAffected) const { NIceDb::TNiceDb db(txc.DB); - pushToAffected.clear(); - planned.clear(); - + pushToAffected.clear(); + planned.clear(); + auto rowset = db.Table<Schema::AffectedSet>().Range(mediatorId).Select(); if (!rowset.IsReady()) return false; - + // Later we will need this to be sorted by stepId TMap<TStepId, TAutoPtr<TMediatorStep>> mediatorSteps; - + while (!rowset.EndOfSet()) { const TTxId txId = rowset.GetValue<Schema::AffectedSet::TransactionID>(); auto itTransaction = Transactions.find(txId); Y_VERIFY(itTransaction != Transactions.end()); - + TStepId step = itTransaction->second.PlanOnStep; auto itStep = mediatorSteps.find(step); if (itStep == mediatorSteps.end()) { itStep = mediatorSteps.insert(std::make_pair(step, new TMediatorStep(mediatorId, step))).first; } TAutoPtr<TMediatorStep>& mediatorStep = itStep->second; - - if (mediatorStep->Transactions.empty() || mediatorStep->Transactions.back().TxId != txId) - mediatorStep->Transactions.push_back(TMediatorStep::TTx(txId)); + + if (mediatorStep->Transactions.empty() || mediatorStep->Transactions.back().TxId != txId) + mediatorStep->Transactions.push_back(TMediatorStep::TTx(txId)); TMediatorStep::TTx &tx = mediatorStep->Transactions.back(); - + TTabletId tablet = rowset.GetValue<Schema::AffectedSet::DataShardID>(); pushToAffected[txId].push_back(tablet); tx.PushToAffected.push_back(tablet); @@ -100,12 +100,12 @@ bool TTxCoordinator::RestoreMediatorInfo(TTabletId mediatorId, TVector<TAutoPtr< if (!rowset.Next()) return false; } - - for (auto& pr : mediatorSteps) + + for (auto& pr : mediatorSteps) planned.push_back(pr.second); - + return true; -} - -} -} +} + +} +} diff --git a/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp b/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp index df8a1a9949..26a916bdff 100644 --- a/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp +++ b/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp @@ -2,26 +2,26 @@ #include <ydb/core/base/appdata.h> #include <ydb/core/tablet/tablet_exception.h> - + #include <util/stream/file.h> -namespace NKikimr { +namespace NKikimr { namespace NFlatTxCoordinator { - + struct TTxCoordinator::TTxRestoreTransactions : public TTransactionBase<TTxCoordinator> { TTxRestoreTransactions(TSelf *coordinator) - : TBase(coordinator) - {} - + : TBase(coordinator) + {} + bool Restore(TTransactions &transactions, TTransactionContext &txc, const TActorContext &ctx) { Y_UNUSED(ctx); NIceDb::TNiceDb db(txc.DB); - { + { auto rowset = db.Table<Schema::Transaction>().Range().Select(); if (!rowset.IsReady()) return false; - + while (!rowset.EndOfSet()) { TTxId txId = rowset.GetValue<Schema::Transaction::ID>(); TTransaction& transaction = transactions[txId]; @@ -34,30 +34,30 @@ struct TTxCoordinator::TTxRestoreTransactions : public TTransactionBase<TTxCoord return false; // data not ready } } - + { int errors = 0; auto rowset = db.Table<Schema::AffectedSet>().Range().Select(); if (!rowset.IsReady()) return false; - + while (!rowset.EndOfSet()) { - const TTxId txId = rowset.GetValue<Schema::AffectedSet::TransactionID>(); + const TTxId txId = rowset.GetValue<Schema::AffectedSet::TransactionID>(); const TTabletId medId = rowset.GetValue<Schema::AffectedSet::MediatorID>(); - const ui64 affectedShardId = rowset.GetValue<Schema::AffectedSet::DataShardID>(); - + const ui64 affectedShardId = rowset.GetValue<Schema::AffectedSet::DataShardID>(); + auto itTransaction = transactions.find(txId); if (itTransaction != transactions.end()) { - itTransaction->second.UnconfirmedAffectedSet[medId].insert(affectedShardId); + itTransaction->second.UnconfirmedAffectedSet[medId].insert(affectedShardId); } else { - LOG_ERROR_S(ctx, NKikimrServices::TX_COORDINATOR, "Transaction not found: MedId = " << medId << " TxId = " << txId << " DataShardId = " << affectedShardId); + LOG_ERROR_S(ctx, NKikimrServices::TX_COORDINATOR, "Transaction not found: MedId = " << medId << " TxId = " << txId << " DataShardId = " << affectedShardId); ++errors; } - + if (!rowset.Next()) return false; } - + if (errors > 0) { // DB is corrupt. Make a dump and stop const NScheme::TTypeRegistry& tr = *AppData(ctx)->TypeRegistry; @@ -70,10 +70,10 @@ struct TTxCoordinator::TTxRestoreTransactions : public TTransactionBase<TTxCoord Y_FAIL("Transaction(s) not found!"); } } - + return true; - } - + } + TTxType GetTxType() const override { return TXTYPE_INIT; } bool Execute(TTransactionContext &txc, const TActorContext &ctx) override { @@ -86,25 +86,25 @@ struct TTxCoordinator::TTxRestoreTransactions : public TTransactionBase<TTxCoord *Self->MonCounters.TxInFly += txCounter; Self->MonCounters.CurrentTxInFly = txCounter; return true; - } - - void Complete(const TActorContext &ctx) override { - // start mediator queues + } + + void Complete(const TActorContext &ctx) override { + // start mediator queues for (ui64 mediatorId: Self->Config.Mediators->List()) { - TMediator &mediator = Self->Mediator(mediatorId, ctx); + TMediator &mediator = Self->Mediator(mediatorId, ctx); Y_UNUSED(mediator); - } - - // start plan process. - Self->Become(&TSelf::StateWork); + } + + // start plan process. + Self->Become(&TSelf::StateWork); Self->SignalTabletActive(ctx); - Self->SchedulePlanTick(ctx); - } -}; - -ITransaction* TTxCoordinator::CreateTxRestoreTransactions() { + Self->SchedulePlanTick(ctx); + } +}; + +ITransaction* TTxCoordinator::CreateTxRestoreTransactions() { return new TTxRestoreTransactions(this); -} - -} -} +} + +} +} diff --git a/ydb/core/tx/coordinator/coordinator__schema.cpp b/ydb/core/tx/coordinator/coordinator__schema.cpp index 7eca419af6..1fb202a258 100644 --- a/ydb/core/tx/coordinator/coordinator__schema.cpp +++ b/ydb/core/tx/coordinator/coordinator__schema.cpp @@ -20,7 +20,7 @@ struct TTxCoordinator::TTxSchema : public TTransactionBase<TTxCoordinator> { } }; -ITransaction* TTxCoordinator::CreateTxSchema() { +ITransaction* TTxCoordinator::CreateTxSchema() { return new TTxSchema(this); } diff --git a/ydb/core/tx/coordinator/coordinator__schema_upgrade.cpp b/ydb/core/tx/coordinator/coordinator__schema_upgrade.cpp index 15180f3155..931a7c993e 100644 --- a/ydb/core/tx/coordinator/coordinator__schema_upgrade.cpp +++ b/ydb/core/tx/coordinator/coordinator__schema_upgrade.cpp @@ -55,7 +55,7 @@ struct TTxCoordinator::TTxUpgrade : public TTransactionBase<TTxCoordinator> { } }; -ITransaction* TTxCoordinator::CreateTxUpgrade() { +ITransaction* TTxCoordinator::CreateTxUpgrade() { return new TTxUpgrade(this); } diff --git a/ydb/core/tx/coordinator/coordinator_impl.cpp b/ydb/core/tx/coordinator/coordinator_impl.cpp index c18c062031..b4eeb184e2 100644 --- a/ydb/core/tx/coordinator/coordinator_impl.cpp +++ b/ydb/core/tx/coordinator/coordinator_impl.cpp @@ -7,65 +7,65 @@ #include <ydb/core/base/counters.h> #include <ydb/core/protos/services.pb.h> #include <ydb/core/tx/tx.h> - -namespace NKikimr { + +namespace NKikimr { namespace NFlatTxCoordinator { - + static constexpr TDuration MaxEmptyPlanDelay = TDuration::Seconds(1); static void SendTransactionStatus(const TActorId &proxy, TEvTxProxy::TEvProposeTransactionStatus::EStatus status, ui64 txid, ui64 stepId, const TActorContext &ctx, ui64 tabletId) { LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR, "tablet# " << tabletId << " txid# " << txid << " step# " << stepId << " Status# " << status << " SEND to# " << proxy.ToString() << " Proxy marker# C1"); - ctx.Send(proxy, new TEvTxProxy::TEvProposeTransactionStatus(status, txid, stepId)); -} - -static TAutoPtr<TTransactionProposal> MakeTransactionProposal(TEvTxProxy::TEvProposeTransaction::TPtr &ev, NMonitoring::TDynamicCounters::TCounterPtr &counter) { + ctx.Send(proxy, new TEvTxProxy::TEvProposeTransactionStatus(status, txid, stepId)); +} + +static TAutoPtr<TTransactionProposal> MakeTransactionProposal(TEvTxProxy::TEvProposeTransaction::TPtr &ev, NMonitoring::TDynamicCounters::TCounterPtr &counter) { const TActorId &sender = ev->Sender; - const NKikimrTx::TEvProposeTransaction &record = ev->Get()->Record; - - const NKikimrTx::TProxyTransaction &txrec = record.GetTransaction(); - const ui64 txId = txrec.HasTxId() ? txrec.GetTxId() : 0; - const ui64 minStep = txrec.HasMinStep() ? txrec.GetMinStep() : 0; - const ui64 maxStep = txrec.HasMaxStep() ? txrec.GetMaxStep() : Max<ui64>(); + const NKikimrTx::TEvProposeTransaction &record = ev->Get()->Record; + + const NKikimrTx::TProxyTransaction &txrec = record.GetTransaction(); + const ui64 txId = txrec.HasTxId() ? txrec.GetTxId() : 0; + const ui64 minStep = txrec.HasMinStep() ? txrec.GetMinStep() : 0; + const ui64 maxStep = txrec.HasMaxStep() ? txrec.GetMaxStep() : Max<ui64>(); const bool ignoreLowDiskSpace = txrec.GetIgnoreLowDiskSpace(); - + TAutoPtr<TTransactionProposal> proposal(new TTransactionProposal(sender, txId, minStep, maxStep, ignoreLowDiskSpace)); - proposal->AffectedSet.resize(txrec.AffectedSetSize()); - for (ui32 i = 0, e = txrec.AffectedSetSize(); i != e; ++i) { - const auto &x = txrec.GetAffectedSet(i); - auto &s = proposal->AffectedSet[i]; - s.TabletId = x.GetTabletId(); - + proposal->AffectedSet.resize(txrec.AffectedSetSize()); + for (ui32 i = 0, e = txrec.AffectedSetSize(); i != e; ++i) { + const auto &x = txrec.GetAffectedSet(i); + auto &s = proposal->AffectedSet[i]; + s.TabletId = x.GetTabletId(); + Y_ASSERT(x.GetFlags() > 0 && x.GetFlags() <= 3); - s.AffectedFlags = x.GetFlags(); - } - - counter->Inc(); - return proposal; -} - + s.AffectedFlags = x.GetFlags(); + } + + counter->Inc(); + return proposal; +} + const ui32 TTxCoordinator::Schema::CurrentVersion = 1; TTxCoordinator::TTxCoordinator(TTabletStorageInfo *info, const TActorId &tablet) - : TActor(&TThis::StateInit) + : TActor(&TThis::StateInit) , TTabletExecutedFlat(info, tablet, new NMiniKQL::TMiniKQLFactory) #ifdef COORDINATOR_LOG_TO_FILE , DebugName(Sprintf("/tmp/coordinator_db_log_%" PRIu64 ".%" PRIi32 ".%" PRIu64 ".gz", TabletID(), getpid(), tablet.LocalId())) , DebugLogFile(DebugName) , DebugLog(&DebugLogFile, ZLib::GZip, 1) #endif -{ +{ #ifdef COORDINATOR_LOG_TO_FILE // HACK Cerr << "Coordinator LOG will be dumped to " << DebugName << Endl; #endif - Config.PlanAhead = 50; + Config.PlanAhead = 50; Config.Resolution = 1250; Config.RapidSlotFlushSize = 1000; // todo: something meaningful - - MonCounters.CurrentTxInFly = 0; + + MonCounters.CurrentTxInFly = 0; TabletCountersPtr.Reset(new TProtobufTabletCounters< ESimpleCounters_descriptor, ECumulativeCounters_descriptor, @@ -73,12 +73,12 @@ TTxCoordinator::TTxCoordinator(TTabletStorageInfo *info, const TActorId &tablet) ETxTypes_descriptor >()); TabletCounters = TabletCountersPtr.Get(); -} - -void TTxCoordinator::PlanTx(TAutoPtr<TTransactionProposal> &proposal, const TActorContext &ctx) { - proposal->AcceptMoment = ctx.Now(); +} + +void TTxCoordinator::PlanTx(TAutoPtr<TTransactionProposal> &proposal, const TActorContext &ctx) { + proposal->AcceptMoment = ctx.Now(); MonCounters.PlanTxCalls->Inc(); - + if (proposal->MaxStep <= VolatileState.LastPlanned) { MonCounters.PlanTxOutdated->Inc(); return SendTransactionStatus(proposal->Proxy @@ -92,122 +92,122 @@ void TTxCoordinator::PlanTx(TAutoPtr<TTransactionProposal> &proposal, const TAct proposal->TxId, 0, ctx, TabletID()); } - bool forRapidExecution = (proposal->MinStep <= VolatileState.LastPlanned); - ui64 planStep = 0; - - // cycle for flow control - for (ui64 cstep = (proposal->MinStep + Config.Resolution - 1) / Config.Resolution * Config.Resolution; /*no-op*/;cstep += Config.Resolution) { + bool forRapidExecution = (proposal->MinStep <= VolatileState.LastPlanned); + ui64 planStep = 0; + + // cycle for flow control + for (ui64 cstep = (proposal->MinStep + Config.Resolution - 1) / Config.Resolution * Config.Resolution; /*no-op*/;cstep += Config.Resolution) { if (cstep >= proposal->MaxStep) { MonCounters.PlanTxOutdated->Inc(); return SendTransactionStatus(proposal->Proxy, TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusOutdated, proposal->TxId, 0, ctx, TabletID()); } - - if (forRapidExecution) { - planStep = VolatileState.LastPlanned + 1; - if ((planStep % Config.Resolution) == 0) // if point on border - do not use rapid slot - forRapidExecution = false; - } else { - planStep = cstep; - } - - break; - } - + + if (forRapidExecution) { + planStep = VolatileState.LastPlanned + 1; + if ((planStep % Config.Resolution) == 0) // if point on border - do not use rapid slot + forRapidExecution = false; + } else { + planStep = cstep; + } + + break; + } + MonCounters.PlanTxAccepted->Inc(); SendTransactionStatus(proposal->Proxy, TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusAccepted, proposal->TxId, planStep, ctx, TabletID()); - if (forRapidExecution) { + if (forRapidExecution) { TQueueType::TSlot &rapidSlot = VolatileState.Queue.RapidSlot; - rapidSlot.Queue->Push(proposal.Release()); - ++rapidSlot.QueueSize; - - if (rapidSlot.QueueSize >= Config.RapidSlotFlushSize && !VolatileState.Queue.RapidFreeze) { + rapidSlot.Queue->Push(proposal.Release()); + ++rapidSlot.QueueSize; + + if (rapidSlot.QueueSize >= Config.RapidSlotFlushSize && !VolatileState.Queue.RapidFreeze) { TVector<TQueueType::TSlot> slots; - slots.push_back(rapidSlot); + slots.push_back(rapidSlot); rapidSlot = TQueueType::TSlot(); - VolatileState.LastPlanned = planStep; - VolatileState.Queue.RapidFreeze = true; - + VolatileState.LastPlanned = planStep; + VolatileState.Queue.RapidFreeze = true; + Execute(CreateTxPlanStep(planStep, slots, true), ctx); - } - } else { + } + } else { TQueueType::TSlot &planSlot = VolatileState.Queue.LowSlot(planStep); - planSlot.Queue->Push(proposal.Release()); - ++planSlot.QueueSize; - } - -} - -void TTxCoordinator::Handle(TEvTxProxy::TEvProposeTransaction::TPtr &ev, const TActorContext &ctx) { - TAutoPtr<TTransactionProposal> proposal = MakeTransactionProposal(ev, MonCounters.TxIn); + planSlot.Queue->Push(proposal.Release()); + ++planSlot.QueueSize; + } + +} + +void TTxCoordinator::Handle(TEvTxProxy::TEvProposeTransaction::TPtr &ev, const TActorContext &ctx) { + TAutoPtr<TTransactionProposal> proposal = MakeTransactionProposal(ev, MonCounters.TxIn); LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR, "tablet# " << TabletID() << " txid# " << proposal->TxId << " HANDLE EvProposeTransaction marker# C0"); - PlanTx(proposal, ctx); -} - -void TTxCoordinator::HandleEnqueue(TEvTxProxy::TEvProposeTransaction::TPtr &ev, const TActorContext &ctx) { - TryInitMonCounters(ctx); - - TAutoPtr<TTransactionProposal> proposal = MakeTransactionProposal(ev, MonCounters.TxIn); + PlanTx(proposal, ctx); +} + +void TTxCoordinator::HandleEnqueue(TEvTxProxy::TEvProposeTransaction::TPtr &ev, const TActorContext &ctx) { + TryInitMonCounters(ctx); + + TAutoPtr<TTransactionProposal> proposal = MakeTransactionProposal(ev, MonCounters.TxIn); LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR, "tablet# " << TabletID() << " txid# " << proposal->TxId << " HANDLE Enqueue EvProposeTransaction"); - + if (Y_UNLIKELY(Stopping)) { return SendTransactionStatus(proposal->Proxy, TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusRestarting, proposal->TxId, 0, ctx, TabletID()); } - if (!VolatileState.Queue.Unsorted) + if (!VolatileState.Queue.Unsorted) VolatileState.Queue.Unsorted.Reset(new TQueueType::TQ()); - - VolatileState.Queue.Unsorted->Push(proposal.Release()); -} - -void TTxCoordinator::Handle(TEvPrivate::TEvPlanTick::TPtr &ev, const TActorContext &ctx) { + + VolatileState.Queue.Unsorted->Push(proposal.Release()); +} + +void TTxCoordinator::Handle(TEvPrivate::TEvPlanTick::TPtr &ev, const TActorContext &ctx) { Y_UNUSED(ev); //LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR, "tablet# " << TabletID() << " HANDLE EvPlanTick LastPlanned " << VolatileState.LastPlanned); - - if (VolatileState.Queue.Unsorted) { - while (TAutoPtr<TTransactionProposal> x = VolatileState.Queue.Unsorted->Pop()) - PlanTx(x, ctx); - VolatileState.Queue.Unsorted.Destroy(); - } - - // do work - const ui64 resolution = Config.Resolution; + + if (VolatileState.Queue.Unsorted) { + while (TAutoPtr<TTransactionProposal> x = VolatileState.Queue.Unsorted->Pop()) + PlanTx(x, ctx); + VolatileState.Queue.Unsorted.Destroy(); + } + + // do work + const ui64 resolution = Config.Resolution; const ui64 now = TAppData::TimeProvider->Now().MilliSeconds(); - const ui64 dirty = now + Config.PlanAhead; - const ui64 next = (dirty + resolution - 1) / resolution * resolution; - - if (next <= VolatileState.LastPlanned) { - return SchedulePlanTick(ctx); + const ui64 dirty = now + Config.PlanAhead; + const ui64 next = (dirty + resolution - 1) / resolution * resolution; + + if (next <= VolatileState.LastPlanned) { + return SchedulePlanTick(ctx); } - + TVector<TQueueType::TSlot> slots; slots.reserve(1000); - if (VolatileState.Queue.RapidSlot.QueueSize) { - slots.push_back(VolatileState.Queue.RapidSlot); + if (VolatileState.Queue.RapidSlot.QueueSize) { + slots.push_back(VolatileState.Queue.RapidSlot); VolatileState.Queue.RapidSlot = TQueueType::TSlot(); - } - - while (!VolatileState.Queue.Low.empty()) { - auto frontIt = VolatileState.Queue.Low.begin(); - if (frontIt->first > next) - break; - - if (frontIt->second.QueueSize) - slots.push_back(frontIt->second); - - VolatileState.Queue.Low.erase(frontIt); - } - - VolatileState.LastPlanned = next; - SchedulePlanTick(ctx); - + } + + while (!VolatileState.Queue.Low.empty()) { + auto frontIt = VolatileState.Queue.Low.begin(); + if (frontIt->first > next) + break; + + if (frontIt->second.QueueSize) + slots.push_back(frontIt->second); + + VolatileState.Queue.Low.erase(frontIt); + } + + VolatileState.LastPlanned = next; + SchedulePlanTick(ctx); + // Check if we have an empty step if (slots.empty()) { auto monotonic = ctx.Monotonic(); @@ -226,48 +226,48 @@ void TTxCoordinator::Handle(TEvPrivate::TEvPlanTick::TPtr &ev, const TActorConte VolatileState.LastEmptyPlanAt = { }; } - Execute(CreateTxPlanStep(next, slots, false), ctx); -} - -void TTxCoordinator::Handle(TEvTxCoordinator::TEvMediatorQueueConfirmations::TPtr &ev, const TActorContext &ctx) { - TEvTxCoordinator::TEvMediatorQueueConfirmations *msg = ev->Get(); + Execute(CreateTxPlanStep(next, slots, false), ctx); +} + +void TTxCoordinator::Handle(TEvTxCoordinator::TEvMediatorQueueConfirmations::TPtr &ev, const TActorContext &ctx) { + TEvTxCoordinator::TEvMediatorQueueConfirmations *msg = ev->Get(); LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR, "tablet# " << TabletID() << " HANDLE EvMediatorQueueConfirmations MediatorId# " << msg->Confirmations->MediatorId); Execute(CreateTxMediatorConfirmations(msg->Confirmations), ctx); -} - -void TTxCoordinator::Handle(TEvTxCoordinator::TEvMediatorQueueStop::TPtr &ev, const TActorContext &ctx) { - const TEvTxCoordinator::TEvMediatorQueueStop *msg = ev->Get(); +} + +void TTxCoordinator::Handle(TEvTxCoordinator::TEvMediatorQueueStop::TPtr &ev, const TActorContext &ctx) { + const TEvTxCoordinator::TEvMediatorQueueStop *msg = ev->Get(); LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR, "tablet# " << TabletID() << " HANDLE EvMediatorQueueStop MediatorId# " << msg->MediatorId); - TMediator &mediator = Mediator(msg->MediatorId, ctx); - mediator.PushUpdates = false; - mediator.GenCookie = Max<ui64>(); - mediator.Queue.Destroy(); -} - -void TTxCoordinator::Handle(TEvTxCoordinator::TEvMediatorQueueRestart::TPtr &ev, const TActorContext &ctx) { - const TEvTxCoordinator::TEvMediatorQueueRestart *msg = ev->Get(); + TMediator &mediator = Mediator(msg->MediatorId, ctx); + mediator.PushUpdates = false; + mediator.GenCookie = Max<ui64>(); + mediator.Queue.Destroy(); +} + +void TTxCoordinator::Handle(TEvTxCoordinator::TEvMediatorQueueRestart::TPtr &ev, const TActorContext &ctx) { + const TEvTxCoordinator::TEvMediatorQueueRestart *msg = ev->Get(); LOG_NOTICE_S(ctx, NKikimrServices::TX_COORDINATOR, "tablet# " << TabletID() << " HANDLE EvMediatorQueueRestart MediatorId# " << msg->MediatorId); - - TMediator &mediator = Mediator(msg->MediatorId, ctx); - mediator.PushUpdates = false; - mediator.GenCookie = msg->GenCookie; - mediator.Queue.Reset(new TMediator::TStepQueue()); + + TMediator &mediator = Mediator(msg->MediatorId, ctx); + mediator.PushUpdates = false; + mediator.GenCookie = msg->GenCookie; + mediator.Queue.Reset(new TMediator::TStepQueue()); Execute(CreateTxRestartMediatorQueue(msg->MediatorId, msg->GenCookie), ctx); -} - -void TTxCoordinator::Handle(TEvTxCoordinator::TEvCoordinatorConfirmPlan::TPtr &ev, const TActorContext &ctx) { - TAutoPtr<TCoordinatorStepConfirmations> confirmations = ev->Get()->Confirmations; - while (TAutoPtr<TCoordinatorStepConfirmations::TEntry> x = confirmations->Queue->Pop()) { +} + +void TTxCoordinator::Handle(TEvTxCoordinator::TEvCoordinatorConfirmPlan::TPtr &ev, const TActorContext &ctx) { + TAutoPtr<TCoordinatorStepConfirmations> confirmations = ev->Get()->Confirmations; + while (TAutoPtr<TCoordinatorStepConfirmations::TEntry> x = confirmations->Queue->Pop()) { LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR, "tablet# " << TabletID() << " txid# " << x->TxId << " stepId# " << x->Step << " Status# " << x->Status << " SEND EvProposeTransactionStatus to# " << x->ProxyId.ToString() << " Proxy"); - ctx.Send(x->ProxyId, new TEvTxProxy::TEvProposeTransactionStatus(x->Status, x->TxId, x->Step)); - } -} - + ctx.Send(x->ProxyId, new TEvTxProxy::TEvProposeTransactionStatus(x->Status, x->TxId, x->Step)); + } +} + void TTxCoordinator::DoConfiguration(const TEvSubDomain::TEvConfigure &ev, const TActorContext &ctx, const TActorId &ackTo) { const TEvSubDomain::TEvConfigure::ProtoRecordType &record = ev.Record; @@ -305,25 +305,25 @@ void TTxCoordinator::Handle(TEvents::TEvPoisonPill::TPtr&, const TActorContext& ctx.Send(Tablet(), new TEvents::TEvPoisonPill); } -void TTxCoordinator::OnActivateExecutor(const TActorContext &ctx) { +void TTxCoordinator::OnActivateExecutor(const TActorContext &ctx) { TryInitMonCounters(ctx); Executor()->RegisterExternalTabletCounters(TabletCountersPtr); Execute(CreateTxSchema(), ctx); -} - -void TTxCoordinator::TryInitMonCounters(const TActorContext &ctx) { - if (MonCounters.Coordinator) - return; - - auto &counters = AppData(ctx)->Counters; +} + +void TTxCoordinator::TryInitMonCounters(const TActorContext &ctx) { + if (MonCounters.Coordinator) + return; + + auto &counters = AppData(ctx)->Counters; MonCounters.Coordinator = GetServiceCounters(counters, "coordinator"); - MonCounters.TxIn = MonCounters.Coordinator->GetCounter("TxIn", true); - MonCounters.TxPlanned = MonCounters.Coordinator->GetCounter("TxPlanned", true); - MonCounters.TxDeclined = MonCounters.Coordinator->GetCounter("TxDeclined", true); - MonCounters.TxInFly = MonCounters.Coordinator->GetCounter("TxInFly", false); - MonCounters.StepsUncommited = MonCounters.Coordinator->GetCounter("StepsUncommited", false); - MonCounters.StepsInFly = MonCounters.Coordinator->GetCounter("StepsInFly", false); - + MonCounters.TxIn = MonCounters.Coordinator->GetCounter("TxIn", true); + MonCounters.TxPlanned = MonCounters.Coordinator->GetCounter("TxPlanned", true); + MonCounters.TxDeclined = MonCounters.Coordinator->GetCounter("TxDeclined", true); + MonCounters.TxInFly = MonCounters.Coordinator->GetCounter("TxInFly", false); + MonCounters.StepsUncommited = MonCounters.Coordinator->GetCounter("StepsUncommited", false); + MonCounters.StepsInFly = MonCounters.Coordinator->GetCounter("StepsInFly", false); + MonCounters.PlanTxCalls = MonCounters.Coordinator->GetCounter("PlanTx/Calls", true); MonCounters.PlanTxOutdated = MonCounters.Coordinator->GetCounter("PlanTx/Outdated", true); MonCounters.PlanTxAccepted = MonCounters.Coordinator->GetCounter("PlanTx/Accepted", true); @@ -332,7 +332,7 @@ void TTxCoordinator::TryInitMonCounters(const TActorContext &ctx) { MonCounters.StepOutdatedTx = MonCounters.Coordinator->GetCounter("Step/OutdatedTx", true); MonCounters.StepPlannedDeclinedTx = MonCounters.Coordinator->GetCounter("Step/PlannedDeclinedTx", true); MonCounters.StepPlannedTx = MonCounters.Coordinator->GetCounter("Step/PlannedTx", true); - MonCounters.StepDeclinedNoSpaceTx = MonCounters.Coordinator->GetCounter("Step/DeclinedNoSpaceTx", true); + MonCounters.StepDeclinedNoSpaceTx = MonCounters.Coordinator->GetCounter("Step/DeclinedNoSpaceTx", true); MonCounters.LegacyTxFromReceiveToPlan.Init(MonCounters.Coordinator.Get(), "TxFromReceiveToPlan", "ms", 1, 20); MonCounters.TxFromReceiveToPlan = MonCounters.Coordinator->GetHistogram( @@ -340,14 +340,14 @@ void TTxCoordinator::TryInitMonCounters(const TActorContext &ctx) { MonCounters.LegacyTxPlanLatency.Init(MonCounters.Coordinator.Get(), "TxPlanLatency", "ms", 1, 20); MonCounters.TxPlanLatency = MonCounters.Coordinator->GetHistogram( "TxPlanLatencyMs", NMonitoring::ExponentialHistogram(20, 2, 1)); -} - -void TTxCoordinator::SendMediatorStep(TMediator &mediator, const TActorContext &ctx) { - while (TMediatorStep *step = mediator.Queue->Head()) { - if (!step->Confirmed) - return; - - TAutoPtr<TMediatorStep> extracted = mediator.Queue->Pop(); +} + +void TTxCoordinator::SendMediatorStep(TMediator &mediator, const TActorContext &ctx) { + while (TMediatorStep *step = mediator.Queue->Head()) { + if (!step->Confirmed) + return; + + TAutoPtr<TMediatorStep> extracted = mediator.Queue->Pop(); for (const auto& tx: extracted->Transactions) { LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR, "Send from# " << TabletID() << " to mediator# " << extracted->MediatorId << ", step# " << extracted->Step @@ -355,17 +355,17 @@ void TTxCoordinator::SendMediatorStep(TMediator &mediator, const TActorContext & } VolatileState.LastSentStep = Max(VolatileState.LastSentStep, extracted->Step); - ctx.Send(mediator.QueueActor, new TEvTxCoordinator::TEvMediatorQueueStep(mediator.GenCookie, extracted)); - } -} - -void TTxCoordinator::SchedulePlanTick(const TActorContext &ctx) { - const ui64 planResolution = Config.Resolution; - ctx.Schedule(TDuration::MilliSeconds(planResolution), new TEvPrivate::TEvPlanTick()); -} - + ctx.Send(mediator.QueueActor, new TEvTxCoordinator::TEvMediatorQueueStep(mediator.GenCookie, extracted)); + } +} + +void TTxCoordinator::SchedulePlanTick(const TActorContext &ctx) { + const ui64 planResolution = Config.Resolution; + ctx.Schedule(TDuration::MilliSeconds(planResolution), new TEvPrivate::TEvPlanTick()); +} + bool TTxCoordinator::OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext &ctx) { - if (!Executor() || !Executor()->GetStats().IsActive) + if (!Executor() || !Executor()->GetStats().IsActive) return false; if (!ev) @@ -373,8 +373,8 @@ bool TTxCoordinator::OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const Execute(CreateTxMonitoring(ev), ctx); return true; -} - +} + void TTxCoordinator::OnTabletStop(TEvTablet::TEvTabletStop::TPtr &ev, const TActorContext &ctx) { const auto* msg = ev->Get(); @@ -434,6 +434,6 @@ void TTxCoordinator::OnStopGuardComplete(const TActorContext &ctx) { IActor* CreateFlatTxCoordinator(const TActorId &tablet, TTabletStorageInfo *info) { return new NFlatTxCoordinator::TTxCoordinator(info, tablet); -} - -} +} + +} diff --git a/ydb/core/tx/coordinator/coordinator_impl.h b/ydb/core/tx/coordinator/coordinator_impl.h index 744fd0cdc8..39018aff1e 100644 --- a/ydb/core/tx/coordinator/coordinator_impl.h +++ b/ydb/core/tx/coordinator/coordinator_impl.h @@ -1,6 +1,6 @@ -#pragma once +#pragma once -#include "defs.h" +#include "defs.h" #include "coordinator.h" #include <ydb/core/protos/counters_coordinator.pb.h> @@ -24,7 +24,7 @@ #include <algorithm> -namespace NKikimr { +namespace NKikimr { namespace NFlatTxCoordinator { typedef ui64 TStepId; @@ -46,7 +46,7 @@ struct TTransactionProposal { TTabletId TabletId; ui64 AffectedFlags : 8; - // reserved + // reserved }; TVector<TAffectedEntry> AffectedSet; @@ -98,7 +98,7 @@ struct TMediatorStep { ui64 Moderator; - TTx(TTxId txId, TTabletId *affected, ui32 affectedSize, ui64 moderator) + TTx(TTxId txId, TTabletId *affected, ui32 affectedSize, ui64 moderator) : TxId(txId) , PushToAffected(affected, affected + affectedSize) , Moderator(moderator) @@ -138,7 +138,7 @@ struct TMediatorConfirmations { IActor* CreateTxCoordinatorMediatorQueue(const TActorId &owner, ui64 coordinator, ui64 mediator, ui64 coordinatorGeneration); using NTabletFlatExecutor::TTabletExecutedFlat; -using NTabletFlatExecutor::ITransaction; +using NTabletFlatExecutor::ITransaction; using NTabletFlatExecutor::TTransactionBase; using NTabletFlatExecutor::TTransactionContext; @@ -167,128 +167,128 @@ do { \ class TTxCoordinator : public TActor<TTxCoordinator>, public TTabletExecutedFlat { - - struct TEvPrivate { - enum EEv { - EvPlanTick = EventSpaceBegin(TEvents::ES_PRIVATE), + + struct TEvPrivate { + enum EEv { + EvPlanTick = EventSpaceBegin(TEvents::ES_PRIVATE), EvAcquireReadStepFlush, - EvEnd - }; - + EvEnd + }; + static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)"); - - struct TEvPlanTick : public TEventLocal<TEvPlanTick, EvPlanTick> {}; + + struct TEvPlanTick : public TEventLocal<TEvPlanTick, EvPlanTick> {}; struct TEvAcquireReadStepFlush : public TEventLocal<TEvAcquireReadStepFlush, EvAcquireReadStepFlush> {}; - }; - + }; + struct TQueueType { - typedef TOneOneQueueInplace<TTransactionProposal *, 512> TQ; - - struct TFlowEntry { - ui16 Weight; - ui16 Limit; - - TFlowEntry() - : Weight(0) - , Limit(0) - {} - }; - - struct TSlot { - TAutoPtr<TQ, TQ::TPtrCleanDestructor> Queue; - ui64 QueueSize; - - TSlot() - : Queue(new TQ()) - , QueueSize(0) - {} - }; - + typedef TOneOneQueueInplace<TTransactionProposal *, 512> TQ; + + struct TFlowEntry { + ui16 Weight; + ui16 Limit; + + TFlowEntry() + : Weight(0) + , Limit(0) + {} + }; + + struct TSlot { + TAutoPtr<TQ, TQ::TPtrCleanDestructor> Queue; + ui64 QueueSize; + + TSlot() + : Queue(new TQ()) + , QueueSize(0) + {} + }; + typedef TMap<TStepId, TSlot> TSlotQueue; - - TSlotQueue Low; - TSlot RapidSlot; // slot for entries with schedule on 'right now' moment (actually - with min-schedule time in past). - bool RapidFreeze; - - TAutoPtr<TQ, TQ::TPtrCleanDestructor> Unsorted; - + + TSlotQueue Low; + TSlot RapidSlot; // slot for entries with schedule on 'right now' moment (actually - with min-schedule time in past). + bool RapidFreeze; + + TAutoPtr<TQ, TQ::TPtrCleanDestructor> Unsorted; + TSlot& LowSlot(TStepId step) { TMap<TStepId, TSlot>::iterator it = Low.find(step); - if (it != Low.end()) - return it->second; + if (it != Low.end()) + return it->second; std::pair<TMap<TStepId, TSlot>::iterator, bool> xit = Low.insert(TSlotQueue::value_type(step, TSlot())); TSlot &ret = xit.first->second; - return ret; - } - + return ret; + } + TQueueType() - : RapidFreeze(false) - {} - }; - - struct TTxInit; + : RapidFreeze(false) + {} + }; + + struct TTxInit; struct TTxRestoreTransactions; struct TTxConfigure; struct TTxSchema; struct TTxUpgrade; - struct TTxPlanStep; - struct TTxRestartMediatorQueue; - struct TTxMediatorConfirmations; + struct TTxPlanStep; + struct TTxRestartMediatorQueue; + struct TTxMediatorConfirmations; struct TTxConsistencyCheck; struct TTxMonitoring; struct TTxStopGuard; struct TTxAcquireReadStep; - - ITransaction* CreateTxInit(); - ITransaction* CreateTxRestoreTransactions(); + + ITransaction* CreateTxInit(); + ITransaction* CreateTxRestoreTransactions(); ITransaction* CreateTxConfigure( TActorId ackTo, ui64 version, ui64 resolution, const TVector<TTabletId> &mediators, const NKikimrSubDomains::TProcessingParams &config); - ITransaction* CreateTxSchema(); - ITransaction* CreateTxUpgrade(); - ITransaction* CreateTxPlanStep(TStepId toStep, TVector<TQueueType::TSlot> &slots, bool rapid); - ITransaction* CreateTxRestartMediatorQueue(TTabletId mediatorId, ui64 genCookie); - ITransaction* CreateTxMediatorConfirmations(TAutoPtr<TMediatorConfirmations> &confirmations); - ITransaction* CreateTxConsistencyCheck(); - ITransaction* CreateTxMonitoring(NMon::TEvRemoteHttpInfo::TPtr& ev); + ITransaction* CreateTxSchema(); + ITransaction* CreateTxUpgrade(); + ITransaction* CreateTxPlanStep(TStepId toStep, TVector<TQueueType::TSlot> &slots, bool rapid); + ITransaction* CreateTxRestartMediatorQueue(TTabletId mediatorId, ui64 genCookie); + ITransaction* CreateTxMediatorConfirmations(TAutoPtr<TMediatorConfirmations> &confirmations); + ITransaction* CreateTxConsistencyCheck(); + ITransaction* CreateTxMonitoring(NMon::TEvRemoteHttpInfo::TPtr& ev); ITransaction* CreateTxStopGuard(); - - struct TConfig { + + struct TConfig { ui64 MediatorsVersion; TMediators::TPtr Mediators; TVector<TTabletId> Coordinators; - - ui64 PlanAhead; - ui64 Resolution; - ui64 RapidSlotFlushSize; - - bool Synthetic; - - TConfig() + + ui64 PlanAhead; + ui64 Resolution; + ui64 RapidSlotFlushSize; + + bool Synthetic; + + TConfig() : MediatorsVersion(0) , PlanAhead(0) - , Resolution(0) - , RapidSlotFlushSize(0) - , Synthetic(false) - {} - }; - - struct TMediator { - typedef TOneOneQueueInplace<TMediatorStep *, 32> TStepQueue; - + , Resolution(0) + , RapidSlotFlushSize(0) + , Synthetic(false) + {} + }; + + struct TMediator { + typedef TOneOneQueueInplace<TMediatorStep *, 32> TStepQueue; + TActorId QueueActor; - ui64 GenCookie; - bool PushUpdates; - - TAutoPtr<TStepQueue, TStepQueue::TPtrCleanDestructor> Queue; - - TMediator() - : GenCookie(0) - , PushUpdates(false) - {} - }; - + ui64 GenCookie; + bool PushUpdates; + + TAutoPtr<TStepQueue, TStepQueue::TPtrCleanDestructor> Queue; + + TMediator() + : GenCookie(0) + , PushUpdates(false) + {} + }; + struct TTransaction { TStepId PlanOnStep; THashSet<TTabletId> AffectedSet; @@ -309,13 +309,13 @@ class TTxCoordinator : public TActor<TTxCoordinator>, public TTabletExecutedFlat { } }; - struct TVolatileState { + struct TVolatileState { ui64 LastPlanned = 0; ui64 LastSentStep = 0; ui64 LastAcquired = 0; ui64 LastEmptyStep = 0; TMonotonic LastEmptyPlanAt{ }; - + TQueueType Queue; ui64 AcquireReadStepInFlight = 0; @@ -325,8 +325,8 @@ class TTxCoordinator : public TActor<TTxCoordinator>, public TTabletExecutedFlat bool AcquireReadStepFlushing = false; bool AcquireReadStepStarting = false; }; - -public: + +public: struct Schema : NIceDb::Schema { static const ui32 CurrentVersion; @@ -334,11 +334,11 @@ public: struct ID : Column<0, NScheme::NTypeIds::Uint64> {}; // PK struct Plan : Column<1, NScheme::NTypeIds::Uint64> {}; struct AffectedSet : Column<2, NScheme::NTypeIds::String> { using Type = TVector<TTabletId>; }; - + using TKey = TableKey<ID>; using TColumns = TableColumns<ID, Plan, AffectedSet>; - }; - + }; + struct AffectedSet : Table<4> { struct MediatorID : Column<1, NScheme::NTypeIds::Uint64> {}; struct TransactionID : Column<2, Transaction::ID::ColumnType> {}; @@ -346,8 +346,8 @@ public: using TKey = TableKey<MediatorID, TransactionID, DataShardID>; using TColumns = TableColumns<MediatorID, TransactionID, DataShardID>; - }; - + }; + struct State : Table<2> { enum EKeyType { KeyLastPlanned, @@ -360,7 +360,7 @@ public: using TKey = TableKey<StateKey>; using TColumns = TableColumns<StateKey, StateValue>; - }; + }; struct DomainConfiguration : Table<5> { struct Version : Column<1, NScheme::NTypeIds::Uint64> {}; @@ -373,18 +373,18 @@ public: }; using TTables = SchemaTables<Transaction, AffectedSet, State, DomainConfiguration>; - }; - -private: - struct TCoordinatorMonCounters { - TIntrusivePtr<NMonitoring::TDynamicCounters> Coordinator; - - NMonitoring::TDynamicCounters::TCounterPtr TxIn; - NMonitoring::TDynamicCounters::TCounterPtr TxPlanned; - NMonitoring::TDynamicCounters::TCounterPtr TxDeclined; - NMonitoring::TDynamicCounters::TCounterPtr TxInFly; - NMonitoring::TDynamicCounters::TCounterPtr StepsUncommited; - NMonitoring::TDynamicCounters::TCounterPtr StepsInFly; + }; + +private: + struct TCoordinatorMonCounters { + TIntrusivePtr<NMonitoring::TDynamicCounters> Coordinator; + + NMonitoring::TDynamicCounters::TCounterPtr TxIn; + NMonitoring::TDynamicCounters::TCounterPtr TxPlanned; + NMonitoring::TDynamicCounters::TCounterPtr TxDeclined; + NMonitoring::TDynamicCounters::TCounterPtr TxInFly; + NMonitoring::TDynamicCounters::TCounterPtr StepsUncommited; + NMonitoring::TDynamicCounters::TCounterPtr StepsInFly; NMonitoring::TDynamicCounters::TCounterPtr PlanTxCalls; NMonitoring::TDynamicCounters::TCounterPtr PlanTxOutdated; @@ -394,25 +394,25 @@ private: NMonitoring::TDynamicCounters::TCounterPtr StepOutdatedTx; NMonitoring::TDynamicCounters::TCounterPtr StepPlannedDeclinedTx; NMonitoring::TDynamicCounters::TCounterPtr StepPlannedTx; - NMonitoring::TDynamicCounters::TCounterPtr StepDeclinedNoSpaceTx; + NMonitoring::TDynamicCounters::TCounterPtr StepDeclinedNoSpaceTx; NMon::THistogramCounterHelper LegacyTxFromReceiveToPlan; NMonitoring::THistogramPtr TxFromReceiveToPlan; NMon::THistogramCounterHelper LegacyTxPlanLatency; NMonitoring::THistogramPtr TxPlanLatency; - - i64 CurrentTxInFly; - }; - - TVolatileState VolatileState; - TConfig Config; - TCoordinatorMonCounters MonCounters; + + i64 CurrentTxInFly; + }; + + TVolatileState VolatileState; + TConfig Config; + TCoordinatorMonCounters MonCounters; TTabletCountersBase* TabletCounters; TAutoPtr<TTabletCountersBase> TabletCountersPtr; - + typedef THashMap<TTabletId, TMediator> TMediatorsIndex; TMediatorsIndex Mediators; - + typedef THashMap<TTxId, TTransaction> TTransactions; TTransactions Transactions; @@ -425,69 +425,69 @@ private: TZLibCompress DebugLog; #endif - void Die(const TActorContext &ctx) override { + void Die(const TActorContext &ctx) override { for (TMediatorsIndex::iterator it = Mediators.begin(), end = Mediators.end(); it != end; ++it) { - TMediator &x = it->second; - ctx.Send(x.QueueActor, new TEvents::TEvPoisonPill()); - } - Mediators.clear(); - - if (MonCounters.CurrentTxInFly && MonCounters.TxInFly) - *MonCounters.TxInFly -= MonCounters.CurrentTxInFly; - - return TActor::Die(ctx); - } - - void OnActivateExecutor(const TActorContext &ctx) override; - + TMediator &x = it->second; + ctx.Send(x.QueueActor, new TEvents::TEvPoisonPill()); + } + Mediators.clear(); + + if (MonCounters.CurrentTxInFly && MonCounters.TxInFly) + *MonCounters.TxInFly -= MonCounters.CurrentTxInFly; + + return TActor::Die(ctx); + } + + void OnActivateExecutor(const TActorContext &ctx) override; + void DefaultSignalTabletActive(const TActorContext &ctx) override { Y_UNUSED(ctx); //unactivate incomming tablet's pipes until StateSync } - void OnDetach(const TActorContext &ctx) override { - return Die(ctx); - } - - void OnTabletDead(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext &ctx) override { + void OnDetach(const TActorContext &ctx) override { + return Die(ctx); + } + + void OnTabletDead(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext &ctx) override { Y_UNUSED(ev); - return Die(ctx); - } - + return Die(ctx); + } + TMediator& Mediator(TTabletId mediatorId, const TActorContext &ctx) { - TMediator &mediator = Mediators[mediatorId]; - if (!mediator.QueueActor) - mediator.QueueActor = ctx.ExecutorThread.RegisterActor(CreateTxCoordinatorMediatorQueue(ctx.SelfID, TabletID(), mediatorId, Executor()->Generation())); - return mediator; - } - - void SendMediatorStep(TMediator &mediator, const TActorContext &ctx); - - void Handle(TEvTxProxy::TEvProposeTransaction::TPtr &ev, const TActorContext &ctx); - void HandleEnqueue(TEvTxProxy::TEvProposeTransaction::TPtr &ev, const TActorContext &ctx); - + TMediator &mediator = Mediators[mediatorId]; + if (!mediator.QueueActor) + mediator.QueueActor = ctx.ExecutorThread.RegisterActor(CreateTxCoordinatorMediatorQueue(ctx.SelfID, TabletID(), mediatorId, Executor()->Generation())); + return mediator; + } + + void SendMediatorStep(TMediator &mediator, const TActorContext &ctx); + + void Handle(TEvTxProxy::TEvProposeTransaction::TPtr &ev, const TActorContext &ctx); + void HandleEnqueue(TEvTxProxy::TEvProposeTransaction::TPtr &ev, const TActorContext &ctx); + void Handle(TEvTxProxy::TEvAcquireReadStep::TPtr &ev, const TActorContext &ctx); void Handle(TEvPrivate::TEvAcquireReadStepFlush::TPtr &ev, const TActorContext &ctx); - void Handle(TEvPrivate::TEvPlanTick::TPtr &ev, const TActorContext &ctx); - void Handle(TEvTxCoordinator::TEvMediatorQueueStop::TPtr &ev, const TActorContext &ctx); - void Handle(TEvTxCoordinator::TEvMediatorQueueRestart::TPtr &ev, const TActorContext &ctx); - void Handle(TEvTxCoordinator::TEvMediatorQueueConfirmations::TPtr &ev, const TActorContext &ctx); - void Handle(TEvTxCoordinator::TEvCoordinatorConfirmPlan::TPtr &ev, const TActorContext &ctx); + void Handle(TEvPrivate::TEvPlanTick::TPtr &ev, const TActorContext &ctx); + void Handle(TEvTxCoordinator::TEvMediatorQueueStop::TPtr &ev, const TActorContext &ctx); + void Handle(TEvTxCoordinator::TEvMediatorQueueRestart::TPtr &ev, const TActorContext &ctx); + void Handle(TEvTxCoordinator::TEvMediatorQueueConfirmations::TPtr &ev, const TActorContext &ctx); + void Handle(TEvTxCoordinator::TEvCoordinatorConfirmPlan::TPtr &ev, const TActorContext &ctx); void Handle(TEvSubDomain::TEvConfigure::TPtr &ev, const TActorContext &ctx); - + void Handle(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx); void DoConfiguration(const TEvSubDomain::TEvConfigure &ev, const TActorContext &ctx, const TActorId &ackTo = TActorId()); - void Sync(ui64 mediator, const TActorContext &ctx); - void Sync(const TActorContext &ctx); - - void PlanTx(TAutoPtr<TTransactionProposal> &proposal, const TActorContext &ctx); - - void SchedulePlanTick(const TActorContext &ctx); + void Sync(ui64 mediator, const TActorContext &ctx); + void Sync(const TActorContext &ctx); + + void PlanTx(TAutoPtr<TTransactionProposal> &proposal, const TActorContext &ctx); + + void SchedulePlanTick(const TActorContext &ctx); bool RestoreMediatorInfo(TTabletId mediatorId, TVector<TAutoPtr<TMediatorStep>> &planned, TTransactionContext &txc, /*TKeyBuilder &kb, */THashMap<TTxId,TVector<TTabletId>> &pushToAffected) const; - - void TryInitMonCounters(const TActorContext &ctx); + + void TryInitMonCounters(const TActorContext &ctx); bool OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext &ctx) override; void OnTabletStop(TEvTablet::TEvTabletStop::TPtr &ev, const TActorContext &ctx) override; @@ -500,17 +500,17 @@ private: void MaybeFlushAcquireReadStep(const TActorContext &ctx); -public: +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TX_COORDINATOR_ACTOR; } TTxCoordinator(TTabletStorageInfo *info, const TActorId &tablet); - + // no incomming pipes is allowed in StateInit STFUNC_TABLET_INIT(StateInit, HFunc(TEvents::TEvPoisonPill, Handle)) - + STFUNC_TABLET_DEF(StateSync, HFunc(TEvTxProxy::TEvProposeTransaction, HandleEnqueue) HFunc(TEvTxProxy::TEvAcquireReadStep, Handle) @@ -519,7 +519,7 @@ public: HFunc(TEvents::TEvPoisonPill, Handle) IgnoreFunc(TEvTabletPipe::TEvServerConnected) IgnoreFunc(TEvTabletPipe::TEvServerDisconnected)) - + STFUNC_TABLET_DEF(StateWork, HFunc(TEvSubDomain::TEvConfigure, Handle) HFunc(TEvTxProxy::TEvProposeTransaction, Handle) @@ -535,8 +535,8 @@ public: IgnoreFunc(TEvTabletPipe::TEvServerDisconnected)) STFUNC_TABLET_IGN(StateBroken,) -}; - -} -} - +}; + +} +} + diff --git a/ydb/core/tx/coordinator/mediator_queue.cpp b/ydb/core/tx/coordinator/mediator_queue.cpp index 5fb038b8bf..9b3955fa1b 100644 --- a/ydb/core/tx/coordinator/mediator_queue.cpp +++ b/ydb/core/tx/coordinator/mediator_queue.cpp @@ -5,176 +5,176 @@ #include <ydb/core/base/tablet_pipe.h> #include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/actors/core/hfunc.h> - -namespace NKikimr { + +namespace NKikimr { namespace NFlatTxCoordinator { - -class TTxCoordinatorMediatorQueue : public TActorBootstrapped<TTxCoordinatorMediatorQueue> { + +class TTxCoordinatorMediatorQueue : public TActorBootstrapped<TTxCoordinatorMediatorQueue> { const TActorId Owner; - - const ui64 Coordinator; - const ui64 Mediator; - const ui64 CoordinatorGeneration; - + + const ui64 Coordinator; + const ui64 Mediator; + const ui64 CoordinatorGeneration; + TActorId PipeClient; - ui64 GenCookie; - - ui64 PrevStep; - - TAutoPtr<TMediatorConfirmations> Confirmations; - - void Die(const TActorContext &ctx) override { - if (PipeClient) { - NTabletPipe::CloseClient(ctx, PipeClient); + ui64 GenCookie; + + ui64 PrevStep; + + TAutoPtr<TMediatorConfirmations> Confirmations; + + void Die(const TActorContext &ctx) override { + if (PipeClient) { + NTabletPipe::CloseClient(ctx, PipeClient); PipeClient = TActorId(); - } - return IActor::Die(ctx); - } - - void Sync(const TActorContext &ctx) { - LOG_DEBUG(ctx, NKikimrServices::TX_COORDINATOR_PRIVATE, "[%" PRIu64 "] to [%" PRIu64 "] sync", Coordinator, Mediator); - - if (PipeClient) { - NTabletPipe::CloseClient(ctx, PipeClient); + } + return IActor::Die(ctx); + } + + void Sync(const TActorContext &ctx) { + LOG_DEBUG(ctx, NKikimrServices::TX_COORDINATOR_PRIVATE, "[%" PRIu64 "] to [%" PRIu64 "] sync", Coordinator, Mediator); + + if (PipeClient) { + NTabletPipe::CloseClient(ctx, PipeClient); PipeClient = TActorId(); - } - + } + PipeClient = ctx.RegisterWithSameMailbox(NTabletPipe::CreateClient(ctx.SelfID, Mediator)); - + LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR_MEDIATOR_QUEUE, "Actor# " << ctx.SelfID.ToString() << " tablet# " << Coordinator << " SEND EvCoordinatorSync to# " << Mediator << " Mediator"); NTabletPipe::SendData(ctx, PipeClient, new TEvTxCoordinator::TEvCoordinatorSync(++GenCookie, Mediator, Coordinator)); - Become(&TThis::StateSync); - } - - void Handle(TEvTxCoordinator::TEvCoordinatorSyncResult::TPtr &ev, const TActorContext &ctx) { - TEvTxCoordinator::TEvCoordinatorSyncResult *msg = ev->Get(); + Become(&TThis::StateSync); + } + + void Handle(TEvTxCoordinator::TEvCoordinatorSyncResult::TPtr &ev, const TActorContext &ctx) { + TEvTxCoordinator::TEvCoordinatorSyncResult *msg = ev->Get(); LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR_MEDIATOR_QUEUE, "Actor# " << ctx.SelfID.ToString() << " tablet# " << Coordinator << " HANDLE EvCoordinatorSyncResult Status# " << NKikimrProto::EReplyStatus_Name(msg->Record.GetStatus())); - - if (msg->Record.GetCookie() != GenCookie) - return; - - if (msg->Record.GetStatus() != NKikimrProto::OK) - return Sync(ctx); - - PrevStep = 0; + + if (msg->Record.GetCookie() != GenCookie) + return; + + if (msg->Record.GetStatus() != NKikimrProto::OK) + return Sync(ctx); + + PrevStep = 0; LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR_MEDIATOR_QUEUE, "Actor# " << ctx.SelfID.ToString() << " tablet# " << Coordinator << " SEND EvMediatorQueueRestart to# " << Owner.ToString() << " Owner"); - ctx.Send(Owner, new TEvTxCoordinator::TEvMediatorQueueRestart(Mediator, 0, ++GenCookie)); - - Become(&TThis::StateWork); - } - - void Handle(TEvTxCoordinator::TEvMediatorQueueStep::TPtr &ev, const TActorContext &ctx) { - TEvTxCoordinator::TEvMediatorQueueStep *msg = ev->Get(); + ctx.Send(Owner, new TEvTxCoordinator::TEvMediatorQueueRestart(Mediator, 0, ++GenCookie)); + + Become(&TThis::StateWork); + } + + void Handle(TEvTxCoordinator::TEvMediatorQueueStep::TPtr &ev, const TActorContext &ctx) { + TEvTxCoordinator::TEvMediatorQueueStep *msg = ev->Get(); LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR_MEDIATOR_QUEUE, "Actor# " << ctx.SelfID.ToString() << " HANDLE EvMediatorQueueStep step# " << msg->Step->Step); - - if (msg->GenCookie == GenCookie && PipeClient) { + + if (msg->GenCookie == GenCookie && PipeClient) { const NFlatTxCoordinator::TMediatorStep &step = *msg->Step; - - LOG_DEBUG(ctx, NKikimrServices::TX_COORDINATOR_PRIVATE, "[%" PRIu64 "] to [%" PRIu64 "], step [%" PRIu64 "]", Coordinator, Mediator, step.Step); - + + LOG_DEBUG(ctx, NKikimrServices::TX_COORDINATOR_PRIVATE, "[%" PRIu64 "] to [%" PRIu64 "], step [%" PRIu64 "]", Coordinator, Mediator, step.Step); + LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR_MEDIATOR_QUEUE, "Actor# " << ctx.SelfID.ToString() << " tablet# " << Coordinator << " SEND to# " << Mediator << " Mediator TEvCoordinatorStep"); NTabletPipe::SendData(ctx, PipeClient, new TEvTxCoordinator::TEvCoordinatorStep( step, PrevStep, Mediator, Coordinator, CoordinatorGeneration)); - PrevStep = step.Step; - } - + PrevStep = step.Step; + } + if (Confirmations) { LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR_MEDIATOR_QUEUE, "Actor# " << ctx.SelfID.ToString() << " tablet# " << Coordinator << " SEND EvMediatorQueueConfirmations to# " << Owner.ToString() << " Owner"); - ctx.Send(Owner, new TEvTxCoordinator::TEvMediatorQueueConfirmations(Confirmations)); + ctx.Send(Owner, new TEvTxCoordinator::TEvMediatorQueueConfirmations(Confirmations)); } - } - + } + void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx) { TEvTabletPipe::TEvClientConnected *msg = ev->Get(); LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR_MEDIATOR_QUEUE, "Actor# " << ctx.SelfID.ToString() << " HANDLE EvClientConnected Status# " << NKikimrProto::EReplyStatus_Name(msg->Status)); - if (msg->ClientId != PipeClient) - return; - - if (msg->Status != NKikimrProto::OK) - return Sync(ctx); - - // actual work is in sync-reply handling - } - + if (msg->ClientId != PipeClient) + return; + + if (msg->Status != NKikimrProto::OK) + return Sync(ctx); + + // actual work is in sync-reply handling + } + void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx) { TEvTabletPipe::TEvClientDestroyed *msg = ev->Get(); LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR_MEDIATOR_QUEUE, "Actor# " << ctx.SelfID.ToString() << " HANDLE EvClientDestroyed"); - if (msg->ClientId != PipeClient) - return; + if (msg->ClientId != PipeClient) + return; LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR_MEDIATOR_QUEUE, "Actor# " << ctx.SelfID.ToString() << " tablet# " << Coordinator << " SEND EvMediatorQueueStop to# " << Owner.ToString() << " Owner Mediator# " << Mediator); - ctx.Send(Owner, new TEvTxCoordinator::TEvMediatorQueueStop(Mediator)); - Sync(ctx); - } - - void Handle(TEvTxProcessing::TEvPlanStepAck::TPtr &ev, const TActorContext &ctx) { - const NKikimrTx::TEvPlanStepAck &record = ev->Get()->Record; + ctx.Send(Owner, new TEvTxCoordinator::TEvMediatorQueueStop(Mediator)); + Sync(ctx); + } + + void Handle(TEvTxProcessing::TEvPlanStepAck::TPtr &ev, const TActorContext &ctx) { + const NKikimrTx::TEvPlanStepAck &record = ev->Get()->Record; LOG_DEBUG_S(ctx, NKikimrServices::TX_COORDINATOR_MEDIATOR_QUEUE, "Actor# " << ctx.SelfID.ToString() << " HANDLE EvPlanStepAck"); - - if (!Confirmations) - Confirmations.Reset(new TMediatorConfirmations(Mediator)); - + + if (!Confirmations) + Confirmations.Reset(new TMediatorConfirmations(Mediator)); + const TTabletId tabletId = record.GetTabletId(); - for (const auto txid : record.GetTxId()) { + for (const auto txid : record.GetTxId()) { Confirmations->Acks[txid].insert(tabletId); - } - } - -public: + } + } + +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TX_COORDINATOR_MEDIATORQ_ACTOR; } TTxCoordinatorMediatorQueue(const TActorId &owner, ui64 coordinator, ui64 mediator, ui64 coordinatorGeneration) - : Owner(owner) - , Coordinator(coordinator) - , Mediator(mediator) - , CoordinatorGeneration(coordinatorGeneration) - , PipeClient() - , GenCookie(0) - , PrevStep(0) + : Owner(owner) + , Coordinator(coordinator) + , Mediator(mediator) + , CoordinatorGeneration(coordinatorGeneration) + , PipeClient() + , GenCookie(0) + , PrevStep(0) {} - - void Bootstrap(const TActorContext &ctx) { - Sync(ctx); - } - - STFUNC(StateSync) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvTxProcessing::TEvPlanStepAck, Handle); - HFunc(TEvTxCoordinator::TEvCoordinatorSyncResult, Handle); + + void Bootstrap(const TActorContext &ctx) { + Sync(ctx); + } + + STFUNC(StateSync) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvTxProcessing::TEvPlanStepAck, Handle); + HFunc(TEvTxCoordinator::TEvCoordinatorSyncResult, Handle); HFunc(TEvTabletPipe::TEvClientConnected, Handle); HFunc(TEvTabletPipe::TEvClientDestroyed, Handle); - CFunc(TEvents::TSystem::PoisonPill, Die); - } - } - - STFUNC(StateWork) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvTxProcessing::TEvPlanStepAck, Handle); - HFunc(TEvTxCoordinator::TEvMediatorQueueStep, Handle); + CFunc(TEvents::TSystem::PoisonPill, Die); + } + } + + STFUNC(StateWork) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvTxProcessing::TEvPlanStepAck, Handle); + HFunc(TEvTxCoordinator::TEvMediatorQueueStep, Handle); HFunc(TEvTabletPipe::TEvClientDestroyed, Handle); - CFunc(TEvents::TSystem::PoisonPill, Die) - } - } -}; - + CFunc(TEvents::TSystem::PoisonPill, Die) + } + } +}; + IActor* CreateTxCoordinatorMediatorQueue(const TActorId &owner, ui64 coordinator, ui64 mediator, ui64 coordinatorGeneration) { return new NFlatTxCoordinator::TTxCoordinatorMediatorQueue(owner, coordinator, mediator, coordinatorGeneration); -} - -} +} + +} } diff --git a/ydb/core/tx/datashard/datashard.cpp b/ydb/core/tx/datashard/datashard.cpp index f5521ec9aa..d86568b4a1 100644 --- a/ydb/core/tx/datashard/datashard.cpp +++ b/ydb/core/tx/datashard/datashard.cpp @@ -140,7 +140,7 @@ TDataShard::TDataShard(const TActorId &tablet, TTabletStorageInfo *info) , ReadColumnsScanInUserPool(0, 0, 1) , BackupReadAheadLo(0, 0, 64*1024*1024) , BackupReadAheadHi(0, 0, 128*1024*1024) - , DataShardSysTables(InitDataShardSysTables(this)) + , DataShardSysTables(InitDataShardSysTables(this)) , ChangeSenderActivator(info->TabletID) , ChangeExchangeSplitter(this) { @@ -331,7 +331,7 @@ void TDataShard::SwitchToWork(const TActorContext &ctx) { Become(&TThis::StateWork); LOG_INFO_S(ctx, NKikimrServices::TX_DATASHARD, "Switched to work state " << DatashardStateName(State) << " tabletId " << TabletID()); - + // Cleanup any removed snapshots from the previous generation Execute(new TTxCleanupRemovedSnapshots(this), ctx); @@ -1067,27 +1067,27 @@ TUserTable::TSpecialUpdate TDataShard::SpecialUpdates(const NTable::TDatabase& d const TUserTable& tableInfo = *it->second; Y_VERIFY(tableInfo.LocalTid != Max<ui32>()); - TUserTable::TSpecialUpdate ret; + TUserTable::TSpecialUpdate ret; + + if (tableInfo.SpecialColTablet != Max<ui32>()) { + ret.ColIdTablet = tableInfo.SpecialColTablet; + ret.Tablet = TabletID(); - if (tableInfo.SpecialColTablet != Max<ui32>()) { - ret.ColIdTablet = tableInfo.SpecialColTablet; - ret.Tablet = TabletID(); - - ret.HasUpdates = true; + ret.HasUpdates = true; } - if (tableInfo.SpecialColEpoch != Max<ui32>() || tableInfo.SpecialColUpdateNo != Max<ui32>()) { - auto dbChange = db.Head(tableInfo.LocalTid); - ret.ColIdEpoch = tableInfo.SpecialColEpoch; - ret.ColIdUpdateNo = tableInfo.SpecialColUpdateNo; - + if (tableInfo.SpecialColEpoch != Max<ui32>() || tableInfo.SpecialColUpdateNo != Max<ui32>()) { + auto dbChange = db.Head(tableInfo.LocalTid); + ret.ColIdEpoch = tableInfo.SpecialColEpoch; + ret.ColIdUpdateNo = tableInfo.SpecialColUpdateNo; + ret.Epoch = dbChange.Epoch.ToCounter(); - ret.UpdateNo = dbChange.Serial; - - ret.HasUpdates = true; - } - - return ret; + ret.UpdateNo = dbChange.Serial; + + ret.HasUpdates = true; + } + + return ret; } void TDataShard::SetTableAccessTime(const TTableId& tableId, TInstant ts) { @@ -1354,7 +1354,7 @@ void TDataShard::Handle(TEvDataShard::TEvStateChangedResult::TPtr& ev, const TAc << " datashard " << TabletID() << " state " << DatashardStateName(State)); // TODO: implement - NTabletPipe::CloseAndForgetClient(SelfId(), StateReportPipe); + NTabletPipe::CloseAndForgetClient(SelfId(), StateReportPipe); } bool TDataShard::CheckDataTxReject(const TString& opDescr, diff --git a/ydb/core/tx/datashard/datashard__engine_host.cpp b/ydb/core/tx/datashard/datashard__engine_host.cpp index 9e5959591e..876c337093 100644 --- a/ydb/core/tx/datashard/datashard__engine_host.cpp +++ b/ydb/core/tx/datashard/datashard__engine_host.cpp @@ -208,7 +208,7 @@ public: } NUdf::TUnboxedValue SelectRow(const TArrayRef<const TCell>& row, TStructLiteral* columnIds, - TOptionalType* returnType, const TReadTarget& readTarget, const THolderFactory& holderFactory) const + TOptionalType* returnType, const TReadTarget& readTarget, const THolderFactory& holderFactory) const { Y_UNUSED(readTarget); @@ -224,15 +224,15 @@ public: return result.CreateResult(lock.MakeRow(false), holderFactory); } - void UpdateRow(const TArrayRef<const TCell>& row, const TArrayRef<const TUpdateCommand>& commands) const - { + void UpdateRow(const TArrayRef<const TCell>& row, const TArrayRef<const TUpdateCommand>& commands) const + { Y_UNUSED(row); Y_UNUSED(commands); Y_ASSERT("Not supported"); } - void EraseRow(const TArrayRef<const TCell>& row) const { + void EraseRow(const TArrayRef<const TCell>& row) const { Self->SysLocksTable().EraseLock(row); } @@ -252,31 +252,31 @@ private: TVector<ui32> KeyTypes; }; - -class TDataShardSysTables : public TThrRefBase { - TDataShardSysTable Locks; - TDataShardSysTable Locks2; -public: + +class TDataShardSysTables : public TThrRefBase { + TDataShardSysTable Locks; + TDataShardSysTable Locks2; +public: TDataShardSysTables(TDataShard *self) - : Locks(TTableId(TSysTables::SysSchemeShard, TSysTables::SysTableLocks), self) - , Locks2(TTableId(TSysTables::SysSchemeShard, TSysTables::SysTableLocks2), self) - {} - + : Locks(TTableId(TSysTables::SysSchemeShard, TSysTables::SysTableLocks), self) + , Locks2(TTableId(TSysTables::SysSchemeShard, TSysTables::SysTableLocks2), self) + {} + const TDataShardSysTable& Get(const TTableId& tableId) const { if (tableId.PathId.LocalPathId == TSysTables::SysTableLocks2) - return Locks2; - + return Locks2; + if (tableId.PathId.LocalPathId == TSysTables::SysTableLocks) - return Locks; - - Y_FAIL("unexpected sys table id"); - } -}; - + return Locks; + + Y_FAIL("unexpected sys table id"); + } +}; + TIntrusivePtr<TThrRefBase> InitDataShardSysTables(TDataShard* self) { - return new TDataShardSysTables(self); -} - + return new TDataShardSysTables(self); +} + /// class TDataShardEngineHost : public TEngineHost { public: @@ -348,7 +348,7 @@ public: bool IsValidKey(TKeyDesc& key, std::pair<ui64, ui64>& maxSnapshotTime) const override { if (TSysTables::IsSystemTable(key.TableId)) - return DataShardSysTable(key.TableId).IsValidKey(key); + return DataShardSysTable(key.TableId).IsValidKey(key); // prevent updates/erases with LockTxId set if (LockTxId && key.RowOperation != TKeyDesc::ERowOperation::Read) { @@ -363,7 +363,7 @@ public: const THolderFactory& holderFactory) override { if (TSysTables::IsSystemTable(tableId)) { - return DataShardSysTable(tableId).SelectRow(row, columnIds, returnType, readTarget, holderFactory); + return DataShardSysTable(tableId).SelectRow(row, columnIds, returnType, readTarget, holderFactory); } Self->SysLocksTable().SetLock(tableId, row, LockTxId); @@ -388,59 +388,59 @@ public: void UpdateRow(const TTableId& tableId, const TArrayRef<const TCell>& row, const TArrayRef<const TUpdateCommand>& commands) override { if (TSysTables::IsSystemTable(tableId)) { - DataShardSysTable(tableId).UpdateRow(row, commands); + DataShardSysTable(tableId).UpdateRow(row, commands); return; } Self->SysLocksTable().BreakLock(tableId, row); Self->SetTableUpdateTime(tableId, Now); - // apply special columns if declared - TUserTable::TSpecialUpdate specUpdates = Self->SpecialUpdates(DB, tableId); - if (specUpdates.HasUpdates) { - TStackVec<TUpdateCommand> extendedCmds; - extendedCmds.reserve(commands.size() + 3); - for (const TUpdateCommand& cmd : commands) { - if (cmd.Column == specUpdates.ColIdTablet) - specUpdates.ColIdTablet = Max<ui32>(); - else if (cmd.Column == specUpdates.ColIdEpoch) - specUpdates.ColIdEpoch = Max<ui32>(); - else if (cmd.Column == specUpdates.ColIdUpdateNo) - specUpdates.ColIdUpdateNo = Max<ui32>(); - - extendedCmds.push_back(cmd); - } - - if (specUpdates.ColIdTablet != Max<ui32>()) { - extendedCmds.emplace_back(TUpdateCommand{ - specUpdates.ColIdTablet, TKeyDesc::EColumnOperation::Set, EInplaceUpdateMode::Unknown, - TCell::Make<ui64>(specUpdates.Tablet) - }); + // apply special columns if declared + TUserTable::TSpecialUpdate specUpdates = Self->SpecialUpdates(DB, tableId); + if (specUpdates.HasUpdates) { + TStackVec<TUpdateCommand> extendedCmds; + extendedCmds.reserve(commands.size() + 3); + for (const TUpdateCommand& cmd : commands) { + if (cmd.Column == specUpdates.ColIdTablet) + specUpdates.ColIdTablet = Max<ui32>(); + else if (cmd.Column == specUpdates.ColIdEpoch) + specUpdates.ColIdEpoch = Max<ui32>(); + else if (cmd.Column == specUpdates.ColIdUpdateNo) + specUpdates.ColIdUpdateNo = Max<ui32>(); + + extendedCmds.push_back(cmd); + } + + if (specUpdates.ColIdTablet != Max<ui32>()) { + extendedCmds.emplace_back(TUpdateCommand{ + specUpdates.ColIdTablet, TKeyDesc::EColumnOperation::Set, EInplaceUpdateMode::Unknown, + TCell::Make<ui64>(specUpdates.Tablet) + }); } - - if (specUpdates.ColIdEpoch != Max<ui32>()) { - extendedCmds.emplace_back(TUpdateCommand{ - specUpdates.ColIdEpoch, TKeyDesc::EColumnOperation::Set, EInplaceUpdateMode::Unknown, - TCell::Make<ui64>(specUpdates.Epoch) - }); - } - - if (specUpdates.ColIdUpdateNo != Max<ui32>()) { - extendedCmds.emplace_back(TUpdateCommand{ - specUpdates.ColIdUpdateNo, TKeyDesc::EColumnOperation::Set, EInplaceUpdateMode::Unknown, - TCell::Make<ui64>(specUpdates.UpdateNo) - }); - } - - TEngineHost::UpdateRow(tableId, row, {extendedCmds.data(), extendedCmds.size()}); - } else { - TEngineHost::UpdateRow(tableId, row, commands); + + if (specUpdates.ColIdEpoch != Max<ui32>()) { + extendedCmds.emplace_back(TUpdateCommand{ + specUpdates.ColIdEpoch, TKeyDesc::EColumnOperation::Set, EInplaceUpdateMode::Unknown, + TCell::Make<ui64>(specUpdates.Epoch) + }); + } + + if (specUpdates.ColIdUpdateNo != Max<ui32>()) { + extendedCmds.emplace_back(TUpdateCommand{ + specUpdates.ColIdUpdateNo, TKeyDesc::EColumnOperation::Set, EInplaceUpdateMode::Unknown, + TCell::Make<ui64>(specUpdates.UpdateNo) + }); + } + + TEngineHost::UpdateRow(tableId, row, {extendedCmds.data(), extendedCmds.size()}); + } else { + TEngineHost::UpdateRow(tableId, row, commands); } } void EraseRow(const TTableId& tableId, const TArrayRef<const TCell>& row) override { if (TSysTables::IsSystemTable(tableId)) { - DataShardSysTable(tableId).EraseRow(row); + DataShardSysTable(tableId).EraseRow(row); return; } @@ -453,7 +453,7 @@ public: // Returns whether row belong this shard. bool IsMyKey(const TTableId& tableId, const TArrayRef<const TCell>& row) const override { if (TSysTables::IsSystemTable(tableId)) - return DataShardSysTable(tableId).IsMyKey(row); + return DataShardSysTable(tableId).IsMyKey(row); auto iter = Self->TableInfos.find(tableId.PathId.LocalPathId); if (iter == Self->TableInfos.end()) { @@ -493,9 +493,9 @@ public: private: const TDataShardSysTable& DataShardSysTable(const TTableId& tableId) const { - return static_cast<const TDataShardSysTables *>(Self->GetDataShardSysTables())->Get(tableId); - } - + return static_cast<const TDataShardSysTables *>(Self->GetDataShardSysTables())->Get(tableId); + } + TDataShard* Self; NTable::TDatabase& DB; const ui64& LockTxId; diff --git a/ydb/core/tx/datashard/datashard__engine_host.h b/ydb/core/tx/datashard/datashard__engine_host.h index 4c2c2bab06..8e3064c83d 100644 --- a/ydb/core/tx/datashard/datashard__engine_host.h +++ b/ydb/core/tx/datashard/datashard__engine_host.h @@ -21,7 +21,7 @@ namespace NDataShard { class TDataShard; TIntrusivePtr<TThrRefBase> InitDataShardSysTables(TDataShard* self); - + /// class TEngineBay : TNonCopyable { public: diff --git a/ydb/core/tx/datashard/datashard__init.cpp b/ydb/core/tx/datashard/datashard__init.cpp index 1009a615c7..dc12c49959 100644 --- a/ydb/core/tx/datashard/datashard__init.cpp +++ b/ydb/core/tx/datashard/datashard__init.cpp @@ -73,8 +73,8 @@ void TDataShard::TTxInit::Complete(const TActorContext &ctx) { Self->SendRegistrationRequestTimeCast(ctx); // InReadSets table might have a lot of garbage due to old bug. - // Run transaction to collect if shard is not going offline. - if (Self->State != TShardState::Offline && Self->State != TShardState::PreOffline) + // Run transaction to collect if shard is not going offline. + if (Self->State != TShardState::Offline && Self->State != TShardState::PreOffline) Self->Execute(Self->CreateTxCheckInReadSets(), ctx); // Tables created with older SchemeShard versions don't have diff --git a/ydb/core/tx/datashard/datashard__op_rows.cpp b/ydb/core/tx/datashard/datashard__op_rows.cpp index 93a0ae3877..3b3c9d9d6f 100644 --- a/ydb/core/tx/datashard/datashard__op_rows.cpp +++ b/ydb/core/tx/datashard/datashard__op_rows.cpp @@ -1,5 +1,5 @@ #include "datashard_impl.h" -#include "datashard_direct_transaction.h" +#include "datashard_direct_transaction.h" namespace NKikimr { namespace NDataShard { @@ -10,9 +10,9 @@ template <typename TEvRequest> class TTxDirectBase : public TTransactionBase<TDataShard> { TEvRequest Ev; - TOperation::TPtr Op; - TVector<EExecutionUnitKind> CompleteList; - + TOperation::TPtr Op; + TVector<EExecutionUnitKind> CompleteList; + public: TTxDirectBase(TDataShard* ds, TEvRequest ev) : TBase(ds) @@ -25,26 +25,26 @@ public: << ": at tablet# " << Self->TabletID()); if (Self->IsFollower()) { - return true; // TODO: report error + return true; // TODO: report error } - if (Ev) { - const ui64 tieBreaker = Self->NextTieBreakerIndex++; - Op = new TDirectTransaction(tieBreaker, ctx.Now(), tieBreaker, Ev); - Op->BuildExecutionPlan(false); - Self->Pipeline.GetExecutionUnit(Op->GetCurrentUnit()).AddOperation(Op); + if (Ev) { + const ui64 tieBreaker = Self->NextTieBreakerIndex++; + Op = new TDirectTransaction(tieBreaker, ctx.Now(), tieBreaker, Ev); + Op->BuildExecutionPlan(false); + Self->Pipeline.GetExecutionUnit(Op->GetCurrentUnit()).AddOperation(Op); - Ev = nullptr; + Ev = nullptr; } - auto status = Self->Pipeline.RunExecutionPlan(Op, CompleteList, txc, ctx); - if (!CompleteList.empty()) { + auto status = Self->Pipeline.RunExecutionPlan(Op, CompleteList, txc, ctx); + if (!CompleteList.empty()) { + return true; + } else if (status == EExecutionStatus::Restart) { + return false; + } else { + Op = nullptr; return true; - } else if (status == EExecutionStatus::Restart) { - return false; - } else { - Op = nullptr; - return true; } } @@ -52,9 +52,9 @@ public: LOG_INFO_S(ctx, NKikimrServices::TX_DATASHARD, "TTxDirectBase(" << GetTxType() << ") Complete" << ": at tablet# " << Self->TabletID()); - Self->Pipeline.RunCompleteList(Op, CompleteList, ctx); + Self->Pipeline.RunCompleteList(Op, CompleteList, ctx); if (Self->Pipeline.CanRunAnotherOp()) { - Self->PlanQueue.Progress(ctx); + Self->PlanQueue.Progress(ctx); } } diff --git a/ydb/core/tx/datashard/datashard__propose_tx_base.cpp b/ydb/core/tx/datashard/datashard__propose_tx_base.cpp index 44014f9ada..7dfb1a294e 100644 --- a/ydb/core/tx/datashard/datashard__propose_tx_base.cpp +++ b/ydb/core/tx/datashard/datashard__propose_tx_base.cpp @@ -169,7 +169,7 @@ void TDataShard::TTxProposeTransactionBase::Complete(const TActorContext &ctx) { Op->SetDelayedCommitTime(commitTime); Self->Pipeline.RunCompleteList(Op, CompleteList, ctx); - } + } Op->DecrementInProgress(); if (!Op->IsInProgress() && !Op->IsExecutionPlanFinished()) diff --git a/ydb/core/tx/datashard/datashard__schema_changed.cpp b/ydb/core/tx/datashard/datashard__schema_changed.cpp index 9cd0ea46fd..3d6b2a31cb 100644 --- a/ydb/core/tx/datashard/datashard__schema_changed.cpp +++ b/ydb/core/tx/datashard/datashard__schema_changed.cpp @@ -27,7 +27,7 @@ public: } void Complete(const TActorContext& ctx) override { - NTabletPipe::CloseAndForgetClient(Self->SelfId(), Self->SchemeShardPipe); + NTabletPipe::CloseAndForgetClient(Self->SelfId(), Self->SchemeShardPipe); Self->CheckStateChange(ctx); } diff --git a/ydb/core/tx/datashard/datashard_common_upload.cpp b/ydb/core/tx/datashard/datashard_common_upload.cpp index 862565e9b4..088da2b521 100644 --- a/ydb/core/tx/datashard/datashard_common_upload.cpp +++ b/ydb/core/tx/datashard/datashard_common_upload.cpp @@ -1,17 +1,17 @@ #include "change_collector.h" #include "datashard_common_upload.h" - -namespace NKikimr { + +namespace NKikimr { namespace NDataShard { - + template <typename TEvRequest, typename TEvResponse> TCommonUploadOps<TEvRequest, TEvResponse>::TCommonUploadOps(typename TEvRequest::TPtr& ev, bool breakLocks, bool collectChanges) : BreakLocks(breakLocks) , CollectChanges(collectChanges) , Ev(ev) -{ -} - +{ +} + template <typename TEvRequest, typename TEvResponse> bool TCommonUploadOps<TEvRequest, TEvResponse>::Execute(TDataShard* self, TTransactionContext& txc, const TRowVersion& readVersion, const TRowVersion& writeVersion) @@ -19,7 +19,7 @@ bool TCommonUploadOps<TEvRequest, TEvResponse>::Execute(TDataShard* self, TTrans const auto& record = Ev->Get()->Record; Result = MakeHolder<TEvResponse>(self->TabletID()); - + TInstant deadline = TInstant::MilliSeconds(record.GetCancelDeadlineMs()); if (deadline && deadline < AppData()->TimeProvider->Now()) { SetError(NKikimrTxDataShard::TError::EXECUTION_CANCELLED, "Deadline exceeded"); @@ -29,31 +29,31 @@ bool TCommonUploadOps<TEvRequest, TEvResponse>::Execute(TDataShard* self, TTrans const ui64 tableId = record.GetTableId(); const TTableId fullTableId(self->GetPathOwnerId(), tableId); const ui64 localTableId = self->GetLocalTableId(fullTableId); - if (localTableId == 0) { - SetError(NKikimrTxDataShard::TError::SCHEME_ERROR, Sprintf("Unknown table id %" PRIu64, tableId)); + if (localTableId == 0) { + SetError(NKikimrTxDataShard::TError::SCHEME_ERROR, Sprintf("Unknown table id %" PRIu64, tableId)); return true; - } + } const ui64 shadowTableId = self->GetShadowTableId(fullTableId); - + const TUserTable& tableInfo = *self->GetUserTables().at(tableId); /// ... find - Y_VERIFY(tableInfo.LocalTid == localTableId); + Y_VERIFY(tableInfo.LocalTid == localTableId); Y_VERIFY(tableInfo.ShadowTid == shadowTableId); - - // Check schemas + + // Check schemas if (record.GetRowScheme().KeyColumnIdsSize() != tableInfo.KeyColumnIds.size()) { - SetError(NKikimrTxDataShard::TError::SCHEME_ERROR, - Sprintf("Key column count mismatch: got %" PRIu64 ", expected %" PRIu64, + SetError(NKikimrTxDataShard::TError::SCHEME_ERROR, + Sprintf("Key column count mismatch: got %" PRIu64 ", expected %" PRIu64, record.GetRowScheme().KeyColumnIdsSize(), tableInfo.KeyColumnIds.size())); return true; - } - - for (size_t i = 0; i < tableInfo.KeyColumnIds.size(); ++i) { + } + + for (size_t i = 0; i < tableInfo.KeyColumnIds.size(); ++i) { if (record.GetRowScheme().GetKeyColumnIds(i) != tableInfo.KeyColumnIds[i]) { - SetError(NKikimrTxDataShard::TError::SCHEME_ERROR, Sprintf("Key column schema at position %" PRISZT, i)); + SetError(NKikimrTxDataShard::TError::SCHEME_ERROR, Sprintf("Key column schema at position %" PRISZT, i)); return true; - } - } - + } + } + const bool writeToTableShadow = record.GetWriteToTableShadow(); const bool readForTableShadow = writeToTableShadow && !shadowTableId; const ui32 writeTableId = writeToTableShadow && shadowTableId ? shadowTableId : localTableId; @@ -66,9 +66,9 @@ bool TCommonUploadOps<TEvRequest, TEvResponse>::Execute(TDataShard* self, TTrans } } - // Prepare (id, Type) vector for value columns + // Prepare (id, Type) vector for value columns TVector<NTable::TTag> tagsForSelect; - TVector<std::pair<ui32, NScheme::TTypeId>> valueCols; + TVector<std::pair<ui32, NScheme::TTypeId>> valueCols; for (const auto& colId : record.GetRowScheme().GetValueColumnIds()) { if (readForTableShadow) { tagsForSelect.push_back(colId); @@ -79,36 +79,36 @@ bool TCommonUploadOps<TEvRequest, TEvResponse>::Execute(TDataShard* self, TTrans return true; } valueCols.emplace_back(colId, col->Type); - } - - TVector<TRawTypeValue> key; - TVector<NTable::TUpdateOp> value; - - TSerializedCellVec keyCells; - TSerializedCellVec valueCells; - + } + + TVector<TRawTypeValue> key; + TVector<NTable::TUpdateOp> value; + + TSerializedCellVec keyCells; + TSerializedCellVec valueCells; + bool pageFault = false; NTable::TRowState rowState; - ui64 bytes = 0; + ui64 bytes = 0; for (const auto& r : record.GetRows()) { - // TODO: use safe parsing! - keyCells.Parse(r.GetKeyColumns()); - valueCells.Parse(r.GetValueColumns()); - - bytes += keyCells.GetBuffer().size() + valueCells.GetBuffer().size(); - - if (keyCells.GetCells().size() != tableInfo.KeyColumnTypes.size() || - valueCells.GetCells().size() != valueCols.size()) - { + // TODO: use safe parsing! + keyCells.Parse(r.GetKeyColumns()); + valueCells.Parse(r.GetValueColumns()); + + bytes += keyCells.GetBuffer().size() + valueCells.GetBuffer().size(); + + if (keyCells.GetCells().size() != tableInfo.KeyColumnTypes.size() || + valueCells.GetCells().size() != valueCols.size()) + { SetError(NKikimrTxDataShard::TError::SCHEME_ERROR, "Cell count doesn't match row scheme"); return true; - } - - key.clear(); - size_t ki = 0; + } + + key.clear(); + size_t ki = 0; ui64 keyBytes = 0; - for (const auto& kt : tableInfo.KeyColumnTypes) { + for (const auto& kt : tableInfo.KeyColumnTypes) { const TCell& c = keyCells.GetCells()[ki]; if (kt == NScheme::NTypeIds::Uint8 && !c.IsNull() && c.AsValue<ui8>() > 127) { SetError(NKikimrTxDataShard::TError::BAD_ARGUMENT, "Keys with Uint8 column values >127 are currently prohibited"); @@ -117,9 +117,9 @@ bool TCommonUploadOps<TEvRequest, TEvResponse>::Execute(TDataShard* self, TTrans keyBytes += c.Size(); key.emplace_back(TRawTypeValue(c.AsRef(), kt)); - ++ki; - } - + ++ki; + } + if (keyBytes > NLimits::MaxWriteKeySize) { SetError(NKikimrTxDataShard::TError::BAD_ARGUMENT, Sprintf("Row key size of %" PRISZT " bytes is larger than the allowed threshold %" PRIu64, @@ -145,9 +145,9 @@ bool TCommonUploadOps<TEvRequest, TEvResponse>::Execute(TDataShard* self, TTrans } } - value.clear(); - size_t vi = 0; - for (const auto& vt : valueCols) { + value.clear(); + size_t vi = 0; + for (const auto& vt : valueCols) { if (valueCells.GetCells()[vi].Size() > NLimits::MaxWriteValueSize) { SetError(NKikimrTxDataShard::TError::BAD_ARGUMENT, Sprintf("Row cell size of %" PRISZT " bytes is larger than the allowed threshold %" PRIu64, @@ -164,9 +164,9 @@ bool TCommonUploadOps<TEvRequest, TEvResponse>::Execute(TDataShard* self, TTrans if (allowUpdate) { value.emplace_back(NTable::TUpdateOp(vt.first, NTable::ECellOp::Set, TRawTypeValue(valueCells.GetCells()[vi].AsRef(), vt.second))); } - ++vi; - } - + ++vi; + } + if (readForTableShadow && rowState != NTable::ERowOp::Absent && value.empty()) { // We don't want to issue an Upsert when key already exists and there are no updates continue; @@ -191,8 +191,8 @@ bool TCommonUploadOps<TEvRequest, TEvResponse>::Execute(TDataShard* self, TTrans } txc.DB.Update(writeTableId, NTable::ERowOp::Upsert, key, value, writeVersion); - } - + } + if (pageFault) { if (ChangeCollector) { ChangeCollector->Reset(); @@ -202,12 +202,12 @@ bool TCommonUploadOps<TEvRequest, TEvResponse>::Execute(TDataShard* self, TTrans } self->IncCounter(COUNTER_UPLOAD_ROWS, record.GetRows().size()); - self->IncCounter(COUNTER_UPLOAD_ROWS_BYTES, bytes); - - tableInfo.Stats.UpdateTime = TAppData::TimeProvider->Now(); + self->IncCounter(COUNTER_UPLOAD_ROWS_BYTES, bytes); + + tableInfo.Stats.UpdateTime = TAppData::TimeProvider->Now(); return true; -} - +} + template <typename TEvRequest, typename TEvResponse> void TCommonUploadOps<TEvRequest, TEvResponse>::SendResult(TDataShard* self, const TActorContext& ctx) { Y_VERIFY(Result); @@ -219,8 +219,8 @@ void TCommonUploadOps<TEvRequest, TEvResponse>::SendResult(TDataShard* self, con } ctx.Send(Ev->Sender, std::move(Result)); -} - +} + template <typename TEvRequest, typename TEvResponse> TVector<NMiniKQL::IChangeCollector::TChange> TCommonUploadOps<TEvRequest, TEvResponse>::GetCollectedChanges() const { if (!ChangeCollector) { diff --git a/ydb/core/tx/datashard/datashard_direct_transaction.cpp b/ydb/core/tx/datashard/datashard_direct_transaction.cpp index 63615d08c8..145f0936cd 100644 --- a/ydb/core/tx/datashard/datashard_direct_transaction.cpp +++ b/ydb/core/tx/datashard/datashard_direct_transaction.cpp @@ -1,35 +1,35 @@ -#include "datashard_direct_transaction.h" +#include "datashard_direct_transaction.h" #include "datashard_direct_erase.h" #include "datashard_direct_upload.h" - -namespace NKikimr { + +namespace NKikimr { namespace NDataShard { - + TDirectTransaction::TDirectTransaction(ui64 txId, TInstant receivedAt, ui64 tieBreakerIndex, TEvDataShard::TEvUploadRowsRequest::TPtr& ev) : TOperation(TBasicOpInfo(txId, EOperationKind::DirectTx, Flags, 0, receivedAt, tieBreakerIndex)) , Impl(new TDirectTxUpload(ev)) { } - + TDirectTransaction::TDirectTransaction(ui64 txId, TInstant receivedAt, ui64 tieBreakerIndex, TEvDataShard::TEvEraseRowsRequest::TPtr& ev) : TOperation(TBasicOpInfo(txId, EOperationKind::DirectTx, Flags, 0, receivedAt, tieBreakerIndex)) , Impl(new TDirectTxErase(ev)) { } -void TDirectTransaction::BuildExecutionPlan(bool loaded) -{ - Y_VERIFY(GetExecutionPlan().empty()); - Y_VERIFY(!loaded); - - TVector<EExecutionUnitKind> plan; - plan.push_back(EExecutionUnitKind::BuildAndWaitDependencies); +void TDirectTransaction::BuildExecutionPlan(bool loaded) +{ + Y_VERIFY(GetExecutionPlan().empty()); + Y_VERIFY(!loaded); + + TVector<EExecutionUnitKind> plan; + plan.push_back(EExecutionUnitKind::BuildAndWaitDependencies); plan.push_back(EExecutionUnitKind::DirectOp); - plan.push_back(EExecutionUnitKind::CompletedOperations); - - RewriteExecutionPlan(plan); -} - + plan.push_back(EExecutionUnitKind::CompletedOperations); + + RewriteExecutionPlan(plan); +} + bool TDirectTransaction::Execute(TDataShard* self, TTransactionContext& txc) { auto [readVersion, writeVersion] = self->GetReadWriteVersions(); if (!Impl->Execute(self, txc, readVersion, writeVersion)) @@ -37,12 +37,12 @@ bool TDirectTransaction::Execute(TDataShard* self, TTransactionContext& txc) { self->PromoteCompleteEdge(writeVersion.Step, txc); return true; -} - +} + void TDirectTransaction::SendResult(TDataShard* self, const TActorContext& ctx) { Impl->SendResult(self, ctx); -} - +} + TVector<NMiniKQL::IChangeCollector::TChange> TDirectTransaction::GetCollectedChanges() const { return Impl->GetCollectedChanges(); } diff --git a/ydb/core/tx/datashard/datashard_direct_transaction.h b/ydb/core/tx/datashard/datashard_direct_transaction.h index 39dd6bfb57..5b42e1f1d7 100644 --- a/ydb/core/tx/datashard/datashard_direct_transaction.h +++ b/ydb/core/tx/datashard/datashard_direct_transaction.h @@ -1,42 +1,42 @@ -#pragma once - -#include "datashard_impl.h" -#include "datashard_locks.h" -#include "operation.h" - +#pragma once + +#include "datashard_impl.h" +#include "datashard_locks.h" +#include "operation.h" + #include <ydb/core/engine/minikql/change_collector_iface.h> #include <ydb/core/tx/tx_processing.h> #include <ydb/core/tablet_flat/flat_cxx_database.h> - -namespace NKikimr { + +namespace NKikimr { namespace NDataShard { - + class IDirectTx { -public: +public: virtual ~IDirectTx() = default; virtual bool Execute(TDataShard* self, TTransactionContext& txc, const TRowVersion& readVersion, const TRowVersion& writeVersion) = 0; virtual void SendResult(TDataShard* self, const TActorContext& ctx) = 0; virtual TVector<NMiniKQL::IChangeCollector::TChange> GetCollectedChanges() const = 0; }; - + class TDirectTransaction : public TOperation { -public: +public: TDirectTransaction(ui64 txId, TInstant receivedAt, ui64 tieBreakerIndex, TEvDataShard::TEvUploadRowsRequest::TPtr& ev); TDirectTransaction(ui64 txId, TInstant receivedAt, ui64 tieBreakerIndex, TEvDataShard::TEvEraseRowsRequest::TPtr& ev); - - void BuildExecutionPlan(bool) override; - -private: + + void BuildExecutionPlan(bool) override; + +private: bool Execute(TDataShard* self, TTransactionContext& txc); void SendResult(TDataShard* self, const TActorContext& ctx); TVector<NMiniKQL::IChangeCollector::TChange> GetCollectedChanges() const; - + friend class TDirectOpUnit; - + private: THolder<IDirectTx> Impl; static constexpr ui32 Flags = NTxDataShard::TTxFlags::Immediate | NTxDataShard::TTxFlags::GlobalWriter; -}; - +}; + } // NDataShard } // NKikimr diff --git a/ydb/core/tx/datashard/datashard_direct_upload.cpp b/ydb/core/tx/datashard/datashard_direct_upload.cpp index fb8a3eb6de..6173c0e218 100644 --- a/ydb/core/tx/datashard/datashard_direct_upload.cpp +++ b/ydb/core/tx/datashard/datashard_direct_upload.cpp @@ -1,8 +1,8 @@ #include "datashard_direct_upload.h" - -namespace NKikimr { + +namespace NKikimr { namespace NDataShard { - + TDirectTxUpload::TDirectTxUpload(TEvDataShard::TEvUploadRowsRequest::TPtr& ev) : TCommonUploadOps(ev, true, true) { @@ -10,12 +10,12 @@ TDirectTxUpload::TDirectTxUpload(TEvDataShard::TEvUploadRowsRequest::TPtr& ev) bool TDirectTxUpload::Execute(TDataShard* self, TTransactionContext& txc, const TRowVersion& readVersion, const TRowVersion& writeVersion) { return TCommonUploadOps::Execute(self, txc, readVersion, writeVersion); -} - +} + void TDirectTxUpload::SendResult(TDataShard* self, const TActorContext& ctx) { TCommonUploadOps::SendResult(self, ctx); -} - +} + TVector<NMiniKQL::IChangeCollector::TChange> TDirectTxUpload::GetCollectedChanges() const { return TCommonUploadOps::GetCollectedChanges(); } diff --git a/ydb/core/tx/datashard/datashard_impl.h b/ydb/core/tx/datashard/datashard_impl.h index b49b70beb5..11313474f8 100644 --- a/ydb/core/tx/datashard/datashard_impl.h +++ b/ydb/core/tx/datashard/datashard_impl.h @@ -567,7 +567,7 @@ class TDataShard using TColumns = TableColumns<SrcTabletId>; }; - // Additional tx artifacts which can be reused on tx restart. + // Additional tx artifacts which can be reused on tx restart. struct TxArtifacts : Table<12> { struct TxId : Column<1, NScheme::NTypeIds::Uint64> {}; // Specify which tx artifacts have been stored to local DB and can be @@ -1016,7 +1016,7 @@ class TDataShard void OnStopGuardComplete(const TActorContext &ctx); void OnTabletDead(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext &ctx) override; void OnActivateExecutor(const TActorContext &ctx) override; - + void Cleanup(const TActorContext &ctx); void SwitchToWork(const TActorContext &ctx); void SyncConfig(); @@ -1044,15 +1044,15 @@ class TDataShard bool CheckMediatorAuthorisation(ui64 mediatorId); - NTabletFlatExecutor::ITransaction* CreateTxInit(); - NTabletFlatExecutor::ITransaction* CreateTxInitSchema(); + NTabletFlatExecutor::ITransaction* CreateTxInit(); + NTabletFlatExecutor::ITransaction* CreateTxInitSchema(); NTabletFlatExecutor::ITransaction* CreateTxInitSchemaDefaults(); - NTabletFlatExecutor::ITransaction* CreateTxSchemaChanged(TEvDataShard::TEvSchemaChangedResult::TPtr& ev); - NTabletFlatExecutor::ITransaction* CreateTxStartSplit(); - NTabletFlatExecutor::ITransaction* CreateTxSplitSnapshotComplete(TIntrusivePtr<TSplitSnapshotContext> snapContext); - NTabletFlatExecutor::ITransaction* CreateTxInitiateBorrowedPartsReturn(); - NTabletFlatExecutor::ITransaction* CreateTxCheckInReadSets(); - NTabletFlatExecutor::ITransaction* CreateTxRemoveOldInReadSets(); + NTabletFlatExecutor::ITransaction* CreateTxSchemaChanged(TEvDataShard::TEvSchemaChangedResult::TPtr& ev); + NTabletFlatExecutor::ITransaction* CreateTxStartSplit(); + NTabletFlatExecutor::ITransaction* CreateTxSplitSnapshotComplete(TIntrusivePtr<TSplitSnapshotContext> snapContext); + NTabletFlatExecutor::ITransaction* CreateTxInitiateBorrowedPartsReturn(); + NTabletFlatExecutor::ITransaction* CreateTxCheckInReadSets(); + NTabletFlatExecutor::ITransaction* CreateTxRemoveOldInReadSets(); NTabletFlatExecutor::ITransaction* CreateTxExecuteMvccStateChange(); TReadWriteVersions GetLocalReadWriteVersions() const; @@ -1252,11 +1252,11 @@ public: void SnapshotComplete(TIntrusivePtr<NTabletFlatExecutor::TTableSnapshotContext> snapContext, const TActorContext &ctx) override; void CompactionComplete(ui32 tableId, const TActorContext &ctx) override; - void CompletedLoansChanged(const TActorContext &ctx) override; + void CompletedLoansChanged(const TActorContext &ctx) override; void ReplyCompactionWaiters(ui32 tableId, ui64 edge, const TActorContext &ctx); - TUserTable::TSpecialUpdate SpecialUpdates(const NTable::TDatabase& db, const TTableId& tableId) const; + TUserTable::TSpecialUpdate SpecialUpdates(const NTable::TDatabase& db, const TTableId& tableId) const; void SetTableAccessTime(const TTableId& tableId, TInstant ts); void SetTableUpdateTime(const TTableId& tableId, TInstant ts); @@ -1397,7 +1397,7 @@ public: static void PersistSchemeTxResult(NIceDb::TNiceDb &db, const TSchemaOperation& op); void NotifySchemeshard(const TActorContext& ctx, ui64 txId = 0); - TThrRefBase* GetDataShardSysTables() { return DataShardSysTables.Get(); } + TThrRefBase* GetDataShardSysTables() { return DataShardSysTables.Get(); } TSnapshotManager& GetSnapshotManager() { return SnapshotManager; } const TSnapshotManager& GetSnapshotManager() const { return SnapshotManager; } @@ -1994,7 +1994,7 @@ private: // Set of InRS keys to remove from local DB. THashSet<TReadSetKey> InRSToRemove; - TIntrusivePtr<TThrRefBase> DataShardSysTables; + TIntrusivePtr<TThrRefBase> DataShardSysTables; // Simple volatile counter ui64 NextTieBreakerIndex = 1; @@ -2118,10 +2118,10 @@ protected: HFuncTraced(TEvMediatorTimecast::TEvRegisterTabletResult, Handle); HFuncTraced(TEvents::TEvPoisonPill, Handle); default: - if (!HandleDefaultEvents(ev, ctx)) { + if (!HandleDefaultEvents(ev, ctx)) { LOG_WARN_S(ctx, NKikimrServices::TX_DATASHARD, "TDataShard::StateInactive unhandled event type: " << ev->GetTypeRewrite() << " event: " << (ev->HasEvent() ? ev->GetBase()->ToString().data() : "serialized?")); - } + } break; } } @@ -2228,11 +2228,11 @@ protected: fFunc(TEvDataShard::EvReplicationSourceOffsetsAck, HandleByReplicationSourceOffsetsServer); fFunc(TEvDataShard::EvReplicationSourceOffsetsCancel, HandleByReplicationSourceOffsetsServer); default: - if (!HandleDefaultEvents(ev, ctx)) { + if (!HandleDefaultEvents(ev, ctx)) { LOG_WARN_S(ctx, NKikimrServices::TX_DATASHARD, "TDataShard::StateWork unhandled event type: "<< ev->GetTypeRewrite() << " event: " << (ev->HasEvent() ? ev->GetBase()->ToString().data() : "serialized?")); - } + } break; } } @@ -2273,11 +2273,11 @@ protected: } void Die(const TActorContext &ctx) override { - NTabletPipe::CloseAndForgetClient(SelfId(), SchemeShardPipe); - NTabletPipe::CloseAndForgetClient(SelfId(), StateReportPipe); - NTabletPipe::CloseAndForgetClient(SelfId(), DbStatsReportPipe); - NTabletPipe::CloseAndForgetClient(SelfId(), TableResolvePipe); - + NTabletPipe::CloseAndForgetClient(SelfId(), SchemeShardPipe); + NTabletPipe::CloseAndForgetClient(SelfId(), StateReportPipe); + NTabletPipe::CloseAndForgetClient(SelfId(), DbStatsReportPipe); + NTabletPipe::CloseAndForgetClient(SelfId(), TableResolvePipe); + if (ReplicationSourceOffsetsServer) { InvokeOtherActor(*ReplicationSourceOffsetsServer, &TReplicationSourceOffsetsServer::PassAway); } diff --git a/ydb/core/tx/datashard/datashard_pipeline.cpp b/ydb/core/tx/datashard/datashard_pipeline.cpp index eddd7abcca..3498162c17 100644 --- a/ydb/core/tx/datashard/datashard_pipeline.cpp +++ b/ydb/core/tx/datashard/datashard_pipeline.cpp @@ -14,21 +14,21 @@ namespace NDataShard { #define LOAD_SYS_UI64(db, row, value) if (!TDataShard::SysGetUi64(db, row, value)) return false; TPipeline::TPipeline(TDataShard * self) - : Self(self) + : Self(self) , DepTracker(self) , ActivePlannedOpsLogicallyCompleteEnd(ActivePlannedOps.end()) , ActivePlannedOpsLogicallyIncompleteEnd(ActivePlannedOps.end()) - , LastPlannedTx(0, 0) - , LastCompleteTx(0, 0) - , UtmostCompleteTx(0, 0) - , KeepSchemaStep(0) - , LastCleanupTime(0) - , SchemaTx(nullptr) -{ - for (ui32 i = 0; i < static_cast<ui32>(EExecutionUnitKind::Count); ++i) - ExecutionUnits[i] = CreateExecutionUnit(static_cast<EExecutionUnitKind>(i), *Self, *this); -} - + , LastPlannedTx(0, 0) + , LastCompleteTx(0, 0) + , UtmostCompleteTx(0, 0) + , KeepSchemaStep(0) + , LastCleanupTime(0) + , SchemaTx(nullptr) +{ + for (ui32 i = 0; i < static_cast<ui32>(EExecutionUnitKind::Count); ++i) + ExecutionUnits[i] = CreateExecutionUnit(static_cast<EExecutionUnitKind>(i), *Self, *this); +} + TPipeline::~TPipeline() { for (auto &pr : ActiveOps) { @@ -754,7 +754,7 @@ void TPipeline::RemoveInReadSets(TOperation::TPtr op, } void TPipeline::RemoveTx(TStepOrder stepTxId) { - // Optimization: faster Alter. Do not wait if no TxInFly. + // Optimization: faster Alter. Do not wait if no TxInFly. // Can't persist KeepSchemaStep here. TxInFly must be restored on init. if (Self->TransQueue.TxInFly() == 0) { KeepSchemaStep = LastPlannedTx.Step; @@ -861,7 +861,7 @@ void TPipeline::SaveLastPlannedTx(NIceDb::TNiceDb& db, TStepOrder stepTxId) { Self->PersistSys(db, Schema::Sys_LastPlannedTx, LastPlannedTx.TxId); } -void TPipeline::CompleteTx(const TOperation::TPtr op, TTransactionContext& txc, const TActorContext &ctx) { +void TPipeline::CompleteTx(const TOperation::TPtr op, TTransactionContext& txc, const TActorContext &ctx) { NIceDb::TNiceDb db(txc.DB); using Schema = TDataShard::Schema; @@ -890,7 +890,7 @@ void TPipeline::CompleteTx(const TOperation::TPtr op, TTransactionContext& txc, while (!DelayedAcks.empty() && DelayedAcks.begin()->first.Step <= OutdatedReadSetStep()) - { + { auto &pr = *DelayedAcks.begin(); LOG_NOTICE(ctx, NKikimrServices::TX_DATASHARD, @@ -948,7 +948,7 @@ ui64 TPipeline::OutdatedCleanupStep() const return LastPlannedTx.Step; } -ui64 TPipeline::GetTxCompleteLag(EOperationKind kind, ui64 timecastStep) const +ui64 TPipeline::GetTxCompleteLag(EOperationKind kind, ui64 timecastStep) const { auto &plan = Self->TransQueue.GetPlan(kind); if (plan.empty()) @@ -961,18 +961,18 @@ ui64 TPipeline::GetTxCompleteLag(EOperationKind kind, ui64 timecastStep) const return 0; } -ui64 TPipeline::GetDataTxCompleteLag(ui64 timecastStep) const +ui64 TPipeline::GetDataTxCompleteLag(ui64 timecastStep) const +{ + return GetTxCompleteLag(EOperationKind::DataTx, timecastStep); +} + +ui64 TPipeline::GetScanTxCompleteLag(ui64 timecastStep) const { - return GetTxCompleteLag(EOperationKind::DataTx, timecastStep); -} - -ui64 TPipeline::GetScanTxCompleteLag(ui64 timecastStep) const -{ - return GetTxCompleteLag(EOperationKind::ReadTable, timecastStep); -} - + return GetTxCompleteLag(EOperationKind::ReadTable, timecastStep); +} + void TPipeline::ProposeTx(TOperation::TPtr op, const TStringBuf &txBody, TTransactionContext &txc, const TActorContext &ctx) -{ +{ NIceDb::TNiceDb db(txc.DB); SetProposed(op->GetTxId(), op->GetTarget()); PreserveSchema(db, op->GetMaxStep()); @@ -1098,13 +1098,13 @@ void TPipeline::SaveForPropose(TValidatedDataTx::TPtr tx) { } void TPipeline::SetProposed(ui64 txId, const TActorId& actorId) { - auto it = DataTxCache.find(txId); - if (it != DataTxCache.end()) { - it->second->SetSource(actorId); - } -} - - + auto it = DataTxCache.find(txId); + if (it != DataTxCache.end()) { + it->second->SetSource(actorId); + } +} + + void TPipeline::ForgetUnproposedTx(ui64 txId) { auto it = DataTxCache.find(txId); if (it != DataTxCache.end() && !it->second->IsProposed()) { @@ -1326,7 +1326,7 @@ TOperation::TPtr TPipeline::BuildOperation(TEvDataShard::TEvProposeTransaction:: return tx; } -void TPipeline::BuildDataTx(TActiveTransaction *tx, TTransactionContext &txc, const TActorContext &ctx) +void TPipeline::BuildDataTx(TActiveTransaction *tx, TTransactionContext &txc, const TActorContext &ctx) { auto dataTx = tx->BuildDataTx(Self, txc, ctx); Y_VERIFY(dataTx->Ready()); @@ -1336,7 +1336,7 @@ void TPipeline::BuildDataTx(TActiveTransaction *tx, TTransactionContext &txc, co dataTx->ExtractKeys(false); } -EExecutionStatus TPipeline::RunExecutionUnit(TOperation::TPtr op, TTransactionContext &txc, const TActorContext &ctx) +EExecutionStatus TPipeline::RunExecutionUnit(TOperation::TPtr op, TTransactionContext &txc, const TActorContext &ctx) { Y_VERIFY(!op->IsExecutionPlanFinished()); auto &unit = GetExecutionUnit(op->GetCurrentUnit()); diff --git a/ydb/core/tx/datashard/datashard_pipeline.h b/ydb/core/tx/datashard/datashard_pipeline.h index 9053c3ef86..67c35260b2 100644 --- a/ydb/core/tx/datashard/datashard_pipeline.h +++ b/ydb/core/tx/datashard/datashard_pipeline.h @@ -118,15 +118,15 @@ public: TOperation::TPtr GetNextActiveOp(bool dryRun); bool IsReadyOp(TOperation::TPtr op); - bool LoadTxDetails(TTransactionContext &txc, const TActorContext &ctx, TActiveTransaction::TPtr tx); + bool LoadTxDetails(TTransactionContext &txc, const TActorContext &ctx, TActiveTransaction::TPtr tx); - void DeactivateOp(TOperation::TPtr op, TTransactionContext& txc, const TActorContext &ctx); + void DeactivateOp(TOperation::TPtr op, TTransactionContext& txc, const TActorContext &ctx); void RemoveTx(TStepOrder stepTxId); const TSchemaOperation* FindSchemaTx(ui64 txId) const; void CompleteSchemaTx(NIceDb::TNiceDb& db, ui64 txId); void MarkOpAsUsingSnapshot(TOperation::TPtr op); - bool PlanTxs(ui64 step, TVector<ui64> &txIds, TTransactionContext &txc, const TActorContext &ctx); + bool PlanTxs(ui64 step, TVector<ui64> &txIds, TTransactionContext &txc, const TActorContext &ctx); void PreserveSchema(NIceDb::TNiceDb& db, ui64 step); TDuration CleanupTimeout() const; ECleanupStatus Cleanup(NIceDb::TNiceDb& db, const TActorContext& ctx); @@ -144,9 +144,9 @@ public: TStepOrder GetLastCompleteTx() const { return LastCompleteTx; } TStepOrder GetUtmostCompleteTx() const { return UtmostCompleteTx; } - ui64 GetTxCompleteLag(EOperationKind kind, ui64 timecastStep) const; - ui64 GetDataTxCompleteLag(ui64 timecastStep) const; - ui64 GetScanTxCompleteLag(ui64 timecastStep) const; + ui64 GetTxCompleteLag(EOperationKind kind, ui64 timecastStep) const; + ui64 GetDataTxCompleteLag(ui64 timecastStep) const; + ui64 GetScanTxCompleteLag(ui64 timecastStep) const; // schema ops @@ -463,7 +463,7 @@ private: bool GetPlannedTx(NIceDb::TNiceDb& db, ui64& step, ui64& txId); void SaveLastPlannedTx(NIceDb::TNiceDb& db, TStepOrder stepTxId); - void CompleteTx(TOperation::TPtr op, TTransactionContext &txc, const TActorContext &ctx); + void CompleteTx(TOperation::TPtr op, TTransactionContext &txc, const TActorContext &ctx); void PersistConfig(NIceDb::TNiceDb& db); void MoveToNextUnit(TOperation::TPtr op); diff --git a/ydb/core/tx/datashard/datashard_split_src.cpp b/ydb/core/tx/datashard/datashard_split_src.cpp index cf9cb87c45..a7349fc9cf 100644 --- a/ydb/core/tx/datashard/datashard_split_src.cpp +++ b/ydb/core/tx/datashard/datashard_split_src.cpp @@ -242,7 +242,7 @@ public: // Build snapshot data of all tables for each destination shard for (ui32 i = 0; i < Self->SrcSplitDescription->DestinationRangesSize(); ++i) { const auto& dstRangeDescr = Self->SrcSplitDescription->GetDestinationRanges(i); - const ui64 dstTablet = dstRangeDescr.GetTabletID(); + const ui64 dstTablet = dstRangeDescr.GetTabletID(); TAutoPtr<NKikimrTxDataShard::TEvSplitTransferSnapshot> snapshot = new NKikimrTxDataShard::TEvSplitTransferSnapshot; snapshot->SetSrcTabletId(Self->TabletID()); @@ -284,10 +284,10 @@ public: } // Apply dst range to user table - snapBody = Self->Executor()->BorrowSnapshot(localTableId, *SnapContext, from, to, dstTablet); + snapBody = Self->Executor()->BorrowSnapshot(localTableId, *SnapContext, from, to, dstTablet); } else { // Transfer full contents of system table - snapBody = Self->Executor()->BorrowSnapshot(localTableId, *SnapContext, {}, {}, dstTablet); + snapBody = Self->Executor()->BorrowSnapshot(localTableId, *SnapContext, {}, {}, dstTablet); } if (snapBody.empty()) { diff --git a/ydb/core/tx/datashard/datashard_user_table.cpp b/ydb/core/tx/datashard/datashard_user_table.cpp index c8e8653788..70bc940073 100644 --- a/ydb/core/tx/datashard/datashard_user_table.cpp +++ b/ydb/core/tx/datashard/datashard_user_table.cpp @@ -260,11 +260,11 @@ void TUserTable::ParseProto(const NKikimrSchemeOp::TTableDescription& descr) descr.GetPartitionRangeBeginIsInclusive(), descr.GetPartitionRangeEndIsInclusive()); } - + TableSchemaVersion = descr.GetTableSchemaVersion(); IsBackup = descr.GetIsBackup(); - CheckSpecialColumns(); + CheckSpecialColumns(); for (const auto& indexDesc : descr.GetTableIndexes()) { Y_VERIFY(indexDesc.HasPathOwnerId() && indexDesc.HasLocalPathId()); @@ -278,27 +278,27 @@ void TUserTable::ParseProto(const NKikimrSchemeOp::TTableDescription& descr) } } -void TUserTable::CheckSpecialColumns() { - SpecialColTablet = Max<ui32>(); - SpecialColEpoch = Max<ui32>(); - SpecialColUpdateNo = Max<ui32>(); - - for (const auto &xpair : Columns) { - const ui32 colId = xpair.first; - const auto &column = xpair.second; - - if (column.IsKey || column.Type != NScheme::NTypeIds::Uint64) - continue; - - if (column.Name == "__tablet") - SpecialColTablet = colId; - else if (column.Name == "__updateEpoch") - SpecialColEpoch = colId; - else if (column.Name == "__updateNo") - SpecialColUpdateNo = colId; - } -} - +void TUserTable::CheckSpecialColumns() { + SpecialColTablet = Max<ui32>(); + SpecialColEpoch = Max<ui32>(); + SpecialColUpdateNo = Max<ui32>(); + + for (const auto &xpair : Columns) { + const ui32 colId = xpair.first; + const auto &column = xpair.second; + + if (column.IsKey || column.Type != NScheme::NTypeIds::Uint64) + continue; + + if (column.Name == "__tablet") + SpecialColTablet = colId; + else if (column.Name == "__updateEpoch") + SpecialColEpoch = colId; + else if (column.Name == "__updateNo") + SpecialColUpdateNo = colId; + } +} + void TUserTable::AlterSchema() { NKikimrSchemeOp::TTableDescription schema; GetSchema(schema); diff --git a/ydb/core/tx/datashard/datashard_user_table.h b/ydb/core/tx/datashard/datashard_user_table.h index 6d25b3386e..0dab30cb84 100644 --- a/ydb/core/tx/datashard/datashard_user_table.h +++ b/ydb/core/tx/datashard/datashard_user_table.h @@ -330,19 +330,19 @@ struct TUserTable : public TThrRefBase { } }; - struct TSpecialUpdate { - bool HasUpdates = false; - - ui32 ColIdTablet = Max<ui32>(); - ui32 ColIdEpoch = Max<ui32>(); - ui32 ColIdUpdateNo = Max<ui32>(); - + struct TSpecialUpdate { + bool HasUpdates = false; + + ui32 ColIdTablet = Max<ui32>(); + ui32 ColIdEpoch = Max<ui32>(); + ui32 ColIdUpdateNo = Max<ui32>(); + ui64 Tablet = 0; ui64 Epoch = 0; ui64 UpdateNo = 0; - }; - - ui32 LocalTid = Max<ui32>(); + }; + + ui32 LocalTid = Max<ui32>(); ui32 ShadowTid = 0; TString Name; TString Path; @@ -363,10 +363,10 @@ struct TUserTable : public TThrRefBase { mutable bool StatsUpdateInProgress = false; mutable bool StatsNeedUpdate = true; - ui32 SpecialColTablet = Max<ui32>(); - ui32 SpecialColEpoch = Max<ui32>(); - ui32 SpecialColUpdateNo = Max<ui32>(); - + ui32 SpecialColTablet = Max<ui32>(); + ui32 SpecialColEpoch = Max<ui32>(); + ui32 SpecialColUpdateNo = Max<ui32>(); + TUserTable() { } TUserTable(ui32 localTid, const NKikimrSchemeOp::TTableDescription& descr, ui32 shadowTid); // for create @@ -416,7 +416,7 @@ private: TString Schema; ui64 TableSchemaVersion = 0; - void CheckSpecialColumns(); + void CheckSpecialColumns(); void AlterSchema(); void ParseProto(const NKikimrSchemeOp::TTableDescription& descr); }; diff --git a/ydb/core/tx/datashard/datashard_ut_common.cpp b/ydb/core/tx/datashard/datashard_ut_common.cpp index 6bd42514bf..d754f7ad0e 100644 --- a/ydb/core/tx/datashard/datashard_ut_common.cpp +++ b/ydb/core/tx/datashard/datashard_ut_common.cpp @@ -43,7 +43,7 @@ void TTester::Setup(TTestActorRuntime& runtime, const TOptions& opts) { auto domain = TDomainsInfo::TDomain::ConstructDomainWithExplicitTabletIds( "dc-1", domainId, FAKE_SCHEMESHARD_TABLET_ID, - domainId, domainId, TVector<ui32>{domainId}, + domainId, domainId, TVector<ui32>{domainId}, domainId, TVector<ui32>{domainId}, planResolution, TVector<ui64>{TDomainsInfo::MakeTxCoordinatorIDFixed(domainId, 1)}, diff --git a/ydb/core/tx/datashard/defs.h b/ydb/core/tx/datashard/defs.h index 528e9d2456..5d005e7918 100644 --- a/ydb/core/tx/datashard/defs.h +++ b/ydb/core/tx/datashard/defs.h @@ -1,15 +1,15 @@ -#pragma once +#pragma once // unique tag to fix pragma once gcc glueing: ./ydb/core/tx/defs.h #include <ydb/core/base/defs.h> #include <ydb/core/base/events.h> #include <ydb/core/util/yverify_stream.h> - -namespace NKikimr { - -class TNoOpDestroy { -public: - template <typename T> - static inline void Destroy(const T &) noexcept {} -}; - -} + +namespace NKikimr { + +class TNoOpDestroy { +public: + template <typename T> + static inline void Destroy(const T &) noexcept {} +}; + +} diff --git a/ydb/core/tx/datashard/direct_tx_unit.cpp b/ydb/core/tx/datashard/direct_tx_unit.cpp index bf3112b8a9..1284b1f6ad 100644 --- a/ydb/core/tx/datashard/direct_tx_unit.cpp +++ b/ydb/core/tx/datashard/direct_tx_unit.cpp @@ -1,29 +1,29 @@ -#include "datashard_direct_transaction.h" +#include "datashard_direct_transaction.h" #include "datashard_pipeline.h" #include "execution_unit_ctors.h" #include "setup_sys_locks.h" - -namespace NKikimr { + +namespace NKikimr { namespace NDataShard { - + class TDirectOpUnit : public TExecutionUnit { -public: +public: TDirectOpUnit(TDataShard& self, TPipeline& pipeline) : TExecutionUnit(EExecutionUnitKind::DirectOp, true, self, pipeline) { } - + ~TDirectOpUnit() { } - + bool IsReadyToExecute(TOperation::TPtr op) const override { return !op->HasRuntimeConflicts(); - } - + } + EExecutionStatus Execute(TOperation::TPtr op, TTransactionContext& txc, const TActorContext& ctx) override { - Y_UNUSED(ctx); - + Y_UNUSED(ctx); + if (op->IsImmediate()) { // Every time we execute immediate transaction we may choose a new mvcc version op->MvccReadWriteVersion.reset(); @@ -33,7 +33,7 @@ public: TDirectTransaction* tx = dynamic_cast<TDirectTransaction*>(op.Get()); Y_VERIFY(tx != nullptr); - + if (!tx->Execute(&DataShard, txc)) { return EExecutionStatus::Restart; } @@ -49,8 +49,8 @@ public: Pipeline.AddCommittingOp(op); return EExecutionStatus::DelayCompleteNoMoreRestarts; - } - + } + void Complete(TOperation::TPtr op, const TActorContext& ctx) override { Pipeline.RemoveCommittingOp(op); DataShard.EnqueueChangeRecords(std::move(op->ChangeRecords())); @@ -59,13 +59,13 @@ public: Y_VERIFY(tx != nullptr); tx->SendResult(&DataShard, ctx); - } - + } + }; // TDirectOpUnit THolder<TExecutionUnit> CreateDirectOpUnit(TDataShard& self, TPipeline& pipeline) { return THolder(new TDirectOpUnit(self, pipeline)); -} - +} + } // NDataShard } // NKikimr diff --git a/ydb/core/tx/datashard/operation.h b/ydb/core/tx/datashard/operation.h index 9d81527bbd..0f4b713e91 100644 --- a/ydb/core/tx/datashard/operation.h +++ b/ydb/core/tx/datashard/operation.h @@ -104,7 +104,7 @@ enum class EOperationKind : ui32 { CommitWrites = NKikimrTxDataShard::ETransactionKind::TX_KIND_COMMIT_WRITES, // Values [100, inf) are used for internal kinds. - DirectTx = 101, + DirectTx = 101, }; class TBasicOpInfo { diff --git a/ydb/core/tx/datashard/progress_queue.h b/ydb/core/tx/datashard/progress_queue.h index 3a50a547cf..116ed33372 100644 --- a/ydb/core/tx/datashard/progress_queue.h +++ b/ydb/core/tx/datashard/progress_queue.h @@ -1,42 +1,42 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include <ydb/core/util/queue_oneone_inplace.h> - -namespace NKikimr { - -template <typename T, typename TDestruct, typename TEvent> -class TTxProgressQueue { - bool HasInFly; - TOneOneQueueInplace<T, 32> Queue; -public: - TTxProgressQueue() - : HasInFly(false) - {} - - ~TTxProgressQueue() { - while (T head = Queue.Pop()) - TDestruct::Destroy(head); - } - - void Progress(T x, const TActorContext &ctx) { - if (!HasInFly) { + +namespace NKikimr { + +template <typename T, typename TDestruct, typename TEvent> +class TTxProgressQueue { + bool HasInFly; + TOneOneQueueInplace<T, 32> Queue; +public: + TTxProgressQueue() + : HasInFly(false) + {} + + ~TTxProgressQueue() { + while (T head = Queue.Pop()) + TDestruct::Destroy(head); + } + + void Progress(T x, const TActorContext &ctx) { + if (!HasInFly) { Y_VERIFY_DEBUG(!Queue.Head()); - ctx.Send(ctx.SelfID, new TEvent(x)); - HasInFly = true; - } else { - Queue.Push(x); - } - } - - void Reset(const TActorContext &ctx) { + ctx.Send(ctx.SelfID, new TEvent(x)); + HasInFly = true; + } else { + Queue.Push(x); + } + } + + void Reset(const TActorContext &ctx) { Y_VERIFY_DEBUG(HasInFly); - if (T x = Queue.Pop()) - ctx.Send(ctx.SelfID, new TEvent(x)); - else - HasInFly = false; - } -}; - + if (T x = Queue.Pop()) + ctx.Send(ctx.SelfID, new TEvent(x)); + else + HasInFly = false; + } +}; + template <typename TEvent> class TTxProgressCountedScalarQueue { ui32 InFly; @@ -103,4 +103,4 @@ public: } }; -} +} diff --git a/ydb/core/tx/datashard/read_table_scan.cpp b/ydb/core/tx/datashard/read_table_scan.cpp index 86bf8aa4a1..63e94fde96 100644 --- a/ydb/core/tx/datashard/read_table_scan.cpp +++ b/ydb/core/tx/datashard/read_table_scan.cpp @@ -324,7 +324,7 @@ public: private: void Die(const TActorContext &ctx) override { - ctx.Send(TActivationContext::InterconnectProxy(Sink.NodeId()), + ctx.Send(TActivationContext::InterconnectProxy(Sink.NodeId()), new TEvents::TEvUnsubscribe()); TActor<TReadTableScan>::Die(ctx); diff --git a/ydb/core/tx/datashard/ya.make b/ydb/core/tx/datashard/ya.make index 19ead6c1d9..9c98e8e79b 100644 --- a/ydb/core/tx/datashard/ya.make +++ b/ydb/core/tx/datashard/ya.make @@ -86,8 +86,8 @@ SRCS( datashard_active_transaction.cpp datashard_active_transaction.h datashard_common_upload.cpp - datashard_direct_transaction.cpp - datashard_direct_transaction.h + datashard_direct_transaction.cpp + datashard_direct_transaction.h datashard_direct_erase.cpp datashard_direct_upload.cpp datashard_distributed_erase.cpp diff --git a/ydb/core/tx/mediator/execute_queue.cpp b/ydb/core/tx/mediator/execute_queue.cpp index 88710d58f2..07740e9f82 100644 --- a/ydb/core/tx/mediator/execute_queue.cpp +++ b/ydb/core/tx/mediator/execute_queue.cpp @@ -5,44 +5,44 @@ #include <library/cpp/actors/core/hfunc.h> #include <ydb/core/tx/time_cast/time_cast.h> -#include <util/generic/hash.h> -#include <util/string/builder.h> - -namespace NKikimr { -namespace NTxMediator { - - class TTxMediatorExecQueue : public TActor<TTxMediatorExecQueue> { - struct TBucket { +#include <util/generic/hash.h> +#include <util/string/builder.h> + +namespace NKikimr { +namespace NTxMediator { + + class TTxMediatorExecQueue : public TActor<TTxMediatorExecQueue> { + struct TBucket { TActorId ActiveActor; - }; - + }; + const TActorId Owner; - const ui64 MediatorId; - const ui64 HashRange; - + const ui64 MediatorId; + const ui64 HashRange; + TTimeCastBuckets BucketSelector; TVector<TBucket> Buckets; - + TBucket& SelectBucket(TTabletId tablet) { const ui32 bucketIdx = BucketSelector.Select(tablet); Y_VERIFY_DEBUG(bucketIdx < Buckets.size()); - return Buckets[bucketIdx]; - } - - template<typename TEv> + return Buckets[bucketIdx]; + } + + template<typename TEv> void SendStepToBucket(TTabletId tablet, TStepId step, TVector<TTx> &tx, const TActorContext &ctx) { - TBucket &bucket = SelectBucket(tablet); - Sort(tx.begin(), tx.end(), TTx::TCmpOrderId()); - - LOG_DEBUG(ctx, NKikimrServices::TX_MEDIATOR_PRIVATE, [&]() { - TStringBuilder ss; - ss << "Mediator exec queue [" << MediatorId << "], step# " << step << " for tablet [" << tablet << "]. TxIds:"; - for (const auto &x : tx) + TBucket &bucket = SelectBucket(tablet); + Sort(tx.begin(), tx.end(), TTx::TCmpOrderId()); + + LOG_DEBUG(ctx, NKikimrServices::TX_MEDIATOR_PRIVATE, [&]() { + TStringBuilder ss; + ss << "Mediator exec queue [" << MediatorId << "], step# " << step << " for tablet [" << tablet << "]. TxIds:"; + for (const auto &x : tx) ss << " txid# " << x.TxId; ss << " marker# M2"; return (TString)ss; - }()); - + }()); + LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_EXEC_QUEUE, "Actor# " << ctx.SelfID.ToString() << " MediatorId# " << MediatorId << " SEND Ev to# " << bucket.ActiveActor.ToString() << " step# " << step << " forTablet# " << tablet << [&]() { @@ -52,159 +52,159 @@ namespace NTxMediator { ss << " marker# M3"; return (TString)ss; }()); - ctx.Send(bucket.ActiveActor, new TEv(step, tablet, tx)); - } - + ctx.Send(bucket.ActiveActor, new TEv(step, tablet, tx)); + } + void Die(const TActorContext &ctx) override { - for (const TBucket &bucket : Buckets) - ctx.Send(bucket.ActiveActor, new TEvents::TEvPoisonPill()); - Buckets.clear(); - return TActor::Die(ctx); - } - - void Handle(TEvTxMediator::TEvCommitStep::TPtr &ev, const TActorContext &ctx) { - TEvTxMediator::TEvCommitStep *msg = ev->Get(); - TMediateStep *step = msg->MediateStep.Get(); - + for (const TBucket &bucket : Buckets) + ctx.Send(bucket.ActiveActor, new TEvents::TEvPoisonPill()); + Buckets.clear(); + return TActor::Die(ctx); + } + + void Handle(TEvTxMediator::TEvCommitStep::TPtr &ev, const TActorContext &ctx) { + TEvTxMediator::TEvCommitStep *msg = ev->Get(); + TMediateStep *step = msg->MediateStep.Get(); + const ui32 totalCoordinators = step->Steps.size(); - + LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_EXEC_QUEUE, "Actor# " << ctx.SelfID.ToString() << " MediatorId# " << MediatorId << " HANDLE TEvCommitStep " << step->ToString() << " marker# M1"); - for (ui32 i = 0; i != totalCoordinators; ++i) { - TCoordinatorStep &coord = *step->Steps[i]; - Sort(coord.TabletsToTransaction.begin(), coord.TabletsToTransaction.end(), TCoordinatorStep::TabletToTransactionCmp()); - } - - ui64 activeTablet = Max<ui64>(); - ui64 lookupTablet = Max<ui64>(); - + for (ui32 i = 0; i != totalCoordinators; ++i) { + TCoordinatorStep &coord = *step->Steps[i]; + Sort(coord.TabletsToTransaction.begin(), coord.TabletsToTransaction.end(), TCoordinatorStep::TabletToTransactionCmp()); + } + + ui64 activeTablet = Max<ui64>(); + ui64 lookupTablet = Max<ui64>(); + TVector<ui64> readPositions(totalCoordinators, 0); TVector<TTx> currentTx; - - do { - for (ui64 ci = 0; ci != totalCoordinators; ++ci) { - ui64 &readPos = readPositions[ci]; - TCoordinatorStep &coord = *step->Steps[ci]; - - const ui64 tttsize = coord.TabletsToTransaction.size(); - while (readPos < tttsize) { + + do { + for (ui64 ci = 0; ci != totalCoordinators; ++ci) { + ui64 &readPos = readPositions[ci]; + TCoordinatorStep &coord = *step->Steps[ci]; + + const ui64 tttsize = coord.TabletsToTransaction.size(); + while (readPos < tttsize) { const std::pair<TTabletId, std::size_t> &x = coord.TabletsToTransaction[readPos]; if (x.first != activeTablet) - break; - + break; + currentTx.emplace_back(coord.Transactions[x.second]); - ++readPos; - } - - if (readPos < tttsize) { + ++readPos; + } + + if (readPos < tttsize) { const std::pair<TTabletId, std::size_t> &x = coord.TabletsToTransaction[readPos]; if (x.first < lookupTablet) lookupTablet = x.first; - } - } - - if (activeTablet != Max<ui64>()) { - SendStepToBucket<TEvTxMediator::TEvCommitTabletStep>(activeTablet, step->To, currentTx, ctx); - } - - activeTablet = lookupTablet; - lookupTablet = Max<ui64>(); - currentTx.clear(); - } while (activeTablet != Max<ui64>()); - - for (const TBucket &bucket : Buckets) { + } + } + + if (activeTablet != Max<ui64>()) { + SendStepToBucket<TEvTxMediator::TEvCommitTabletStep>(activeTablet, step->To, currentTx, ctx); + } + + activeTablet = lookupTablet; + lookupTablet = Max<ui64>(); + currentTx.clear(); + } while (activeTablet != Max<ui64>()); + + for (const TBucket &bucket : Buckets) { LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_EXEC_QUEUE, "Actor# " << ctx.SelfID.ToString() << " MediatorId# " << MediatorId << " SEND TEvStepPlanComplete to# " << bucket.ActiveActor.ToString() << " bucket.ActiveActor step# " << step->To); - ctx.Send(bucket.ActiveActor, new TEvTxMediator::TEvStepPlanComplete(step->To)); - } - } - - void Handle(TEvTxMediator::TEvRequestLostAcks::TPtr &ev, const TActorContext &ctx) { - TEvTxMediator::TEvRequestLostAcks *msg = ev->Get(); - TCoordinatorStep *step = msg->CoordinatorStep.Get(); + ctx.Send(bucket.ActiveActor, new TEvTxMediator::TEvStepPlanComplete(step->To)); + } + } + + void Handle(TEvTxMediator::TEvRequestLostAcks::TPtr &ev, const TActorContext &ctx) { + TEvTxMediator::TEvRequestLostAcks *msg = ev->Get(); + TCoordinatorStep *step = msg->CoordinatorStep.Get(); const TActorId &ackTo = msg->AckTo; LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_EXEC_QUEUE, "Actor# " << ctx.SelfID.ToString() << " MediatorId# " << MediatorId << " HANDLE TEvRequestLostAcks " << step->ToString() << " AckTo# " << ackTo.ToString()); - - Sort(step->TabletsToTransaction.begin(), step->TabletsToTransaction.end(), TCoordinatorStep::TabletToTransactionCmp()); - + + Sort(step->TabletsToTransaction.begin(), step->TabletsToTransaction.end(), TCoordinatorStep::TabletToTransactionCmp()); + TVector<TTx> currentTx; TTabletId activeTablet = 0; - + for (TVector<std::pair<TTabletId, std::size_t>>::const_iterator it = step->TabletsToTransaction.begin(), end = step->TabletsToTransaction.end(); it != end; ++it) { if (activeTablet != it->first) { - if (activeTablet) + if (activeTablet) SendStepToBucket<TEvTxMediator::TEvOoOTabletStep>(activeTablet, step->Step, currentTx, ctx); activeTablet = it->first; - currentTx.clear(); - } - + currentTx.clear(); + } + currentTx.emplace_back(step->Transactions[it->second]); - currentTx.back().AckTo = ackTo; - } - - if (activeTablet) + currentTx.back().AckTo = ackTo; + } + + if (activeTablet) SendStepToBucket<TEvTxMediator::TEvOoOTabletStep>(activeTablet, step->Step, currentTx, ctx); - } - - void Handle(TEvMediatorTimecast::TEvWatch::TPtr &ev, const TActorContext &ctx) { - const NKikimrTxMediatorTimecast::TEvWatch &record = ev->Get()->Record; - // todo: check config coherence + } + + void Handle(TEvMediatorTimecast::TEvWatch::TPtr &ev, const TActorContext &ctx) { + const NKikimrTxMediatorTimecast::TEvWatch &record = ev->Get()->Record; + // todo: check config coherence const TActorId &sender = ev->Sender; LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_EXEC_QUEUE, "Actor# " << ctx.SelfID.ToString() << " MediatorId# " << MediatorId << " HANDLE TEvWatch"); - for (ui32 bucketIdx : record.GetBucket()) { + for (ui32 bucketIdx : record.GetBucket()) { LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_EXEC_QUEUE, "Actor# " << ctx.SelfID.ToString() << " MediatorId# " << MediatorId << " SEND TEvWatchBucket to# " << Buckets[bucketIdx].ActiveActor.ToString() << " bucket.ActiveActor"); - ctx.Send(Buckets[bucketIdx].ActiveActor, new TEvTxMediator::TEvWatchBucket(sender)); - } - } - - void Bootstrap(const TActorContext &ctx) { + ctx.Send(Buckets[bucketIdx].ActiveActor, new TEvTxMediator::TEvWatchBucket(sender)); + } + } + + void Bootstrap(const TActorContext &ctx) { Buckets.resize(BucketSelector.Buckets()); for (ui32 bucketIdx = 0; bucketIdx < Buckets.size(); ++bucketIdx) Buckets[bucketIdx].ActiveActor = ctx.ExecutorThread.RegisterActor(CreateTxMediatorTabletQueue(ctx.SelfID, MediatorId, 1, bucketIdx), TMailboxType::ReadAsFilled); - } - - public: + } + + public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TX_MEDIATOR_ACTOR; } TTxMediatorExecQueue(const TActorId &owner, ui64 mediator, ui64 hashRange, ui32 timecastBuckets) - : TActor(&TThis::StateWork) - , Owner(owner) - , MediatorId(mediator) - , HashRange(hashRange) + : TActor(&TThis::StateWork) + , Owner(owner) + , MediatorId(mediator) + , HashRange(hashRange) , BucketSelector(timecastBuckets) { Y_UNUSED(HashRange); } - + TAutoPtr<IEventHandle> AfterRegister(const TActorId &self, const TActorId& parentId) override { Y_UNUSED(parentId); - return new IEventHandle(self, self, new TEvents::TEvBootstrap()); - } - - STFUNC(StateWork) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvTxMediator::TEvCommitStep, Handle); - HFunc(TEvTxMediator::TEvRequestLostAcks, Handle); - HFunc(TEvMediatorTimecast::TEvWatch, Handle); - CFunc(TEvents::TSystem::PoisonPill, Die); - CFunc(TEvents::TSystem::Bootstrap, Bootstrap); - } - } - }; -} - + return new IEventHandle(self, self, new TEvents::TEvBootstrap()); + } + + STFUNC(StateWork) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvTxMediator::TEvCommitStep, Handle); + HFunc(TEvTxMediator::TEvRequestLostAcks, Handle); + HFunc(TEvMediatorTimecast::TEvWatch, Handle); + CFunc(TEvents::TSystem::PoisonPill, Die); + CFunc(TEvents::TSystem::Bootstrap, Bootstrap); + } + } + }; +} + IActor* CreateTxMediatorExecQueue(const TActorId &owner, ui64 mediator, ui64 hashRange, ui32 timecastBuckets) { return new NTxMediator::TTxMediatorExecQueue(owner, mediator, hashRange, timecastBuckets); -} - -} +} + +} diff --git a/ydb/core/tx/mediator/mediator.cpp b/ydb/core/tx/mediator/mediator.cpp index c4811cd0ff..0fbd44403c 100644 --- a/ydb/core/tx/mediator/mediator.cpp +++ b/ydb/core/tx/mediator/mediator.cpp @@ -1,41 +1,41 @@ #include "mediator.h" #include "mediator_impl.h" -#include <util/generic/intrlist.h> - -namespace NKikimr { -namespace NTxMediator { - - TCoordinatorStep::TCoordinatorStep(const NKikimrTx::TEvCoordinatorStep &record) - : Step(record.GetStep()) - , PrevStep(record.GetPrevStep()) - { +#include <util/generic/intrlist.h> + +namespace NKikimr { +namespace NTxMediator { + + TCoordinatorStep::TCoordinatorStep(const NKikimrTx::TEvCoordinatorStep &record) + : Step(record.GetStep()) + , PrevStep(record.GetPrevStep()) + { const std::size_t txsize = record.TransactionsSize(); - - // todo: save body as-is, without any processing - // and defer parsing and per-tablet mapping for latter stage, when we could merge all selected steps - // (for mediator exec queue, to split latency sensitive stuff from calculations) - - Transactions.reserve(txsize); - TabletsToTransaction.reserve(record.GetTotalTxAffectedEntries()); - + + // todo: save body as-is, without any processing + // and defer parsing and per-tablet mapping for latter stage, when we could merge all selected steps + // (for mediator exec queue, to split latency sensitive stuff from calculations) + + Transactions.reserve(txsize); + TabletsToTransaction.reserve(record.GetTotalTxAffectedEntries()); + for (std::size_t i = 0; i != txsize; ++i) { - const NKikimrTx::TCoordinatorTransaction &c = record.GetTransactions(i); - + const NKikimrTx::TCoordinatorTransaction &c = record.GetTransactions(i); + Transactions.emplace_back( - c.HasModerator() ? c.GetModerator() : 0, - c.GetTxId() + c.HasModerator() ? c.GetModerator() : 0, + c.GetTxId() ); - - for (ui32 tabi = 0, tabe = c.GetAffectedSet().size(); tabi != tabe; ++tabi) + + for (ui32 tabi = 0, tabe = c.GetAffectedSet().size(); tabi != tabe; ++tabi) TabletsToTransaction.emplace_back(c.GetAffectedSet(tabi), i); - } - } - -} - + } + } + +} + IActor* CreateTxMediator(const TActorId &tablet, TTabletStorageInfo *info) { - return new NTxMediator::TTxMediator(info, tablet); -} - -} + return new NTxMediator::TTxMediator(info, tablet); +} + +} diff --git a/ydb/core/tx/mediator/mediator__init.cpp b/ydb/core/tx/mediator/mediator__init.cpp index 13b5a8d5fb..51c566699c 100644 --- a/ydb/core/tx/mediator/mediator__init.cpp +++ b/ydb/core/tx/mediator/mediator__init.cpp @@ -93,7 +93,7 @@ struct TTxMediator::TTxInit : public TTransactionBase<TTxMediator> { } }; -ITransaction* TTxMediator::CreateTxInit() { +ITransaction* TTxMediator::CreateTxInit() { return new TTxMediator::TTxInit(this); } diff --git a/ydb/core/tx/mediator/mediator__schema.cpp b/ydb/core/tx/mediator/mediator__schema.cpp index d7f63562d7..8279ad5b05 100644 --- a/ydb/core/tx/mediator/mediator__schema.cpp +++ b/ydb/core/tx/mediator/mediator__schema.cpp @@ -25,7 +25,7 @@ struct TTxMediator::TTxSchema : public TTransactionBase<TTxMediator> { } }; -ITransaction* TTxMediator::CreateTxSchema() { +ITransaction* TTxMediator::CreateTxSchema() { return new TTxSchema(this); } diff --git a/ydb/core/tx/mediator/mediator__schema_upgrade.cpp b/ydb/core/tx/mediator/mediator__schema_upgrade.cpp index 5d40df6be7..7eb7228b86 100644 --- a/ydb/core/tx/mediator/mediator__schema_upgrade.cpp +++ b/ydb/core/tx/mediator/mediator__schema_upgrade.cpp @@ -56,7 +56,7 @@ struct TTxMediator::TTxUpgrade : public TTransactionBase<TTxMediator> { } }; -ITransaction* TTxMediator::CreateTxUpgrade() { +ITransaction* TTxMediator::CreateTxUpgrade() { return new TTxUpgrade(this); } diff --git a/ydb/core/tx/mediator/mediator_impl.h b/ydb/core/tx/mediator/mediator_impl.h index cbe080a886..c98bd4246b 100644 --- a/ydb/core/tx/mediator/mediator_impl.h +++ b/ydb/core/tx/mediator/mediator_impl.h @@ -1,5 +1,5 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include <ydb/core/base/appdata.h> #include <ydb/core/scheme_types/scheme_types.h> @@ -13,36 +13,36 @@ #include <ydb/core/base/tablet_pipe.h> #include <ydb/core/base/tx_processing.h> #include <ydb/core/tx/tx.h> - + #include <util/generic/map.h> -namespace NKikimr { +namespace NKikimr { namespace NTxMediator { - + using TStepId = ui64; using TTxId = ui64; using TTabletId = ui64; - struct TTx { - // transaction body - ui64 Moderator; + struct TTx { + // transaction body + ui64 Moderator; TTxId TxId; TActorId AckTo; - + TTx(ui64 moderator, TTxId txid) - : Moderator(moderator) - , TxId(txid) - , AckTo() // must be updated before commit + : Moderator(moderator) + , TxId(txid) + , AckTo() // must be updated before commit { Y_VERIFY(TxId != 0); } - - struct TCmpOrderId { + + struct TCmpOrderId { bool operator()(const TTx &left, const TTx &right) const noexcept { - return left.TxId < right.TxId; - } - }; + return left.TxId < right.TxId; + } + }; TString ToString() const { TStringStream str; @@ -52,23 +52,23 @@ namespace NTxMediator { str << "}"; return str.Str(); } - }; - - struct TCoordinatorStep { + }; + + struct TCoordinatorStep { const TStepId Step; const TStepId PrevStep; - + TVector<TTx> Transactions; - + TVector<std::pair<TTabletId, std::size_t>> TabletsToTransaction; // tablet -> tx index in Transactions - - struct TabletToTransactionCmp { + + struct TabletToTransactionCmp { bool operator()(const std::pair<TTabletId, std::size_t> &left, const std::pair<TTabletId, std::size_t> &right) const { - return left.first < right.first; - } - }; - - TCoordinatorStep(const NKikimrTx::TEvCoordinatorStep &record); + return left.first < right.first; + } + }; + + TCoordinatorStep(const NKikimrTx::TEvCoordinatorStep &record); TString ToString() const { TStringStream str; @@ -93,18 +93,18 @@ namespace NTxMediator { str << "}"; return str.Str(); } - }; - - struct TMediateStep { + }; + + struct TMediateStep { TStepId From; TStepId To; - + TVector<TAutoPtr<TCoordinatorStep>> Steps; - + TMediateStep(TStepId from, TStepId to) - : From(from) - , To(to) - {} + : From(from) + , To(to) + {} TString ToString() const { TStringStream str; @@ -120,34 +120,34 @@ namespace NTxMediator { str << "}"; return str.Str(); } - }; -} - -struct TEvTxMediator { + }; +} + +struct TEvTxMediator { using TTabletId = NTxMediator::TTabletId; using TStepId = NTxMediator::TStepId; - enum EEv { - EvCommitStep = EventSpaceBegin(TKikimrEvents::ES_TX_MEDIATOR), - EvRequestLostAcks, + enum EEv { + EvCommitStep = EventSpaceBegin(TKikimrEvents::ES_TX_MEDIATOR), + EvRequestLostAcks, EvMediatorConfiguration, - - EvCommitTabletStep = EvCommitStep + 1 * 512, - EvStepPlanComplete, - EvOoOTabletStep, - EvWatchBucket, - - EvEnd - }; - + + EvCommitTabletStep = EvCommitStep + 1 * 512, + EvStepPlanComplete, + EvOoOTabletStep, + EvWatchBucket, + + EvEnd + }; + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_TX_MEDIATOR), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_TX_MEDIATOR)"); - - struct TEvCommitStep : public TEventLocal<TEvCommitStep, EvCommitStep> { - TAutoPtr<NTxMediator::TMediateStep> MediateStep; - - TEvCommitStep(TAutoPtr<NTxMediator::TMediateStep> &mds) - : MediateStep(mds) - {} + + struct TEvCommitStep : public TEventLocal<TEvCommitStep, EvCommitStep> { + TAutoPtr<NTxMediator::TMediateStep> MediateStep; + + TEvCommitStep(TAutoPtr<NTxMediator::TMediateStep> &mds) + : MediateStep(mds) + {} TString ToString() const { TStringStream str; @@ -155,16 +155,16 @@ struct TEvTxMediator { str << "}"; return str.Str(); } - }; - - struct TEvRequestLostAcks : public TEventLocal<TEvRequestLostAcks, EvRequestLostAcks> { - TAutoPtr<NTxMediator::TCoordinatorStep> CoordinatorStep; + }; + + struct TEvRequestLostAcks : public TEventLocal<TEvRequestLostAcks, EvRequestLostAcks> { + TAutoPtr<NTxMediator::TCoordinatorStep> CoordinatorStep; const TActorId AckTo; - + TEvRequestLostAcks(TAutoPtr<NTxMediator::TCoordinatorStep> &cds, const TActorId &ackTo) - : CoordinatorStep(cds) - , AckTo(ackTo) - {} + : CoordinatorStep(cds) + , AckTo(ackTo) + {} TString ToString() const { TStringStream str; @@ -173,19 +173,19 @@ struct TEvTxMediator { str << "}"; return str.Str(); } - }; - - // just reschedule command, actual transport is over command queue - struct TEvCommitTabletStep : public TEventLocal<TEvCommitTabletStep, EvCommitTabletStep> { + }; + + // just reschedule command, actual transport is over command queue + struct TEvCommitTabletStep : public TEventLocal<TEvCommitTabletStep, EvCommitTabletStep> { const TStepId Step; const TTabletId TabletId; TVector<NTxMediator::TTx> Transactions; // todo: inplace placing - + TEvCommitTabletStep(TStepId step, TTabletId tabletId, TVector<NTxMediator::TTx> &transactions) - : Step(step) - , TabletId(tabletId) - , Transactions(transactions.begin(), transactions.end()) - {} + : Step(step) + , TabletId(tabletId) + , Transactions(transactions.begin(), transactions.end()) + {} TString ToString() const { TStringStream str; @@ -198,14 +198,14 @@ struct TEvTxMediator { str << "}}"; return str.Str(); } - }; - - struct TEvStepPlanComplete : public TEventLocal<TEvStepPlanComplete, EvStepPlanComplete> { + }; + + struct TEvStepPlanComplete : public TEventLocal<TEvStepPlanComplete, EvStepPlanComplete> { const TStepId Step; - + TEvStepPlanComplete(TStepId step) - : Step(step) - {} + : Step(step) + {} TString ToString() const { TStringStream str; @@ -213,18 +213,18 @@ struct TEvTxMediator { str << "}"; return str.Str(); } - }; - - struct TEvOoOTabletStep : public TEventLocal<TEvOoOTabletStep, EvOoOTabletStep> { + }; + + struct TEvOoOTabletStep : public TEventLocal<TEvOoOTabletStep, EvOoOTabletStep> { const TStepId Step; const TTabletId TabletId; TVector<NTxMediator::TTx> Transactions; - + TEvOoOTabletStep(TStepId step, TTabletId tabletId, TVector<NTxMediator::TTx> &transactions) - : Step(step) - , TabletId(tabletId) - , Transactions(transactions.begin(), transactions.end()) - {} + : Step(step) + , TabletId(tabletId) + , Transactions(transactions.begin(), transactions.end()) + {} TString ToString() const { TStringStream str; @@ -237,14 +237,14 @@ struct TEvTxMediator { str << "}}"; return str.Str(); } - }; - - struct TEvWatchBucket : public TEventLocal<TEvWatchBucket, EvWatchBucket> { + }; + + struct TEvWatchBucket : public TEventLocal<TEvWatchBucket, EvWatchBucket> { const TActorId Source; - + TEvWatchBucket(const TActorId &source) - : Source(source) - {} + : Source(source) + {} TString ToString() const { TStringStream str; @@ -252,14 +252,14 @@ struct TEvTxMediator { str << "}"; return str.Str(); } - }; + }; }; - + namespace NTxMediator { typedef ui64 TCoordinatorId; -using NTabletFlatExecutor::ITransaction; +using NTabletFlatExecutor::ITransaction; using NActors::TActorContext; class TTxMediator : public TActor<TTxMediator>, public NTabletFlatExecutor::TTabletExecutedFlat { @@ -308,10 +308,10 @@ class TTxMediator : public TActor<TTxMediator>, public NTabletFlatExecutor::TTab struct TTxSchema; struct TTxUpgrade; - ITransaction* CreateTxInit(); + ITransaction* CreateTxInit(); ITransaction* CreateTxConfigure(TActorId ackTo, ui64 version, const TVector<TCoordinatorId> &coordinators, ui32 timeCastBuckets); - ITransaction* CreateTxSchema(); - ITransaction* CreateTxUpgrade(); + ITransaction* CreateTxSchema(); + ITransaction* CreateTxUpgrade(); TConfig Config; @@ -411,10 +411,10 @@ public: IgnoreFunc(TEvTabletPipe::TEvServerDisconnected)) STFUNC_TABLET_IGN(StateBroken,) -}; +}; } - + IActor* CreateTxMediatorTabletQueue(const TActorId &owner, ui64 mediator, ui64 hashRange, ui64 hashBucket); IActor* CreateTxMediatorExecQueue(const TActorId &owner, ui64 mediator, ui64 hashRange, ui32 timecastBuckets); - -} + +} diff --git a/ydb/core/tx/mediator/tablet_queue.cpp b/ydb/core/tx/mediator/tablet_queue.cpp index ccf716fa81..b28179517c 100644 --- a/ydb/core/tx/mediator/tablet_queue.cpp +++ b/ydb/core/tx/mediator/tablet_queue.cpp @@ -12,186 +12,186 @@ #include <ydb/core/tx/time_cast/time_cast.h> #include <ydb/core/tablet/tablet_pipe_client_cache.h> -#include <util/string/builder.h> +#include <util/string/builder.h> #include <util/generic/hash_set.h> - -namespace NKikimr { -namespace NTxMediator { - -class TTxMediatorTabletQueue : public TActor<TTxMediatorTabletQueue> { - struct TStepEntry { + +namespace NKikimr { +namespace NTxMediator { + +class TTxMediatorTabletQueue : public TActor<TTxMediatorTabletQueue> { + struct TStepEntry { const TStepId Step; - ui64 RefCounter; - + ui64 RefCounter; + TStepEntry(TStepId step) - : Step(step) - , RefCounter(0) - {} - }; - - struct TTabletEntry { - enum EState { - StateInit, - StateConnect, - StateConnected, - }; - - struct TStep { - TStepEntry * const StepRef; + : Step(step) + , RefCounter(0) + {} + }; + + struct TTabletEntry { + enum EState { + StateInit, + StateConnect, + StateConnected, + }; + + struct TStep { + TStepEntry * const StepRef; TVector<TTx> Transactions; - - TStep(TStepEntry *stepRef) - : StepRef(stepRef) - {} - }; - + + TStep(TStepEntry *stepRef) + : StepRef(stepRef) + {} + }; + typedef TOneOneQueueInplace<TStep *, 32> TQueueType; - - EState State; + + EState State; TAutoPtr<TQueueType, TQueueType::TPtrCleanDestructor> Queue; TMap<TStepId, TVector<TTx>> OutOfOrder; // todo: replace TVector<> with chunked queue to conserve copying - - TTabletEntry() - : State(StateInit) + + TTabletEntry() + : State(StateInit) , Queue(new TQueueType()) - {} - - void MergeOutOfOrder(TStep *x); + {} + + void MergeOutOfOrder(TStep *x); void MergeToOutOfOrder(TStepId step, TVector<TTx> &update); - }; - + }; + const TActorId Owner; - const ui64 Mediator; - const ui64 HashRange; - const ui64 HashBucket; - + const ui64 Mediator; + const ui64 HashRange; + const ui64 HashBucket; + THashMap<TTabletId, TTabletEntry> PerTabletPlanQueue; // by tablet entries - - typedef TOneOneQueueInplace<TStepEntry *, 512> TStepCommitQueue; - TAutoPtr<TStepCommitQueue, TStepCommitQueue::TPtrCleanDestructor> StepCommitQueue; - - TAutoPtr<NTabletPipe::IClientCache> Pipes; - + + typedef TOneOneQueueInplace<TStepEntry *, 512> TStepCommitQueue; + TAutoPtr<TStepCommitQueue, TStepCommitQueue::TPtrCleanDestructor> StepCommitQueue; + + TAutoPtr<NTabletPipe::IClientCache> Pipes; + TStepId AcceptedStep; TStepId CommitedStep; - TStepEntry *ActiveStep; - + TStepEntry *ActiveStep; + THashSet<TActorId> TimecastWatches; - NMonitoring::TDynamicCounters::TCounterPtr TimecastLagCounter; - - void SendToTablet(TTabletEntry::TStep *tabletStep, ui64 tablet, const TActorContext &ctx) { + NMonitoring::TDynamicCounters::TCounterPtr TimecastLagCounter; + + void SendToTablet(TTabletEntry::TStep *tabletStep, ui64 tablet, const TActorContext &ctx) { auto evx = new TEvTxProcessing::TEvPlanStep(tabletStep->StepRef->Step, Mediator, tablet); evx->Record.MutableTransactions()->Reserve(tabletStep->Transactions.size()); - for (const TTx &tx : tabletStep->Transactions) { + for (const TTx &tx : tabletStep->Transactions) { NKikimrTx::TMediatorTransaction *x = evx->Record.AddTransactions(); - x->SetTxId(tx.TxId); - if (tx.Moderator) - x->SetModerator(tx.Moderator); + x->SetTxId(tx.TxId); + if (tx.Moderator) + x->SetModerator(tx.Moderator); ActorIdToProto(tx.AckTo, x->MutableAckTo()); LOG_DEBUG(ctx, NKikimrServices::TX_MEDIATOR_PRIVATE, "Send from %" PRIu64 " to tablet %" PRIu64 ", step# %" PRIu64 ", txid# %" PRIu64 ", marker M5" PRIu64, Mediator, tablet, tabletStep->StepRef->Step, tx.TxId); - } + } LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString() << " Mediator# " << Mediator << " SEND to# " << tablet << " " << evx->ToString()); - Pipes->Send(ctx, tablet, evx); - } - - void CheckStepHead(const TActorContext &ctx) { + Pipes->Send(ctx, tablet, evx); + } + + void CheckStepHead(const TActorContext &ctx) { Y_UNUSED(ctx); - - bool updateTimecast = false; - while (TStepEntry *sx = StepCommitQueue->Head()) { - if (sx->RefCounter != 0 || sx->Step > AcceptedStep) - break; - - updateTimecast = true; - CommitedStep = sx->Step; - delete StepCommitQueue->Pop(); - } - - if (updateTimecast) { - if (!TimecastLagCounter) + + bool updateTimecast = false; + while (TStepEntry *sx = StepCommitQueue->Head()) { + if (sx->RefCounter != 0 || sx->Step > AcceptedStep) + break; + + updateTimecast = true; + CommitedStep = sx->Step; + delete StepCommitQueue->Pop(); + } + + if (updateTimecast) { + if (!TimecastLagCounter) TimecastLagCounter = GetServiceCounters(AppData(ctx)->Counters, "processing")->GetSubgroup("mediator", ToString(Mediator))->GetSubgroup("sensor", "TimecastLag")->GetNamedCounter("Bucket", ToString(HashBucket)); - *TimecastLagCounter = (AcceptedStep - CommitedStep); - - TEvMediatorTimecast::TEvUpdate evx; - evx.Record.SetMediator(Mediator); - evx.Record.SetBucket(HashBucket); - evx.Record.SetTimeBarrier(CommitedStep); + *TimecastLagCounter = (AcceptedStep - CommitedStep); + + TEvMediatorTimecast::TEvUpdate evx; + evx.Record.SetMediator(Mediator); + evx.Record.SetBucket(HashBucket); + evx.Record.SetTimeBarrier(CommitedStep); TAllocChunkSerializer serializer; const bool success = evx.SerializeToArcadiaStream(&serializer); Y_VERIFY(success); TIntrusivePtr<TEventSerializedData> data = serializer.Release(evx.IsExtendedFormat()); - - // todo: we must throttle delivery - const ui32 sendFlags = IEventHandle::FlagTrackDelivery; + + // todo: we must throttle delivery + const ui32 sendFlags = IEventHandle::FlagTrackDelivery; for (const TActorId &x : TimecastWatches) { LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString() << " Mediator# " << Mediator << " SEND to# " << x.ToString() << " " << evx.ToString()); ctx.ExecutorThread.Send(new IEventHandle(TEvMediatorTimecast::TEvUpdate::EventType, sendFlags, x, ctx.SelfID, data, 0)); - } - } - } - - void Handle(TEvTxMediator::TEvCommitTabletStep::TPtr &ev, const TActorContext &ctx) { - TEvTxMediator::TEvCommitTabletStep *msg = ev->Get(); + } + } + } + + void Handle(TEvTxMediator::TEvCommitTabletStep::TPtr &ev, const TActorContext &ctx) { + TEvTxMediator::TEvCommitTabletStep *msg = ev->Get(); const TStepId step = msg->Step; const TTabletId tablet = msg->TabletId; - + LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString() << " Mediator# " << Mediator << " HANDLE " << msg->ToString() << " marker# M4"); - TTabletEntry &tabletEntry = PerTabletPlanQueue[tablet]; - if (!ActiveStep) { - ActiveStep = new TStepEntry(step); - StepCommitQueue->Push(ActiveStep); - } - + TTabletEntry &tabletEntry = PerTabletPlanQueue[tablet]; + if (!ActiveStep) { + ActiveStep = new TStepEntry(step); + StepCommitQueue->Push(ActiveStep); + } + Y_VERIFY(ActiveStep->Step == step); - ++ActiveStep->RefCounter; - - TTabletEntry::TStep *tabletStep = new TTabletEntry::TStep(ActiveStep); - tabletStep->Transactions.swap(msg->Transactions); - tabletEntry.Queue->Push(tabletStep); - - switch (tabletEntry.State) { - case TTabletEntry::StateInit: - Pipes->Prepare(ctx, tablet); - tabletEntry.State = TTabletEntry::StateConnect; - break; - case TTabletEntry::StateConnect: - break; - case TTabletEntry::StateConnected: - SendToTablet(tabletStep, tablet, ctx); - break; - } - } - - void Handle(TEvTxMediator::TEvOoOTabletStep::TPtr &ev, const TActorContext &ctx) { - TEvTxMediator::TEvOoOTabletStep *msg = ev->Get(); + ++ActiveStep->RefCounter; + + TTabletEntry::TStep *tabletStep = new TTabletEntry::TStep(ActiveStep); + tabletStep->Transactions.swap(msg->Transactions); + tabletEntry.Queue->Push(tabletStep); + + switch (tabletEntry.State) { + case TTabletEntry::StateInit: + Pipes->Prepare(ctx, tablet); + tabletEntry.State = TTabletEntry::StateConnect; + break; + case TTabletEntry::StateConnect: + break; + case TTabletEntry::StateConnected: + SendToTablet(tabletStep, tablet, ctx); + break; + } + } + + void Handle(TEvTxMediator::TEvOoOTabletStep::TPtr &ev, const TActorContext &ctx) { + TEvTxMediator::TEvOoOTabletStep *msg = ev->Get(); const TStepId step = msg->Step; const TTabletId tablet = msg->TabletId; LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString() << " Mediator# " << Mediator << " HANDLE " << msg->ToString()); - - TTabletEntry &tabletEntry = PerTabletPlanQueue[tablet]; - TTabletEntry::TStep *headStep = tabletEntry.Queue->Head(); - if (!headStep || headStep->StepRef->Step > step) { - AckOoO(tablet, step, msg->Transactions, ctx); // from already confirmed space, just reply right here - } else { // not yet confirmed, save for later use - tabletEntry.MergeToOutOfOrder(step, msg->Transactions); - } - } - - void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx) { - const TEvTabletPipe::TEvClientConnected *msg = ev->Get(); + + TTabletEntry &tabletEntry = PerTabletPlanQueue[tablet]; + TTabletEntry::TStep *headStep = tabletEntry.Queue->Head(); + if (!headStep || headStep->StepRef->Step > step) { + AckOoO(tablet, step, msg->Transactions, ctx); // from already confirmed space, just reply right here + } else { // not yet confirmed, save for later use + tabletEntry.MergeToOutOfOrder(step, msg->Transactions); + } + } + + void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx) { + const TEvTabletPipe::TEvClientConnected *msg = ev->Get(); const TTabletId tablet = msg->TabletId; LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString() << " Mediator# " << Mediator << " HANDLE " << msg->ToString()); - - TTabletEntry &tabletEntry = PerTabletPlanQueue[tablet]; + + TTabletEntry &tabletEntry = PerTabletPlanQueue[tablet]; Y_VERIFY(tabletEntry.State == TTabletEntry::StateConnect); - + if (!Pipes->OnConnect(ev)) { if (msg->Dead) { LOG_WARN_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString() @@ -207,9 +207,9 @@ class TTxMediatorTabletQueue : public TActor<TTxMediatorTabletQueue> { return; } - Pipes->Prepare(ctx, tablet); + Pipes->Prepare(ctx, tablet); return; - } + } tabletEntry.State = TTabletEntry::StateConnected; TTabletEntry::TQueueType::TReadIterator it = tabletEntry.Queue->Iterator(); @@ -217,111 +217,111 @@ class TTxMediatorTabletQueue : public TActor<TTxMediatorTabletQueue> { tabletEntry.MergeOutOfOrder(sx); SendToTablet(sx, tablet, ctx); } - } - - void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx) { - const TEvTabletPipe::TEvClientDestroyed *msg = ev->Get(); + } + + void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx) { + const TEvTabletPipe::TEvClientDestroyed *msg = ev->Get(); const TTabletId tablet = msg->TabletId; LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString() << " Mediator# " << Mediator << " HANDLE " << msg->ToString()); - + Pipes->OnDisconnect(ev); - - TTabletEntry &tabletEntry = PerTabletPlanQueue[tablet]; + + TTabletEntry &tabletEntry = PerTabletPlanQueue[tablet]; Y_VERIFY(tabletEntry.State == TTabletEntry::StateConnected); - - // if connect to tablet lost and tablet is in no use - just forget connection - if (tabletEntry.Queue->Head() == nullptr) { - PerTabletPlanQueue.erase(tablet); - } else { // if have smth in queue - request reconnect - Pipes->Prepare(ctx, tablet); - tabletEntry.State = TTabletEntry::StateConnect; - } - } - - void Handle(TEvTxMediator::TEvStepPlanComplete::TPtr &ev, const TActorContext &ctx) { - const TEvTxMediator::TEvStepPlanComplete *msg = ev->Get(); + + // if connect to tablet lost and tablet is in no use - just forget connection + if (tabletEntry.Queue->Head() == nullptr) { + PerTabletPlanQueue.erase(tablet); + } else { // if have smth in queue - request reconnect + Pipes->Prepare(ctx, tablet); + tabletEntry.State = TTabletEntry::StateConnect; + } + } + + void Handle(TEvTxMediator::TEvStepPlanComplete::TPtr &ev, const TActorContext &ctx) { + const TEvTxMediator::TEvStepPlanComplete *msg = ev->Get(); const TStepId step = msg->Step; LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString() << " Mediator# " << Mediator << " HANDLE " << msg->ToString()); - - if (ActiveStep) - ActiveStep = nullptr; - else - StepCommitQueue->Push(new TStepEntry(step)); - - AcceptedStep = step; - CheckStepHead(ctx); - } - - void Handle(TEvTxProcessing::TEvPlanStepAccepted::TPtr &ev, const TActorContext &ctx) { - const NKikimrTx::TEvPlanStepAccepted &record = ev->Get()->Record; + + if (ActiveStep) + ActiveStep = nullptr; + else + StepCommitQueue->Push(new TStepEntry(step)); + + AcceptedStep = step; + CheckStepHead(ctx); + } + + void Handle(TEvTxProcessing::TEvPlanStepAccepted::TPtr &ev, const TActorContext &ctx) { + const NKikimrTx::TEvPlanStepAccepted &record = ev->Get()->Record; const TTabletId tablet = record.GetTabletId(); const TStepId step = record.GetStep(); LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString() << " Mediator# " << Mediator << " HANDLE " << ev->Get()->ToString()); - - TTabletEntry *tabletEntry = PerTabletPlanQueue.FindPtr(tablet); - if (!tabletEntry) - return; - - TTabletEntry::TStep *headStep = tabletEntry->Queue->Head(); - if (!headStep) - return; - - // if non-head step confirmed - just skip and wait for head confirmation - if (headStep->StepRef->Step != step) - return; - - --headStep->StepRef->RefCounter; - delete tabletEntry->Queue->Pop(); - - // confirm out of order request (if any). - const auto ooIt = tabletEntry->OutOfOrder.find(step); - if (ooIt != tabletEntry->OutOfOrder.end()) { - AckOoO(tablet, step, ooIt->second, ctx); - tabletEntry->OutOfOrder.erase(ooIt); - } - - CheckStepHead(ctx); - } - - void Handle(TEvTxMediator::TEvWatchBucket::TPtr &ev, const TActorContext &ctx) { + + TTabletEntry *tabletEntry = PerTabletPlanQueue.FindPtr(tablet); + if (!tabletEntry) + return; + + TTabletEntry::TStep *headStep = tabletEntry->Queue->Head(); + if (!headStep) + return; + + // if non-head step confirmed - just skip and wait for head confirmation + if (headStep->StepRef->Step != step) + return; + + --headStep->StepRef->RefCounter; + delete tabletEntry->Queue->Pop(); + + // confirm out of order request (if any). + const auto ooIt = tabletEntry->OutOfOrder.find(step); + if (ooIt != tabletEntry->OutOfOrder.end()) { + AckOoO(tablet, step, ooIt->second, ctx); + tabletEntry->OutOfOrder.erase(ooIt); + } + + CheckStepHead(ctx); + } + + void Handle(TEvTxMediator::TEvWatchBucket::TPtr &ev, const TActorContext &ctx) { LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString() << " Mediator# " << Mediator << " HANDLE " << ev->Get()->ToString()); const TActorId &source = ev->Get()->Source; - TimecastWatches.insert(source); - } - - void Handle(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) { + TimecastWatches.insert(source); + } + + void Handle(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) { LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString() << " Mediator# " << Mediator << " HANDLE TEvUndelivered"); - // for now every non-delivery is reason to drop watch - TimecastWatches.erase(ev->Sender); - } - + // for now every non-delivery is reason to drop watch + TimecastWatches.erase(ev->Sender); + } + void AckOoO(TTabletId tablet, TStepId step, const TVector<TTx> &transactions, const TActorContext &ctx) { TMap<TActorId, TAutoPtr<TEvTxProcessing::TEvPlanStepAck>> acks; - for (const TTx &tx : transactions) { - TAutoPtr<TEvTxProcessing::TEvPlanStepAck> &ack = acks[tx.AckTo]; - if (!ack) - ack = new TEvTxProcessing::TEvPlanStepAck(tablet, step, (const ui64 *)nullptr, (const ui64 *)nullptr); - ack->Record.AddTxId(tx.TxId); - } - + for (const TTx &tx : transactions) { + TAutoPtr<TEvTxProcessing::TEvPlanStepAck> &ack = acks[tx.AckTo]; + if (!ack) + ack = new TEvTxProcessing::TEvPlanStepAck(tablet, step, (const ui64 *)nullptr, (const ui64 *)nullptr); + ack->Record.AddTxId(tx.TxId); + } + for (const auto &x : acks) { LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString() << " Mediator# " << Mediator << " SEND to# " << x.first.ToString() << " " << x.second->ToString()); - ctx.Send(x.first, x.second.Release()); + ctx.Send(x.first, x.second.Release()); } - } - - void Die(const TActorContext &ctx) override { - Pipes->Detach(ctx); - Pipes.Destroy(); - - TActor::Die(ctx); - } + } + + void Die(const TActorContext &ctx) override { + Pipes->Detach(ctx); + Pipes.Destroy(); + + TActor::Die(ctx); + } static NTabletPipe::TClientConfig GetPipeClientConfig() { NTabletPipe::TClientConfig config; @@ -335,41 +335,41 @@ class TTxMediatorTabletQueue : public TActor<TTxMediatorTabletQueue> { return config; } -public: +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TX_MEDIATOR_ACTOR; } TTxMediatorTabletQueue(const TActorId &owner, ui64 mediator, ui64 hashRange, ui64 hashBucket) - : TActor(&TThis::StateFunc) - , Owner(owner) - , Mediator(mediator) - , HashRange(hashRange) - , HashBucket(hashBucket) - , StepCommitQueue(new TStepCommitQueue()) + : TActor(&TThis::StateFunc) + , Owner(owner) + , Mediator(mediator) + , HashRange(hashRange) + , HashBucket(hashBucket) + , StepCommitQueue(new TStepCommitQueue()) , Pipes(NTabletPipe::CreateUnboundedClientCache(GetPipeClientConfig())) - , AcceptedStep(0) - , CommitedStep(0) - , ActiveStep(nullptr) + , AcceptedStep(0) + , CommitedStep(0) + , ActiveStep(nullptr) { Y_UNUSED(HashRange); } - - STFUNC(StateFunc) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvTxProcessing::TEvPlanStepAccepted, Handle); - HFunc(TEvTxMediator::TEvCommitTabletStep, Handle); - HFunc(TEvTxMediator::TEvStepPlanComplete, Handle); - HFunc(TEvTxMediator::TEvOoOTabletStep, Handle); - HFunc(TEvTxMediator::TEvWatchBucket, Handle); - HFunc(TEvTabletPipe::TEvClientConnected, Handle); - HFunc(TEvTabletPipe::TEvClientDestroyed, Handle); - HFunc(TEvents::TEvUndelivered, Handle); - CFunc(TEvents::TSystem::PoisonPill, Die); - } - } -}; - + + STFUNC(StateFunc) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvTxProcessing::TEvPlanStepAccepted, Handle); + HFunc(TEvTxMediator::TEvCommitTabletStep, Handle); + HFunc(TEvTxMediator::TEvStepPlanComplete, Handle); + HFunc(TEvTxMediator::TEvOoOTabletStep, Handle); + HFunc(TEvTxMediator::TEvWatchBucket, Handle); + HFunc(TEvTabletPipe::TEvClientConnected, Handle); + HFunc(TEvTabletPipe::TEvClientDestroyed, Handle); + HFunc(TEvents::TEvUndelivered, Handle); + CFunc(TEvents::TSystem::PoisonPill, Die); + } + } +}; + TString yvector2str(const TVector<TTx>& v) { TStringStream stream; stream << '{'; @@ -383,10 +383,10 @@ TString yvector2str(const TVector<TTx>& v) { } // -void TTxMediatorTabletQueue::TTabletEntry::MergeOutOfOrder(TStep *sx) { +void TTxMediatorTabletQueue::TTabletEntry::MergeOutOfOrder(TStep *sx) { const TStepId step = sx->StepRef->Step; - const auto ox = OutOfOrder.find(step); - if (ox != OutOfOrder.end()) { + const auto ox = OutOfOrder.find(step); + if (ox != OutOfOrder.end()) { const TVector<TTx> &o = ox->second; Y_VERIFY_DEBUG( IsSorted(sx->Transactions.begin(), sx->Transactions.end(), TTx::TCmpOrderId()), @@ -395,68 +395,68 @@ void TTxMediatorTabletQueue::TTabletEntry::MergeOutOfOrder(TStep *sx) { ); Y_VERIFY_DEBUG(IsSorted(o.begin(), o.end(), TTx::TCmpOrderId()), "%s", yvector2str(o).c_str()); // - // ok, now merge sorted arrays replacing ack-to + // ok, now merge sorted arrays replacing ack-to TVector<TTx>::iterator planIt = sx->Transactions.begin(); TVector<TTx>::iterator planEnd = sx->Transactions.end(); TVector<TTx>::const_iterator oooIt = o.begin(); TVector<TTx>::const_iterator oooEnd = o.end(); - while (oooIt != oooEnd && planIt != planEnd) { - if (planIt->TxId < oooIt->TxId) { - ++planIt; - } else if (planIt->TxId == oooIt->TxId) { - planIt->AckTo = oooIt->AckTo; - ++oooIt; - ++planIt; - } else { + while (oooIt != oooEnd && planIt != planEnd) { + if (planIt->TxId < oooIt->TxId) { + ++planIt; + } else if (planIt->TxId == oooIt->TxId) { + planIt->AckTo = oooIt->AckTo; + ++oooIt; + ++planIt; + } else { Y_FAIL("Inconsistency: Plan TxId %" PRIu64 " > OutOfOrder TxId %" PRIu64, planIt->TxId, oooIt->TxId); - } - } - OutOfOrder.erase(ox); - } -} - + } + } + OutOfOrder.erase(ox); + } +} + void TTxMediatorTabletQueue::TTabletEntry::MergeToOutOfOrder(TStepId step, TVector<TTx> &update) { TVector<TTx> ¤t = OutOfOrder[step]; - if (current.empty()) { - current.swap(update); - } else { + if (current.empty()) { + current.swap(update); + } else { TVector<TTx> old; - old.swap(current); + old.swap(current); Y_VERIFY_DEBUG(IsSorted(old.begin(), old.end(), TTx::TCmpOrderId()), "%s", yvector2str(old).c_str()); Y_VERIFY_DEBUG(IsSorted(update.begin(), update.end(), TTx::TCmpOrderId()), "%s", yvector2str(update).c_str()); // - // now merge old with update + // now merge old with update TVector<TTx>::const_iterator oldIt = old.begin(); TVector<TTx>::const_iterator oldEnd = old.end(); TVector<TTx>::const_iterator updIt = update.begin(); TVector<TTx>::const_iterator updEnd = update.end(); - - while (oldIt != oldEnd && updIt != updEnd) { + + while (oldIt != oldEnd && updIt != updEnd) { if (oldIt->TxId < updIt->TxId) { - current.push_back(*oldIt); - ++oldIt; + current.push_back(*oldIt); + ++oldIt; } else if (updIt->TxId < oldIt->TxId) { current.push_back(*updIt); - ++updIt; - } else { + ++updIt; + } else { current.push_back(*updIt); - ++updIt; - ++oldIt; - } - } - - // append tail - current.insert(current.end(), oldIt, oldEnd); - current.insert(current.end(), updIt, updEnd); + ++updIt; + ++oldIt; + } + } + + // append tail + current.insert(current.end(), oldIt, oldEnd); + current.insert(current.end(), updIt, updEnd); Y_VERIFY_DEBUG(IsSorted(current.begin(), current.end(), TTx::TCmpOrderId()), "%s", yvector2str(current).c_str()); // - } -} - -} - + } +} + +} + IActor* CreateTxMediatorTabletQueue(const TActorId &owner, ui64 mediator, ui64 hashRange, ui64 hashBucket) { - return new NTxMediator::TTxMediatorTabletQueue(owner, mediator, hashRange, hashBucket); -} - -} + return new NTxMediator::TTxMediatorTabletQueue(owner, mediator, hashRange, hashBucket); +} + +} diff --git a/ydb/core/tx/scheme_board/cache.cpp b/ydb/core/tx/scheme_board/cache.cpp index cf56cc17b9..8e778a4a1d 100644 --- a/ydb/core/tx/scheme_board/cache.cpp +++ b/ydb/core/tx/scheme_board/cache.cpp @@ -676,10 +676,10 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> { TableKind = TResolve::KindUnknown; Created = false; CreateStep = 0; - - // pathid is never changed (yet) so must be kept + + // pathid is never changed (yet) so must be kept AbandonedSchemeShardsIds.clear(); - + SecurityObject.Drop(); DomainInfo.Drop(); Attributes.clear(); @@ -687,9 +687,9 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> { ListNodeEntry.Drop(); IsPrivatePath = false; - - // virtual must be kept - + + // virtual must be kept + Columns.clear(); KeyColumnTypes.clear(); NotNullColumns.clear(); @@ -959,8 +959,8 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> { , TableKind(TResolve::EKind::KindUnknown) , Created(false) , CreateStep(0) - , IsPrivatePath(false) - , IsVirtual(isVirtual) + , IsPrivatePath(false) + , IsVirtual(isVirtual) , SchemaVersion(0) { } @@ -977,8 +977,8 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> { , Created(other.Created) , CreateStep(other.CreateStep) , PathId(other.PathId) - , IsPrivatePath(other.IsPrivatePath) - , IsVirtual(other.IsVirtual) + , IsPrivatePath(other.IsPrivatePath) + , IsVirtual(other.IsVirtual) , SchemaVersion(other.SchemaVersion) { if (other.Subscriber) { @@ -1196,11 +1196,11 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> { } template <typename TContextPtr> - void AddInFlight(TContextPtr context, const size_t entryIndex, const bool isSync) const { + void AddInFlight(TContextPtr context, const size_t entryIndex, const bool isSync) const { if (IsVirtual) { - return; + return; } - + if (isSync) { SendSyncRequest(); } @@ -1266,8 +1266,8 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> { Created = true; PathId = TPathId(TSysTables::SysSchemeShard, 0); Path = "/sys"; - - IsVirtual = true; + + IsVirtual = true; } void FillAsSysLocks(const bool v2) { @@ -1285,9 +1285,9 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> { for (ui32 type : keyColumnTypes) { KeyColumnTypes.push_back(type); } - - IsPrivatePath = true; - IsVirtual = true; + + IsPrivatePath = true; + IsVirtual = true; } void Fill(TSchemeBoardEvents::TEvNotifyUpdate& notify) { @@ -1899,7 +1899,7 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> { NSchemeCache::TDomainInfo::TPtr DomainInfo; THashMap<TString, TString> Attributes; bool IsPrivatePath; - bool IsVirtual; + bool IsVirtual; // Used for Table and Index ui64 SchemaVersion; @@ -2121,7 +2121,7 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> { } Y_VERIFY(byPath == byPathByPathId); - + if (!byPath->IsFilled() || byPath->GetPathId().OwnerId == notifyPathId.OwnerId) { if (byPath->GetPathId() < notifyPathId) { return SwapSubscriberAndUpsert(byPath, notifyPathId, notifyPath); diff --git a/ydb/core/tx/scheme_board/double_indexed.h b/ydb/core/tx/scheme_board/double_indexed.h index 6035a1d502..99dad5aea4 100644 --- a/ydb/core/tx/scheme_board/double_indexed.h +++ b/ydb/core/tx/scheme_board/double_indexed.h @@ -118,7 +118,7 @@ protected: return; } - // storage entry must be kept by other index, we clean only one + // storage entry must be kept by other index, we clean only one Y_VERIFY(AnotherIndexIterator(pIt) != sIndex.end()); IndexIterator(pIt) = pIndex.end(); diff --git a/ydb/core/tx/scheme_board/events.h b/ydb/core/tx/scheme_board/events.h index 4dd45d981b..018ebbff7d 100644 --- a/ydb/core/tx/scheme_board/events.h +++ b/ydb/core/tx/scheme_board/events.h @@ -59,13 +59,13 @@ struct TSchemeBoardEvents { explicit TEvRequestDescribe(const TPathId pathId, const TActorId& replica) : PathId(pathId) - , Replica(replica) + , Replica(replica) { } }; struct TEvDescribeResult: public TEventLocal<TEvDescribeResult, EvDescribeResult> { - const bool Commit = false; + const bool Commit = false; const TLocalPathId DeletedPathBegin = 0; // The points are inclusive const TLocalPathId DeletedPathEnd = 0; // [DeletedPathBegin; DeletedPathEnd] const TLocalPathId MigratedPathId = InvalidLocalPathId; @@ -78,19 +78,19 @@ struct TSchemeBoardEvents { { } - explicit TEvDescribeResult(TLocalPathId deletedPathBegin, TLocalPathId deletedPathEnd) + explicit TEvDescribeResult(TLocalPathId deletedPathBegin, TLocalPathId deletedPathEnd) : Commit(false) - , DeletedPathBegin(deletedPathBegin) - , DeletedPathEnd(deletedPathEnd) + , DeletedPathBegin(deletedPathBegin) + , DeletedPathEnd(deletedPathEnd) { } explicit TEvDescribeResult( - TLocalPathId deletedPathBegin, TLocalPathId deletedPathEnd, + TLocalPathId deletedPathBegin, TLocalPathId deletedPathEnd, const NSchemeBoard::TTwoPartDescription& description) : Commit(false) - , DeletedPathBegin(deletedPathBegin) - , DeletedPathEnd(deletedPathEnd) + , DeletedPathBegin(deletedPathBegin) + , DeletedPathEnd(deletedPathEnd) , Description(description) { } @@ -106,7 +106,7 @@ struct TSchemeBoardEvents { } bool HasDeletedLocalPathIds() const { - return DeletedPathBegin != 0; + return DeletedPathBegin != 0; } bool HasMigratedPath() const { diff --git a/ydb/core/tx/scheme_board/helpers.cpp b/ydb/core/tx/scheme_board/helpers.cpp index 7bc6c5b1c9..3b53323ad3 100644 --- a/ydb/core/tx/scheme_board/helpers.cpp +++ b/ydb/core/tx/scheme_board/helpers.cpp @@ -13,7 +13,7 @@ namespace NKikimr { namespace NSchemeBoard { TActorId MakeInterconnectProxyId(const ui32 nodeId) { - return TActivationContext::InterconnectProxy(nodeId); + return TActivationContext::InterconnectProxy(nodeId); } ui64 GetPathVersion(const NKikimrScheme::TEvDescribeSchemeResult& record) { diff --git a/ydb/core/tx/scheme_board/helpers.h b/ydb/core/tx/scheme_board/helpers.h index 6863ec4062..3b07df3e06 100644 --- a/ydb/core/tx/scheme_board/helpers.h +++ b/ydb/core/tx/scheme_board/helpers.h @@ -26,7 +26,7 @@ #define SB_LOG_N(service, stream) LOG_NOTICE_S((TlsActivationContext->AsActorContext()), NKikimrServices::service, stream) #define SB_LOG_W(service, stream) LOG_WARN_S((TlsActivationContext->AsActorContext()), NKikimrServices::service, stream) #define SB_LOG_E(service, stream) LOG_ERROR_S((TlsActivationContext->AsActorContext()), NKikimrServices::service, stream) -#define SB_LOG_CRIT(service, stream) LOG_CRIT_S((TlsActivationContext->AsActorContext()), NKikimrServices::service, stream) +#define SB_LOG_CRIT(service, stream) LOG_CRIT_S((TlsActivationContext->AsActorContext()), NKikimrServices::service, stream) namespace NKikimr { namespace NSchemeBoard { diff --git a/ydb/core/tx/scheme_board/load_test.cpp b/ydb/core/tx/scheme_board/load_test.cpp index 22362cba6d..d993f1e5ed 100644 --- a/ydb/core/tx/scheme_board/load_test.cpp +++ b/ydb/core/tx/scheme_board/load_test.cpp @@ -190,20 +190,20 @@ class TLoadProducer: public TActorBootstrapped<TLoadProducer> { } void Populate() { - const ui32 ssId = StateStorageGroupFromTabletID(Owner); - + const ui32 ssId = StateStorageGroupFromTabletID(Owner); + Descriptions = GenerateDescriptions(Owner, Config, NextPathId); Populator = Register(CreateSchemeBoardPopulator( - Owner, Max<ui64>(), ssId, Descriptions, NextPathId + Owner, Max<ui64>(), ssId, Descriptions, NextPathId )); TPathId pathId(Owner, NextPathId - 1); Y_VERIFY(Descriptions.contains(pathId)); const TString& topPath = Descriptions.at(pathId).Record.GetPath(); - + // subscriber will help us to know when sync is completed Subscriber = Register(CreateSchemeBoardSubscriber( - SelfId(), topPath, ssId, + SelfId(), topPath, ssId, ESchemeBoardSubscriberDeletionPolicy::Majority )); @@ -324,10 +324,10 @@ private: class TLoadConsumer: public TActorBootstrapped<TLoadConsumer> { void Subscribe(const TPathId& pathId) { - const ui32 ssId = StateStorageGroupFromTabletID(Owner); + const ui32 ssId = StateStorageGroupFromTabletID(Owner); for (ui32 i = 0; i < Config.SubscriberMulti; ++i) { const TActorId subscriber = Register(CreateSchemeBoardSubscriber( - SelfId(), pathId, ssId, + SelfId(), pathId, ssId, ESchemeBoardSubscriberDeletionPolicy::Majority )); diff --git a/ydb/core/tx/scheme_board/populator.cpp b/ydb/core/tx/scheme_board/populator.cpp index 1105af1933..f860bb88cb 100644 --- a/ydb/core/tx/scheme_board/populator.cpp +++ b/ydb/core/tx/scheme_board/populator.cpp @@ -16,15 +16,15 @@ #include <library/cpp/actors/core/interconnect.h> #include <library/cpp/actors/core/log.h> -#include <util/digest/city.h> - +#include <util/digest/city.h> + #include <util/generic/hash.h> #include <util/generic/map.h> #include <util/generic/ptr.h> #include <util/generic/set.h> #include <util/generic/string.h> #include <util/generic/vector.h> -#include <util/generic/algorithm.h> +#include <util/generic/algorithm.h> namespace NKikimr { namespace NSchemeBoard { @@ -33,7 +33,7 @@ namespace NSchemeBoard { #define SBP_LOG_D(stream) SB_LOG_D(SCHEME_BOARD_POPULATOR, stream) #define SBP_LOG_N(stream) SB_LOG_N(SCHEME_BOARD_POPULATOR, stream) #define SBP_LOG_E(stream) SB_LOG_E(SCHEME_BOARD_POPULATOR, stream) -#define SBP_LOG_CRIT(stream) SB_LOG_CRIT(SCHEME_BOARD_POPULATOR, stream) +#define SBP_LOG_CRIT(stream) SB_LOG_CRIT(SCHEME_BOARD_POPULATOR, stream) namespace { @@ -70,8 +70,8 @@ class TReplicaPopulator: public TMonitorableActor<TReplicaPopulator> { if (msg->HasDeletedLocalPathIds()) { auto& deletedLocalPathIds = *update->Record.MutableDeletedLocalPathIds(); - deletedLocalPathIds.SetBegin(msg->DeletedPathBegin); - deletedLocalPathIds.SetEnd(msg->DeletedPathEnd); + deletedLocalPathIds.SetBegin(msg->DeletedPathBegin); + deletedLocalPathIds.SetEnd(msg->DeletedPathEnd); CurPathId = TPathId(Owner, msg->DeletedPathEnd); } @@ -410,8 +410,8 @@ public: explicit TReplicaPopulator( const TActorId& parent, const TActorId& replica, - const ui64 owner, - const ui64 generation) + const ui64 owner, + const ui64 generation) : Parent(parent) , Replica(replica) , Owner(owner) @@ -498,40 +498,40 @@ private: class TPopulator: public TMonitorableActor<TPopulator> { TConstArrayRef<TActorId> SelectReplicas(TPathId pathId, TStringBuf path) { - SelectionReplicaCache.clear(); + SelectionReplicaCache.clear(); - const ui64 pathHash = CityHash64(path); + const ui64 pathHash = CityHash64(path); const ui64 idHash = pathId.Hash(); - TStateStorageInfo::TSelection selection; + TStateStorageInfo::TSelection selection; - GroupInfo->SelectReplicas(pathHash, &selection); - SelectionReplicaCache.insert(SelectionReplicaCache.end(), selection.begin(), selection.end()); + GroupInfo->SelectReplicas(pathHash, &selection); + SelectionReplicaCache.insert(SelectionReplicaCache.end(), selection.begin(), selection.end()); - GroupInfo->SelectReplicas(idHash, &selection); + GroupInfo->SelectReplicas(idHash, &selection); for (const TActorId& replica : selection) { if (Find(SelectionReplicaCache, replica) == SelectionReplicaCache.end()) { - SelectionReplicaCache.emplace_back(replica); + SelectionReplicaCache.emplace_back(replica); } } - + if (SelectionReplicaCache) { return TConstArrayRef<TActorId>(&SelectionReplicaCache.front(), SelectionReplicaCache.size()); } else { return TConstArrayRef<TActorId>(); } - } - + } + void Update(const TPathId pathId, const bool isDeletion, const ui64 cookie) { auto it = Descriptions.find(pathId); Y_VERIFY(it != Descriptions.end()); - + const auto& record = it->second.Record; TConstArrayRef<TActorId> replicas = SelectReplicas(pathId, record.GetPath()); - for (const auto& replica : replicas) { + for (const auto& replica : replicas) { const TActorId* replicaPopulator = ReplicaToReplicaPopulator.FindPtr(replica); - Y_VERIFY(replicaPopulator != nullptr); + Y_VERIFY(replicaPopulator != nullptr); auto update = MakeHolder<TSchemeBoardEvents::TEvUpdateBuilder>(Owner, Generation, record, isDeletion); if (!isDeletion) { @@ -552,14 +552,14 @@ class TPopulator: public TMonitorableActor<TPopulator> { const TActorId replicaPopulator = ev->Sender; const TActorId replica = ev->Get()->Replica; - if (ReplicaToReplicaPopulator[replica] != replicaPopulator) { + if (ReplicaToReplicaPopulator[replica] != replicaPopulator) { SBP_LOG_CRIT("Inconsistent replica populator" << ": self# " << SelfId() << ", replica# " << replica << ", replicaPopulator# " << replicaPopulator); - return; - } - + return; + } + if (Descriptions.empty()) { Send(replicaPopulator, new TSchemeBoardEvents::TEvDescribeResult(true)); return; @@ -788,9 +788,9 @@ class TPopulator: public TMonitorableActor<TPopulator> { << ": self# " << SelfId() << ", sender# " << ev->Sender); - const auto& info = ev->Get()->Info; + const auto& info = ev->Get()->Info; - if (!info) { + if (!info) { SBP_LOG_E("Publish on unconfigured SchemeBoard" << ": self# " << SelfId() << ", StateStorage group# " << StateStorageGroup); @@ -798,7 +798,7 @@ class TPopulator: public TMonitorableActor<TPopulator> { return; } - GroupInfo = info; + GroupInfo = info; for (auto& replica : info->SelectAllReplicas()) { IActor* replicaPopulator = new TReplicaPopulator(SelfId(), replica, Owner, Generation); ReplicaToReplicaPopulator.emplace(replica, Register(replicaPopulator, TMailboxType::ReadAsFilled)); @@ -908,12 +908,12 @@ public: explicit TPopulator( const ui64 owner, const ui64 generation, - const ui32 ssId, + const ui32 ssId, TMap<TPathId, TTwoPartDescription> descriptions, const ui64 maxPathId) : Owner(owner) , Generation(generation) - , StateStorageGroup(ssId) + , StateStorageGroup(ssId) , Descriptions(std::move(descriptions)) , MaxPathId(TPathId(owner, maxPathId)) { @@ -975,7 +975,7 @@ private: TDelayedUpdates DelayedUpdates; - TIntrusiveConstPtr<TStateStorageInfo> GroupInfo; + TIntrusiveConstPtr<TStateStorageInfo> GroupInfo; THashMap<TActorId, TActorId> ReplicaToReplicaPopulator; TVector<TActorId> SelectionReplicaCache; @@ -994,11 +994,11 @@ private: IActor* CreateSchemeBoardPopulator( const ui64 owner, const ui64 generation, - const ui32 ssId, + const ui32 ssId, TMap<TPathId, NSchemeBoard::TTwoPartDescription> descriptions, const ui64 maxPathId ) { - return new NSchemeBoard::TPopulator(owner, generation, ssId, std::move(descriptions), maxPathId); + return new NSchemeBoard::TPopulator(owner, generation, ssId, std::move(descriptions), maxPathId); } } // NKikimr diff --git a/ydb/core/tx/scheme_board/populator.h b/ydb/core/tx/scheme_board/populator.h index 4fa65e2663..8105c56ba4 100644 --- a/ydb/core/tx/scheme_board/populator.h +++ b/ydb/core/tx/scheme_board/populator.h @@ -12,7 +12,7 @@ namespace NKikimr { IActor* CreateSchemeBoardPopulator( const ui64 owner, const ui64 generation, - const ui32 schemeBoardSSId, + const ui32 schemeBoardSSId, TMap<TPathId, NSchemeBoard::TTwoPartDescription> descriptions, const ui64 maxPathId ); diff --git a/ydb/core/tx/scheme_board/replica.cpp b/ydb/core/tx/scheme_board/replica.cpp index 4079ab5ef4..638656e91d 100644 --- a/ydb/core/tx/scheme_board/replica.cpp +++ b/ydb/core/tx/scheme_board/replica.cpp @@ -493,8 +493,8 @@ public: private: struct TPopulatorInfo { - ui64 Generation = 0; - ui64 PendingGeneration = 0; + ui64 Generation = 0; + ui64 PendingGeneration = 0; TActorId PopulatorActor; bool IsCommited() const { @@ -776,8 +776,8 @@ private: << ", generation# " << generation); info.PendingGeneration = generation; - info.PopulatorActor = ev->Sender; - + info.PopulatorActor = ev->Sender; + Send(ev->Sender, new TSchemeBoardEvents::TEvHandshakeResponse(owner, info.Generation), 0, ev->Cookie); } @@ -1284,19 +1284,19 @@ private: Send(MakeInterconnectProxyId(nodeId), new TEvents::TEvUnsubscribe()); } - void PassAway() override { - for (auto &xpair : Populators) { + void PassAway() override { + for (auto &xpair : Populators) { if (const TActorId populator = xpair.second.PopulatorActor) { - Send(populator, new TEvStateStorage::TEvReplicaShutdown()); - } - } - - for (auto &xpair : Subscribers) { - Send(xpair.first, new TEvStateStorage::TEvReplicaShutdown()); - } - + Send(populator, new TEvStateStorage::TEvReplicaShutdown()); + } + } + + for (auto &xpair : Subscribers) { + Send(xpair.first, new TEvStateStorage::TEvReplicaShutdown()); + } + TMonitorableActor::PassAway(); - } + } public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { @@ -1308,7 +1308,7 @@ public: Become(&TThis::StateWork); } - STATEFN(StateWork) { + STATEFN(StateWork) { switch (ev->GetTypeRewrite()) { hFunc(TSchemeBoardEvents::TEvHandshakeRequest, Handle); hFunc(TSchemeBoardEvents::TEvUpdate, Handle); @@ -1322,7 +1322,7 @@ public: hFunc(TSchemeBoardMonEvents::TEvDescribeRequest, Handle); hFunc(TEvInterconnect::TEvNodeDisconnected, Handle); - cFunc(TEvents::TEvPoison::EventType, PassAway); + cFunc(TEvents::TEvPoison::EventType, PassAway); } } diff --git a/ydb/core/tx/scheme_board/subscriber_ut.cpp b/ydb/core/tx/scheme_board/subscriber_ut.cpp index fe8aa8a102..7e1d580305 100644 --- a/ydb/core/tx/scheme_board/subscriber_ut.cpp +++ b/ydb/core/tx/scheme_board/subscriber_ut.cpp @@ -25,8 +25,8 @@ class TSubscriberTest: public NUnitTest::TTestBase { Context->Send(proxy, edge, new TEvStateStorage::TEvListSchemeBoard()); auto ev = Context->GrabEdgeEvent<TEvStateStorage::TEvListSchemeBoardResult>(edge); - Y_VERIFY(ev->Get()->Info); - auto allReplicas = ev->Get()->Info->SelectAllReplicas(); + Y_VERIFY(ev->Get()->Info); + auto allReplicas = ev->Get()->Info->SelectAllReplicas(); return TVector<TActorId>(allReplicas.begin(), allReplicas.end()); } diff --git a/ydb/core/tx/scheme_board/ut_helpers.h b/ydb/core/tx/scheme_board/ut_helpers.h index b4eff238f4..1f2e4d5e9b 100644 --- a/ydb/core/tx/scheme_board/ut_helpers.h +++ b/ydb/core/tx/scheme_board/ut_helpers.h @@ -178,7 +178,7 @@ class TTestWithSchemeshard: public NUnitTest::TTestBase { ui32 planResolution = 50; auto domain = TDomainsInfo::TDomain::ConstructDomainWithExplicitTabletIds( name, domainUid, schemeshardTabletId, - stateStorageGroup, stateStorageGroup, TVector<ui32>{stateStorageGroup}, + stateStorageGroup, stateStorageGroup, TVector<ui32>{stateStorageGroup}, domainUid, TVector<ui32>{domainUid}, planResolution, TVector<ui64>{TDomainsInfo::MakeTxCoordinatorIDFixed(domainUid, 1)}, @@ -228,7 +228,7 @@ class TTestWithSchemeshard: public NUnitTest::TTestBase { void BootCoordinator(TTestActorRuntime& runtime, ui64 tabletId) { CoordinatorState = new TFakeCoordinator::TState(); - BootFakeCoordinator(runtime, tabletId, CoordinatorState); + BootFakeCoordinator(runtime, tabletId, CoordinatorState); } void BootHive(TTestActorRuntime& runtime, ui64 tabletId) { diff --git a/ydb/core/tx/scheme_cache/scheme_cache.cpp b/ydb/core/tx/scheme_cache/scheme_cache.cpp index 75712788ed..5cf9a0b0d5 100644 --- a/ydb/core/tx/scheme_cache/scheme_cache.cpp +++ b/ydb/core/tx/scheme_cache/scheme_cache.cpp @@ -1,25 +1,25 @@ -#include "scheme_cache.h" +#include "scheme_cache.h" #include <ydb/core/base/path.h> #include <util/string/builder.h> -namespace NKikimr { +namespace NKikimr { namespace NSchemeCache { - + TSchemeCacheConfig::TSchemeCacheConfig(const TAppData* appData, NMonitoring::TDynamicCounterPtr counters) : Counters(counters) { Y_VERIFY(appData); Y_VERIFY(appData->DomainsInfo); - + for (const auto& [_, domain] : appData->DomainsInfo->Domains) { Y_VERIFY(domain); if (!domain->SchemeRoot) { continue; - } - + } + Roots.emplace_back(domain->DomainRootTag(), domain->SchemeRoot, domain->Name); } } @@ -30,8 +30,8 @@ TString TDomainInfo::ToString() const { << " ResourcesDomainKey: " << ResourcesDomainKey << " Params { " << Params.ShortDebugString() << " }" << " }"; -} - +} + TString TSchemeCacheNavigate::TEntry::ToString() const { return TStringBuilder() << "{" << " Path: " << JoinPath(Path) @@ -45,8 +45,8 @@ TString TSchemeCacheNavigate::TEntry::ToString() const { << " Kind: " << Kind << " DomainInfo " << (DomainInfo ? DomainInfo->ToString() : "<null>") << " }"; -} - +} + TString TSchemeCacheNavigate::TEntry::ToString(const NScheme::TTypeRegistry& typeRegistry) const { Y_UNUSED(typeRegistry); return ToString(); @@ -55,18 +55,18 @@ TString TSchemeCacheNavigate::TEntry::ToString(const NScheme::TTypeRegistry& typ template <typename TResultSet> static TString ResultSetToString(const TResultSet& rs, const NScheme::TTypeRegistry& typeRegistry) { TStringBuilder out; - + for (ui32 i = 0; i < rs.size(); ++i) { if (i) { out << ","; } - + out << rs.at(i).ToString(typeRegistry); - } - + } + return out; -} - +} + TString TSchemeCacheNavigate::ToString(const NScheme::TTypeRegistry& typeRegistry) const { return TStringBuilder() << "{" << " ErrorCount: " << ErrorCount @@ -74,8 +74,8 @@ TString TSchemeCacheNavigate::ToString(const NScheme::TTypeRegistry& typeRegistr << " DomainOwnerId: " << DomainOwnerId << " ResultSet [" << ResultSetToString(ResultSet, typeRegistry) << "]" << " }"; -} - +} + TString TSchemeCacheRequest::TEntry::ToString() const { return TStringBuilder() << "{" << " TableId: " << (KeyDescription ? ::ToString(KeyDescription->TableId.PathId) : "<moved>") @@ -86,8 +86,8 @@ TString TSchemeCacheRequest::TEntry::ToString() const { << " PartitionsCount: " << (KeyDescription ? ::ToString(KeyDescription->Partitions.size()) : "<moved>") << " DomainInfo " << (DomainInfo ? DomainInfo->ToString() : "<null>") << " }"; -} - +} + TString TSchemeCacheRequest::TEntry::ToString(const NScheme::TTypeRegistry& typeRegistry) const { TStringBuilder out; out << "{" @@ -98,11 +98,11 @@ TString TSchemeCacheRequest::TEntry::ToString(const NScheme::TTypeRegistry& type << " Kind: " << Kind << " PartitionsCount: " << (KeyDescription ? ::ToString(KeyDescription->Partitions.size()) : "<moved>") << " DomainInfo " << (DomainInfo ? DomainInfo->ToString() : "<null>"); - + if (KeyDescription) { TDbTupleRef from(KeyDescription->KeyColumnTypes.data(), KeyDescription->Range.From.data(), KeyDescription->Range.From.size()); TDbTupleRef to(KeyDescription->KeyColumnTypes.data(), KeyDescription->Range.To.data(), KeyDescription->Range.To.size()); - + if (KeyDescription->Range.Point) { out << " Point: " << DbgPrintTuple(from, typeRegistry); } else { @@ -111,8 +111,8 @@ TString TSchemeCacheRequest::TEntry::ToString(const NScheme::TTypeRegistry& type << " To: " << DbgPrintTuple(to, typeRegistry) << " IncTo: " << KeyDescription->Range.InclusiveTo; } - } - + } + out << " }"; return out; } @@ -124,7 +124,7 @@ TString TSchemeCacheRequest::ToString(const NScheme::TTypeRegistry& typeRegistry << " DomainOwnerId: " << DomainOwnerId << " ResultSet [" << ResultSetToString(ResultSet, typeRegistry) << "]" << " }"; -} - +} + } // NSchemeCache } // NKikimr diff --git a/ydb/core/tx/scheme_cache/scheme_cache.h b/ydb/core/tx/scheme_cache/scheme_cache.h index 5ea882d163..26a07897a1 100644 --- a/ydb/core/tx/scheme_cache/scheme_cache.h +++ b/ydb/core/tx/scheme_cache/scheme_cache.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include <ydb/core/base/appdata.h> #include <ydb/core/base/events.h> @@ -13,33 +13,33 @@ #include <ydb/library/aclib/aclib.h> #include <util/datetime/base.h> -#include <util/generic/hash.h> -#include <util/generic/hash_set.h> -#include <util/generic/ptr.h> - -namespace NKikimr { +#include <util/generic/hash.h> +#include <util/generic/hash_set.h> +#include <util/generic/ptr.h> + +namespace NKikimr { namespace NSchemeCache { - -struct TSchemeCacheConfig : public TThrRefBase { - struct TTagEntry { + +struct TSchemeCacheConfig : public TThrRefBase { + struct TTagEntry { ui32 Tag = 0; ui64 RootSchemeShard = 0; TString Name; - + explicit TTagEntry(ui32 tag, ui64 rootSchemeShard, const TString& name) - : Tag(tag) - , RootSchemeShard(rootSchemeShard) - , Name(name) - {} - }; - + : Tag(tag) + , RootSchemeShard(rootSchemeShard) + , Name(name) + {} + }; + TSchemeCacheConfig() = default; explicit TSchemeCacheConfig(const TAppData* appData, NMonitoring::TDynamicCounterPtr counters); TVector<TTagEntry> Roots; NMonitoring::TDynamicCounterPtr Counters; -}; - +}; + struct TDomainInfo : public TAtomicRefCount<TDomainInfo> { using TPtr = TIntrusivePtr<TDomainInfo>; @@ -104,19 +104,19 @@ struct TSchemeCacheNavigate { OpUnknown = 0, OpTable = 1, // would return table info OpPath = 2, // would return owning scheme shard id - OpTopic = 3, // would return topic info - OpList = 4, // would list children and cache them + OpTopic = 3, // would return topic info + OpList = 4, // would list children and cache them }; - enum EKind { - KindUnknown = 0, - KindPath = 2, - KindTable = 3, - KindTopic = 4, + enum EKind { + KindUnknown = 0, + KindPath = 2, + KindTable = 3, + KindTopic = 4, KindRtmr = 5, KindKesus = 6, - KindSolomon = 7, - KindSubdomain = 8, + KindSolomon = 7, + KindSubdomain = 8, KindExtSubdomain = 9, KindIndex = 10, KindOlapStore = 11, @@ -124,9 +124,9 @@ struct TSchemeCacheNavigate { KindCdcStream = 13, KindSequence = 14, KindReplication = 15, - }; - - struct TListNodeEntry : public TAtomicRefCount<TListNodeEntry> { + }; + + struct TListNodeEntry : public TAtomicRefCount<TListNodeEntry> { struct TChild { const TString Name; const TPathId PathId; @@ -143,8 +143,8 @@ struct TSchemeCacheNavigate { EKind Kind = KindUnknown; TVector<TChild> Children; - }; - + }; + struct TDirEntryInfo : public TAtomicRefCount<TDirEntryInfo>{ NKikimrSchemeOp::TDirEntry Info; }; @@ -154,11 +154,11 @@ struct TSchemeCacheNavigate { NKikimrSubDomains::TDomainDescription Description; }; - struct TPQGroupInfo : public TAtomicRefCount<TPQGroupInfo> { - EKind Kind = KindUnknown; + struct TPQGroupInfo : public TAtomicRefCount<TPQGroupInfo> { + EKind Kind = KindUnknown; NKikimrSchemeOp::TPersQueueGroupDescription Description; - }; - + }; + struct TRtmrVolumeInfo : public TAtomicRefCount<TRtmrVolumeInfo> { EKind Kind = KindUnknown; NKikimrSchemeOp::TRtmrVolumeDescription Description; @@ -236,7 +236,7 @@ struct TSchemeCacheNavigate { // other TIntrusiveConstPtr<TDomainDescription> DomainDescription; - TIntrusiveConstPtr<TPQGroupInfo> PQGroupInfo; + TIntrusiveConstPtr<TPQGroupInfo> PQGroupInfo; TIntrusiveConstPtr<TRtmrVolumeInfo> RTMRVolumeInfo; TIntrusiveConstPtr<TKesusInfo> KesusInfo; TIntrusiveConstPtr<TSolomonVolumeInfo> SolomonVolumeInfo; @@ -245,7 +245,7 @@ struct TSchemeCacheNavigate { TIntrusiveConstPtr<TCdcStreamInfo> CdcStreamInfo; TIntrusiveConstPtr<TSequenceInfo> SequenceInfo; TIntrusiveConstPtr<TReplicationInfo> ReplicationInfo; - + TString ToString() const; TString ToString(const NScheme::TTypeRegistry& typeRegistry) const; }; @@ -335,32 +335,32 @@ struct TSchemeCacheRequest { struct TSchemeCacheRequestContext : TAtomicRefCount<TSchemeCacheRequestContext>, TNonCopyable { TActorId Sender; - ui64 WaitCounter; + ui64 WaitCounter; TAutoPtr<TSchemeCacheRequest> Request; const TInstant CreatedAt; - + TSchemeCacheRequestContext(const TActorId& sender, TAutoPtr<TSchemeCacheRequest> request, const TInstant& now = TInstant::Now()) - : Sender(sender) - , WaitCounter(0) - , Request(request) + : Sender(sender) + , WaitCounter(0) + , Request(request) , CreatedAt(now) - {} -}; - + {} +}; + struct TSchemeCacheNavigateContext : TAtomicRefCount<TSchemeCacheNavigateContext>, TNonCopyable { TActorId Sender; - ui64 WaitCounter; + ui64 WaitCounter; TAutoPtr<TSchemeCacheNavigate> Request; const TInstant CreatedAt; - + TSchemeCacheNavigateContext(const TActorId& sender, TAutoPtr<TSchemeCacheNavigate> request, const TInstant& now = TInstant::Now()) - : Sender(sender) - , WaitCounter(0) - , Request(request) + : Sender(sender) + , WaitCounter(0) + , Request(request) , CreatedAt(now) - {} -}; - + {} +}; + class TDescribeResult : public TAtomicRefCount<TDescribeResult> , public NKikimrScheme::TEvDescribeSchemeResult diff --git a/ydb/core/tx/schemeshard/schemeshard.h b/ydb/core/tx/schemeshard/schemeshard.h index af6b3980d4..d33173508c 100644 --- a/ydb/core/tx/schemeshard/schemeshard.h +++ b/ydb/core/tx/schemeshard/schemeshard.h @@ -17,9 +17,9 @@ namespace NKikimr { namespace NSchemeShard { -static constexpr ui64 RootSchemeShardId = 0; -static constexpr ui64 RootPathId = 1; - +static constexpr ui64 RootSchemeShardId = 0; +static constexpr ui64 RootPathId = 1; + struct TSchemeLimits; struct TEvSchemeShard { @@ -226,18 +226,18 @@ struct TEvSchemeShard { { Record.SetPath(path); } - + TEvDescribeScheme(ui64 tabletId, ui64 pathId) { Record.SetSchemeshardId(tabletId); Record.SetPathId(pathId); } - TEvDescribeScheme(TTableId tableId) - { + TEvDescribeScheme(TTableId tableId) + { Record.SetSchemeshardId(tableId.PathId.OwnerId); Record.SetPathId(tableId.PathId.LocalPathId); - } + } TEvDescribeScheme(NKikimr::TPathId pathId) { @@ -254,7 +254,7 @@ struct TEvSchemeShard { TEvDescribeSchemeResult(const TString& path, ui64 pathOwner, TPathId pathId) { Record.SetPath(path); - Record.SetPathOwner(pathOwner); + Record.SetPathOwner(pathOwner); Record.SetPathId(pathId.LocalPathId); Record.SetPathOwnerId(pathId.OwnerId); } diff --git a/ydb/core/tx/schemeshard/schemeshard__init_populator.cpp b/ydb/core/tx/schemeshard/schemeshard__init_populator.cpp index 52b1c4c692..299757e38b 100644 --- a/ydb/core/tx/schemeshard/schemeshard__init_populator.cpp +++ b/ydb/core/tx/schemeshard/schemeshard__init_populator.cpp @@ -56,13 +56,13 @@ struct TSchemeShard::TTxInitPopulator : public TTransactionBase<TSchemeShard> { } void Complete(const TActorContext& ctx) override { - const ui64 tabletId = Self->TabletID(); - const auto &domains = *AppData()->DomainsInfo; - const ui32 domainId = domains.GetDomainUidByTabletId(tabletId); - const ui32 boardSSId = domains.GetDomain(domainId).DefaultSchemeBoardGroup; - + const ui64 tabletId = Self->TabletID(); + const auto &domains = *AppData()->DomainsInfo; + const ui32 domainId = domains.GetDomainUidByTabletId(tabletId); + const ui32 boardSSId = domains.GetDomain(domainId).DefaultSchemeBoardGroup; + IActor* populator = CreateSchemeBoardPopulator( - tabletId, Self->Generation(), boardSSId, + tabletId, Self->Generation(), boardSSId, std::move(Descriptions), Self->NextLocalPathId ); diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_copy_table.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_copy_table.cpp index 95daa4695f..f504c34ef5 100644 --- a/ydb/core/tx/schemeshard/schemeshard__operation_copy_table.cpp +++ b/ydb/core/tx/schemeshard/schemeshard__operation_copy_table.cpp @@ -452,19 +452,19 @@ public: Y_VERIFY(context.SS->Tables.contains(srcPath.Base()->PathId)); TTableInfo::TPtr srcTableInfo = context.SS->Tables.at(srcPath.Base()->PathId); - // do not allow copy from table with enabled external blobs - { + // do not allow copy from table with enabled external blobs + { const NKikimrSchemeOp::TPartitionConfig &srcPartitionConfig = srcTableInfo->PartitionConfig(); - if (PartitionConfigHasExternalBlobsEnabled(srcPartitionConfig)) { + if (PartitionConfigHasExternalBlobsEnabled(srcPartitionConfig)) { result->SetError(NKikimrScheme::StatusPreconditionFailed, "source table contains external blobs, copy operation is not safe so prohibited"); - return result; - } + return result; + } if (srcPartitionConfig.GetShadowData()) { result->SetError(NKikimrScheme::StatusPreconditionFailed, "Cannot copy tables with enabled ShadowData"); return result; } - } - + } + auto schema = Transaction.GetCreateTable(); const bool omitFollowers = schema.GetOmitFollowers(); const bool isBackup = schema.GetIsBackup(); diff --git a/ydb/core/tx/schemeshard/schemeshard_impl.cpp b/ydb/core/tx/schemeshard/schemeshard_impl.cpp index da67c4a0ff..0715543a22 100644 --- a/ydb/core/tx/schemeshard/schemeshard_impl.cpp +++ b/ydb/core/tx/schemeshard/schemeshard_impl.cpp @@ -3996,14 +3996,14 @@ void TSchemeShard::StateWork(STFUNC_SIG) { HFuncTraced(TEvSchemeShard::TEvLogin, Handle); - default: + default: if (!HandleDefaultEvents(ev, ctx)) { LOG_WARN_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, "StateWork:" << " unhandled event type: " << ev->GetTypeRewrite() << " event: " << (ev->HasEvent() ? ev->GetBase()->ToString().data() : "serialized?")); } - break; + break; } } @@ -5742,11 +5742,11 @@ bool TSchemeShard::FillUniformPartitioning(TVector<TString>& rangeEnds, ui32 key // Check that first key column has integer type switch(firstKeyColType) { case NScheme::NTypeIds::Uint32: - maxVal = Max<ui32>(); + maxVal = Max<ui32>(); valSz = 4; break; case NScheme::NTypeIds::Uint64: - maxVal = Max<ui64>(); + maxVal = Max<ui64>(); valSz = 8; break; default: diff --git a/ydb/core/tx/schemeshard/ut_helpers/test_env.cpp b/ydb/core/tx/schemeshard/ut_helpers/test_env.cpp index 4cf009ab8f..9cfd8037b7 100644 --- a/ydb/core/tx/schemeshard/ut_helpers/test_env.cpp +++ b/ydb/core/tx/schemeshard/ut_helpers/test_env.cpp @@ -624,7 +624,7 @@ void NSchemeShardUT_Private::TTestEnv::AddDomain(TTestActorRuntime &runtime, TAp ui32 planResolution = 50; auto domain = TDomainsInfo::TDomain::ConstructDomainWithExplicitTabletIds( "MyRoot", domainUid, schemeRoot, - ssId, ssId, TVector<ui32>{ssId}, + ssId, ssId, TVector<ui32>{ssId}, domainUid, TVector<ui32>{domainUid}, planResolution, TVector<ui64>{TDomainsInfo::MakeTxCoordinatorIDFixed(domainUid, 1)}, diff --git a/ydb/core/tx/schemeshard/ut_subdomain.cpp b/ydb/core/tx/schemeshard/ut_subdomain.cpp index abd97369cc..d0d30bf7da 100644 --- a/ydb/core/tx/schemeshard/ut_subdomain.cpp +++ b/ydb/core/tx/schemeshard/ut_subdomain.cpp @@ -690,17 +690,17 @@ Y_UNIT_TEST_SUITE(TSchemeShardSubDomainTest) { TTestEnv env(runtime); ui64 txId = 100; - TestCreateSubDomain(runtime, ++txId, "/MyRoot", R"( - StoragePools { - Name: "/dc-1/users/tenant-1:hdd" - Kind: "hdd" - } - PlanResolution: 50 - Coordinators: 1 - Mediators: 1 - TimeCastBucketsPerMediator: 2 - Name: "USER_0" - )"); + TestCreateSubDomain(runtime, ++txId, "/MyRoot", R"( + StoragePools { + Name: "/dc-1/users/tenant-1:hdd" + Kind: "hdd" + } + PlanResolution: 50 + Coordinators: 1 + Mediators: 1 + TimeCastBucketsPerMediator: 2 + Name: "USER_0" + )"); TestCreateSubDomain(runtime, ++txId, "/MyRoot", "PlanResolution: 50 " @@ -715,35 +715,35 @@ Y_UNIT_TEST_SUITE(TSchemeShardSubDomainTest) { "Columns { Name: \"Value\" Type: \"Utf8\"}" "KeyColumnNames: [\"RowId\"]"); - TestCreateTable(runtime, ++txId, "/MyRoot/USER_0", R"( - Name: "ex_blobs" - Columns { Name: "key" Type: "Uint64" } - Columns { Name: "value" Type: "String" } - KeyColumnNames: ["key"] - PartitionConfig { - ColumnFamilies { - Id: 0 - StorageConfig { - SysLog { - PreferredPoolKind: "hdd" - } - Log { - PreferredPoolKind: "hdd" - } - Data { - PreferredPoolKind: "hdd" - } - External { - PreferredPoolKind: "hdd" - } - ExternalThreshold: 524288 - } - } - } - )"); - - env.TestWaitNotification(runtime, {100, 101, 102, 103, 104}); - + TestCreateTable(runtime, ++txId, "/MyRoot/USER_0", R"( + Name: "ex_blobs" + Columns { Name: "key" Type: "Uint64" } + Columns { Name: "value" Type: "String" } + KeyColumnNames: ["key"] + PartitionConfig { + ColumnFamilies { + Id: 0 + StorageConfig { + SysLog { + PreferredPoolKind: "hdd" + } + Log { + PreferredPoolKind: "hdd" + } + Data { + PreferredPoolKind: "hdd" + } + External { + PreferredPoolKind: "hdd" + } + ExternalThreshold: 524288 + } + } + } + )"); + + env.TestWaitNotification(runtime, {100, 101, 102, 103, 104}); + TestCopyTable(runtime, ++txId, "/MyRoot/USER_1", "dst", "/MyRoot/USER_0/src", NKikimrScheme::StatusInvalidParameter); TestCopyTable(runtime, ++txId, "/MyRoot", "dst", "/MyRoot/USER_0/src", NKikimrScheme::StatusInvalidParameter); TestCopyTable(runtime, ++txId, "/MyRoot/USER_0", "ex_blobs_copy", "/MyRoot/USER_0/ex_blobs", NKikimrScheme::StatusPreconditionFailed); diff --git a/ydb/core/tx/time_cast/time_cast.cpp b/ydb/core/tx/time_cast/time_cast.cpp index c52682e683..08042194fc 100644 --- a/ydb/core/tx/time_cast/time_cast.cpp +++ b/ydb/core/tx/time_cast/time_cast.cpp @@ -10,25 +10,25 @@ #include <util/generic/hash.h> #include <util/generic/hash_set.h> - + #include <queue> -namespace NKikimr { - -ui64 TMediatorTimecastEntry::Get(ui64 tabletId) const { +namespace NKikimr { + +ui64 TMediatorTimecastEntry::Get(ui64 tabletId) const { Y_UNUSED(tabletId); - return AtomicGet(Step); -} - -void TMediatorTimecastEntry::Update(ui64 step, ui64 *exemption, ui64 exsz) { + return AtomicGet(Step); +} + +void TMediatorTimecastEntry::Update(ui64 step, ui64 *exemption, ui64 exsz) { Y_VERIFY(exsz == 0, "exemption lists not supported yet"); Y_UNUSED(exemption); Y_UNUSED(exsz); - - AtomicSet(Step, step); -} - -class TMediatorTimecastProxy : public TActor<TMediatorTimecastProxy> { + + AtomicSet(Step, step); +} + +class TMediatorTimecastProxy : public TActor<TMediatorTimecastProxy> { struct TWaiter { TActorId Sender; ui64 TabletId; @@ -53,25 +53,25 @@ class TMediatorTimecastProxy : public TActor<TMediatorTimecastProxy> { std::priority_queue<TWaiter> Waiters; }; - struct TMediator { - const ui32 BucketsSz; + struct TMediator { + const ui32 BucketsSz; TArrayHolder<TMediatorBucket> Buckets; - + TActorId PipeClient; - - TMediator(ui32 bucketsSz) - : BucketsSz(bucketsSz) + + TMediator(ui32 bucketsSz) + : BucketsSz(bucketsSz) , Buckets(new TMediatorBucket[bucketsSz]) - {} - }; - + {} + }; + struct TTabletInfo { ui64 MediatorTabletId; TMediator* Mediator; ui32 BucketId; ui32 RefCount = 0; }; - + THashMap<ui64, TMediator> Mediators; // mediator tablet -> info THashMap<ui64, TTabletInfo> Tablets; @@ -81,92 +81,92 @@ class TMediatorTimecastProxy : public TActor<TMediatorTimecastProxy> { Y_VERIFY(pr.first->second.BucketsSz == processing.GetTimeCastBucketsPerMediator()); } return pr.first->second; - } - - void RegisterMediator(ui64 mediatorTabletId, TMediator &mediator, const TActorContext &ctx) { - TAutoPtr<TEvMediatorTimecast::TEvWatch> ev(new TEvMediatorTimecast::TEvWatch()); - for (ui32 bucketId = 0, e = mediator.BucketsSz; bucketId != e; ++bucketId) { - auto &x = mediator.Buckets[bucketId]; + } + + void RegisterMediator(ui64 mediatorTabletId, TMediator &mediator, const TActorContext &ctx) { + TAutoPtr<TEvMediatorTimecast::TEvWatch> ev(new TEvMediatorTimecast::TEvWatch()); + for (ui32 bucketId = 0, e = mediator.BucketsSz; bucketId != e; ++bucketId) { + auto &x = mediator.Buckets[bucketId]; if (!x.Entry) - continue; + continue; if (x.Entry.RefCount() == 1) { x.Entry.Drop(); x.Waiters = { }; - continue; - } - - ev->Record.AddBucket(bucketId); - } - - if (ev->Record.BucketSize()) { + continue; + } + + ev->Record.AddBucket(bucketId); + } + + if (ev->Record.BucketSize()) { mediator.PipeClient = ctx.RegisterWithSameMailbox(NTabletPipe::CreateClient(ctx.SelfID, mediatorTabletId)); LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TIMECAST, "Actor# " << ctx.SelfID.ToString() << " SEND to# " << mediatorTabletId << " Mediator " << ev->ToString()); - NTabletPipe::SendData(ctx, mediator.PipeClient, ev.Release()); - } - } - - void SubscribeBucket(ui64 mediatorTabletId, TMediator &mediator, ui32 bucketId, const TActorContext &ctx) { + NTabletPipe::SendData(ctx, mediator.PipeClient, ev.Release()); + } + } + + void SubscribeBucket(ui64 mediatorTabletId, TMediator &mediator, ui32 bucketId, const TActorContext &ctx) { if (mediator.PipeClient) { TAutoPtr<TEvMediatorTimecast::TEvWatch> ev(new TEvMediatorTimecast::TEvWatch(bucketId)); LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TIMECAST, "Actor# " << ctx.SelfID.ToString() << " SEND to# " << mediatorTabletId << " Mediator " << ev->ToString()); NTabletPipe::SendData(ctx, mediator.PipeClient, ev.Release()); } else { - RegisterMediator(mediatorTabletId, mediator, ctx); + RegisterMediator(mediatorTabletId, mediator, ctx); } - } - + } + void TryResync(const TActorId &pipeClient, ui64 tabletId, const TActorContext &ctx) { for (auto &xpair : Mediators) { - const ui64 mediatorTabletId = xpair.first; + const ui64 mediatorTabletId = xpair.first; TMediator &mediator = xpair.second; - + if (mediator.PipeClient == pipeClient) { Y_VERIFY(tabletId == mediatorTabletId); mediator.PipeClient = TActorId(); RegisterMediator(mediatorTabletId, mediator, ctx); - return; - } - } - } - - void Handle(TEvMediatorTimecast::TEvRegisterTablet::TPtr &ev, const TActorContext &ctx); - void Handle(TEvMediatorTimecast::TEvUnregisterTablet::TPtr &ev, const TActorContext &ctx); + return; + } + } + } + + void Handle(TEvMediatorTimecast::TEvRegisterTablet::TPtr &ev, const TActorContext &ctx); + void Handle(TEvMediatorTimecast::TEvUnregisterTablet::TPtr &ev, const TActorContext &ctx); void Handle(TEvMediatorTimecast::TEvWaitPlanStep::TPtr &ev, const TActorContext &ctx); - void Handle(TEvMediatorTimecast::TEvUpdate::TPtr &ev, const TActorContext &ctx); - void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx); - void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx); + void Handle(TEvMediatorTimecast::TEvUpdate::TPtr &ev, const TActorContext &ctx); + void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx); + void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx); -public: +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TX_MEDIATOR_ACTOR; } - TMediatorTimecastProxy() - : TActor(&TThis::StateFunc) - {} - - STFUNC(StateFunc) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvMediatorTimecast::TEvRegisterTablet, Handle); + TMediatorTimecastProxy() + : TActor(&TThis::StateFunc) + {} + + STFUNC(StateFunc) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvMediatorTimecast::TEvRegisterTablet, Handle); HFunc(TEvMediatorTimecast::TEvUnregisterTablet, Handle); HFunc(TEvMediatorTimecast::TEvWaitPlanStep, Handle); - HFunc(TEvMediatorTimecast::TEvUpdate, Handle); - - HFunc(TEvTabletPipe::TEvClientConnected, Handle); - HFunc(TEvTabletPipe::TEvClientDestroyed, Handle); - } - } -}; - -void TMediatorTimecastProxy::Handle(TEvMediatorTimecast::TEvRegisterTablet::TPtr &ev, const TActorContext &ctx) { - const TEvMediatorTimecast::TEvRegisterTablet *msg = ev->Get(); + HFunc(TEvMediatorTimecast::TEvUpdate, Handle); + + HFunc(TEvTabletPipe::TEvClientConnected, Handle); + HFunc(TEvTabletPipe::TEvClientDestroyed, Handle); + } + } +}; + +void TMediatorTimecastProxy::Handle(TEvMediatorTimecast::TEvRegisterTablet::TPtr &ev, const TActorContext &ctx) { + const TEvMediatorTimecast::TEvRegisterTablet *msg = ev->Get(); LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TIMECAST, "Actor# " << ctx.SelfID.ToString() << " HANDLE " << msg->ToString()); - const ui64 tabletId = msg->TabletId; + const ui64 tabletId = msg->TabletId; const NKikimrSubDomains::TProcessingParams &processingParams = msg->ProcessingParams; - + auto& tabletInfo = Tablets[tabletId]; TMediators mediators(processingParams); @@ -177,15 +177,15 @@ void TMediatorTimecastProxy::Handle(TEvMediatorTimecast::TEvRegisterTablet::TPtr TTimeCastBuckets buckets(processingParams); const ui32 bucketId = buckets.Select(tabletId); tabletInfo.BucketId = bucketId; - + TMediator &mediator = MediatorInfo(mediatorTabletId, processingParams); tabletInfo.Mediator = &mediator; - + Y_VERIFY(bucketId < mediator.BucketsSz); auto &bucket = mediator.Buckets[bucketId]; if (!bucket.Entry) bucket.Entry = new TMediatorTimecastEntry(); - + ++tabletInfo.RefCount; TAutoPtr<TEvMediatorTimecast::TEvRegisterTabletResult> result( @@ -193,11 +193,11 @@ void TMediatorTimecastProxy::Handle(TEvMediatorTimecast::TEvRegisterTablet::TPtr LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TIMECAST, "Actor# " << ctx.SelfID.ToString() << " SEND to# " << ev->Sender.ToString() << " Sender " << result->ToString()); ctx.Send(ev->Sender, result.Release()); - - SubscribeBucket(mediatorTabletId, mediator, bucketId, ctx); -} - -void TMediatorTimecastProxy::Handle(TEvMediatorTimecast::TEvUnregisterTablet::TPtr &ev, const TActorContext &ctx) { + + SubscribeBucket(mediatorTabletId, mediator, bucketId, ctx); +} + +void TMediatorTimecastProxy::Handle(TEvMediatorTimecast::TEvUnregisterTablet::TPtr &ev, const TActorContext &ctx) { const auto *msg = ev->Get(); LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TIMECAST, "Actor# " << ctx.SelfID.ToString() << " HANDLE " << msg->ToString()); @@ -211,8 +211,8 @@ void TMediatorTimecastProxy::Handle(TEvMediatorTimecast::TEvUnregisterTablet::TP Tablets.erase(it); } } -} - +} + void TMediatorTimecastProxy::Handle(TEvMediatorTimecast::TEvWaitPlanStep::TPtr &ev, const TActorContext &ctx) { const auto *msg = ev->Get(); LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TIMECAST, "Actor# " << ctx.SelfID.ToString() @@ -241,30 +241,30 @@ void TMediatorTimecastProxy::Handle(TEvMediatorTimecast::TEvWaitPlanStep::TPtr & ctx.Send(ev->Sender, new TEvMediatorTimecast::TEvNotifyPlanStep(tabletId, currentStep)); } -void TMediatorTimecastProxy::Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx) { +void TMediatorTimecastProxy::Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx) { LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TIMECAST, "Actor# " << ctx.SelfID.ToString() << " HANDLE EvClientConnected"); - TEvTabletPipe::TEvClientConnected *msg = ev->Get(); - if (msg->Status != NKikimrProto::OK) { - TryResync(msg->ClientId, msg->TabletId, ctx); - } -} - -void TMediatorTimecastProxy::Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx) { + TEvTabletPipe::TEvClientConnected *msg = ev->Get(); + if (msg->Status != NKikimrProto::OK) { + TryResync(msg->ClientId, msg->TabletId, ctx); + } +} + +void TMediatorTimecastProxy::Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx) { LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TIMECAST, "Actor# " << ctx.SelfID.ToString() << " HANDLE EvClientDestroyed"); - TEvTabletPipe::TEvClientDestroyed *msg = ev->Get(); - TryResync(msg->ClientId, msg->TabletId, ctx); -} - -void TMediatorTimecastProxy::Handle(TEvMediatorTimecast::TEvUpdate::TPtr &ev, const TActorContext &ctx) { + TEvTabletPipe::TEvClientDestroyed *msg = ev->Get(); + TryResync(msg->ClientId, msg->TabletId, ctx); +} + +void TMediatorTimecastProxy::Handle(TEvMediatorTimecast::TEvUpdate::TPtr &ev, const TActorContext &ctx) { LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TIMECAST, "Actor# " << ctx.SelfID.ToString() << " HANDLE "<< ev->Get()->ToString()); - - const NKikimrTxMediatorTimecast::TEvUpdate &record = ev->Get()->Record; + + const NKikimrTxMediatorTimecast::TEvUpdate &record = ev->Get()->Record; Y_VERIFY(record.ExemptionSize() == 0, "exemption lists are not supported yet"); - - const ui64 mediatorTabletId = record.GetMediator(); + + const ui64 mediatorTabletId = record.GetMediator(); auto it = Mediators.find(mediatorTabletId); if (it != Mediators.end()) { auto &mediator = it->second; @@ -293,12 +293,12 @@ void TMediatorTimecastProxy::Handle(TEvMediatorTimecast::TEvUpdate::TPtr &ev, co } break; } - } - } -} - -IActor* CreateMediatorTimecastProxy() { - return new TMediatorTimecastProxy(); -} - -} + } + } +} + +IActor* CreateMediatorTimecastProxy() { + return new TMediatorTimecastProxy(); +} + +} diff --git a/ydb/core/tx/time_cast/time_cast.h b/ydb/core/tx/time_cast/time_cast.h index acae9b8421..1202d5a799 100644 --- a/ydb/core/tx/time_cast/time_cast.h +++ b/ydb/core/tx/time_cast/time_cast.h @@ -1,55 +1,55 @@ -#pragma once +#pragma once -#include "defs.h" +#include "defs.h" #include <ydb/core/protos/subdomains.pb.h> #include <ydb/core/protos/tx_mediator_timecast.pb.h> - + #include <util/stream/str.h> #include <util/string/builder.h> -namespace NKikimr { - -class TMediatorTimecastEntry : public TThrRefBase { - TAtomic Step; -public: - TMediatorTimecastEntry() - : Step(0) - {} - - ui64 Get(ui64 tabletId) const; - void Update(ui64 step, ui64 *exemption, ui64 exsz); -}; - -struct TEvMediatorTimecast { - enum EEv { - // local part - EvRegisterTablet = EventSpaceBegin(TKikimrEvents::ES_TX_MEDIATORTIMECAST), - EvUnregisterTablet, +namespace NKikimr { + +class TMediatorTimecastEntry : public TThrRefBase { + TAtomic Step; +public: + TMediatorTimecastEntry() + : Step(0) + {} + + ui64 Get(ui64 tabletId) const; + void Update(ui64 step, ui64 *exemption, ui64 exsz); +}; + +struct TEvMediatorTimecast { + enum EEv { + // local part + EvRegisterTablet = EventSpaceBegin(TKikimrEvents::ES_TX_MEDIATORTIMECAST), + EvUnregisterTablet, EvWaitPlanStep, - - EvRegisterTabletResult = EvRegisterTablet + 1 * 512, + + EvRegisterTabletResult = EvRegisterTablet + 1 * 512, EvNotifyPlanStep, - - // mediator part - EvWatch = EvRegisterTablet + 2 * 512, - - EvUpdate = EvRegisterTablet + 3 * 512, - - EvEnd - }; - - static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_TX_MEDIATORTIMECAST), "expected EvEnd < EventSpaceEnd()"); - - struct TEvRegisterTablet : public TEventLocal<TEvRegisterTablet, EvRegisterTablet> { - const ui64 TabletId; + + // mediator part + EvWatch = EvRegisterTablet + 2 * 512, + + EvUpdate = EvRegisterTablet + 3 * 512, + + EvEnd + }; + + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_TX_MEDIATORTIMECAST), "expected EvEnd < EventSpaceEnd()"); + + struct TEvRegisterTablet : public TEventLocal<TEvRegisterTablet, EvRegisterTablet> { + const ui64 TabletId; NKikimrSubDomains::TProcessingParams ProcessingParams; - + TEvRegisterTablet(ui64 tabletId, const NKikimrSubDomains::TProcessingParams &processing) - : TabletId(tabletId) + : TabletId(tabletId) , ProcessingParams(processing) - {} + {} TString ToString() const { TStringStream str; @@ -61,16 +61,16 @@ struct TEvMediatorTimecast { str << "}"; return str.Str(); } - }; - - struct TEvRegisterTabletResult : public TEventLocal<TEvRegisterTabletResult, EvRegisterTabletResult> { - const ui64 TabletId; - const TIntrusivePtr<TMediatorTimecastEntry> Entry; - - TEvRegisterTabletResult(ui64 tabletId, TIntrusivePtr<TMediatorTimecastEntry> &entry) - : TabletId(tabletId) - , Entry(entry) - {} + }; + + struct TEvRegisterTabletResult : public TEventLocal<TEvRegisterTabletResult, EvRegisterTabletResult> { + const ui64 TabletId; + const TIntrusivePtr<TMediatorTimecastEntry> Entry; + + TEvRegisterTabletResult(ui64 tabletId, TIntrusivePtr<TMediatorTimecastEntry> &entry) + : TabletId(tabletId) + , Entry(entry) + {} TString ToString() const { TStringStream str; @@ -84,14 +84,14 @@ struct TEvMediatorTimecast { str << "}"; return str.Str(); } - }; - - struct TEvUnregisterTablet : public TEventLocal<TEvUnregisterTablet, EvUnregisterTablet> { - const ui64 TabletId; - - TEvUnregisterTablet(ui64 tabletId) - : TabletId(tabletId) - {} + }; + + struct TEvUnregisterTablet : public TEventLocal<TEvUnregisterTablet, EvUnregisterTablet> { + const ui64 TabletId; + + TEvUnregisterTablet(ui64 tabletId) + : TabletId(tabletId) + {} TString ToString() const { TStringStream str; @@ -100,8 +100,8 @@ struct TEvMediatorTimecast { str << "}"; return str.Str(); } - }; - + }; + struct TEvWaitPlanStep : public TEventLocal<TEvWaitPlanStep, EvWaitPlanStep> { const ui64 TabletId; const ui64 PlanStep; @@ -138,14 +138,14 @@ struct TEvMediatorTimecast { } }; - struct TEvWatch : public TEventPB<TEvWatch, NKikimrTxMediatorTimecast::TEvWatch, EvWatch> { - TEvWatch() - {} - - TEvWatch(ui32 bucket) - { - Record.AddBucket(bucket); - } + struct TEvWatch : public TEventPB<TEvWatch, NKikimrTxMediatorTimecast::TEvWatch, EvWatch> { + TEvWatch() + {} + + TEvWatch(ui32 bucket) + { + Record.AddBucket(bucket); + } TString ToString() const { TStringStream str; @@ -156,9 +156,9 @@ struct TEvMediatorTimecast { str << "}"; return str.Str(); } - }; - - struct TEvUpdate : public TEventPB<TEvUpdate, NKikimrTxMediatorTimecast::TEvUpdate, EvUpdate> { + }; + + struct TEvUpdate : public TEventPB<TEvUpdate, NKikimrTxMediatorTimecast::TEvUpdate, EvUpdate> { TString ToString() const { TStringStream str; str << "{TEvUpdate "; @@ -177,13 +177,13 @@ struct TEvMediatorTimecast { str << "}"; return str.Str(); } - }; -}; - -IActor* CreateMediatorTimecastProxy(); - + }; +}; + +IActor* CreateMediatorTimecastProxy(); + inline TActorId MakeMediatorTimecastProxyID() { return TActorId(0, TStringBuf("txmdtimecast")); -} - -} +} + +} diff --git a/ydb/core/tx/tx.cpp b/ydb/core/tx/tx.cpp index 68c51835c3..56b32469ff 100644 --- a/ydb/core/tx/tx.cpp +++ b/ydb/core/tx/tx.cpp @@ -4,7 +4,7 @@ namespace NKikimr { -TEvTxProxy::TEvProposeTransaction::TEvProposeTransaction(ui64 coordinator, ui64 txId, ui8 execLevel, ui64 minStep, ui64 maxStep) { +TEvTxProxy::TEvProposeTransaction::TEvProposeTransaction(ui64 coordinator, ui64 txId, ui8 execLevel, ui64 minStep, ui64 maxStep) { Record.SetCoordinatorID(coordinator); NKikimrTx::TProxyTransaction *x = Record.MutableTransaction(); x->SetTxId(txId); diff --git a/ydb/core/tx/tx.h b/ydb/core/tx/tx.h index 1e560e35ab..bacde44237 100644 --- a/ydb/core/tx/tx.h +++ b/ydb/core/tx/tx.h @@ -1,5 +1,5 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include <ydb/core/base/tabletid.h> #include <ydb/core/base/tablet_types.h> #include <ydb/core/protos/tx.pb.h> @@ -8,51 +8,51 @@ #include <ydb/core/base/appdata.h> #include <library/cpp/actors/core/event_pb.h> - -namespace NKikimr { -struct TEvTxProxy { - enum EEv { - EvProposeTransaction = EventSpaceBegin(TKikimrEvents::ES_TX_PROXY), + +namespace NKikimr { +struct TEvTxProxy { + enum EEv { + EvProposeTransaction = EventSpaceBegin(TKikimrEvents::ES_TX_PROXY), EvAcquireReadStep, - - EvProposeTransactionStatus = EvProposeTransaction + 1 * 512, + + EvProposeTransactionStatus = EvProposeTransaction + 1 * 512, EvAcquireReadStepResult, - - EvEnd - }; - + + EvEnd + }; + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_TX_PROXY), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_TX_PROXY)"); - - struct TEvProposeTransaction : public TEventPB<TEvProposeTransaction, NKikimrTx::TEvProposeTransaction, EvProposeTransaction> { + + struct TEvProposeTransaction : public TEventPB<TEvProposeTransaction, NKikimrTx::TEvProposeTransaction, EvProposeTransaction> { TEvProposeTransaction() = default; - - TEvProposeTransaction(ui64 coordinator, ui64 txId, ui8 execLevel, ui64 minStep, ui64 maxStep); - }; - - struct TEvProposeTransactionStatus : public TEventPB<TEvProposeTransactionStatus, NKikimrTx::TEvProposeTransactionStatus, EvProposeTransactionStatus> { - enum class EStatus { - StatusUnknown, - StatusDeclined, - StatusOutdated, - StatusAborted, - StatusDeclinedNoSpace, + + TEvProposeTransaction(ui64 coordinator, ui64 txId, ui8 execLevel, ui64 minStep, ui64 maxStep); + }; + + struct TEvProposeTransactionStatus : public TEventPB<TEvProposeTransactionStatus, NKikimrTx::TEvProposeTransactionStatus, EvProposeTransactionStatus> { + enum class EStatus { + StatusUnknown, + StatusDeclined, + StatusOutdated, + StatusAborted, + StatusDeclinedNoSpace, StatusRestarting, // coordinator is restarting (tx dropped) - - StatusAccepted = 16, // accepted by coordinator - StatusPlanned, // planned by coordinator - StatusProcessed, // plan entry delivered to all tablets (for synth-exec-level) - StatusConfirmed, // execution confirmed by moderator (for synth-exec-level) - }; - + + StatusAccepted = 16, // accepted by coordinator + StatusPlanned, // planned by coordinator + StatusProcessed, // plan entry delivered to all tablets (for synth-exec-level) + StatusConfirmed, // execution confirmed by moderator (for synth-exec-level) + }; + TEvProposeTransactionStatus() = default; - + TEvProposeTransactionStatus(EStatus status, ui64 txid, ui64 stepId); - - EStatus GetStatus() const { + + EStatus GetStatus() const { Y_VERIFY_DEBUG(Record.HasStatus()); - return static_cast<EStatus>(Record.GetStatus()); - } - }; + return static_cast<EStatus>(Record.GetStatus()); + } + }; struct TEvAcquireReadStep : public TEventPB<TEvAcquireReadStep, NKikimrTx::TEvAcquireReadStep, EvAcquireReadStep> @@ -74,39 +74,39 @@ struct TEvTxProxy { Record.SetStep(step); } }; -}; - -// basic - -struct TExecLevelHierarchy { - struct TEntry { - ui32 ExecLevel; - ui64 ReversedDomainMask; - }; - +}; + +// basic + +struct TExecLevelHierarchy { + struct TEntry { + ui32 ExecLevel; + ui64 ReversedDomainMask; + }; + TVector<TEntry> Entries; - - ui32 Select(ui64 mask) const { - for (ui32 i = 0, e = Entries.size(); i != e; ++i) { - const TEntry &x = Entries[i]; - - if ((x.ReversedDomainMask & mask) == 0) - return x.ExecLevel; - } - return 0; - } -}; - -// test hierarchy -// one availability domain #0. -// one synthetic execution level (#0) with 2 controller shards (#0, #1). -// one domain execution level (#1) with 2 controller shards (#0, #1). -// one proxy #0. -// one mediator (0-#0) -// three dummy tx-tablets in domain (##0-2) -// or 8 data shard in domain (##0-7) -// one scheme shard (#F0) - + + ui32 Select(ui64 mask) const { + for (ui32 i = 0, e = Entries.size(); i != e; ++i) { + const TEntry &x = Entries[i]; + + if ((x.ReversedDomainMask & mask) == 0) + return x.ExecLevel; + } + return 0; + } +}; + +// test hierarchy +// one availability domain #0. +// one synthetic execution level (#0) with 2 controller shards (#0, #1). +// one domain execution level (#1) with 2 controller shards (#0, #1). +// one proxy #0. +// one mediator (0-#0) +// three dummy tx-tablets in domain (##0-2) +// or 8 data shard in domain (##0-7) +// one scheme shard (#F0) + struct TTestTxConfig { static constexpr ui64 DomainUid = 0; static constexpr ui64 Coordinator = 0x0000000000800001; @@ -125,8 +125,8 @@ struct TTestTxConfig { static constexpr ui64 SchemeShard = 0x00000000008587a0; static constexpr ui64 Hive = 0x000000000000A001; static constexpr ui64 UseLessId = 0xFFFFFFFFFFFFFFF; -}; - +}; + struct TEvSubDomain { enum EEv { EvConfigure = EventSpaceBegin(TKikimrEvents::ES_SUB_DOMAIN), @@ -154,7 +154,7 @@ struct TEvSubDomain { TAutoPtr<TEvSubDomain::TEvConfigure> CreateDomainConfigurationFromStatic(const TAppData *appdata, ui64 tabletId); -} +} template<> inline void Out<NKikimr::TEvTxProxy::TEvProposeTransactionStatus::EStatus>(IOutputStream& o, diff --git a/ydb/core/tx/tx_allocator/txallocator__reserve.cpp b/ydb/core/tx/tx_allocator/txallocator__reserve.cpp index be9bda28a1..69473e0f82 100644 --- a/ydb/core/tx/tx_allocator/txallocator__reserve.cpp +++ b/ydb/core/tx/tx_allocator/txallocator__reserve.cpp @@ -64,7 +64,7 @@ struct TTxAllocator::TTxReserve: public TTransactionBase<TTxAllocator> { } }; -ITransaction* TTxAllocator::CreateTxReserve(TEvTxAllocator::TEvAllocate::TPtr &ev) { +ITransaction* TTxAllocator::CreateTxReserve(TEvTxAllocator::TEvAllocate::TPtr &ev) { return new TTxReserve(this, ev); } diff --git a/ydb/core/tx/tx_allocator/txallocator__scheme.cpp b/ydb/core/tx/tx_allocator/txallocator__scheme.cpp index 624a3f0ce9..53e9c11d68 100644 --- a/ydb/core/tx/tx_allocator/txallocator__scheme.cpp +++ b/ydb/core/tx/tx_allocator/txallocator__scheme.cpp @@ -26,7 +26,7 @@ struct TTxAllocator::TTxSchema: public TTransactionBase<TTxAllocator> { } }; -ITransaction* TTxAllocator::CreateTxSchema() { +ITransaction* TTxAllocator::CreateTxSchema() { return new TTxSchema(this); } diff --git a/ydb/core/tx/tx_allocator/txallocator_impl.h b/ydb/core/tx/tx_allocator/txallocator_impl.h index 055ff615e5..5a539f9b7b 100644 --- a/ydb/core/tx/tx_allocator/txallocator_impl.h +++ b/ydb/core/tx/tx_allocator/txallocator_impl.h @@ -10,7 +10,7 @@ namespace NKikimr { using namespace NTabletFlatExecutor; -using NTabletFlatExecutor::ITransaction; +using NTabletFlatExecutor::ITransaction; namespace NTxAllocator { @@ -29,8 +29,8 @@ private: struct TTxSchema; struct TTxReserve; - ITransaction* CreateTxSchema(); - ITransaction* CreateTxReserve(TEvTxAllocator::TEvAllocate::TPtr &ev); + ITransaction* CreateTxSchema(); + ITransaction* CreateTxReserve(TEvTxAllocator::TEvAllocate::TPtr &ev); const ui64 PrivateMarker; TTxAllocatorMonCounters MonCounters; diff --git a/ydb/core/tx/tx_allocator/txallocator_ut_helpers.cpp b/ydb/core/tx/tx_allocator/txallocator_ut_helpers.cpp index 25ef4a9bf4..95566493b6 100644 --- a/ydb/core/tx/tx_allocator/txallocator_ut_helpers.cpp +++ b/ydb/core/tx/tx_allocator/txallocator_ut_helpers.cpp @@ -76,7 +76,7 @@ void TTestEnv::Setup(TTestActorRuntime &runtime) { SetupLogging(runtime); TAppPrepare app; auto domain = TDomainsInfo::TDomain::ConstructDomainWithExplicitTabletIds("dc-1", domainId, 0, - domainId, domainId, TVector<ui32>{domainId}, + domainId, domainId, TVector<ui32>{domainId}, domainId, TVector<ui32>{domainId}, 100500, TVector<ui64>{}, diff --git a/ydb/core/tx/tx_processing.h b/ydb/core/tx/tx_processing.h index 52bdea91c7..72276c1af3 100644 --- a/ydb/core/tx/tx_processing.h +++ b/ydb/core/tx/tx_processing.h @@ -1,44 +1,44 @@ -#pragma once -#include "defs.h" -#include "tx.h" - -namespace NKikimr { - -struct TEvTxProcessing { - enum EEv { - EvPlanStep = EventSpaceBegin(TKikimrEvents::ES_TX_PROCESSING), - EvReadSet, - EvPrePlanTx, // unused +#pragma once +#include "defs.h" +#include "tx.h" + +namespace NKikimr { + +struct TEvTxProcessing { + enum EEv { + EvPlanStep = EventSpaceBegin(TKikimrEvents::ES_TX_PROCESSING), + EvReadSet, + EvPrePlanTx, // unused EvStreamClearanceRequest, EvStreamQuotaRequest, EvStreamQuotaRelease, EvStreamIsDead, EvInterruptTransaction, - - EvPlanStepAck = EvPlanStep + 512, - EvPrePlanTxAck, // unused + + EvPlanStepAck = EvPlanStep + 512, + EvPrePlanTxAck, // unused EvReadSetAck, - EvPlanStepAccepted, + EvPlanStepAccepted, EvStreamClearanceResponse, EvStreamQuotaResponse, EvStreamClearancePending, EvStreamDataAck, - - EvEnd - }; - + + EvEnd + }; + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_TX_PROCESSING), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_TX_PROCESSING)"); - - struct TEvPlanStep : public TEventPB<TEvPlanStep, NKikimrTx::TEvMediatorPlanStep, EvPlanStep> { - TEvPlanStep() - {} - - TEvPlanStep(ui64 step, ui64 mediator, ui64 tablet) - { - Record.SetStep(step); - Record.SetMediatorID(mediator); - Record.SetTabletID(tablet); - } + + struct TEvPlanStep : public TEventPB<TEvPlanStep, NKikimrTx::TEvMediatorPlanStep, EvPlanStep> { + TEvPlanStep() + {} + + TEvPlanStep(ui64 step, ui64 mediator, ui64 tablet) + { + Record.SetStep(step); + Record.SetMediatorID(mediator); + Record.SetTabletID(tablet); + } TString ToString() const { TStringStream str; @@ -48,12 +48,12 @@ struct TEvTxProcessing { str << "}"; return str.Str(); } - }; - - struct TEvPlanStepAck : public TEventPB<TEvPlanStepAck, NKikimrTx::TEvPlanStepAck, EvPlanStepAck> { - TEvPlanStepAck() - {} - + }; + + struct TEvPlanStepAck : public TEventPB<TEvPlanStepAck, NKikimrTx::TEvPlanStepAck, EvPlanStepAck> { + TEvPlanStepAck() + {} + TEvPlanStepAck(ui64 tabletId, ui64 step, ui64 txid) { Record.SetTabletId(tabletId); @@ -61,18 +61,18 @@ struct TEvTxProcessing { Record.AddTxId(txid); } - template<typename TIterator> - TEvPlanStepAck(ui64 tabletId, ui64 step, TIterator begin, const TIterator &end) - { - Record.SetTabletId(tabletId); - Record.SetStep(step); - - while (begin != end) { + template<typename TIterator> + TEvPlanStepAck(ui64 tabletId, ui64 step, TIterator begin, const TIterator &end) + { + Record.SetTabletId(tabletId); + Record.SetStep(step); + + while (begin != end) { const ui64 x = ui64(*begin); - Record.AddTxId(x); - ++begin; - } - } + Record.AddTxId(x); + ++begin; + } + } TString ToString() const { TStringStream str; @@ -84,17 +84,17 @@ struct TEvTxProcessing { str << "}"; return str.Str(); } - }; - - struct TEvPlanStepAccepted : public TEventPB<TEvPlanStepAccepted, NKikimrTx::TEvPlanStepAccepted, EvPlanStepAccepted> { - TEvPlanStepAccepted() - {} - - TEvPlanStepAccepted(ui64 tabletId, ui64 step) - { - Record.SetTabletId(tabletId); - Record.SetStep(step); - } + }; + + struct TEvPlanStepAccepted : public TEventPB<TEvPlanStepAccepted, NKikimrTx::TEvPlanStepAccepted, EvPlanStepAccepted> { + TEvPlanStepAccepted() + {} + + TEvPlanStepAccepted(ui64 tabletId, ui64 step) + { + Record.SetTabletId(tabletId); + Record.SetStep(step); + } TString ToString() const { TStringStream str; @@ -103,22 +103,22 @@ struct TEvTxProcessing { str << "}"; return str.Str(); } - }; - - struct TEvReadSet : public TEventPB<TEvReadSet, NKikimrTx::TEvReadSet, EvReadSet> { - TEvReadSet() - {} - + }; + + struct TEvReadSet : public TEventPB<TEvReadSet, NKikimrTx::TEvReadSet, EvReadSet> { + TEvReadSet() + {} + TEvReadSet(ui64 step, ui64 orderId, ui64 tabletSource, ui64 tabletDest, ui64 tabletProducer, const TString &readSet, ui64 seqno = 0) - { - Record.SetStep(step); - Record.SetTxId(orderId); - Record.SetTabletSource(tabletSource); - Record.SetTabletDest(tabletDest); + { + Record.SetStep(step); + Record.SetTxId(orderId); + Record.SetTabletSource(tabletSource); + Record.SetTabletDest(tabletDest); Record.SetTabletProducer(tabletProducer); - Record.SetReadSet(readSet); + Record.SetReadSet(readSet); Record.SetSeqno(seqno); - } + } TString ToString() const { TStringStream str; @@ -133,7 +133,7 @@ struct TEvTxProcessing { str << "}"; return str.Str(); } - }; + }; struct TEvReadSetAck : public TThrRefBase, public TEventPB<TEvReadSetAck, NKikimrTx::TEvReadSetAck, EvReadSetAck> { TEvReadSetAck() @@ -244,6 +244,6 @@ struct TEvTxProcessing { EvStreamDataAck> { }; -}; - -} +}; + +} diff --git a/ydb/core/tx/tx_proxy/datareq.cpp b/ydb/core/tx/tx_proxy/datareq.cpp index 034c76354b..af48b42d60 100644 --- a/ydb/core/tx/tx_proxy/datareq.cpp +++ b/ydb/core/tx/tx_proxy/datareq.cpp @@ -27,16 +27,16 @@ #include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/actors/core/hfunc.h> -#include <util/generic/hash_set.h> +#include <util/generic/hash_set.h> #include <util/generic/queue.h> - -#ifndef KIKIMR_DATAREQ_WATCHDOG_PERIOD -#define KIKIMR_DATAREQ_WATCHDOG_PERIOD 10000 -#endif - -namespace NKikimr { -namespace NTxProxy { - + +#ifndef KIKIMR_DATAREQ_WATCHDOG_PERIOD +#define KIKIMR_DATAREQ_WATCHDOG_PERIOD 10000 +#endif + +namespace NKikimr { +namespace NTxProxy { + const ui32 MaxDatashardProgramSize = 48 * 1024 * 1024; // 48 MB const ui32 ShardCancelDeadlineShiftSec = 60; @@ -46,8 +46,8 @@ namespace { static constexpr TDuration MaxReattachDuration = TDuration::Seconds(4); } -struct TFlatMKQLRequest : public TThrRefBase { - TAutoPtr<NMiniKQL::IEngineFlat> Engine; +struct TFlatMKQLRequest : public TThrRefBase { + TAutoPtr<NMiniKQL::IEngineFlat> Engine; ui64 LockTxId; bool NeedDiagnostics; bool LlvmRuntime; @@ -56,14 +56,14 @@ struct TFlatMKQLRequest : public TThrRefBase { TMaybe<ui64> PerShardKeysSizeLimitBytes; NKikimrTxUserProxy::TMiniKQLTransaction::TLimits Limits; TRowVersion Snapshot = TRowVersion::Min(); - + TMap<ui64, TAutoPtr<TBalanceCoverageBuilder>> BalanceCoverageBuilders; - - NMiniKQL::IEngineFlat::EResult EngineResultStatusCode; - NMiniKQL::IEngineFlat::EStatus EngineResponseStatus; + + NMiniKQL::IEngineFlat::EResult EngineResultStatusCode; + NMiniKQL::IEngineFlat::EStatus EngineResponseStatus; TString EngineResponse; - NKikimrMiniKQL::TResult EngineEvaluatedResponse; - + NKikimrMiniKQL::TResult EngineEvaluatedResponse; + TFlatMKQLRequest() : LockTxId(0) , NeedDiagnostics(false) @@ -71,8 +71,8 @@ struct TFlatMKQLRequest : public TThrRefBase { , CollectStats(false) , ReadOnlyProgram(false) , EngineResultStatusCode(NMiniKQL::IEngineFlat::EResult::Unknown) - , EngineResponseStatus(NMiniKQL::IEngineFlat::EStatus::Unknown) - {} + , EngineResponseStatus(NMiniKQL::IEngineFlat::EStatus::Unknown) + {} void RequestAdditionResults(ui64 txId) { auto lockTxId = Engine->GetLockTxId(); @@ -83,8 +83,8 @@ struct TFlatMKQLRequest : public TThrRefBase { NeedDiagnostics = Engine->HasDiagnosticsRequest(); } -}; - +}; + // Class used to merge key ranges and arrange shards for ordered scans. class TKeySpace { public: @@ -182,7 +182,7 @@ struct TReadTableRequest : public TThrRefBase { } }; -class TDataReq : public TActor<TDataReq> { +class TDataReq : public TActor<TDataReq> { public: enum class EParseRangeKeyExp { NONE, @@ -239,14 +239,14 @@ public: } }; - struct TPerTablet { - enum { - AffectedRead = 1 << 0, - AffectedWrite = 1 << 1, - }; - + struct TPerTablet { + enum { + AffectedRead = 1 << 0, + AffectedWrite = 1 << 1, + }; + #define DATA_REQ_PER_TABLET_STATUS_MAP(XX) \ - XX(StatusUnknown, 128) \ + XX(StatusUnknown, 128) \ XX(StatusWait, 0) \ XX(StatusPrepared, 1) \ XX(StatusError, 2) \ @@ -254,36 +254,36 @@ public: enum class ETabletStatus { DATA_REQ_PER_TABLET_STATUS_MAP(ENUM_VALUE_GEN) - }; - - ui64 MinStep = 0; - ui64 MaxStep = 0; - ui32 AffectedFlags = 0; - ETabletStatus TabletStatus = ETabletStatus::StatusUnknown; - ui64 ReadSize = 0; - ui64 ReplySize = 0; + }; + + ui64 MinStep = 0; + ui64 MaxStep = 0; + ui32 AffectedFlags = 0; + ETabletStatus TabletStatus = ETabletStatus::StatusUnknown; + ui64 ReadSize = 0; + ui64 ReplySize = 0; ui64 ProgramSize = 0; - ui64 IncomingReadSetsSize = 0; + ui64 IncomingReadSetsSize = 0; ui64 OutgoingReadSetsSize = 0; bool StreamCleared = false; bool Restarting = false; size_t RestartCount = 0; - TTableId TableId; + TTableId TableId; THolder<NKikimrQueryStats::TTxStats> Stats; TReattachState ReattachState; - }; + }; private: - - struct TEvPrivate { - enum EEv { - EvProxyDataReqOngoingTransactionsWatchdog = EventSpaceBegin(TEvents::ES_PRIVATE), + + struct TEvPrivate { + enum EEv { + EvProxyDataReqOngoingTransactionsWatchdog = EventSpaceBegin(TEvents::ES_PRIVATE), EvReattachToShard, - EvEnd - }; - - static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)"); - - struct TEvProxyDataReqOngoingTransactionWatchdog : public TEventSimple<TEvProxyDataReqOngoingTransactionWatchdog, EvProxyDataReqOngoingTransactionsWatchdog> {}; + EvEnd + }; + + static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)"); + + struct TEvProxyDataReqOngoingTransactionWatchdog : public TEventSimple<TEvProxyDataReqOngoingTransactionWatchdog, EvProxyDataReqOngoingTransactionsWatchdog> {}; struct TEvReattachToShard : public TEventLocal<TEvReattachToShard, EvReattachToShard> { const ui64 TabletId; @@ -292,82 +292,82 @@ private: : TabletId(tabletId) { } }; - }; - - const TTxProxyServices Services; - const ui64 TxId; - ui64 SelectedCoordinator; - - ui64 ProxyFlags; - TDuration ExecTimeoutPeriod; + }; + + const TTxProxyServices Services; + const ui64 TxId; + ui64 SelectedCoordinator; + + ui64 ProxyFlags; + TDuration ExecTimeoutPeriod; TDuration CancelAfter; - TSchedulerCookieHolder ExecTimeoutCookieHolder; - + TSchedulerCookieHolder ExecTimeoutCookieHolder; + TActorId RequestSource; ui32 TxFlags; bool CanUseFollower; bool StreamResponse; - - TIntrusivePtr<TFlatMKQLRequest> FlatMKQLRequest; + + TIntrusivePtr<TFlatMKQLRequest> FlatMKQLRequest; TIntrusivePtr<TReadTableRequest> ReadTableRequest; TString DatashardErrors; TVector<ui64> ComplainingDatashards; TVector<TString> UnresolvedKeys; TAutoPtr<const NACLib::TUserToken> UserToken; - + THashMap<ui64, TPerTablet> PerTablet; - NYql::TIssueManager IssueManager; + NYql::TIssueManager IssueManager; TTablePathHashSet InvalidatedTables; - ui64 TabletsLeft; // todo: add scale modifiers - ui64 TabletErrors; - - ui64 AggrMinStep; - ui64 AggrMaxStep; - - ui64 PlanStep; + ui64 TabletsLeft; // todo: add scale modifiers + ui64 TabletErrors; + + ui64 AggrMinStep; + ui64 AggrMaxStep; + + ui64 PlanStep; ECoordinatorStatus CoordinatorStatus = ECoordinatorStatus::Unknown; - + ui64 ResultsReceivedCount; ui64 ResultsReceivedSize; TRequestControls RequestControls; - TInstant WallClockAccepted; + TInstant WallClockAccepted; TInstant WallClockResolveStarted; - TInstant WallClockResolved; - TInstant WallClockPrepared; - TInstant WallClockPlanned; - - TDuration ElapsedPrepareExec; - TDuration ElapsedExecExec; - TDuration ElapsedPrepareComplete; - TDuration ElapsedExecComplete; - - TInstant WallClockFirstPrepareReply; - TInstant WallClockLastPrepareReply; - - TInstant WallClockMinPrepareArrive; - TInstant WallClockMaxPrepareArrive; - TDuration WallClockMinPrepareComplete; - TDuration WallClockMaxPrepareComplete; - - TInstant WallClockFirstExecReply; - TInstant WallClockLastExecReply; - + TInstant WallClockResolved; + TInstant WallClockPrepared; + TInstant WallClockPlanned; + + TDuration ElapsedPrepareExec; + TDuration ElapsedExecExec; + TDuration ElapsedPrepareComplete; + TDuration ElapsedExecComplete; + + TInstant WallClockFirstPrepareReply; + TInstant WallClockLastPrepareReply; + + TInstant WallClockMinPrepareArrive; + TInstant WallClockMaxPrepareArrive; + TDuration WallClockMinPrepareComplete; + TDuration WallClockMaxPrepareComplete; + + TInstant WallClockFirstExecReply; + TInstant WallClockLastExecReply; + TDuration CpuTime; - TAutoPtr<TEvTxProxySchemeCache::TEvResolveKeySet> PrepareFlatMKQLRequest(TStringBuf miniKQLProgram, TStringBuf miniKQLParams, const TActorContext &ctx); + TAutoPtr<TEvTxProxySchemeCache::TEvResolveKeySet> PrepareFlatMKQLRequest(TStringBuf miniKQLProgram, TStringBuf miniKQLParams, const TActorContext &ctx); void ProcessFlatMKQLResolve(NSchemeCache::TSchemeCacheRequest *cacheRequest, const TActorContext &ctx); void ProcessReadTableResolve(NSchemeCache::TSchemeCacheRequest *cacheRequest, const TActorContext &ctx); - + TIntrusivePtr<TTxProxyMon> TxProxyMon; - void Die(const TActorContext &ctx) override { - --*TxProxyMon->DataReqInFly; - + void Die(const TActorContext &ctx) override { + --*TxProxyMon->DataReqInFly; + Send(Services.FollowerPipeCache, new TEvPipeCache::TEvUnlink(0)); Send(Services.LeaderPipeCache, new TEvPipeCache::TEvUnlink(0)); - + ProcessStreamClearance(false, ctx); if (ReadTableRequest) { for (auto &tr : ReadTableRequest->StreamingShards) { @@ -375,19 +375,19 @@ private: } } - TActor::Die(ctx); - } - + TActor::Die(ctx); + } + static TInstant Now() { return AppData()->TimeProvider->Now(); } - void ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus status, NKikimrIssues::TStatusIds::EStatusCode code, bool reportIssues, const TActorContext &ctx); - void MarkShardError(ui64 tabletId, TDataReq::TPerTablet &perTablet, bool invalidateDistCache, const TActorContext &ctx); - void TryToInvalidateTable(TTableId tableId, const TActorContext &ctx); - - void RegisterPlan(const TActorContext &ctx); - void MergeResult(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, const TActorContext &ctx); + void ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus status, NKikimrIssues::TStatusIds::EStatusCode code, bool reportIssues, const TActorContext &ctx); + void MarkShardError(ui64 tabletId, TDataReq::TPerTablet &perTablet, bool invalidateDistCache, const TActorContext &ctx); + void TryToInvalidateTable(TTableId tableId, const TActorContext &ctx); + + void RegisterPlan(const TActorContext &ctx); + void MergeResult(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, const TActorContext &ctx); void MakeFlatMKQLResponse(const TActorContext &ctx, const NCpuTime::TCpuTimer& timer); void ProcessStreamResponseData(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, @@ -397,41 +397,41 @@ private: ui64 SelectCoordinator(NSchemeCache::TSchemeCacheRequest &cacheRequest, const TActorContext &ctx); const TDomainsInfo::TDomain& SelectDomain(NSchemeCache::TSchemeCacheRequest &cacheRequest, const TActorContext &ctx); - - void HandleWatchdog(const TActorContext &ctx); - + + void HandleWatchdog(const TActorContext &ctx); + void HandleUndeliveredResolve(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx); - void Handle(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx); - - void Handle(TEvTxProxyReq::TEvMakeRequest::TPtr &ev, const TActorContext &ctx); + void Handle(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx); + + void Handle(TEvTxProxyReq::TEvMakeRequest::TPtr &ev, const TActorContext &ctx); void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev, const TActorContext &ctx); - void Handle(TEvTxProxySchemeCache::TEvResolveKeySetResult::TPtr &ev, const TActorContext &ctx); + void Handle(TEvTxProxySchemeCache::TEvResolveKeySetResult::TPtr &ev, const TActorContext &ctx); void Handle(TEvDataShard::TEvProposeTransactionRestart::TPtr &ev, const TActorContext &ctx); void HandlePrepare(TEvDataShard::TEvProposeTransactionAttachResult::TPtr &ev, const TActorContext &ctx); - void HandlePrepare(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, const TActorContext &ctx); - void HandlePrepareErrors(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, const TActorContext &ctx); - void HandlePrepareErrorTimeout(const TActorContext &ctx); + void HandlePrepare(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, const TActorContext &ctx); + void HandlePrepareErrors(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, const TActorContext &ctx); + void HandlePrepareErrorTimeout(const TActorContext &ctx); void HandlePlan(TEvDataShard::TEvProposeTransactionAttachResult::TPtr &ev, const TActorContext &ctx); - void HandlePlan(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, const TActorContext &ctx); + void HandlePlan(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, const TActorContext &ctx); void Handle(TEvDataShard::TEvGetReadTableSinkStateRequest::TPtr &ev, const TActorContext &ctx); void Handle(TEvDataShard::TEvGetReadTableStreamStateRequest::TPtr &ev, const TActorContext &ctx); - void Handle(TEvTxProxy::TEvProposeTransactionStatus::TPtr &ev, const TActorContext &ctx); + void Handle(TEvTxProxy::TEvProposeTransactionStatus::TPtr &ev, const TActorContext &ctx); void Handle(TEvTxProcessing::TEvStreamClearanceRequest::TPtr &ev, const TActorContext &ctx); void Handle(TEvTxProcessing::TEvStreamIsDead::TPtr &ev, const TActorContext &ctx); - void HandleResolve(TEvTxProcessing::TEvStreamIsDead::TPtr &ev, const TActorContext &ctx); + void HandleResolve(TEvTxProcessing::TEvStreamIsDead::TPtr &ev, const TActorContext &ctx); void Handle(TEvTxProcessing::TEvStreamQuotaRequest::TPtr &ev, const TActorContext &ctx); void Handle(TEvTxProcessing::TEvStreamQuotaResponse::TPtr &ev, const TActorContext &ctx); void Handle(TEvTxProcessing::TEvStreamQuotaRelease::TPtr &ev, const TActorContext &ctx); - + void Handle(TEvPrivate::TEvReattachToShard::TPtr &ev, const TActorContext &ctx); - void HandlePrepare(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TActorContext &ctx); - void HandlePrepareErrors(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TActorContext &ctx); - void HandlePlan(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TActorContext &ctx); - void HandleExecTimeout(const TActorContext &ctx); - void HandleExecTimeoutResolve(const TActorContext &ctx); + void HandlePrepare(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TActorContext &ctx); + void HandlePrepareErrors(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TActorContext &ctx); + void HandlePlan(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TActorContext &ctx); + void HandleExecTimeout(const TActorContext &ctx); + void HandleExecTimeoutResolve(const TActorContext &ctx); void ExtractDatashardErrors(const NKikimrTxDataShard::TEvProposeTransactionResult & record); - void CancelProposal(ui64 exceptTablet); + void CancelProposal(ui64 exceptTablet); void FailProposedRequest(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus status, TString errMsg, const TActorContext &ctx); void SendStreamClearanceResponse(ui64 shard, bool cleared, const TActorContext &ctx); @@ -447,25 +447,25 @@ private: void BuildTxStats(NKikimrQueryStats::TTxStats& stats); bool IsReadOnlyRequest() const; -public: +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TX_REQ_PROXY; } TDataReq(const TTxProxyServices &services, ui64 txid, const TIntrusivePtr<TTxProxyMon> mon, const TRequestControls& requestControls) - : TActor(&TThis::StateWaitInit) - , Services(services) - , TxId(txid) - , SelectedCoordinator(0) - , ProxyFlags(0) + : TActor(&TThis::StateWaitInit) + , Services(services) + , TxId(txid) + , SelectedCoordinator(0) + , ProxyFlags(0) , TxFlags(0) , CanUseFollower(true) - , TabletsLeft(0) - , TabletErrors(0) - , AggrMinStep(0) - , AggrMaxStep(Max<ui64>()) - , PlanStep(0) + , TabletsLeft(0) + , TabletErrors(0) + , AggrMinStep(0) + , AggrMaxStep(Max<ui64>()) + , PlanStep(0) , ResultsReceivedCount(0) , ResultsReceivedSize(0) , RequestControls(requestControls) @@ -475,41 +475,41 @@ public: , WallClockPrepared(TInstant::MicroSeconds(0)) , WallClockPlanned(TInstant::MicroSeconds(0)) , TxProxyMon(mon) - { - ++*TxProxyMon->DataReqInFly; - } - - STFUNC(StateWaitInit) { + { + ++*TxProxyMon->DataReqInFly; + } + + STFUNC(StateWaitInit) { TRACE_EVENT(NKikimrServices::TX_PROXY); - switch (ev->GetTypeRewrite()) { + switch (ev->GetTypeRewrite()) { HFuncTraced(TEvTxProxyReq::TEvMakeRequest, Handle); - } - } - - STFUNC(StateWaitResolve) { + } + } + + STFUNC(StateWaitResolve) { TRACE_EVENT(NKikimrServices::TX_PROXY); - switch (ev->GetTypeRewrite()) { - HFuncTraced(TEvTxProcessing::TEvStreamIsDead, HandleResolve); + switch (ev->GetTypeRewrite()) { + HFuncTraced(TEvTxProcessing::TEvStreamIsDead, HandleResolve); HFuncTraced(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle); HFuncTraced(TEvTxProxySchemeCache::TEvResolveKeySetResult, Handle); HFuncTraced(TEvents::TEvUndelivered, HandleUndeliveredResolve); // we must wait for resolve completion - CFunc(TEvents::TSystem::Wakeup, HandleExecTimeoutResolve); // we must wait for resolve completion to keep key description - CFunc(TEvPrivate::EvProxyDataReqOngoingTransactionsWatchdog, HandleWatchdog); - } - } - - // resolve zombie state to keep shared key desc - STFUNC(StateResolveTimeout) { - TRACE_EVENT(NKikimrServices::TX_PROXY); - switch (ev->GetTypeRewrite()) { - CFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult::EventType, Die); - CFunc(TEvTxProxySchemeCache::TEvResolveKeySetResult::EventType, Die); - } - } - - STFUNC(StateWaitPrepare) { + CFunc(TEvents::TSystem::Wakeup, HandleExecTimeoutResolve); // we must wait for resolve completion to keep key description + CFunc(TEvPrivate::EvProxyDataReqOngoingTransactionsWatchdog, HandleWatchdog); + } + } + + // resolve zombie state to keep shared key desc + STFUNC(StateResolveTimeout) { TRACE_EVENT(NKikimrServices::TX_PROXY); - switch (ev->GetTypeRewrite()) { + switch (ev->GetTypeRewrite()) { + CFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult::EventType, Die); + CFunc(TEvTxProxySchemeCache::TEvResolveKeySetResult::EventType, Die); + } + } + + STFUNC(StateWaitPrepare) { + TRACE_EVENT(NKikimrServices::TX_PROXY); + switch (ev->GetTypeRewrite()) { HFuncTraced(TEvDataShard::TEvGetReadTableSinkStateRequest, Handle); HFuncTraced(TEvDataShard::TEvGetReadTableStreamStateRequest, Handle); HFuncTraced(TEvDataShard::TEvProposeTransactionResult, HandlePrepare); @@ -520,28 +520,28 @@ public: HFuncTraced(TEvTxProcessing::TEvStreamQuotaRequest, Handle); HFuncTraced(TEvTxProcessing::TEvStreamQuotaResponse, Handle); HFuncTraced(TEvTxProcessing::TEvStreamQuotaRelease, Handle); - HFuncTraced(TEvPipeCache::TEvDeliveryProblem, HandlePrepare); + HFuncTraced(TEvPipeCache::TEvDeliveryProblem, HandlePrepare); HFuncTraced(TEvPrivate::TEvReattachToShard, Handle); - HFuncTraced(TEvents::TEvUndelivered, Handle); + HFuncTraced(TEvents::TEvUndelivered, Handle); CFunc(TEvents::TSystem::Wakeup, HandleExecTimeout); - CFunc(TEvPrivate::EvProxyDataReqOngoingTransactionsWatchdog, HandleWatchdog); - } - } - - STFUNC(StatePrepareErrors) { + CFunc(TEvPrivate::EvProxyDataReqOngoingTransactionsWatchdog, HandleWatchdog); + } + } + + STFUNC(StatePrepareErrors) { TRACE_EVENT(NKikimrServices::TX_PROXY); - switch (ev->GetTypeRewrite()) { + switch (ev->GetTypeRewrite()) { HFuncTraced(TEvDataShard::TEvProposeTransactionResult, HandlePrepareErrors); HFuncTraced(TEvTxProcessing::TEvStreamIsDead, Handle); - HFuncTraced(TEvPipeCache::TEvDeliveryProblem, HandlePrepareErrors); - HFuncTraced(TEvents::TEvUndelivered, Handle); - CFunc(TEvents::TSystem::Wakeup, HandlePrepareErrorTimeout); - } - } - - STFUNC(StateWaitPlan) { + HFuncTraced(TEvPipeCache::TEvDeliveryProblem, HandlePrepareErrors); + HFuncTraced(TEvents::TEvUndelivered, Handle); + CFunc(TEvents::TSystem::Wakeup, HandlePrepareErrorTimeout); + } + } + + STFUNC(StateWaitPlan) { TRACE_EVENT(NKikimrServices::TX_PROXY); - switch (ev->GetTypeRewrite()) { + switch (ev->GetTypeRewrite()) { HFuncTraced(TEvDataShard::TEvGetReadTableSinkStateRequest, Handle); HFuncTraced(TEvDataShard::TEvGetReadTableStreamStateRequest, Handle); HFuncTraced(TEvTxProxy::TEvProposeTransactionStatus, Handle); @@ -553,15 +553,15 @@ public: HFuncTraced(TEvTxProcessing::TEvStreamQuotaRequest, Handle); HFuncTraced(TEvTxProcessing::TEvStreamQuotaResponse, Handle); HFuncTraced(TEvTxProcessing::TEvStreamQuotaRelease, Handle); - HFuncTraced(TEvPipeCache::TEvDeliveryProblem, HandlePlan); + HFuncTraced(TEvPipeCache::TEvDeliveryProblem, HandlePlan); HFuncTraced(TEvPrivate::TEvReattachToShard, Handle); - HFuncTraced(TEvents::TEvUndelivered, Handle); + HFuncTraced(TEvents::TEvUndelivered, Handle); CFunc(TEvents::TSystem::Wakeup, HandleExecTimeout); - CFunc(TEvPrivate::EvProxyDataReqOngoingTransactionsWatchdog, HandleWatchdog); - } - } -}; - + CFunc(TEvPrivate::EvProxyDataReqOngoingTransactionsWatchdog, HandleWatchdog); + } + } +}; + TKeySpace::TKeySpace() : OrderedQueue(false) { @@ -707,39 +707,39 @@ bool TKeySpace::TryToMergeWithPrev(TRanges::iterator it) return false; } -void TDataReq::ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus status, NKikimrIssues::TStatusIds::EStatusCode code, bool reportIssues, const TActorContext &ctx) { - auto *x = new TEvTxUserProxy::TEvProposeTransactionStatus(status); - x->Record.SetTxId(TxId); - - if (reportIssues && IssueManager.GetIssues()) { - IssuesToMessage(IssueManager.GetIssues(), x->Record.MutableIssues()); - IssueManager.Reset(); - } - - x->Record.SetStatusCode(code); - +void TDataReq::ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus status, NKikimrIssues::TStatusIds::EStatusCode code, bool reportIssues, const TActorContext &ctx) { + auto *x = new TEvTxUserProxy::TEvProposeTransactionStatus(status); + x->Record.SetTxId(TxId); + + if (reportIssues && IssueManager.GetIssues()) { + IssuesToMessage(IssueManager.GetIssues(), x->Record.MutableIssues()); + IssueManager.Reset(); + } + + x->Record.SetStatusCode(code); + for (auto& unresolvedKey : UnresolvedKeys) { x->Record.AddUnresolvedKeys(unresolvedKey); } - if (PlanStep) - x->Record.SetStep(PlanStep); - - if (FlatMKQLRequest) { - x->Record.SetExecutionEngineStatus((ui32)FlatMKQLRequest->EngineResultStatusCode); - if (FlatMKQLRequest->EngineResponseStatus != NMiniKQL::IEngineFlat::EStatus::Unknown) - x->Record.SetExecutionEngineResponseStatus((ui32)FlatMKQLRequest->EngineResponseStatus); - if (!FlatMKQLRequest->EngineResponse.empty()) - x->Record.SetExecutionEngineResponse(FlatMKQLRequest->EngineResponse); + if (PlanStep) + x->Record.SetStep(PlanStep); + + if (FlatMKQLRequest) { + x->Record.SetExecutionEngineStatus((ui32)FlatMKQLRequest->EngineResultStatusCode); + if (FlatMKQLRequest->EngineResponseStatus != NMiniKQL::IEngineFlat::EStatus::Unknown) + x->Record.SetExecutionEngineResponseStatus((ui32)FlatMKQLRequest->EngineResponseStatus); + if (!FlatMKQLRequest->EngineResponse.empty()) + x->Record.SetExecutionEngineResponse(FlatMKQLRequest->EngineResponse); x->Record.MutableExecutionEngineEvaluatedResponse()->Swap(&FlatMKQLRequest->EngineEvaluatedResponse); - if (FlatMKQLRequest->Engine) { - auto errors = FlatMKQLRequest->Engine->GetErrors(); + if (FlatMKQLRequest->Engine) { + auto errors = FlatMKQLRequest->Engine->GetErrors(); if (!errors.empty()) { - x->Record.SetMiniKQLErrors(errors); - } - } - } - + x->Record.SetMiniKQLErrors(errors); + } + } + } + if (ReadTableRequest) { x->Record.SetSerializedReadTableResponse(ReadTableRequest->ResponseData); x->Record.SetDataShardTabletId(ReadTableRequest->ResponseDataFrom); @@ -749,36 +749,36 @@ void TDataReq::ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus if (!DatashardErrors.empty()) x->Record.SetDataShardErrors(DatashardErrors); - if (const ui32 cs = ComplainingDatashards.size()) { - x->Record.MutableComplainingDataShards()->Reserve(cs); - for (auto ds : ComplainingDatashards) - x->Record.AddComplainingDataShards(ds); - } - - if (ProxyFlags & TEvTxUserProxy::TEvProposeTransaction::ProxyTrackWallClock) { + if (const ui32 cs = ComplainingDatashards.size()) { + x->Record.MutableComplainingDataShards()->Reserve(cs); + for (auto ds : ComplainingDatashards) + x->Record.AddComplainingDataShards(ds); + } + + if (ProxyFlags & TEvTxUserProxy::TEvProposeTransaction::ProxyTrackWallClock) { auto *timings = x->Record.MutableTimings(); - if (WallClockAccepted.GetValue()) + if (WallClockAccepted.GetValue()) timings->SetWallClockAccepted(WallClockAccepted.MicroSeconds()); - if (WallClockResolved.GetValue()) + if (WallClockResolved.GetValue()) timings->SetWallClockResolved(WallClockResolved.MicroSeconds()); - if (WallClockPrepared.GetValue()) + if (WallClockPrepared.GetValue()) timings->SetWallClockPrepared(WallClockPrepared.MicroSeconds()); - if (WallClockPlanned.GetValue()) + if (WallClockPlanned.GetValue()) timings->SetWallClockPlanned(WallClockPlanned.MicroSeconds()); - if (ElapsedExecExec.GetValue()) + if (ElapsedExecExec.GetValue()) timings->SetElapsedExecExec(ElapsedExecExec.MicroSeconds()); - if (ElapsedExecComplete.GetValue()) + if (ElapsedExecComplete.GetValue()) timings->SetElapsedExecComplete(ElapsedExecComplete.MicroSeconds()); - if (ElapsedPrepareExec.GetValue()) + if (ElapsedPrepareExec.GetValue()) timings->SetElapsedPrepareExec(ElapsedExecExec.MicroSeconds()); - if (ElapsedPrepareComplete.GetValue()) + if (ElapsedPrepareComplete.GetValue()) timings->SetElapsedPrepareComplete(ElapsedExecComplete.MicroSeconds()); timings->SetWallClockNow(Now().MicroSeconds()); - } - + } + TInstant wallClockEnd = Now(); - TDuration prepareTime = WallClockPrepared.GetValue() ? WallClockPrepared - WallClockAccepted : TDuration::Zero(); - TDuration executeTime = WallClockPrepared.GetValue() ? wallClockEnd - WallClockPrepared : wallClockEnd - WallClockAccepted; + TDuration prepareTime = WallClockPrepared.GetValue() ? WallClockPrepared - WallClockAccepted : TDuration::Zero(); + TDuration executeTime = WallClockPrepared.GetValue() ? wallClockEnd - WallClockPrepared : wallClockEnd - WallClockAccepted; TDuration totalTime = wallClockEnd - WallClockAccepted; (*TxProxyMon->ResultsReceivedCount) += ResultsReceivedCount; @@ -797,58 +797,58 @@ void TDataReq::ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus stats->SetDurationUs(totalTime.MicroSeconds()); } - switch (status) { - case TEvTxUserProxy::TResultStatus::ProxyAccepted: - case TEvTxUserProxy::TResultStatus::ProxyResolved: - case TEvTxUserProxy::TResultStatus::ProxyPrepared: - case TEvTxUserProxy::TResultStatus::CoordinatorPlanned: - case TEvTxUserProxy::TResultStatus::ExecComplete: - case TEvTxUserProxy::TResultStatus::ExecAborted: - case TEvTxUserProxy::TResultStatus::ExecAlready: - LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_INFO, NKikimrServices::TX_PROXY, TxId, - "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId - << " RESPONSE Status# " << TEvTxUserProxy::TResultStatus::Str(status) - << " prepare time: " << prepareTime.ToString() - << " execute time: " << executeTime.ToString() - << " total time: " << totalTime.ToString() - << " marker# P13"); - + switch (status) { + case TEvTxUserProxy::TResultStatus::ProxyAccepted: + case TEvTxUserProxy::TResultStatus::ProxyResolved: + case TEvTxUserProxy::TResultStatus::ProxyPrepared: + case TEvTxUserProxy::TResultStatus::CoordinatorPlanned: + case TEvTxUserProxy::TResultStatus::ExecComplete: + case TEvTxUserProxy::TResultStatus::ExecAborted: + case TEvTxUserProxy::TResultStatus::ExecAlready: + LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_INFO, NKikimrServices::TX_PROXY, TxId, + "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId + << " RESPONSE Status# " << TEvTxUserProxy::TResultStatus::Str(status) + << " prepare time: " << prepareTime.ToString() + << " execute time: " << executeTime.ToString() + << " total time: " << totalTime.ToString() + << " marker# P13"); + TxProxyMon->ReportStatusOK->Inc(); - - TxProxyMon->TxPrepareTimeHgram->Collect(prepareTime.MilliSeconds()); - TxProxyMon->TxExecuteTimeHgram->Collect(executeTime.MilliSeconds()); - TxProxyMon->TxTotalTimeHgram->Collect(totalTime.MilliSeconds()); - - if (PerTablet.size() > 1) { - if (WallClockFirstPrepareReply.GetValue()) { - TxProxyMon->TxPrepareSpreadHgram->Collect((WallClockLastPrepareReply - WallClockFirstPrepareReply).MilliSeconds()); - TxProxyMon->TxPrepareArriveSpreadHgram->Collect((WallClockMaxPrepareArrive - WallClockMinPrepareArrive).MilliSeconds()); - TxProxyMon->TxPrepareCompleteSpreadHgram->Collect((WallClockMaxPrepareComplete - WallClockMinPrepareComplete).MilliSeconds()); - } - if (WallClockFirstExecReply.GetValue()) { - TxProxyMon->TxExecSpreadHgram->Collect((WallClockLastExecReply - WallClockFirstExecReply).MilliSeconds()); - } - } - break; - case TEvTxUserProxy::TResultStatus::ProxyShardTryLater: - case TEvTxUserProxy::TResultStatus::ProxyShardOverloaded: + + TxProxyMon->TxPrepareTimeHgram->Collect(prepareTime.MilliSeconds()); + TxProxyMon->TxExecuteTimeHgram->Collect(executeTime.MilliSeconds()); + TxProxyMon->TxTotalTimeHgram->Collect(totalTime.MilliSeconds()); + + if (PerTablet.size() > 1) { + if (WallClockFirstPrepareReply.GetValue()) { + TxProxyMon->TxPrepareSpreadHgram->Collect((WallClockLastPrepareReply - WallClockFirstPrepareReply).MilliSeconds()); + TxProxyMon->TxPrepareArriveSpreadHgram->Collect((WallClockMaxPrepareArrive - WallClockMinPrepareArrive).MilliSeconds()); + TxProxyMon->TxPrepareCompleteSpreadHgram->Collect((WallClockMaxPrepareComplete - WallClockMinPrepareComplete).MilliSeconds()); + } + if (WallClockFirstExecReply.GetValue()) { + TxProxyMon->TxExecSpreadHgram->Collect((WallClockLastExecReply - WallClockFirstExecReply).MilliSeconds()); + } + } + break; + case TEvTxUserProxy::TResultStatus::ProxyShardTryLater: + case TEvTxUserProxy::TResultStatus::ProxyShardOverloaded: LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_NOTICE, NKikimrServices::TX_PROXY, TxId, - "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId - << " RESPONSE Status# " << TEvTxUserProxy::TResultStatus::Str(status) - << " shard: " << ComplainingDatashards.front() + "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId + << " RESPONSE Status# " << TEvTxUserProxy::TResultStatus::Str(status) + << " shard: " << ComplainingDatashards.front() << " table: " << fnGetTableIdByShard(ComplainingDatashards.front()) - << " marker# P13a"); + << " marker# P13a"); + TxProxyMon->ReportStatusNotOK->Inc(); + break; + case TEvTxUserProxy::TResultStatus::ProxyShardNotAvailable: + case TEvTxUserProxy::TResultStatus::ProxyShardUnknown: + LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_INFO, NKikimrServices::TX_PROXY, TxId, + "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId + << " RESPONSE Status# " << TEvTxUserProxy::TResultStatus::Str(status) + << " shard: " << (ComplainingDatashards ? ComplainingDatashards.front() : 0) + << " marker# P13b"); TxProxyMon->ReportStatusNotOK->Inc(); - break; - case TEvTxUserProxy::TResultStatus::ProxyShardNotAvailable: - case TEvTxUserProxy::TResultStatus::ProxyShardUnknown: - LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_INFO, NKikimrServices::TX_PROXY, TxId, - "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId - << " RESPONSE Status# " << TEvTxUserProxy::TResultStatus::Str(status) - << " shard: " << (ComplainingDatashards ? ComplainingDatashards.front() : 0) - << " marker# P13b"); - TxProxyMon->ReportStatusNotOK->Inc(); - break; + break; case TEvTxUserProxy::TResultStatus::ExecResponseData: LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_DEBUG, NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId @@ -856,18 +856,18 @@ void TDataReq::ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus << " marker# P13d"); TxProxyMon->ReportStatusStreamData->Inc(); break; - default: + default: LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_ERROR, NKikimrServices::TX_PROXY, TxId, - "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId - << " RESPONSE Status# " << TEvTxUserProxy::TResultStatus::Str(status) - << " marker# P13c"); - TxProxyMon->ReportStatusNotOK->Inc(); - break; - } - - ctx.Send(RequestSource, x); // todo: error tracking -} - + "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId + << " RESPONSE Status# " << TEvTxUserProxy::TResultStatus::Str(status) + << " marker# P13c"); + TxProxyMon->ReportStatusNotOK->Inc(); + break; + } + + ctx.Send(RequestSource, x); // todo: error tracking +} + void Aggregate(NKikimrQueryStats::TReadOpStats& aggr, const NKikimrQueryStats::TReadOpStats& stats) { aggr.SetCount(aggr.GetCount() + stats.GetCount()); aggr.SetRows(aggr.GetRows() + stats.GetRows()); @@ -930,8 +930,8 @@ void TDataReq::BuildTxStats(NKikimrQueryStats::TTxStats& stats) { } void TDataReq::ProcessFlatMKQLResolve(NSchemeCache::TSchemeCacheRequest *cacheRequest, const TActorContext &ctx) { - NMiniKQL::IEngineFlat &engine = *FlatMKQLRequest->Engine; - + NMiniKQL::IEngineFlat &engine = *FlatMKQLRequest->Engine; + // Restore DbKeys auto &keyDescriptions = engine.GetDbKeys(); Y_VERIFY(keyDescriptions.size() == cacheRequest->ResultSet.size()); @@ -949,23 +949,23 @@ void TDataReq::ProcessFlatMKQLResolve(NSchemeCache::TSchemeCacheRequest *cacheRe } FlatMKQLRequest->EngineResultStatusCode = engine.PrepareShardPrograms(shardLimits); auto afterBuild = Now(); - - if (FlatMKQLRequest->EngineResultStatusCode != NMiniKQL::IEngineFlat::EResult::Ok) { - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::ENGINE_ERROR)); - ReportStatus( - TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, - NKikimrIssues::TStatusIds::BAD_REQUEST, true, ctx); - TxProxyMon->MiniKQLWrongRequest->Inc(); - return Die(ctx); - } - + + if (FlatMKQLRequest->EngineResultStatusCode != NMiniKQL::IEngineFlat::EResult::Ok) { + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::ENGINE_ERROR)); + ReportStatus( + TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, + NKikimrIssues::TStatusIds::BAD_REQUEST, true, ctx); + TxProxyMon->MiniKQLWrongRequest->Inc(); + return Die(ctx); + } + FlatMKQLRequest->ReadOnlyProgram = engine.IsReadOnlyProgram(); - TxProxyMon->TxPrepareBuildShardProgramsHgram->Collect((afterBuild - beforeBuild).MicroSeconds()); - + TxProxyMon->TxPrepareBuildShardProgramsHgram->Collect((afterBuild - beforeBuild).MicroSeconds()); + if (engine.GetAffectedShardCount() > 1 || FlatMKQLRequest->Snapshot) // TODO KIKIMR-11912 CanUseFollower = false; - + TDuration shardCancelAfter = ExecTimeoutPeriod; if (CancelAfter) { shardCancelAfter = Min(shardCancelAfter, CancelAfter); @@ -974,13 +974,13 @@ void TDataReq::ProcessFlatMKQLResolve(NSchemeCache::TSchemeCacheRequest *cacheRe TInstant shardCancelDeadline = WallClockAccepted + shardCancelAfter + TDuration::Seconds(ShardCancelDeadlineShiftSec); - for (ui32 shx = 0, affectedShards = engine.GetAffectedShardCount(); shx != affectedShards; ++shx) { - NMiniKQL::IEngineFlat::TShardData shardData; - const auto shardDataRes = engine.GetAffectedShard(shx, shardData); + for (ui32 shx = 0, affectedShards = engine.GetAffectedShardCount(); shx != affectedShards; ++shx) { + NMiniKQL::IEngineFlat::TShardData shardData; + const auto shardDataRes = engine.GetAffectedShard(shx, shardData); Y_VERIFY(shardDataRes == NMiniKQL::IEngineFlat::EResult::Ok); - - NKikimrTxDataShard::TDataTransaction dataTransaction; - dataTransaction.SetMiniKQL(shardData.Program); + + NKikimrTxDataShard::TDataTransaction dataTransaction; + dataTransaction.SetMiniKQL(shardData.Program); dataTransaction.SetImmediate(shardData.Immediate || FlatMKQLRequest->Snapshot && FlatMKQLRequest->ReadOnlyProgram); dataTransaction.SetReadOnly(FlatMKQLRequest->ReadOnlyProgram); dataTransaction.SetCancelAfterMs(shardCancelAfter.MilliSeconds()); @@ -995,7 +995,7 @@ void TDataReq::ProcessFlatMKQLResolve(NSchemeCache::TSchemeCacheRequest *cacheRe if (FlatMKQLRequest->PerShardKeysSizeLimitBytes) dataTransaction.SetPerShardKeysSizeLimitBytes(*FlatMKQLRequest->PerShardKeysSizeLimitBytes); const TString transactionBuffer = dataTransaction.SerializeAsString(); - + if (transactionBuffer.size() > MaxDatashardProgramSize) { TString error = TStringBuilder() << "Datashard program size limit exceeded (" << transactionBuffer.size() << " > " << MaxDatashardProgramSize << ")"; @@ -1018,34 +1018,34 @@ void TDataReq::ProcessFlatMKQLResolve(NSchemeCache::TSchemeCacheRequest *cacheRe return Die(ctx); } - const auto affectedType = shardData.HasWrites ? TPerTablet::AffectedWrite : TPerTablet::AffectedRead; - - TPerTablet &perTablet = PerTablet[shardData.ShardId]; - Y_VERIFY(perTablet.TabletStatus == TPerTablet::ETabletStatus::StatusUnknown); - perTablet.TabletStatus = TPerTablet::ETabletStatus::StatusWait; + const auto affectedType = shardData.HasWrites ? TPerTablet::AffectedWrite : TPerTablet::AffectedRead; + + TPerTablet &perTablet = PerTablet[shardData.ShardId]; + Y_VERIFY(perTablet.TabletStatus == TPerTablet::ETabletStatus::StatusUnknown); + perTablet.TabletStatus = TPerTablet::ETabletStatus::StatusWait; perTablet.ProgramSize = transactionBuffer.size(); - ++TabletsLeft; - - perTablet.AffectedFlags |= affectedType; - - // we would need shard -> table mapping for scheme cache invalidation on errors + ++TabletsLeft; + + perTablet.AffectedFlags |= affectedType; + + // we would need shard -> table mapping for scheme cache invalidation on errors for (const auto& keyDescription : keyDescriptions) { for (auto& partition : keyDescription->Partitions) { if (auto *x = PerTablet.FindPtr(partition.ShardId)) { x->TableId = keyDescription->TableId; } - } - } - - TxProxyMon->MiniKQLResolveSentToShard->Inc(); - - LOG_DEBUG_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, - "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId + } + } + + TxProxyMon->MiniKQLResolveSentToShard->Inc(); + + LOG_DEBUG_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, + "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId << " SEND TEvProposeTransaction to datashard " << shardData.ShardId << " with " << shardData.Program.size() << " bytes program" << " affected shards " << engine.GetAffectedShardCount() << " followers " << (CanUseFollower ? "allowed" : "disallowed") << " marker# P4"); - + const TActorId pipeCache = CanUseFollower ? Services.FollowerPipeCache : Services.LeaderPipeCache; TEvDataShard::TEvProposeTransaction* ev; if (FlatMKQLRequest->Snapshot && FlatMKQLRequest->ReadOnlyProgram) { @@ -1055,18 +1055,18 @@ void TDataReq::ProcessFlatMKQLResolve(NSchemeCache::TSchemeCacheRequest *cacheRe ev = new TEvDataShard::TEvProposeTransaction(NKikimrTxDataShard::TX_KIND_DATA, ctx.SelfID, TxId, transactionBuffer, TxFlags | (shardData.Immediate ? NTxDataShard::TTxFlags::Immediate : 0)); } - + Send(pipeCache, new TEvPipeCache::TEvForward(ev, shardData.ShardId, true)); - - FlatMKQLRequest->BalanceCoverageBuilders[shardData.ShardId] = new TBalanceCoverageBuilder(); - } - - engine.AfterShardProgramsExtracted(); + + FlatMKQLRequest->BalanceCoverageBuilders[shardData.ShardId] = new TBalanceCoverageBuilder(); + } + + engine.AfterShardProgramsExtracted(); TxProxyMon->TxPrepareSendShardProgramsHgram->Collect((Now() - afterBuild).MicroSeconds()); - - Become(&TThis::StateWaitPrepare); -} - + + Become(&TThis::StateWaitPrepare); +} + void TDataReq::ProcessReadTableResolve(NSchemeCache::TSchemeCacheRequest *cacheRequest, const TActorContext &ctx) { auto &entry = cacheRequest->ResultSet[0]; @@ -1135,27 +1135,27 @@ void TDataReq::ProcessReadTableResolve(NSchemeCache::TSchemeCacheRequest *cacheR Become(&TThis::StateWaitPrepare); } -TAutoPtr<TEvTxProxySchemeCache::TEvResolveKeySet> TDataReq::PrepareFlatMKQLRequest(TStringBuf miniKQLProgram, TStringBuf miniKQLParams, const TActorContext &ctx) { +TAutoPtr<TEvTxProxySchemeCache::TEvResolveKeySet> TDataReq::PrepareFlatMKQLRequest(TStringBuf miniKQLProgram, TStringBuf miniKQLParams, const TActorContext &ctx) { Y_UNUSED(ctx); - + TAutoPtr<NSchemeCache::TSchemeCacheRequest> request(new NSchemeCache::TSchemeCacheRequest()); - - *TxProxyMon->MiniKQLParamsSize += miniKQLParams.size(); - *TxProxyMon->MiniKQLProgramSize += miniKQLProgram.size(); - + + *TxProxyMon->MiniKQLParamsSize += miniKQLParams.size(); + *TxProxyMon->MiniKQLProgramSize += miniKQLProgram.size(); + auto beforeSetProgram = Now(); - FlatMKQLRequest->EngineResultStatusCode = FlatMKQLRequest->Engine->SetProgram(miniKQLProgram, miniKQLParams); + FlatMKQLRequest->EngineResultStatusCode = FlatMKQLRequest->Engine->SetProgram(miniKQLProgram, miniKQLParams); TxProxyMon->TxPrepareSetProgramHgram->Collect((Now() - beforeSetProgram).MicroSeconds()); - - if (FlatMKQLRequest->EngineResultStatusCode != NMiniKQL::IEngineFlat::EResult::Ok) - return nullptr; - + + if (FlatMKQLRequest->EngineResultStatusCode != NMiniKQL::IEngineFlat::EResult::Ok) + return nullptr; + WallClockResolveStarted = Now(); - auto &keyDescriptions = FlatMKQLRequest->Engine->GetDbKeys(); - + auto &keyDescriptions = FlatMKQLRequest->Engine->GetDbKeys(); + // check keys and set use follower flag CanUseFollower = true; - request->ResultSet.reserve(keyDescriptions.size()); + request->ResultSet.reserve(keyDescriptions.size()); for (auto &keyd : keyDescriptions) { if (keyd->RowOperation != TKeyDesc::ERowOperation::Read || keyd->ReadTarget.GetMode() != TReadTarget::EMode::Follower) { CanUseFollower = false; @@ -1166,56 +1166,56 @@ TAutoPtr<TEvTxProxySchemeCache::TEvResolveKeySet> TDataReq::PrepareFlatMKQLReque } request->ResultSet.emplace_back(std::move(keyd)); } - - return new TEvTxProxySchemeCache::TEvResolveKeySet(request); -} - -void TDataReq::TryToInvalidateTable(TTableId tableId, const TActorContext &ctx) { - const bool notYetInvalidated = InvalidatedTables.insert(tableId).second; - if (notYetInvalidated) + + return new TEvTxProxySchemeCache::TEvResolveKeySet(request); +} + +void TDataReq::TryToInvalidateTable(TTableId tableId, const TActorContext &ctx) { + const bool notYetInvalidated = InvalidatedTables.insert(tableId).second; + if (notYetInvalidated) ctx.Send(Services.SchemeCache, new TEvTxProxySchemeCache::TEvInvalidateTable(tableId, TActorId())); -} - -void TDataReq::MarkShardError(ui64 shardId, TDataReq::TPerTablet &perTablet, bool invalidateDistCache, const TActorContext &ctx) { +} + +void TDataReq::MarkShardError(ui64 shardId, TDataReq::TPerTablet &perTablet, bool invalidateDistCache, const TActorContext &ctx) { if (perTablet.TabletStatus == TDataReq::TPerTablet::ETabletStatus::StatusError) - return; - + return; + perTablet.TabletStatus = TDataReq::TPerTablet::ETabletStatus::StatusError; - - if (invalidateDistCache) - TryToInvalidateTable(perTablet.TableId, ctx); - + + if (invalidateDistCache) + TryToInvalidateTable(perTablet.TableId, ctx); + Y_UNUSED(shardId); - + if (++TabletErrors == TabletsLeft) { LOG_ERROR_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId << " invalidateDistCache: " << invalidateDistCache << " DIE TDataReq MarkShardError TabletsLeft# " << TabletsLeft); TxProxyMon->MarkShardError->Inc(); - return Die(ctx); + return Die(ctx); } -} - -void TDataReq::Handle(TEvTxProxyReq::TEvMakeRequest::TPtr &ev, const TActorContext &ctx) { +} + +void TDataReq::Handle(TEvTxProxyReq::TEvMakeRequest::TPtr &ev, const TActorContext &ctx) { RequestControls.Reqister(ctx); - TEvTxProxyReq::TEvMakeRequest *msg = ev->Get(); - const NKikimrTxUserProxy::TEvProposeTransaction &record = msg->Ev->Get()->Record; + TEvTxProxyReq::TEvMakeRequest *msg = ev->Get(); + const NKikimrTxUserProxy::TEvProposeTransaction &record = msg->Ev->Get()->Record; Y_VERIFY(record.HasTransaction()); - - ProxyFlags = record.HasProxyFlags() ? record.GetProxyFlags() : 0; + + ProxyFlags = record.HasProxyFlags() ? record.GetProxyFlags() : 0; ExecTimeoutPeriod = record.HasExecTimeoutPeriod() ? TDuration::MilliSeconds(record.GetExecTimeoutPeriod()) : TDuration::MilliSeconds(RequestControls.DefaultTimeoutMs); - if (ExecTimeoutPeriod.Minutes() > 60) { + if (ExecTimeoutPeriod.Minutes() > 60) { LOG_WARN_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId << " huge ExecTimeoutPeriod requested " << ExecTimeoutPeriod.ToString() << ", trimming to 30 min"); - ExecTimeoutPeriod = TDuration::Minutes(30); - } - + ExecTimeoutPeriod = TDuration::Minutes(30); + } + CancelAfter = TDuration::MilliSeconds(record.GetCancelAfterMs()); if (CancelAfter.Hours() > 8) { LOG_WARN_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, @@ -1226,8 +1226,8 @@ void TDataReq::Handle(TEvTxProxyReq::TEvMakeRequest::TPtr &ev, const TActorConte } WallClockAccepted = Now(); - ctx.Schedule(TDuration::MilliSeconds(KIKIMR_DATAREQ_WATCHDOG_PERIOD), new TEvPrivate::TEvProxyDataReqOngoingTransactionWatchdog()); - + ctx.Schedule(TDuration::MilliSeconds(KIKIMR_DATAREQ_WATCHDOG_PERIOD), new TEvPrivate::TEvProxyDataReqOngoingTransactionWatchdog()); + // Schedule execution timeout { TAutoPtr<IEventHandle> wakeupEv(new IEventHandle(ctx.SelfID, ctx.SelfID, new TEvents::TEvWakeup())); @@ -1236,11 +1236,11 @@ void TDataReq::Handle(TEvTxProxyReq::TEvMakeRequest::TPtr &ev, const TActorConte CreateLongTimer(ctx, ExecTimeoutPeriod, wakeupEv, AppData(ctx)->SystemPoolId, ExecTimeoutCookieHolder.Get()); } - const NKikimrTxUserProxy::TTransaction &txbody = record.GetTransaction(); - RequestSource = msg->Ev->Sender; + const NKikimrTxUserProxy::TTransaction &txbody = record.GetTransaction(); + RequestSource = msg->Ev->Sender; TxFlags = txbody.GetFlags() & ~NTxDataShard::TTxFlags::Immediate; // Ignore external immediate flag StreamResponse = record.GetStreamResponse(); - + // Subscribe for TEvStreamIsDead event. if (StreamResponse) ctx.Send(RequestSource, new TEvents::TEvSubscribe, IEventHandle::FlagTrackDelivery); @@ -1273,13 +1273,13 @@ void TDataReq::Handle(TEvTxProxyReq::TEvMakeRequest::TPtr &ev, const TActorConte TAutoPtr<TEvTxProxySchemeCache::TEvResolveKeySet> resolveReq; NCpuTime::TCpuTimer timer(CpuTime); - if (txbody.HasMiniKQLTransaction()) { + if (txbody.HasMiniKQLTransaction()) { const auto& mkqlTxBody = txbody.GetMiniKQLTransaction(); const TAppData* appData = AppData(ctx); const auto functionRegistry = appData->FunctionRegistry; - if (mkqlTxBody.GetFlatMKQL()) { + if (mkqlTxBody.GetFlatMKQL()) { FlatMKQLRequest = new TFlatMKQLRequest; FlatMKQLRequest->LlvmRuntime = mkqlTxBody.GetLlvmRuntime(); FlatMKQLRequest->CollectStats = mkqlTxBody.GetCollectStats(); @@ -1294,88 +1294,88 @@ void TDataReq::Handle(TEvTxProxyReq::TEvMakeRequest::TPtr &ev, const TActorConte NMiniKQL::TEngineFlatSettings settings(NMiniKQL::IEngineFlat::EProtocol::V1, functionRegistry, *TAppData::RandomProvider, *TAppData::TimeProvider, nullptr, TxProxyMon->AllocPoolCounters); - settings.EvaluateResultType = mkqlTxBody.GetEvaluateResultType(); - settings.EvaluateResultValue = mkqlTxBody.GetEvaluateResultValue(); + settings.EvaluateResultType = mkqlTxBody.GetEvaluateResultType(); + settings.EvaluateResultValue = mkqlTxBody.GetEvaluateResultValue(); if (FlatMKQLRequest->LlvmRuntime) { LOG_DEBUG_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, "Using LLVM runtime to execute transaction: " << TxId); settings.LlvmRuntime = true; } - if (ctx.LoggerSettings()->Satisfies(NLog::PRI_DEBUG, NKikimrServices::MINIKQL_ENGINE, TxId)) { - auto actorSystem = ctx.ExecutorThread.ActorSystem; - auto txId = TxId; - settings.BacktraceWriter = [txId, actorSystem](const char* operation, ui32 line, const TBackTrace* backtrace) { - LOG_DEBUG_SAMPLED_BY(*actorSystem, NKikimrServices::MINIKQL_ENGINE, txId, - "Proxy data request, txId: %" PRIu64 ", %s (%" PRIu32 ")\n%s", + if (ctx.LoggerSettings()->Satisfies(NLog::PRI_DEBUG, NKikimrServices::MINIKQL_ENGINE, TxId)) { + auto actorSystem = ctx.ExecutorThread.ActorSystem; + auto txId = TxId; + settings.BacktraceWriter = [txId, actorSystem](const char* operation, ui32 line, const TBackTrace* backtrace) { + LOG_DEBUG_SAMPLED_BY(*actorSystem, NKikimrServices::MINIKQL_ENGINE, txId, + "Proxy data request, txId: %" PRIu64 ", %s (%" PRIu32 ")\n%s", txId, operation, line, backtrace ? backtrace->PrintToString().data() : ""); - }; + }; settings.LogErrorWriter = [txId, actorSystem](const TString& message) { LOG_ERROR_S(*actorSystem, NKikimrServices::MINIKQL_ENGINE, "Proxy data request, txId: " << txId << ", engine error: " << message); }; - } - - if ((TxFlags & NTxDataShard::TTxFlags::ForceOnline) != 0) { - settings.ForceOnline = true; - } + } + + if ((TxFlags & NTxDataShard::TTxFlags::ForceOnline) != 0) { + settings.ForceOnline = true; + } - FlatMKQLRequest->Engine = NMiniKQL::CreateEngineFlat(settings); + FlatMKQLRequest->Engine = NMiniKQL::CreateEngineFlat(settings); FlatMKQLRequest->Engine->SetStepTxId({ 0, TxId }); TString program = mkqlTxBody.GetProgram().GetBin(); TString params = mkqlTxBody.GetParams().GetBin(); - resolveReq = PrepareFlatMKQLRequest(program, params, ctx); + resolveReq = PrepareFlatMKQLRequest(program, params, ctx); FlatMKQLRequest->RequestAdditionResults(TxId); - } - } - - if (!resolveReq || !resolveReq->Request) { - ReportStatus( - TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, - NKikimrIssues::TStatusIds::BAD_REQUEST, true, ctx); + } + } + + if (!resolveReq || !resolveReq->Request) { + ReportStatus( + TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, + NKikimrIssues::TStatusIds::BAD_REQUEST, true, ctx); TxProxyMon->MakeRequestWrongRequest->Inc(); - return Die(ctx); - } else if (resolveReq->Request->ResultSet.empty()) { + return Die(ctx); + } else if (resolveReq->Request->ResultSet.empty()) { TxProxyMon->MakeRequestEmptyAffectedSet->Inc(); - if (FlatMKQLRequest) { + if (FlatMKQLRequest) { FlatMKQLRequest->EngineResultStatusCode = FlatMKQLRequest->Engine->PrepareShardPrograms( NMiniKQL::IEngineFlat::TShardLimits(0, 0)); - if (FlatMKQLRequest->EngineResultStatusCode != NMiniKQL::IEngineFlat::EResult::Ok) { - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::ENGINE_ERROR, "could not prepare shard programs")); - ReportStatus( - TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, - NKikimrIssues::TStatusIds::QUERY_ERROR, true, ctx); - TxProxyMon->MiniKQLWrongRequest->Inc(); - return Die(ctx); - } - FlatMKQLRequest->Engine->AfterShardProgramsExtracted(); + if (FlatMKQLRequest->EngineResultStatusCode != NMiniKQL::IEngineFlat::EResult::Ok) { + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::ENGINE_ERROR, "could not prepare shard programs")); + ReportStatus( + TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, + NKikimrIssues::TStatusIds::QUERY_ERROR, true, ctx); + TxProxyMon->MiniKQLWrongRequest->Inc(); + return Die(ctx); + } + FlatMKQLRequest->Engine->AfterShardProgramsExtracted(); return MakeFlatMKQLResponse(ctx, timer); - } else { - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::ENGINE_ERROR, "empty affected set")); - ReportStatus( - TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::EmptyAffectedSet, - NKikimrIssues::TStatusIds::QUERY_ERROR, true, ctx); - return Die(ctx); - } - } else { - if (ProxyFlags & TEvTxUserProxy::TEvProposeTransaction::ProxyReportAccepted) - ReportStatus( - TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyAccepted, - NKikimrIssues::TStatusIds::TRANSIENT, false, ctx); - } - + } else { + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::ENGINE_ERROR, "empty affected set")); + ReportStatus( + TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::EmptyAffectedSet, + NKikimrIssues::TStatusIds::QUERY_ERROR, true, ctx); + return Die(ctx); + } + } else { + if (ProxyFlags & TEvTxUserProxy::TEvProposeTransaction::ProxyReportAccepted) + ReportStatus( + TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyAccepted, + NKikimrIssues::TStatusIds::TRANSIENT, false, ctx); + } + resolveReq->Request->DatabaseName = record.GetDatabaseName(); TxProxyMon->MakeRequestProxyAccepted->Inc(); LOG_DEBUG_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId - << " SEND to# " << Services.SchemeCache.ToString() << " TSchemeCache with " + << " SEND to# " << Services.SchemeCache.ToString() << " TSchemeCache with " << resolveReq->Request->ResultSet.size() << " scheme entries. DataReq marker# P2" ); - - ctx.Send(Services.SchemeCache, resolveReq.Release()); - Become(&TThis::StateWaitResolve); -} - + + ctx.Send(Services.SchemeCache, resolveReq.Release()); + Become(&TThis::StateWaitResolve); +} + void TDataReq::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev, const TActorContext &ctx) { TEvTxProxySchemeCache::TEvNavigateKeySetResult *msg = ev->Get(); NSchemeCache::TSchemeCacheNavigate *resp = msg->Request.Get(); @@ -1387,12 +1387,12 @@ void TDataReq::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev, << resp->ErrorCount); if (resp->ErrorCount > 0) { - const TString errorExplanation = "unresolved table: " + ReadTableRequest->TablePath; - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::GENERIC_RESOLVE_ERROR, errorExplanation)); + const TString errorExplanation = "unresolved table: " + ReadTableRequest->TablePath; + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::GENERIC_RESOLVE_ERROR, errorExplanation)); + + UnresolvedKeys.push_back(errorExplanation); + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError, NKikimrIssues::TStatusIds::SCHEME_ERROR, true, ctx); - UnresolvedKeys.push_back(errorExplanation); - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError, NKikimrIssues::TStatusIds::SCHEME_ERROR, true, ctx); - TxProxyMon->ResolveKeySetWrongRequest->Inc(); return Die(ctx); } @@ -1403,10 +1403,10 @@ void TDataReq::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev, for (size_t i = 0; i < ReadTableRequest->Columns.size(); ++i) { auto &col = ReadTableRequest->Columns[i]; if (colNames.contains(col.Name)) { - const TString errorExplanation = "duplicated columns are not supported: " + col.Name; - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::GENERIC_RESOLVE_ERROR, errorExplanation)); - UnresolvedKeys.push_back(errorExplanation); - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError, NKikimrIssues::TStatusIds::SCHEME_ERROR, true, ctx); + const TString errorExplanation = "duplicated columns are not supported: " + col.Name; + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::GENERIC_RESOLVE_ERROR, errorExplanation)); + UnresolvedKeys.push_back(errorExplanation); + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError, NKikimrIssues::TStatusIds::SCHEME_ERROR, true, ctx); TxProxyMon->ResolveKeySetWrongRequest->Inc(); @@ -1456,12 +1456,12 @@ void TDataReq::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev, // Report unresolved columns. if (!colNames.empty()) { - for (auto entry: colNames) { - const TString &errorExplanation = "unresolved column: " + entry.first; - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::GENERIC_RESOLVE_ERROR, errorExplanation)); - UnresolvedKeys.push_back(errorExplanation); - } - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError, NKikimrIssues::TStatusIds::SCHEME_ERROR, true, ctx); + for (auto entry: colNames) { + const TString &errorExplanation = "unresolved column: " + entry.first; + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::GENERIC_RESOLVE_ERROR, errorExplanation)); + UnresolvedKeys.push_back(errorExplanation); + } + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError, NKikimrIssues::TStatusIds::SCHEME_ERROR, true, ctx); TxProxyMon->ResolveKeySetWrongRequest->Inc(); return Die(ctx); } @@ -1490,8 +1490,8 @@ void TDataReq::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev, ReadTableRequest->FromValues, fromExpand) || !ParseRangeKey(ReadTableRequest->Range.GetTo(), keyTypes, ReadTableRequest->ToValues, toExpand)) { - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::KEY_PARSE_ERROR, "could not parse key string")); - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError, NKikimrIssues::TStatusIds::QUERY_ERROR, true, ctx); + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::KEY_PARSE_ERROR, "could not parse key string")); + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError, NKikimrIssues::TStatusIds::QUERY_ERROR, true, ctx); TxProxyMon->ResolveKeySetWrongRequest->Inc(); return Die(ctx); } @@ -1502,10 +1502,10 @@ void TDataReq::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev, toInclusive); if (range.IsEmptyRange({keyTypes.begin(), keyTypes.end()})) { - const TString errorExplanation = "empty range requested"; - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::EMPTY_OP_RANGE, errorExplanation)); - UnresolvedKeys.push_back(errorExplanation); - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError, NKikimrIssues::TStatusIds::QUERY_ERROR, true, ctx); + const TString errorExplanation = "empty range requested"; + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::EMPTY_OP_RANGE, errorExplanation)); + UnresolvedKeys.push_back(errorExplanation); + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError, NKikimrIssues::TStatusIds::QUERY_ERROR, true, ctx); TxProxyMon->ResolveKeySetWrongRequest->Inc(); return Die(ctx); } @@ -1522,10 +1522,10 @@ void TDataReq::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev, ctx.Send(Services.SchemeCache, new TEvTxProxySchemeCache::TEvResolveKeySet(request)); } -void TDataReq::Handle(TEvTxProxySchemeCache::TEvResolveKeySetResult::TPtr &ev, const TActorContext &ctx) { - TEvTxProxySchemeCache::TEvResolveKeySetResult *msg = ev->Get(); +void TDataReq::Handle(TEvTxProxySchemeCache::TEvResolveKeySetResult::TPtr &ev, const TActorContext &ctx) { + TEvTxProxySchemeCache::TEvResolveKeySetResult *msg = ev->Get(); NSchemeCache::TSchemeCacheRequest *request = msg->Request.Get(); - + LOG_LOG_S_SAMPLED_BY(ctx, (request->ErrorCount == 0 ? NActors::NLog::PRI_DEBUG : NActors::NLog::PRI_ERROR), NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId @@ -1533,48 +1533,48 @@ void TDataReq::Handle(TEvTxProxySchemeCache::TEvResolveKeySetResult::TPtr &ev, c TxProxyMon->CacheRequestLatency->Collect((Now() - WallClockAccepted).MilliSeconds()); WallClockResolved = Now(); - - if (request->ErrorCount > 0) { - bool gotHardResolveError = false; - for (const auto &x : request->ResultSet) { + + if (request->ErrorCount > 0) { + bool gotHardResolveError = false; + for (const auto &x : request->ResultSet) { if ((ui32)x.Status < (ui32) NSchemeCache::TSchemeCacheRequest::EStatus::OkScheme) { - TryToInvalidateTable(x.KeyDescription->TableId, ctx); - + TryToInvalidateTable(x.KeyDescription->TableId, ctx); + TStringStream ss; - switch (x.Status) { - case NSchemeCache::TSchemeCacheRequest::EStatus::PathErrorNotExist: - gotHardResolveError = true; + switch (x.Status) { + case NSchemeCache::TSchemeCacheRequest::EStatus::PathErrorNotExist: + gotHardResolveError = true; ss << "table not exists: " << x.KeyDescription->TableId; - break; - case NSchemeCache::TSchemeCacheRequest::EStatus::TypeCheckError: - gotHardResolveError = true; + break; + case NSchemeCache::TSchemeCacheRequest::EStatus::TypeCheckError: + gotHardResolveError = true; ss << "type check error: " << x.KeyDescription->TableId; - break; - default: + break; + default: ss << "unresolved table: " << x.KeyDescription->TableId << ". Status: " << x.Status; - break; - } - - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::GENERIC_RESOLVE_ERROR, ss.Str())); + break; + } + + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::GENERIC_RESOLVE_ERROR, ss.Str())); UnresolvedKeys.push_back(ss.Str()); } } - - if (gotHardResolveError) { - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError, NKikimrIssues::TStatusIds::SCHEME_ERROR, true, ctx); - TxProxyMon->ResolveKeySetWrongRequest->Inc(); - } else { - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardNotAvailable, NKikimrIssues::TStatusIds::REJECTED, true, ctx); - } - - return Die(ctx); - } - + + if (gotHardResolveError) { + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError, NKikimrIssues::TStatusIds::SCHEME_ERROR, true, ctx); + TxProxyMon->ResolveKeySetWrongRequest->Inc(); + } else { + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardNotAvailable, NKikimrIssues::TStatusIds::REJECTED, true, ctx); + } + + return Die(ctx); + } + if (ProxyFlags & TEvTxUserProxy::TEvProposeTransaction::ProxyReportResolved) - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyResolved, NKikimrIssues::TStatusIds::TRANSIENT, false, ctx); + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyResolved, NKikimrIssues::TStatusIds::TRANSIENT, false, ctx); + + TxProxyMon->TxPrepareResolveHgram->Collect((WallClockResolved - WallClockResolveStarted).MicroSeconds()); - TxProxyMon->TxPrepareResolveHgram->Collect((WallClockResolved - WallClockResolveStarted).MicroSeconds()); - NCpuTime::TCpuTimer timer(CpuTime); for (const NSchemeCache::TSchemeCacheRequest::TEntry& entry : request->ResultSet) { ui32 access = 0; @@ -1596,14 +1596,14 @@ void TDataReq::Handle(TEvTxProxySchemeCache::TEvResolveKeySetResult::TPtr &ev, c && entry.KeyDescription->Status == TKeyDesc::EStatus::Ok && entry.KeyDescription->SecurityObject != nullptr && !entry.KeyDescription->SecurityObject->CheckAccess(access, *UserToken)) { - TStringStream explanation; - explanation << "Access denied for " << UserToken->GetUserSID() - << " with access " << NACLib::AccessRightsToString(access) + TStringStream explanation; + explanation << "Access denied for " << UserToken->GetUserSID() + << " with access " << NACLib::AccessRightsToString(access) << " to tableId# " << entry.KeyDescription->TableId; - - LOG_ERROR_S(ctx, NKikimrServices::TX_PROXY, explanation.Str()); - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::ACCESS_DENIED, explanation.Str())); - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::AccessDenied, NKikimrIssues::TStatusIds::ACCESS_DENIED, true, ctx); + + LOG_ERROR_S(ctx, NKikimrServices::TX_PROXY, explanation.Str()); + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::ACCESS_DENIED, explanation.Str())); + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::AccessDenied, NKikimrIssues::TStatusIds::ACCESS_DENIED, true, ctx); return Die(ctx); } @@ -1628,8 +1628,8 @@ void TDataReq::Handle(TEvTxProxySchemeCache::TEvResolveKeySetResult::TPtr &ev, c } if (!CheckDomainLocality(*request)) { - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::DOMAIN_LOCALITY_ERROR)); - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::DomainLocalityError, NKikimrIssues::TStatusIds::BAD_REQUEST, true, ctx); + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::DOMAIN_LOCALITY_ERROR)); + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::DomainLocalityError, NKikimrIssues::TStatusIds::BAD_REQUEST, true, ctx); TxProxyMon->ResolveKeySetDomainLocalityFail->Inc(); return Die(ctx); } @@ -1645,8 +1645,8 @@ void TDataReq::Handle(TEvTxProxySchemeCache::TEvResolveKeySetResult::TPtr &ev, c } else { Y_FAIL("No request"); } -} - +} + void TDataReq::Handle(TEvPrivate::TEvReattachToShard::TPtr &ev, const TActorContext &ctx) { const ui64 tabletId = ev->Get()->TabletId; TPerTablet *perTablet = PerTablet.FindPtr(tabletId); @@ -1664,31 +1664,31 @@ void TDataReq::Handle(TEvPrivate::TEvReattachToShard::TPtr &ev, const TActorCont tabletId, true), 0, ++perTablet->ReattachState.Cookie); } -void TDataReq::HandlePrepare(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TActorContext &ctx) { - TEvPipeCache::TEvDeliveryProblem *msg = ev->Get(); - TPerTablet *perTablet = PerTablet.FindPtr(msg->TabletId); - Y_VERIFY(perTablet); - +void TDataReq::HandlePrepare(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TActorContext &ctx) { + TEvPipeCache::TEvDeliveryProblem *msg = ev->Get(); + TPerTablet *perTablet = PerTablet.FindPtr(msg->TabletId); + Y_VERIFY(perTablet); + bool wasRestarting = std::exchange(perTablet->Restarting, false); // We can only be sure tx was not prepared if initial propose was not delivered bool notPrepared = msg->NotDelivered && !perTablet->RestartCount; // Disconnected while waiting for initial propose response - if (perTablet->TabletStatus == TPerTablet::ETabletStatus::StatusWait) { - LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_ERROR, - NKikimrServices::TX_PROXY, TxId, + if (perTablet->TabletStatus == TPerTablet::ETabletStatus::StatusWait) { + LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_ERROR, + NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId << " shard " << msg->TabletId << " delivery problem" << " (waiting, notDelivered=" << msg->NotDelivered << ", notPrepared=" << notPrepared << ")"); - - ComplainingDatashards.push_back(msg->TabletId); + + ComplainingDatashards.push_back(msg->TabletId); CancelProposal(notPrepared ? msg->TabletId : 0); - + if (notPrepared) { - TStringStream explanation; + TStringStream explanation; explanation << "could not deliver program to shard " << msg->TabletId << " with txid# " << TxId; - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::SHARD_NOT_AVAILABLE, explanation.Str())); - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardNotAvailable, NKikimrIssues::TStatusIds::REJECTED, true, ctx); + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::SHARD_NOT_AVAILABLE, explanation.Str())); + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardNotAvailable, NKikimrIssues::TStatusIds::REJECTED, true, ctx); } else if (wasRestarting) { // We are waiting for propose and have a restarting flag, which means shard was // persisting our tx. We did not receive a reply, so we cannot be sure if it @@ -1698,20 +1698,20 @@ void TDataReq::HandlePrepare(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const T explanation << "could not prepare program at shard " << msg->TabletId << " with txid# " << TxId; IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::SHARD_NOT_AVAILABLE, explanation.Str())); ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardNotAvailable, NKikimrIssues::TStatusIds::REJECTED, true, ctx); - } else { - TStringStream explanation; + } else { + TStringStream explanation; explanation << "tx state unknown for shard " << msg->TabletId << " with txid# " << TxId; - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::TX_STATE_UNKNOWN, explanation.Str())); + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::TX_STATE_UNKNOWN, explanation.Str())); auto status = IsReadOnlyRequest() ? TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardNotAvailable : TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardUnknown; ReportStatus(status, NKikimrIssues::TStatusIds::TIMEOUT, true, ctx); - } - - Become(&TThis::StatePrepareErrors, ctx, TDuration::MilliSeconds(500), new TEvents::TEvWakeup); + } + + Become(&TThis::StatePrepareErrors, ctx, TDuration::MilliSeconds(500), new TEvents::TEvWakeup); TxProxyMon->ClientConnectedError->Inc(); - return HandlePrepareErrors(ev, ctx); - } + return HandlePrepareErrors(ev, ctx); + } // Disconnected while waiting for other shards to prepare if (perTablet->TabletStatus == TPerTablet::ETabletStatus::StatusPrepared) { @@ -1748,29 +1748,29 @@ void TDataReq::HandlePrepare(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const T TxProxyMon->ClientConnectedError->Inc(); return HandlePrepareErrors(ev, ctx); } -} - -void TDataReq::HandlePrepareErrors(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TActorContext &ctx) { - TEvPipeCache::TEvDeliveryProblem *msg = ev->Get(); - TPerTablet *perTablet = PerTablet.FindPtr(msg->TabletId); - Y_VERIFY(perTablet); - - if (perTablet->TabletStatus == TPerTablet::ETabletStatus::StatusWait) { - LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_ERROR, - NKikimrServices::TX_PROXY, TxId, +} + +void TDataReq::HandlePrepareErrors(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TActorContext &ctx) { + TEvPipeCache::TEvDeliveryProblem *msg = ev->Get(); + TPerTablet *perTablet = PerTablet.FindPtr(msg->TabletId); + Y_VERIFY(perTablet); + + if (perTablet->TabletStatus == TPerTablet::ETabletStatus::StatusWait) { + LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_ERROR, + NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId << " shard " << msg->TabletId << " delivery problem (gathering prepare errors)"); - - return MarkShardError(msg->TabletId, *perTablet, true, ctx); - } -} - - -void TDataReq::HandlePrepare(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, const TActorContext &ctx) { - TEvDataShard::TEvProposeTransactionResult *msg = ev->Get(); - const NKikimrTxDataShard::TEvProposeTransactionResult &record = msg->Record; - - const ui64 tabletId = msg->GetOrigin(); - TPerTablet *perTablet = PerTablet.FindPtr(tabletId); + + return MarkShardError(msg->TabletId, *perTablet, true, ctx); + } +} + + +void TDataReq::HandlePrepare(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, const TActorContext &ctx) { + TEvDataShard::TEvProposeTransactionResult *msg = ev->Get(); + const NKikimrTxDataShard::TEvProposeTransactionResult &record = msg->Record; + + const ui64 tabletId = msg->GetOrigin(); + TPerTablet *perTablet = PerTablet.FindPtr(tabletId); Y_VERIFY(perTablet); LOG_LOG_S_SAMPLED_BY(ctx, (msg->GetStatus() != NKikimrTxDataShard::TEvProposeTransactionResult::ERROR ? @@ -1778,34 +1778,34 @@ void TDataReq::HandlePrepare(TEvDataShard::TEvProposeTransactionResult::TPtr &ev NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId << " HANDLE Prepare TEvProposeTransactionResult TDataReq TabletStatus# " << perTablet->TabletStatus - << " GetStatus# " << msg->GetStatus() - << " shard id " << tabletId + << " GetStatus# " << msg->GetStatus() + << " shard id " << tabletId << " read size " << record.GetReadSize() << " out readset size " << record.OutgoingReadSetInfoSize() - << " marker# P6"); - + << " marker# P6"); + WallClockLastPrepareReply = Now(); - const TInstant reportedArriveTime = TInstant::MicroSeconds(record.GetPrepareArriveTime()); - const TDuration completionDelta = WallClockLastPrepareReply - reportedArriveTime; - WallClockMinPrepareArrive = WallClockMinPrepareArrive.GetValue() ? Min(WallClockMinPrepareArrive, reportedArriveTime) : reportedArriveTime; - WallClockMaxPrepareArrive = Max(WallClockMaxPrepareArrive, reportedArriveTime); - WallClockMinPrepareComplete = WallClockMaxPrepareComplete.GetValue() ? Min(WallClockMaxPrepareComplete, completionDelta) : completionDelta; - WallClockMaxPrepareComplete = Max(WallClockMaxPrepareComplete, completionDelta); - - if (WallClockFirstPrepareReply.GetValue() == 0) - WallClockFirstPrepareReply = WallClockLastPrepareReply; - + const TInstant reportedArriveTime = TInstant::MicroSeconds(record.GetPrepareArriveTime()); + const TDuration completionDelta = WallClockLastPrepareReply - reportedArriveTime; + WallClockMinPrepareArrive = WallClockMinPrepareArrive.GetValue() ? Min(WallClockMinPrepareArrive, reportedArriveTime) : reportedArriveTime; + WallClockMaxPrepareArrive = Max(WallClockMaxPrepareArrive, reportedArriveTime); + WallClockMinPrepareComplete = WallClockMaxPrepareComplete.GetValue() ? Min(WallClockMaxPrepareComplete, completionDelta) : completionDelta; + WallClockMaxPrepareComplete = Max(WallClockMaxPrepareComplete, completionDelta); + + if (WallClockFirstPrepareReply.GetValue() == 0) + WallClockFirstPrepareReply = WallClockLastPrepareReply; + if (perTablet->TabletStatus == TPerTablet::ETabletStatus::StatusPrepared) { // do nothing TxProxyMon->TxResultTabletPrepared->Inc(); - return; + return; } - - switch (msg->GetStatus()) { - case NKikimrTxDataShard::TEvProposeTransactionResult::PREPARED: + + switch (msg->GetStatus()) { + case NKikimrTxDataShard::TEvProposeTransactionResult::PREPARED: { perTablet->TabletStatus = TPerTablet::ETabletStatus::StatusPrepared; - perTablet->MinStep = record.GetMinStep(); - perTablet->MaxStep = record.GetMaxStep(); + perTablet->MinStep = record.GetMinStep(); + perTablet->MaxStep = record.GetMaxStep(); perTablet->ReadSize = record.GetReadSize(); perTablet->ReplySize = record.GetReplySize(); perTablet->OutgoingReadSetsSize = record.OutgoingReadSetInfoSize(); @@ -1817,17 +1817,17 @@ void TDataReq::HandlePrepare(TEvDataShard::TEvProposeTransactionResult::TPtr &ev Y_VERIFY(targetTablet); targetTablet->IncomingReadSetsSize += size; } - - AggrMaxStep = Min(AggrMaxStep, perTablet->MaxStep); - AggrMinStep = Max(AggrMinStep, perTablet->MinStep); - + + AggrMaxStep = Min(AggrMaxStep, perTablet->MaxStep); + AggrMinStep = Max(AggrMinStep, perTablet->MinStep); + TxProxyMon->TxResultPrepared->Inc(); - if (record.HasExecLatency()) - ElapsedPrepareExec = Max<TDuration>(ElapsedPrepareExec, TDuration::MilliSeconds(record.GetExecLatency())); - if (record.HasProposeLatency()) - ElapsedPrepareComplete = Max<TDuration>(ElapsedPrepareComplete, TDuration::MilliSeconds(record.GetProposeLatency())); - + if (record.HasExecLatency()) + ElapsedPrepareExec = Max<TDuration>(ElapsedPrepareExec, TDuration::MilliSeconds(record.GetExecLatency())); + if (record.HasProposeLatency()) + ElapsedPrepareComplete = Max<TDuration>(ElapsedPrepareComplete, TDuration::MilliSeconds(record.GetProposeLatency())); + ui64 privateCoordinator = TCoordinators(TVector<ui64>( record.GetDomainCoordinators().begin(), record.GetDomainCoordinators().end())) @@ -1866,22 +1866,22 @@ void TDataReq::HandlePrepare(TEvDataShard::TEvProposeTransactionResult::TPtr &ev return RegisterPlan(ctx); } - case NKikimrTxDataShard::TEvProposeTransactionResult::COMPLETE: + case NKikimrTxDataShard::TEvProposeTransactionResult::COMPLETE: perTablet->TabletStatus = TPerTablet::ETabletStatus::StatusFinished; - if (record.HasExecLatency()) - ElapsedExecExec = Max<TDuration>(ElapsedExecExec, TDuration::MilliSeconds(record.GetExecLatency())); - if (record.HasProposeLatency()) - ElapsedExecComplete = Max<TDuration>(ElapsedExecComplete, TDuration::MilliSeconds(record.GetProposeLatency())); - + if (record.HasExecLatency()) + ElapsedExecExec = Max<TDuration>(ElapsedExecExec, TDuration::MilliSeconds(record.GetExecLatency())); + if (record.HasProposeLatency()) + ElapsedExecComplete = Max<TDuration>(ElapsedExecComplete, TDuration::MilliSeconds(record.GetProposeLatency())); + TxProxyMon->TxResultComplete->Inc(); - return MergeResult(ev, ctx); + return MergeResult(ev, ctx); case NKikimrTxDataShard::TEvProposeTransactionResult::RESPONSE_DATA: ProcessStreamResponseData(ev, ctx); return; case NKikimrTxDataShard::TEvProposeTransactionResult::ERROR: { ExtractDatashardErrors(record); - CancelProposal(tabletId); + CancelProposal(tabletId); bool schemeChanged = false; for (const auto& e : record.GetError()) { if (e.GetKind() == NKikimrTxDataShard::TError::SCHEME_CHANGED) { @@ -1893,26 +1893,26 @@ void TDataReq::HandlePrepare(TEvDataShard::TEvProposeTransactionResult::TPtr &ev } else { ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardNotAvailable, NKikimrIssues::TStatusIds::REJECTED, true, ctx); } - Become(&TThis::StatePrepareErrors, ctx, TDuration::MilliSeconds(500), new TEvents::TEvWakeup); + Become(&TThis::StatePrepareErrors, ctx, TDuration::MilliSeconds(500), new TEvents::TEvWakeup); TxProxyMon->TxResultError->Inc(); - return HandlePrepareErrors(ev, ctx); + return HandlePrepareErrors(ev, ctx); } case NKikimrTxDataShard::TEvProposeTransactionResult::ABORTED: - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecAborted, NKikimrIssues::TStatusIds::SUCCESS, true, ctx); + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecAborted, NKikimrIssues::TStatusIds::SUCCESS, true, ctx); TxProxyMon->TxResultAborted->Inc(); return Die(ctx); - case NKikimrTxDataShard::TEvProposeTransactionResult::TRY_LATER: - ExtractDatashardErrors(record); - CancelProposal(tabletId); - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardTryLater, NKikimrIssues::TStatusIds::REJECTED, true, ctx); - TxProxyMon->TxResultShardTryLater->Inc(); - return Die(ctx); - case NKikimrTxDataShard::TEvProposeTransactionResult::OVERLOADED: - ExtractDatashardErrors(record); - CancelProposal(tabletId); - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardOverloaded, NKikimrIssues::TStatusIds::OVERLOADED, true, ctx); - TxProxyMon->TxResultShardOverloaded->Inc(); - return Die(ctx); + case NKikimrTxDataShard::TEvProposeTransactionResult::TRY_LATER: + ExtractDatashardErrors(record); + CancelProposal(tabletId); + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardTryLater, NKikimrIssues::TStatusIds::REJECTED, true, ctx); + TxProxyMon->TxResultShardTryLater->Inc(); + return Die(ctx); + case NKikimrTxDataShard::TEvProposeTransactionResult::OVERLOADED: + ExtractDatashardErrors(record); + CancelProposal(tabletId); + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardOverloaded, NKikimrIssues::TStatusIds::OVERLOADED, true, ctx); + TxProxyMon->TxResultShardOverloaded->Inc(); + return Die(ctx); case NKikimrTxDataShard::TEvProposeTransactionResult::EXEC_ERROR: ExtractDatashardErrors(record); ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecError, NKikimrIssues::TStatusIds::ERROR, true, ctx); @@ -1933,30 +1933,30 @@ void TDataReq::HandlePrepare(TEvDataShard::TEvProposeTransactionResult::TPtr &ev ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::WrongRequest, NKikimrIssues::TStatusIds::BAD_REQUEST, true, ctx); TxProxyMon->TxResultCancelled->Inc(); return Die(ctx); - default: - // everything other is hard error - ExtractDatashardErrors(record); - CancelProposal(tabletId); - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardUnknown, NKikimrIssues::TStatusIds::ERROR, true, ctx); + default: + // everything other is hard error + ExtractDatashardErrors(record); + CancelProposal(tabletId); + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardUnknown, NKikimrIssues::TStatusIds::ERROR, true, ctx); TxProxyMon->TxResultFatal->Inc(); - return Die(ctx); - } -} - -void TDataReq::CancelProposal(ui64 exceptTablet) { + return Die(ctx); + } +} + +void TDataReq::CancelProposal(ui64 exceptTablet) { if (CanUseFollower) - return; - - for (const auto &x : PerTablet) - if (x.first != exceptTablet) { + return; + + for (const auto &x : PerTablet) + if (x.first != exceptTablet) { Send(Services.LeaderPipeCache, new TEvPipeCache::TEvForward( - new TEvDataShard::TEvCancelTransactionProposal(TxId), - x.first, - false - )); - } -} - + new TEvDataShard::TEvCancelTransactionProposal(TxId), + x.first, + false + )); + } +} + void TDataReq::ExtractDatashardErrors(const NKikimrTxDataShard::TEvProposeTransactionResult & record) { TString allErrors; for (const auto &er : record.GetError()) { @@ -1964,109 +1964,109 @@ void TDataReq::ExtractDatashardErrors(const NKikimrTxDataShard::TEvProposeTransa } DatashardErrors = allErrors; - ComplainingDatashards.push_back(record.GetOrigin()); + ComplainingDatashards.push_back(record.GetOrigin()); } -void TDataReq::HandlePrepareErrors(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, const TActorContext &ctx) { - TEvDataShard::TEvProposeTransactionResult *msg = ev->Get(); - const NKikimrTxDataShard::TEvProposeTransactionResult &record = msg->Record; - - const ui64 tabletId = msg->GetOrigin(); - TPerTablet *perTablet = PerTablet.FindPtr(tabletId); +void TDataReq::HandlePrepareErrors(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, const TActorContext &ctx) { + TEvDataShard::TEvProposeTransactionResult *msg = ev->Get(); + const NKikimrTxDataShard::TEvProposeTransactionResult &record = msg->Record; + + const ui64 tabletId = msg->GetOrigin(); + TPerTablet *perTablet = PerTablet.FindPtr(tabletId); Y_VERIFY(perTablet); - + LOG_LOG_S_SAMPLED_BY(ctx, (msg->GetStatus() != NKikimrTxDataShard::TEvProposeTransactionResult::ERROR ? NActors::NLog::PRI_DEBUG : NActors::NLog::PRI_ERROR), NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId - << " HANDLE PrepareErrors TEvProposeTransactionResult TDataReq TabletStatus# " << perTablet->TabletStatus - << " shard id " << tabletId); + << " HANDLE PrepareErrors TEvProposeTransactionResult TDataReq TabletStatus# " << perTablet->TabletStatus + << " shard id " << tabletId); if (perTablet->TabletStatus != TPerTablet::ETabletStatus::StatusWait) // do nothing for already processed cases - return; - - switch (msg->GetStatus()) { - case NKikimrTxDataShard::TEvProposeTransactionResult::ERROR: - for (const auto &er : record.GetError()) { - const NKikimrTxDataShard::TError::EKind errorKind = er.GetKind(); - switch (errorKind) { - case NKikimrTxDataShard::TError::SCHEME_ERROR: - case NKikimrTxDataShard::TError::WRONG_PAYLOAD_TYPE: - case NKikimrTxDataShard::TError::WRONG_SHARD_STATE: - case NKikimrTxDataShard::TError::SCHEME_CHANGED: - return MarkShardError(tabletId, *perTablet, true, ctx); - default: - break; - } - } + return; + + switch (msg->GetStatus()) { + case NKikimrTxDataShard::TEvProposeTransactionResult::ERROR: + for (const auto &er : record.GetError()) { + const NKikimrTxDataShard::TError::EKind errorKind = er.GetKind(); + switch (errorKind) { + case NKikimrTxDataShard::TError::SCHEME_ERROR: + case NKikimrTxDataShard::TError::WRONG_PAYLOAD_TYPE: + case NKikimrTxDataShard::TError::WRONG_SHARD_STATE: + case NKikimrTxDataShard::TError::SCHEME_CHANGED: + return MarkShardError(tabletId, *perTablet, true, ctx); + default: + break; + } + } [[fallthrough]]; - default: - return MarkShardError(tabletId, *perTablet, false, ctx); - } -} - -void TDataReq::HandlePrepareErrorTimeout(const TActorContext &ctx) { + default: + return MarkShardError(tabletId, *perTablet, false, ctx); + } +} + +void TDataReq::HandlePrepareErrorTimeout(const TActorContext &ctx) { TxProxyMon->PrepareErrorTimeout->Inc(); - return Die(ctx); -} - -void TDataReq::Handle(TEvTxProxy::TEvProposeTransactionStatus::TPtr &ev, const TActorContext &ctx) { - // from coordinator - TEvTxProxy::TEvProposeTransactionStatus *msg = ev->Get(); - const NKikimrTx::TEvProposeTransactionStatus &record = msg->Record; - switch (msg->GetStatus()) { - case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusAccepted: + return Die(ctx); +} + +void TDataReq::Handle(TEvTxProxy::TEvProposeTransactionStatus::TPtr &ev, const TActorContext &ctx) { + // from coordinator + TEvTxProxy::TEvProposeTransactionStatus *msg = ev->Get(); + const NKikimrTx::TEvProposeTransactionStatus &record = msg->Record; + switch (msg->GetStatus()) { + case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusAccepted: TxProxyMon->ClientTxStatusAccepted->Inc(); // nop LOG_DEBUG_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId << " HANDLE TEvProposeTransactionStatus TDataReq marker# P11 Status# " << msg->GetStatus()); break; - case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusProcessed: + case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusProcessed: TxProxyMon->ClientTxStatusProcessed->Inc(); // nop LOG_DEBUG_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId << " HANDLE TEvProposeTransactionStatus TDataReq marker# P11 Status# " << msg->GetStatus()); break; - case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusConfirmed: + case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusConfirmed: TxProxyMon->ClientTxStatusConfirmed->Inc(); - // nop + // nop LOG_DEBUG_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId << " HANDLE TEvProposeTransactionStatus TDataReq marker# P11 Status# " << msg->GetStatus()); - break; - case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusPlanned: - // ok - PlanStep = record.GetStepId(); + break; + case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusPlanned: + // ok + PlanStep = record.GetStepId(); CoordinatorStatus = ECoordinatorStatus::Planned; - + TxProxyMon->ClientTxStatusPlanned->Inc(); LOG_DEBUG_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId << " HANDLE TEvProposeTransactionStatus TDataReq marker# P10 Status# " << msg->GetStatus()); WallClockPlanned = Now(); - if (ProxyFlags & TEvTxUserProxy::TEvProposeTransaction::ProxyReportPlanned) - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorPlanned, NKikimrIssues::TStatusIds::TRANSIENT, false, ctx); - break; - case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusOutdated: - case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusDeclined: - case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusDeclinedNoSpace: + if (ProxyFlags & TEvTxUserProxy::TEvProposeTransaction::ProxyReportPlanned) + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorPlanned, NKikimrIssues::TStatusIds::TRANSIENT, false, ctx); + break; + case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusOutdated: + case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusDeclined: + case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusDeclinedNoSpace: case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusRestarting: // TODO: retry // cancel proposal only for defined cases and fall through for generic error handling - CancelProposal(0); + CancelProposal(0); [[fallthrough]]; - default: - // smth goes wrong + default: + // smth goes wrong LOG_ERROR_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId << " HANDLE TEvProposeTransactionStatus TDataReq marker# P9 Status# " << msg->GetStatus()); - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorDeclined, NKikimrIssues::TStatusIds::REJECTED, true, ctx); + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorDeclined, NKikimrIssues::TStatusIds::REJECTED, true, ctx); TxProxyMon->ClientTxStatusCoordinatorDeclined->Inc(); - return Die(ctx); - } -} - + return Die(ctx); + } +} + void TDataReq::Handle(TEvDataShard::TEvProposeTransactionRestart::TPtr &ev, const TActorContext &ctx) { Y_UNUSED(ctx); const auto &record = ev->Get()->Record; @@ -2179,11 +2179,11 @@ void TDataReq::HandlePlan(TEvDataShard::TEvProposeTransactionAttachResult::TPtr return Die(ctx); } -void TDataReq::HandlePlan(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, const TActorContext &ctx) { - // from tablets - TEvDataShard::TEvProposeTransactionResult *msg = ev->Get(); - const auto &record = msg->Record; - +void TDataReq::HandlePlan(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, const TActorContext &ctx) { + // from tablets + TEvDataShard::TEvProposeTransactionResult *msg = ev->Get(); + const auto &record = msg->Record; + const ui64 tabletId = msg->GetOrigin(); TPerTablet *perTablet = PerTablet.FindPtr(tabletId); @@ -2193,29 +2193,29 @@ void TDataReq::HandlePlan(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, c ? NActors::NLog::PRI_DEBUG : NActors::NLog::PRI_ERROR), NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId - << " HANDLE Plan TEvProposeTransactionResult TDataReq GetStatus# " << msg->GetStatus() + << " HANDLE Plan TEvProposeTransactionResult TDataReq GetStatus# " << msg->GetStatus() << " shard id " << tabletId - << " marker# P12"); - - if (record.HasExecLatency()) - ElapsedExecExec = Max<TDuration>(ElapsedExecExec, TDuration::MilliSeconds(record.GetExecLatency())); - if (record.HasProposeLatency()) - ElapsedExecComplete = Max<TDuration>(ElapsedExecComplete, TDuration::MilliSeconds(record.GetProposeLatency())); - - switch (msg->GetStatus()) { - case NKikimrTxDataShard::TEvProposeTransactionResult::COMPLETE: + << " marker# P12"); + + if (record.HasExecLatency()) + ElapsedExecExec = Max<TDuration>(ElapsedExecExec, TDuration::MilliSeconds(record.GetExecLatency())); + if (record.HasProposeLatency()) + ElapsedExecComplete = Max<TDuration>(ElapsedExecComplete, TDuration::MilliSeconds(record.GetProposeLatency())); + + switch (msg->GetStatus()) { + case NKikimrTxDataShard::TEvProposeTransactionResult::COMPLETE: if (Y_LIKELY(perTablet)) { perTablet->TabletStatus = TPerTablet::ETabletStatus::StatusFinished; } TxProxyMon->PlanClientTxResultComplete->Inc(); - return MergeResult(ev, ctx); + return MergeResult(ev, ctx); case NKikimrTxDataShard::TEvProposeTransactionResult::RESPONSE_DATA: ProcessStreamResponseData(ev, ctx); return; - case NKikimrTxDataShard::TEvProposeTransactionResult::ABORTED: - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecAborted, NKikimrIssues::TStatusIds::SUCCESS, true, ctx); + case NKikimrTxDataShard::TEvProposeTransactionResult::ABORTED: + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecAborted, NKikimrIssues::TStatusIds::SUCCESS, true, ctx); TxProxyMon->PlanClientTxResultAborted->Inc(); - return Die(ctx); + return Die(ctx); case NKikimrTxDataShard::TEvProposeTransactionResult::RESULT_UNAVAILABLE: ExtractDatashardErrors(record); ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecResultUnavailable, NKikimrIssues::TStatusIds::ERROR, true, ctx); @@ -2226,54 +2226,54 @@ void TDataReq::HandlePlan(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, c ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecCancelled, NKikimrIssues::TStatusIds::ERROR, true, ctx); TxProxyMon->PlanClientTxResultCancelled->Inc(); return Die(ctx); - default: + default: ExtractDatashardErrors(record); - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecError, NKikimrIssues::TStatusIds::ERROR, true, ctx); + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecError, NKikimrIssues::TStatusIds::ERROR, true, ctx); TxProxyMon->PlanClientTxResultExecError->Inc(); - return Die(ctx); - } -} - -void TDataReq::HandlePlan(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TActorContext &ctx) { - TEvPipeCache::TEvDeliveryProblem *msg = ev->Get(); - - if (msg->TabletId == SelectedCoordinator) { - if (msg->NotDelivered) { - LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_ERROR, - NKikimrServices::TX_PROXY, TxId, - "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId - << " not delivered to coordinator" - << " coordinator id " << msg->TabletId << " marker# P8"); - - TStringStream explanation; - explanation << "tx failed to plan with txid#" << TxId; - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::TX_DECLINED_BY_COORDINATOR, explanation.Str())); - - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorDeclined, NKikimrIssues::TStatusIds::REJECTED, true, ctx); - TxProxyMon->PlanCoordinatorDeclined->Inc(); + return Die(ctx); + } +} + +void TDataReq::HandlePlan(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TActorContext &ctx) { + TEvPipeCache::TEvDeliveryProblem *msg = ev->Get(); + + if (msg->TabletId == SelectedCoordinator) { + if (msg->NotDelivered) { + LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_ERROR, + NKikimrServices::TX_PROXY, TxId, + "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId + << " not delivered to coordinator" + << " coordinator id " << msg->TabletId << " marker# P8"); + + TStringStream explanation; + explanation << "tx failed to plan with txid#" << TxId; + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::TX_DECLINED_BY_COORDINATOR, explanation.Str())); + + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorDeclined, NKikimrIssues::TStatusIds::REJECTED, true, ctx); + TxProxyMon->PlanCoordinatorDeclined->Inc(); } else if (CoordinatorStatus == ECoordinatorStatus::Planned) { // We lost pipe to coordinator, but we already know tx is planned return; - } else { - LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_ERROR, - NKikimrServices::TX_PROXY, TxId, - "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId - << " delivery problem to coordinator" - << " coordinator id " << msg->TabletId << " marker# P8b"); - - TStringStream explanation; - explanation << "tx state unknown, lost pipe with selected tx coordinator with txid#" << TxId; - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::TX_STATE_UNKNOWN, explanation.Str())); - + } else { + LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_ERROR, + NKikimrServices::TX_PROXY, TxId, + "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId + << " delivery problem to coordinator" + << " coordinator id " << msg->TabletId << " marker# P8b"); + + TStringStream explanation; + explanation << "tx state unknown, lost pipe with selected tx coordinator with txid#" << TxId; + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::TX_STATE_UNKNOWN, explanation.Str())); + auto status = IsReadOnlyRequest() ? TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorDeclined : TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::CoordinatorUnknown; ReportStatus(status, NKikimrIssues::TStatusIds::TIMEOUT, true, ctx); - TxProxyMon->PlanClientDestroyed->Inc(); - } - - return Die(ctx); + TxProxyMon->PlanClientDestroyed->Inc(); + } + + return Die(ctx); } else if (TPerTablet *perTablet = PerTablet.FindPtr(msg->TabletId)) { bool wasRestarting = std::exchange(perTablet->Restarting, false); switch (perTablet->TabletStatus) { @@ -2305,31 +2305,31 @@ void TDataReq::HandlePlan(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TAct return; } - LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_ERROR, - NKikimrServices::TX_PROXY, TxId, + LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_ERROR, + NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId << " shard " << msg->TabletId << " lost pipe while waiting for reply" << (msg->NotDelivered ? " (last message not delivered)" : "")); - - ComplainingDatashards.push_back(msg->TabletId); - - TStringStream explanation; - explanation << "tx state unknown for shard " << msg->TabletId << " with txid#" << TxId; - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::TX_STATE_UNKNOWN, explanation.Str())); - + + ComplainingDatashards.push_back(msg->TabletId); + + TStringStream explanation; + explanation << "tx state unknown for shard " << msg->TabletId << " with txid#" << TxId; + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::TX_STATE_UNKNOWN, explanation.Str())); + auto status = IsReadOnlyRequest() ? TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardNotAvailable : TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyShardUnknown; ReportStatus(status, NKikimrIssues::TStatusIds::TIMEOUT, true, ctx); - TxProxyMon->ClientConnectedError->Inc(); - - return Die(ctx); - } - - LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_ERROR, - NKikimrServices::TX_PROXY, TxId, - "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId << " lost pipe with unknown endpoint, ignoring"); -} - + TxProxyMon->ClientConnectedError->Inc(); + + return Die(ctx); + } + + LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_ERROR, + NKikimrServices::TX_PROXY, TxId, + "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId << " lost pipe with unknown endpoint, ignoring"); +} + void TDataReq::Handle(TEvDataShard::TEvGetReadTableSinkStateRequest::TPtr &ev, const TActorContext &ctx) { auto *response = new TEvDataShard::TEvGetReadTableSinkStateResponse; @@ -2397,8 +2397,8 @@ void TDataReq::Handle(TEvTxProcessing::TEvStreamClearanceRequest::TPtr &ev, cons // Handle shard restart. For now temporary snapshots are used by scan transaction // and therefore any shard restart may cause inconsistent response. if (ReadTableRequest->ClearanceSenders.contains(shard) || PerTablet[shard].StreamCleared) { - LOG_ERROR_S(ctx, NKikimrServices::TX_PROXY, - "Cannot recover from shard restart, shard: " << shard << ", txid: " << TxId); + LOG_ERROR_S(ctx, NKikimrServices::TX_PROXY, + "Cannot recover from shard restart, shard: " << shard << ", txid: " << TxId); // We must send response to current request too auto response = MakeHolder<TEvTxProcessing::TEvStreamClearanceResponse>(); @@ -2406,10 +2406,10 @@ void TDataReq::Handle(TEvTxProcessing::TEvStreamClearanceRequest::TPtr &ev, cons response->Record.SetCleared(false); ctx.Send(ev->Sender, response.Release()); - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecError, NKikimrIssues::TStatusIds::ERROR, true, ctx); - Die(ctx); - return; - } + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecError, NKikimrIssues::TStatusIds::ERROR, true, ctx); + Die(ctx); + return; + } LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, "Got clearance request, shard: " << rec.GetShardId() @@ -2428,9 +2428,9 @@ void TDataReq::Handle(TEvTxProcessing::TEvStreamClearanceRequest::TPtr &ev, cons ProcessStreamClearance(true, ctx); } -void TDataReq::Handle(TEvTxProcessing::TEvStreamIsDead::TPtr &ev, const TActorContext &ctx) +void TDataReq::Handle(TEvTxProcessing::TEvStreamIsDead::TPtr &ev, const TActorContext &ctx) { - Y_UNUSED(ev); + Y_UNUSED(ev); Y_VERIFY(ReadTableRequest); LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, @@ -2440,16 +2440,16 @@ void TDataReq::Handle(TEvTxProcessing::TEvStreamIsDead::TPtr &ev, const TActorCo Die(ctx); } -void TDataReq::HandleResolve(TEvTxProcessing::TEvStreamIsDead::TPtr &ev, const TActorContext &ctx) { - Y_UNUSED(ev); - Y_VERIFY(ReadTableRequest); - LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, - "Abort read table transaction because stream is dead txid: " << TxId); - - ReportStatus(TEvTxUserProxy::TResultStatus::ExecComplete, NKikimrIssues::TStatusIds::REJECTED, true, ctx); - Become(&TThis::StateResolveTimeout); -} - +void TDataReq::HandleResolve(TEvTxProcessing::TEvStreamIsDead::TPtr &ev, const TActorContext &ctx) { + Y_UNUSED(ev); + Y_VERIFY(ReadTableRequest); + LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, + "Abort read table transaction because stream is dead txid: " << TxId); + + ReportStatus(TEvTxUserProxy::TResultStatus::ExecComplete, NKikimrIssues::TStatusIds::REJECTED, true, ctx); + Become(&TThis::StateResolveTimeout); +} + void TDataReq::Handle(TEvTxProcessing::TEvStreamQuotaRequest::TPtr &ev, const TActorContext &ctx) { Y_VERIFY_DEBUG(ReadTableRequest); @@ -2479,34 +2479,34 @@ void TDataReq::Handle(TEvTxProcessing::TEvStreamQuotaRelease::TPtr &ev, const TA ctx.Send(ev->Forward(RequestSource)); } -void TDataReq::HandleExecTimeoutResolve(const TActorContext &ctx) { - LOG_ERROR_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, - "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId - << " HANDLE ExecTimeout TDataReq"); - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecTimeout, NKikimrIssues::TStatusIds::TIMEOUT, true, ctx); - TxProxyMon->ExecTimeout->Inc(); - Become(&TThis::StateResolveTimeout); -} - -void TDataReq::HandleExecTimeout(const TActorContext &ctx) { +void TDataReq::HandleExecTimeoutResolve(const TActorContext &ctx) { LOG_ERROR_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId << " HANDLE ExecTimeout TDataReq"); - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecTimeout, NKikimrIssues::TStatusIds::TIMEOUT, true, ctx); + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecTimeout, NKikimrIssues::TStatusIds::TIMEOUT, true, ctx); TxProxyMon->ExecTimeout->Inc(); - return Die(ctx); -} - -void TDataReq::MergeResult(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, const TActorContext &ctx) { + Become(&TThis::StateResolveTimeout); +} + +void TDataReq::HandleExecTimeout(const TActorContext &ctx) { + LOG_ERROR_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, + "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId + << " HANDLE ExecTimeout TDataReq"); + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecTimeout, NKikimrIssues::TStatusIds::TIMEOUT, true, ctx); + TxProxyMon->ExecTimeout->Inc(); + return Die(ctx); +} + +void TDataReq::MergeResult(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, const TActorContext &ctx) { NKikimrTxDataShard::TEvProposeTransactionResult &record = ev->Get()->Record; - + ResultsReceivedCount++; ResultsReceivedSize += record.GetTxResult().size(); WallClockLastExecReply = Now(); - if (WallClockFirstExecReply.GetValue() == 0) - WallClockFirstExecReply = WallClockLastExecReply; - + if (WallClockFirstExecReply.GetValue() == 0) + WallClockFirstExecReply = WallClockLastExecReply; + const ui64 tabletId = record.GetOrigin(); TPerTablet *perTablet = PerTablet.FindPtr(tabletId); @@ -2555,27 +2555,27 @@ void TDataReq::MergeResult(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, )); } - const ui64 originShard = record.GetOrigin(); - auto builderIt = FlatMKQLRequest->BalanceCoverageBuilders.find(originShard); - if (builderIt != FlatMKQLRequest->BalanceCoverageBuilders.end()) { - if (builderIt->second->AddResult(record.GetBalanceTrackList())) { + const ui64 originShard = record.GetOrigin(); + auto builderIt = FlatMKQLRequest->BalanceCoverageBuilders.find(originShard); + if (builderIt != FlatMKQLRequest->BalanceCoverageBuilders.end()) { + if (builderIt->second->AddResult(record.GetBalanceTrackList())) { engine.AddShardReply(originShard, record.GetTxResult()); - if (builderIt->second->IsComplete()) { - engine.FinalizeOriginReplies(originShard); - FlatMKQLRequest->BalanceCoverageBuilders.erase(builderIt); - } - } - } - + if (builderIt->second->IsComplete()) { + engine.FinalizeOriginReplies(originShard); + FlatMKQLRequest->BalanceCoverageBuilders.erase(builderIt); + } + } + } + if (FlatMKQLRequest->BalanceCoverageBuilders.empty()) { return MakeFlatMKQLResponse(ctx, timer); } else { CpuTime += timer.GetTime(); } -} - +} + void TDataReq::MakeFlatMKQLResponse(const TActorContext &ctx, const NCpuTime::TCpuTimer& timer) { - NMiniKQL::IEngineFlat &engine = *FlatMKQLRequest->Engine; + NMiniKQL::IEngineFlat &engine = *FlatMKQLRequest->Engine; engine.SetStepTxId({ PlanStep, TxId }); engine.SetDeadline(WallClockAccepted + ExecTimeoutPeriod); @@ -2583,30 +2583,30 @@ void TDataReq::MakeFlatMKQLResponse(const TActorContext &ctx, const NCpuTime::TC engine.SetMemoryLimit(FlatMKQLRequest->Limits.GetComputeNodeMemoryLimitBytes()); } - engine.BuildResult(); - FlatMKQLRequest->EngineResponseStatus = engine.GetStatus(); - - switch (FlatMKQLRequest->EngineResponseStatus) { - case NMiniKQL::IEngineFlat::EStatus::Unknown: - case NMiniKQL::IEngineFlat::EStatus::Error: - LOG_ERROR_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, - "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId - << " MergeResult ExecError TDataReq marker# P16"); + engine.BuildResult(); + FlatMKQLRequest->EngineResponseStatus = engine.GetStatus(); + + switch (FlatMKQLRequest->EngineResponseStatus) { + case NMiniKQL::IEngineFlat::EStatus::Unknown: + case NMiniKQL::IEngineFlat::EStatus::Error: + LOG_ERROR_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, + "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId + << " MergeResult ExecError TDataReq marker# P16"); CpuTime += timer.GetTime(); - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecError, NKikimrIssues::TStatusIds::ERROR, true, ctx); - TxProxyMon->MergeResultMiniKQLExecError->Inc(); - return Die(ctx); - case NMiniKQL::IEngineFlat::EStatus::Complete: + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecError, NKikimrIssues::TStatusIds::ERROR, true, ctx); + TxProxyMon->MergeResultMiniKQLExecError->Inc(); + return Die(ctx); + case NMiniKQL::IEngineFlat::EStatus::Complete: case NMiniKQL::IEngineFlat::EStatus::Aborted: { - LOG_DEBUG_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, - "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId - << " MergeResult ExecComplete TDataReq marker# P17"); + LOG_DEBUG_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, + "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId + << " MergeResult ExecComplete TDataReq marker# P17"); auto fillResult = engine.FillResultValue(FlatMKQLRequest->EngineEvaluatedResponse); switch (fillResult) { case NMiniKQL::IEngineFlat::EResult::Ok: CpuTime += timer.GetTime(); - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecComplete, NKikimrIssues::TStatusIds::SUCCESS, true, ctx); + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ExecComplete, NKikimrIssues::TStatusIds::SUCCESS, true, ctx); TxProxyMon->MergeResultMiniKQLExecComplete->Inc(); break; case NMiniKQL::IEngineFlat::EResult::ResultTooBig: @@ -2639,13 +2639,13 @@ void TDataReq::MakeFlatMKQLResponse(const TActorContext &ctx, const NCpuTime::TC break; } - return Die(ctx); + return Die(ctx); } - default: + default: Y_FAIL("unknown engine status# %" PRIu32 " txid# %" PRIu64, (ui32)FlatMKQLRequest->EngineResponseStatus, (ui64)TxId); - } -} - + } +} + void TDataReq::ProcessStreamResponseData(TEvDataShard::TEvProposeTransactionResult::TPtr &ev, const TActorContext &ctx) { @@ -2694,7 +2694,7 @@ void TDataReq::FinishShardStream(TEvDataShard::TEvProposeTransactionResult::TPtr } void TDataReq::FinishStreamResponse(const TActorContext &ctx) { - ReportStatus(TEvTxUserProxy::TResultStatus::ExecComplete, NKikimrIssues::TStatusIds::SUCCESS, true, ctx); + ReportStatus(TEvTxUserProxy::TResultStatus::ExecComplete, NKikimrIssues::TStatusIds::SUCCESS, true, ctx); Die(ctx); } @@ -2747,8 +2747,8 @@ void TDataReq::FailProposedRequest(TEvTxUserProxy::TEvProposeTransactionStatus:: DatashardErrors = errMsg; // Cancel the Tx on all shards (so we pass invalid tablet id) - CancelProposal(0); - ReportStatus(status, NKikimrIssues::TStatusIds::ERROR, true, ctx); + CancelProposal(0); + ReportStatus(status, NKikimrIssues::TStatusIds::ERROR, true, ctx); Become(&TThis::StatePrepareErrors, ctx, TDuration::MilliSeconds(500), new TEvents::TEvWakeup); TxProxyMon->TxResultError->Inc(); } @@ -2775,20 +2775,20 @@ bool TDataReq::CheckDomainLocality(NSchemeCache::TSchemeCacheRequest &cacheReque return true; } -void TDataReq::RegisterPlan(const TActorContext &ctx) { +void TDataReq::RegisterPlan(const TActorContext &ctx) { WallClockPrepared = Now(); - TDomainsInfo *domainsInfo = AppData(ctx)->DomainsInfo.Get(); + TDomainsInfo *domainsInfo = AppData(ctx)->DomainsInfo.Get(); Y_VERIFY(domainsInfo); - + ui64 totalReadSize = 0; TSet<ui32> affectedDomains; - for (const auto &xp : PerTablet) { - const ui32 tabletDomain = domainsInfo->GetDomainUidByTabletId(xp.first); + for (const auto &xp : PerTablet) { + const ui32 tabletDomain = domainsInfo->GetDomainUidByTabletId(xp.first); Y_VERIFY(tabletDomain != Max<ui32>()); - affectedDomains.insert(tabletDomain); + affectedDomains.insert(tabletDomain); totalReadSize += xp.second.ReadSize; - } - + } + // Check reply size ui64 sizeLimit = RequestControls.PerRequestDataSizeLimit; if (FlatMKQLRequest && FlatMKQLRequest->Limits.GetTotalReadSizeLimitBytes()) { @@ -2822,50 +2822,50 @@ void TDataReq::RegisterPlan(const TActorContext &ctx) { } if (ProxyFlags & TEvTxUserProxy::TEvProposeTransaction::ProxyReportPrepared) - ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyPrepared, NKikimrIssues::TStatusIds::TRANSIENT, false, ctx); + ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ProxyPrepared, NKikimrIssues::TStatusIds::TRANSIENT, false, ctx); Y_VERIFY(SelectedCoordinator, "shouldn't be run with null SelectedCoordinator"); - TAutoPtr<TEvTxProxy::TEvProposeTransaction> req(new TEvTxProxy::TEvProposeTransaction(SelectedCoordinator, TxId, 0, - AggrMinStep, AggrMaxStep)); - - auto *reqAffectedSet = req->Record.MutableTransaction()->MutableAffectedSet(); - reqAffectedSet->Reserve(PerTablet.size()); - - for (const auto &xp : PerTablet) { - auto x = reqAffectedSet->Add(); - x->SetTabletId(xp.first); - x->SetFlags(xp.second.AffectedFlags); - } - + TAutoPtr<TEvTxProxy::TEvProposeTransaction> req(new TEvTxProxy::TEvProposeTransaction(SelectedCoordinator, TxId, 0, + AggrMinStep, AggrMaxStep)); + + auto *reqAffectedSet = req->Record.MutableTransaction()->MutableAffectedSet(); + reqAffectedSet->Reserve(PerTablet.size()); + + for (const auto &xp : PerTablet) { + auto x = reqAffectedSet->Add(); + x->SetTabletId(xp.first); + x->SetFlags(xp.second.AffectedFlags); + } + LOG_DEBUG_S_SAMPLED_BY(ctx, NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId - << " SEND EvProposeTransaction to# " << SelectedCoordinator << " Coordinator marker# P7 "); - + << " SEND EvProposeTransaction to# " << SelectedCoordinator << " Coordinator marker# P7 "); + Send(Services.LeaderPipeCache, new TEvPipeCache::TEvForward(req.Release(), SelectedCoordinator, true)); CoordinatorStatus = ECoordinatorStatus::Waiting; - Become(&TThis::StateWaitPlan); -} - + Become(&TThis::StateWaitPlan); +} + void TDataReq::HandleUndeliveredResolve(TEvents::TEvUndelivered::TPtr &, const TActorContext &ctx) { IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::GENERIC_TXPROXY_ERROR, "unexpected event delivery problem")); ReportStatus(TEvTxUserProxy::TResultStatus::Unknown, NKikimrIssues::TStatusIds::INTERNAL_ERROR, true, ctx); Become(&TThis::StateResolveTimeout); } -void TDataReq::Handle(TEvents::TEvUndelivered::TPtr &, const TActorContext &ctx) { - IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::GENERIC_TXPROXY_ERROR, "unexpected event delivery problem")); - ReportStatus(TEvTxUserProxy::TResultStatus::Unknown, NKikimrIssues::TStatusIds::INTERNAL_ERROR, true, ctx); - return Die(ctx); -} - -void TDataReq::HandleWatchdog(const TActorContext &ctx) { +void TDataReq::Handle(TEvents::TEvUndelivered::TPtr &, const TActorContext &ctx) { + IssueManager.RaiseIssue(MakeIssue(NKikimrIssues::TIssuesIds::GENERIC_TXPROXY_ERROR, "unexpected event delivery problem")); + ReportStatus(TEvTxUserProxy::TResultStatus::Unknown, NKikimrIssues::TStatusIds::INTERNAL_ERROR, true, ctx); + return Die(ctx); +} + +void TDataReq::HandleWatchdog(const TActorContext &ctx) { const TDuration fromStart = Now() - this->WallClockAccepted; LOG_LOG_S_SAMPLED_BY(ctx, NActors::NLog::PRI_INFO, NKikimrServices::TX_PROXY, TxId, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId << " Transactions still running for " << fromStart); - ctx.Schedule(TDuration::MilliSeconds(KIKIMR_DATAREQ_WATCHDOG_PERIOD), new TEvPrivate::TEvProxyDataReqOngoingTransactionWatchdog()); -} - + ctx.Schedule(TDuration::MilliSeconds(KIKIMR_DATAREQ_WATCHDOG_PERIOD), new TEvPrivate::TEvProxyDataReqOngoingTransactionWatchdog()); +} + void TDataReq::SendStreamClearanceResponse(ui64 shard, bool cleared, const TActorContext &ctx) { TAutoPtr<TEvTxProcessing::TEvStreamClearanceResponse> response @@ -2979,9 +2979,9 @@ bool TDataReq::IsReadOnlyRequest() const { IActor* CreateTxProxyDataReq(const TTxProxyServices &services, const ui64 txid, const TIntrusivePtr<NKikimr::NTxProxy::TTxProxyMon>& mon, const TRequestControls& requestControls) { return new NTxProxy::TDataReq(services, txid, mon, requestControls); -} - -}} +} + +}} #define STATUS_TO_STRING_IMPL_ITEM(name, ...) \ diff --git a/ydb/core/tx/tx_proxy/describe.cpp b/ydb/core/tx/tx_proxy/describe.cpp index 75f986addc..deb38ca2b7 100644 --- a/ydb/core/tx/tx_proxy/describe.cpp +++ b/ydb/core/tx/tx_proxy/describe.cpp @@ -8,35 +8,35 @@ #include <ydb/core/sys_view/common/schema.h> #include <ydb/library/aclib/aclib.h> - + #include <library/cpp/actors/core/hfunc.h> -namespace NKikimr { -namespace NTxProxy { - +namespace NKikimr { +namespace NTxProxy { + class TDescribeReq : public TActor<TDescribeReq> { const TTxProxyServices Services; - + THolder<TEvTxProxyReq::TEvNavigateScheme> SchemeRequest; - TIntrusivePtr<TTxProxyMon> TxProxyMon; - + TIntrusivePtr<TTxProxyMon> TxProxyMon; + TInstant WallClockStarted; TActorId Source; - ui64 SourceCookie; - + ui64 SourceCookie; + TAutoPtr<const NACLib::TUserToken> UserToken; TString TextPath; - - void Die(const TActorContext &ctx) override { - --*TxProxyMon->NavigateReqInFly; - + + void Die(const TActorContext &ctx) override { + --*TxProxyMon->NavigateReqInFly; + Send(Services.LeaderPipeCache, new TEvPipeCache::TEvUnlink(0)); - - TActor::Die(ctx); - } - + + TActor::Die(ctx); + } + void ReportError(NKikimrScheme::EStatus status, const TString& reason, const TActorContext &ctx) { TAutoPtr<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResultBuilder> result = new NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResultBuilder(); @@ -47,13 +47,13 @@ class TDescribeReq : public TActor<TDescribeReq> { result->Record.SetPath(record.GetDescribePath().GetPath()); } } - + result->Record.SetStatus(status); result->Record.SetReason(reason); - - ctx.Send(Source, result.Release(), 0, SourceCookie); - } - + + ctx.Send(Source, result.Release(), 0, SourceCookie); + } + void FillRootDescr(NKikimrSchemeOp::TDirEntry* descr, const TString& name, ui64 schemeRootId) { descr->SetPathId(NSchemeShard::RootPathId); descr->SetName(name); @@ -65,7 +65,7 @@ class TDescribeReq : public TActor<TDescribeReq> { //descr->SetCreateStep(0); //descr->SetOwner(BUILTIN_ACL_ROOT); } - + void FillSystemViewDescr(NKikimrSchemeOp::TDirEntry* descr, ui64 schemeShardId) { descr->SetSchemeshardId(schemeShardId); descr->SetPathId(InvalidLocalPathId); @@ -176,54 +176,54 @@ class TDescribeReq : public TActor<TDescribeReq> { return Die(ctx); } - void Handle(TEvTxProxyReq::TEvNavigateScheme::TPtr &ev, const TActorContext &ctx); - void Handle(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TActorContext &ctx); + void Handle(TEvTxProxyReq::TEvNavigateScheme::TPtr &ev, const TActorContext &ctx); + void Handle(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TActorContext &ctx); void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev, const TActorContext &ctx); void Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr &ev, const TActorContext &ctx); -public: +public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TX_PROXY_NAVIGATE; } TDescribeReq(const TTxProxyServices &services, const TIntrusivePtr<TTxProxyMon>& txProxyMon) - : TActor(&TThis::StateWaitInit) + : TActor(&TThis::StateWaitInit) , Services(services) - , TxProxyMon(txProxyMon) - { - ++*TxProxyMon->NavigateReqInFly; - } - - STFUNC(StateWaitInit) { - switch (ev->GetTypeRewrite()) { - HFunc(TEvTxProxyReq::TEvNavigateScheme, Handle); - } - } - + , TxProxyMon(txProxyMon) + { + ++*TxProxyMon->NavigateReqInFly; + } + + STFUNC(StateWaitInit) { + switch (ev->GetTypeRewrite()) { + HFunc(TEvTxProxyReq::TEvNavigateScheme, Handle); + } + } + STFUNC(StateWaitResolve) { switch (ev->GetTypeRewrite()) { HFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle); } } - STFUNC(StateWaitExec) { - switch (ev->GetTypeRewrite()) { + STFUNC(StateWaitExec) { + switch (ev->GetTypeRewrite()) { HFunc(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult, Handle); - HFunc(TEvPipeCache::TEvDeliveryProblem, Handle); - } - } -}; - + HFunc(TEvPipeCache::TEvDeliveryProblem, Handle); + } + } +}; + void TDescribeReq::Handle(TEvTxProxyReq::TEvNavigateScheme::TPtr &ev, const TActorContext &ctx) { - TEvTxProxyReq::TEvNavigateScheme *msg = ev->Get(); - const auto &record = msg->Ev->Get()->Record; + TEvTxProxyReq::TEvNavigateScheme *msg = ev->Get(); + const auto &record = msg->Ev->Get()->Record; LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, "Actor# " << ctx.SelfID.ToString() << " HANDLE EvNavigateScheme " << record.GetDescribePath().GetPath()); - + WallClockStarted = ctx.Now(); - Source = msg->Ev->Sender; - SourceCookie = msg->Ev->Cookie; - + Source = msg->Ev->Sender; + SourceCookie = msg->Ev->Cookie; + if (record.GetDescribePath().HasPath()) { TDomainsInfo *domainsInfo = AppData(ctx)->DomainsInfo.Get(); Y_VERIFY(!domainsInfo->Domains.empty()); @@ -239,7 +239,7 @@ void TDescribeReq::Handle(TEvTxProxyReq::TEvNavigateScheme::TPtr &ev, const TAct FillRootDescr(entry, domain.second->Name, domain.second->SchemeRoot); } - ctx.Send(Source, result.Release(), 0, SourceCookie); + ctx.Send(Source, result.Release(), 0, SourceCookie); return Die(ctx); } } @@ -262,13 +262,13 @@ void TDescribeReq::Handle(TEvTxProxyReq::TEvNavigateScheme::TPtr &ev, const TAct LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, "Actor# " << ctx.SelfID.ToString() << " SEND to# " << shardToRequest << " shardToRequest " << req->ToString()); - + Send(Services.LeaderPipeCache, new TEvPipeCache::TEvForward(req.Release(), shardToRequest, true), 0, SourceCookie); - + Become(&TThis::StateWaitExec); return; } - + TAutoPtr<NSchemeCache::TSchemeCacheNavigate> request(new NSchemeCache::TSchemeCacheNavigate()); request->DatabaseName = record.GetDatabaseName(); NSchemeCache::TSchemeCacheNavigate::TEntry entry; @@ -296,17 +296,17 @@ void TDescribeReq::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr & TxProxyMon->CacheRequestLatency->Collect((ctx.Now() - WallClockStarted).MilliSeconds()); - Y_VERIFY(navigate->ResultSet.size() == 1); - const auto& entry = navigate->ResultSet.front(); - + Y_VERIFY(navigate->ResultSet.size() == 1); + const auto& entry = navigate->ResultSet.front(); + LOG_LOG_S(ctx, (navigate->ErrorCount == 0 ? NActors::NLog::PRI_DEBUG : NActors::NLog::PRI_INFO), NKikimrServices::TX_PROXY, "Actor# " << ctx.SelfID.ToString() << " HANDLE EvNavigateKeySetResult TDescribeReq marker# P5 ErrorCount# " << navigate->ErrorCount); if (navigate->ErrorCount > 0) { - switch (entry.Status) { - case NSchemeCache::TSchemeCacheNavigate::EStatus::PathErrorUnknown: + switch (entry.Status) { + case NSchemeCache::TSchemeCacheNavigate::EStatus::PathErrorUnknown: if (UserToken != nullptr && entry.SecurityObject != nullptr) { ui32 access = NACLib::EAccessRights::DescribeSchema; if (!entry.SecurityObject->CheckAccess(access, *UserToken)) { @@ -321,19 +321,19 @@ void TDescribeReq::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr & ReportError(NKikimrScheme::StatusPathDoesNotExist, "Path not found", ctx); break; - case NSchemeCache::TSchemeCacheNavigate::EStatus::RootUnknown: + case NSchemeCache::TSchemeCacheNavigate::EStatus::RootUnknown: ReportError(NKikimrScheme::StatusPathDoesNotExist, "Root not found", ctx); - TxProxyMon->ResolveKeySetWrongRequest->Inc(); - break; + TxProxyMon->ResolveKeySetWrongRequest->Inc(); + break; case NSchemeCache::TSchemeCacheNavigate::EStatus::RedirectLookupError: ReportError(NKikimrScheme::StatusNotAvailable, "Could not resolve redirected path", ctx); TxProxyMon->ResolveKeySetRedirectUnavaible->Inc(); break; - default: + default: ReportError(NKikimrScheme::StatusNotAvailable, "Could not resolve path", ctx); - TxProxyMon->ResolveKeySetFail->Inc(); - break; - } + TxProxyMon->ResolveKeySetFail->Inc(); + break; + } return Die(ctx); } @@ -370,11 +370,11 @@ void TDescribeReq::Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr & LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, "Actor# " << ctx.SelfID.ToString() << " SEND to# " << shardToRequest << " shardToRequest " << req->ToString()); - + Send(Services.LeaderPipeCache, new TEvPipeCache::TEvForward(req.Release(), shardToRequest, true), 0, SourceCookie); - Become(&TThis::StateWaitExec); -} - + Become(&TThis::StateWaitExec); +} + void TDescribeReq::Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr &ev, const TActorContext &ctx) { LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, @@ -429,19 +429,19 @@ void TDescribeReq::Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult: } } - ctx.ExecutorThread.Send(ev->Forward(Source)); - return Die(ctx); -} - -void TDescribeReq::Handle(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TActorContext &ctx) { - Y_UNUSED(ev); + ctx.ExecutorThread.Send(ev->Forward(Source)); + return Die(ctx); +} + +void TDescribeReq::Handle(TEvPipeCache::TEvDeliveryProblem::TPtr &ev, const TActorContext &ctx) { + Y_UNUSED(ev); ReportError(NKikimrScheme::StatusNotAvailable, "Schemeshard not available", ctx); return Die(ctx); -} - +} + IActor* CreateTxProxyDescribeFlatSchemeReq(const TTxProxyServices &services, const TIntrusivePtr<TTxProxyMon>& txProxyMon) { return new TDescribeReq(services, txProxyMon); -} - -} -} +} + +} +} diff --git a/ydb/core/tx/tx_proxy/mon.cpp b/ydb/core/tx/tx_proxy/mon.cpp index 08d42c25c7..14f5d47064 100644 --- a/ydb/core/tx/tx_proxy/mon.cpp +++ b/ydb/core/tx/tx_proxy/mon.cpp @@ -1,39 +1,39 @@ #include "mon.h" - + #include <ydb/core/base/counters.h> -namespace NKikimr { -namespace NTxProxy { - -TTxProxyMon::TTxProxyMon(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters) - : Counters(counters) +namespace NKikimr { +namespace NTxProxy { + +TTxProxyMon::TTxProxyMon(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters) + : Counters(counters) , TxGroup(GetServiceCounters(counters, "proxy")->GetSubgroup("subsystem", "tx")) , DataReqGroup(GetServiceCounters(counters, "proxy")->GetSubgroup("subsystem", "datareq")) , AllocPoolCounters(counters, "tx_proxy") -{ +{ CacheRequestLatency = TxGroup->GetHistogram("CacheRequest/LatencyMs", NMonitoring::ExponentialHistogram(10, 4, 1)); - Navigate = TxGroup->GetCounter("Navigate/Request", true); + Navigate = TxGroup->GetCounter("Navigate/Request", true); NavigateLatency = TxGroup->GetHistogram("Navigate/LatencyMs", NMonitoring::ExponentialHistogram(10, 4, 1)); - - SchemeRequest = TxGroup->GetCounter("Propose/SchemeRequest", true); + + SchemeRequest = TxGroup->GetCounter("Propose/SchemeRequest", true); SchemeRequestLatency = TxGroup->GetHistogram("SchemeRequest/LatencyMs", NMonitoring::ExponentialHistogram(10, 4, 1)); - SchemeRequestProxyNotReady = TxGroup->GetCounter("Propose/SchemeRequestProxyNotReady", true); - MakeRequest = TxGroup->GetCounter("Propose/MakeRequest", true); + SchemeRequestProxyNotReady = TxGroup->GetCounter("Propose/SchemeRequestProxyNotReady", true); + MakeRequest = TxGroup->GetCounter("Propose/MakeRequest", true); SnapshotRequest = TxGroup->GetCounter("Propose/SnapshotRequest", true); CommitWritesRequest = TxGroup->GetCounter("Propose/CommitWritesRequest", true); - MakeRequestProxyNotReady = TxGroup->GetCounter("Propose/MakeRequestProxyNotReady", true); - TxNotImplemented = TxGroup->GetCounter("Propose/TxNotImplemented", true); + MakeRequestProxyNotReady = TxGroup->GetCounter("Propose/MakeRequestProxyNotReady", true); + TxNotImplemented = TxGroup->GetCounter("Propose/TxNotImplemented", true); KqpRequest = TxGroup->GetCounter("Propose/KqpRequest", true); - - DataReqInFly = TxGroup->GetCounter("InFly/DataTx", false); - SchemeReqInFly = TxGroup->GetCounter("InFly/SchemeOp", false); - NavigateReqInFly = TxGroup->GetCounter("InFly/Navigate", false); - - ReportStatusOK = DataReqGroup->GetCounter("ReportStatus/OK", true); - ReportStatusNotOK = DataReqGroup->GetCounter("ReportStatus/NotOK", true); + + DataReqInFly = TxGroup->GetCounter("InFly/DataTx", false); + SchemeReqInFly = TxGroup->GetCounter("InFly/SchemeOp", false); + NavigateReqInFly = TxGroup->GetCounter("InFly/Navigate", false); + + ReportStatusOK = DataReqGroup->GetCounter("ReportStatus/OK", true); + ReportStatusNotOK = DataReqGroup->GetCounter("ReportStatus/NotOK", true); ReportStatusStreamData = DataReqGroup->GetCounter("ReportStatus/StreamData", true); - + TxPrepareTimeHgram = DataReqGroup->GetHistogram("TxPrepareTimesMs", NMonitoring::ExponentialHistogram(20, 2, 1)); TxExecuteTimeHgram = DataReqGroup->GetHistogram("TxExecuteTimesMs", @@ -48,7 +48,7 @@ TTxProxyMon::TTxProxyMon(const TIntrusivePtr<NMonitoring::TDynamicCounters>& cou NMonitoring::ExponentialHistogram(10, 2, 1)); TxExecSpreadHgram = DataReqGroup->GetHistogram("TxExecSpreadMs", NMonitoring::ExponentialHistogram(10, 2, 1)); - + TxPrepareSetProgramHgram = DataReqGroup->GetHistogram("TxPrepareSetProgramUs", NMonitoring::ExponentialHistogram(10, 2, 100)); TxPrepareResolveHgram = DataReqGroup->GetHistogram("TxPrepareResolveUs", @@ -57,76 +57,76 @@ TTxProxyMon::TTxProxyMon(const TIntrusivePtr<NMonitoring::TDynamicCounters>& cou NMonitoring::ExponentialHistogram(10, 2, 100)); TxPrepareSendShardProgramsHgram = DataReqGroup->GetHistogram("TxPrepareSendShardProgramsUs", NMonitoring::ExponentialHistogram(10, 2, 100)); - - MiniKQLResolveSentToShard = DataReqGroup->GetCounter("MiniKQLResolve/SentToShard", true); - MiniKQLWrongRequest = DataReqGroup->GetCounter("MiniKQLResolve/WrongRequest", true); - + + MiniKQLResolveSentToShard = DataReqGroup->GetCounter("MiniKQLResolve/SentToShard", true); + MiniKQLWrongRequest = DataReqGroup->GetCounter("MiniKQLResolve/WrongRequest", true); + ReadTableResolveSentToShard = DataReqGroup->GetCounter("ReadTableResolve/SentToShard", true); ReadTableWrongRequest = DataReqGroup->GetCounter("ReadTableResolve/WrongRequest", true); - MiniKQLProgramSize = DataReqGroup->GetCounter("MiniKQLProgramSize", true); - MiniKQLParamsSize = DataReqGroup->GetCounter("MiniKQLParamsSize", true); - - ExecTimeout = DataReqGroup->GetCounter("ExecTimeout", true); - - MarkShardError = DataReqGroup->GetCounter("MarkShardError", true); - - PrepareErrorTimeout = DataReqGroup->GetCounter("PrepareErrorTimeout", true); - - PlanClientDestroyed = DataReqGroup->GetCounter("Plan/ClientDestroyed", true); - PlanClientConnected = DataReqGroup->GetCounter("Plan/ClientConnected", true); - PlanCoordinatorDeclined = DataReqGroup->GetCounter("Plan/CoordinatorDeclined", true); - - PlanClientTxResultComplete = DataReqGroup->GetCounter("Plan/TxResult/Complete", true); - PlanClientTxResultAborted = DataReqGroup->GetCounter("Plan/TxResult/Aborted", true); + MiniKQLProgramSize = DataReqGroup->GetCounter("MiniKQLProgramSize", true); + MiniKQLParamsSize = DataReqGroup->GetCounter("MiniKQLParamsSize", true); + + ExecTimeout = DataReqGroup->GetCounter("ExecTimeout", true); + + MarkShardError = DataReqGroup->GetCounter("MarkShardError", true); + + PrepareErrorTimeout = DataReqGroup->GetCounter("PrepareErrorTimeout", true); + + PlanClientDestroyed = DataReqGroup->GetCounter("Plan/ClientDestroyed", true); + PlanClientConnected = DataReqGroup->GetCounter("Plan/ClientConnected", true); + PlanCoordinatorDeclined = DataReqGroup->GetCounter("Plan/CoordinatorDeclined", true); + + PlanClientTxResultComplete = DataReqGroup->GetCounter("Plan/TxResult/Complete", true); + PlanClientTxResultAborted = DataReqGroup->GetCounter("Plan/TxResult/Aborted", true); PlanClientTxResultResultUnavailable = DataReqGroup->GetCounter("Plan/TxResult/ResultUnavailable", true); PlanClientTxResultCancelled = DataReqGroup->GetCounter("Plan/TxResult/Cancelled", true); - PlanClientTxResultExecError = DataReqGroup->GetCounter("Plan/TxResult/ExecError", true); - - ClientTxStatusAccepted = DataReqGroup->GetCounter("ClientTx/Status/Accepted", true); - ClientTxStatusProcessed = DataReqGroup->GetCounter("ClientTx/Status/Processed", true); - ClientTxStatusConfirmed = DataReqGroup->GetCounter("ClientTx/Status/Confirmed", true); - ClientTxStatusPlanned = DataReqGroup->GetCounter("ClientTx/Status/Planned", true); - ClientTxStatusCoordinatorDeclined = DataReqGroup->GetCounter("ClientTx/Status/CoordinatorDeclined", true); - - MakeRequestProxyAccepted = DataReqGroup->GetCounter("MakeRequest/ProxyAccepted", true); - MakeRequestWrongRequest = DataReqGroup->GetCounter("MakeRequest/WrongRequest", true); - MakeRequestEmptyAffectedSet = DataReqGroup->GetCounter("MakeRequest/EmptyAffectedSet", true); - - ResolveKeySetLegacySuccess = DataReqGroup->GetCounter("ResolveKeySet/LegacySuccess", true); - ResolveKeySetMiniKQLSuccess = DataReqGroup->GetCounter("ResolveKeySet/MiniKQLSuccess", true); + PlanClientTxResultExecError = DataReqGroup->GetCounter("Plan/TxResult/ExecError", true); + + ClientTxStatusAccepted = DataReqGroup->GetCounter("ClientTx/Status/Accepted", true); + ClientTxStatusProcessed = DataReqGroup->GetCounter("ClientTx/Status/Processed", true); + ClientTxStatusConfirmed = DataReqGroup->GetCounter("ClientTx/Status/Confirmed", true); + ClientTxStatusPlanned = DataReqGroup->GetCounter("ClientTx/Status/Planned", true); + ClientTxStatusCoordinatorDeclined = DataReqGroup->GetCounter("ClientTx/Status/CoordinatorDeclined", true); + + MakeRequestProxyAccepted = DataReqGroup->GetCounter("MakeRequest/ProxyAccepted", true); + MakeRequestWrongRequest = DataReqGroup->GetCounter("MakeRequest/WrongRequest", true); + MakeRequestEmptyAffectedSet = DataReqGroup->GetCounter("MakeRequest/EmptyAffectedSet", true); + + ResolveKeySetLegacySuccess = DataReqGroup->GetCounter("ResolveKeySet/LegacySuccess", true); + ResolveKeySetMiniKQLSuccess = DataReqGroup->GetCounter("ResolveKeySet/MiniKQLSuccess", true); ResolveKeySetReadTableSuccess = DataReqGroup->GetCounter("ResolveKeySet/ReadTableSuccess", true); ResolveKeySetRedirectUnavaible = DataReqGroup->GetCounter("ResolveKeySet/RedirectUnavaible", true); - ResolveKeySetFail = DataReqGroup->GetCounter("ResolveKeySet/Fail", true); - ResolveKeySetWrongRequest = DataReqGroup->GetCounter("ResolveKeySet/WrongRequest", true); + ResolveKeySetFail = DataReqGroup->GetCounter("ResolveKeySet/Fail", true); + ResolveKeySetWrongRequest = DataReqGroup->GetCounter("ResolveKeySet/WrongRequest", true); ResolveKeySetDomainLocalityFail = DataReqGroup->GetCounter("ResolveKeySet/DomainLocalityFail", true); - - ClientConnectedOk = DataReqGroup->GetCounter("ClientConnected/Ok", true); - ClientConnectedError = DataReqGroup->GetCounter("ClientConnected/Error", true); - - ClientDestroyedOk = DataReqGroup->GetCounter("ClientDestoroyed/Ok", true); - ClientDestroyedError = DataReqGroup->GetCounter("ClientDestoroyed/Error", true); - - TxResultTabletPrepared = DataReqGroup->GetCounter("TxResult/TabletPrepared", true); - TxResultPrepared = DataReqGroup->GetCounter("TxResult/Prepared", true); - TxResultComplete = DataReqGroup->GetCounter("TxResult/Complete", true); - TxResultError = DataReqGroup->GetCounter("TxResult/Error", true); - TxResultAborted = DataReqGroup->GetCounter("TxResult/Aborted", true); - TxResultFatal = DataReqGroup->GetCounter("TxResult/Fatal", true); - TxResultShardOverloaded = DataReqGroup->GetCounter("TxResult/Overloaded", true); - TxResultShardTryLater = DataReqGroup->GetCounter("TxResult/TryLater", true); + + ClientConnectedOk = DataReqGroup->GetCounter("ClientConnected/Ok", true); + ClientConnectedError = DataReqGroup->GetCounter("ClientConnected/Error", true); + + ClientDestroyedOk = DataReqGroup->GetCounter("ClientDestoroyed/Ok", true); + ClientDestroyedError = DataReqGroup->GetCounter("ClientDestoroyed/Error", true); + + TxResultTabletPrepared = DataReqGroup->GetCounter("TxResult/TabletPrepared", true); + TxResultPrepared = DataReqGroup->GetCounter("TxResult/Prepared", true); + TxResultComplete = DataReqGroup->GetCounter("TxResult/Complete", true); + TxResultError = DataReqGroup->GetCounter("TxResult/Error", true); + TxResultAborted = DataReqGroup->GetCounter("TxResult/Aborted", true); + TxResultFatal = DataReqGroup->GetCounter("TxResult/Fatal", true); + TxResultShardOverloaded = DataReqGroup->GetCounter("TxResult/Overloaded", true); + TxResultShardTryLater = DataReqGroup->GetCounter("TxResult/TryLater", true); TxResultExecError = DataReqGroup->GetCounter("TxResult/ExecError", true); TxResultResultUnavailable = DataReqGroup->GetCounter("TxResult/ResultUnavailable", true); TxResultCancelled = DataReqGroup->GetCounter("TxResult/Cancelled", true); - - MergeResultRequestExecError = DataReqGroup->GetCounter("MergeResult/RequestExecError", true); - MergeResultRequestExecComplete = DataReqGroup->GetCounter("MergeResult/RequestExecComplete", true); - MergeResultMiniKQLExecError = DataReqGroup->GetCounter("MergeResult/MiniKQLExecError", true); - MergeResultMiniKQLExecComplete = DataReqGroup->GetCounter("MergeResult/MiniKQLExecComplete", true); - MergeResultMiniKQLUnknownStatus = DataReqGroup->GetCounter("MergeResult/MiniKQLUnknownStatus", true); + + MergeResultRequestExecError = DataReqGroup->GetCounter("MergeResult/RequestExecError", true); + MergeResultRequestExecComplete = DataReqGroup->GetCounter("MergeResult/RequestExecComplete", true); + MergeResultMiniKQLExecError = DataReqGroup->GetCounter("MergeResult/MiniKQLExecError", true); + MergeResultMiniKQLExecComplete = DataReqGroup->GetCounter("MergeResult/MiniKQLExecComplete", true); + MergeResultMiniKQLUnknownStatus = DataReqGroup->GetCounter("MergeResult/MiniKQLUnknownStatus", true); ResultsReceivedCount = DataReqGroup->GetCounter("ResultsReceived/Count", true); ResultsReceivedSize = DataReqGroup->GetCounter("ResultsReceived/Size", true); -} - -}} +} + +}} diff --git a/ydb/core/tx/tx_proxy/mon.h b/ydb/core/tx/tx_proxy/mon.h index 8e3732fe86..d747ab4f99 100644 --- a/ydb/core/tx/tx_proxy/mon.h +++ b/ydb/core/tx/tx_proxy/mon.h @@ -34,10 +34,10 @@ namespace NTxProxy { NMonitoring::TDynamicCounters::TCounterPtr TxNotImplemented; NMonitoring::TDynamicCounters::TCounterPtr KqpRequest; - NMonitoring::TDynamicCounters::TCounterPtr DataReqInFly; - NMonitoring::TDynamicCounters::TCounterPtr SchemeReqInFly; - NMonitoring::TDynamicCounters::TCounterPtr NavigateReqInFly; - + NMonitoring::TDynamicCounters::TCounterPtr DataReqInFly; + NMonitoring::TDynamicCounters::TCounterPtr SchemeReqInFly; + NMonitoring::TDynamicCounters::TCounterPtr NavigateReqInFly; + // tx_proxy_datareq group TIntrusivePtr<NMonitoring::TDynamicCounters> DataReqGroup; @@ -45,28 +45,28 @@ namespace NTxProxy { NMonitoring::TDynamicCounters::TCounterPtr ReportStatusNotOK; NMonitoring::TDynamicCounters::TCounterPtr ReportStatusStreamData; - NMonitoring::THistogramPtr TxPrepareTimeHgram; - NMonitoring::THistogramPtr TxExecuteTimeHgram; - NMonitoring::THistogramPtr TxTotalTimeHgram; - NMonitoring::THistogramPtr TxPrepareSpreadHgram; - NMonitoring::THistogramPtr TxPrepareArriveSpreadHgram; - NMonitoring::THistogramPtr TxPrepareCompleteSpreadHgram; - NMonitoring::THistogramPtr TxExecSpreadHgram; - - NMonitoring::THistogramPtr TxPrepareSetProgramHgram; - NMonitoring::THistogramPtr TxPrepareResolveHgram; - NMonitoring::THistogramPtr TxPrepareBuildShardProgramsHgram; - NMonitoring::THistogramPtr TxPrepareSendShardProgramsHgram; - + NMonitoring::THistogramPtr TxPrepareTimeHgram; + NMonitoring::THistogramPtr TxExecuteTimeHgram; + NMonitoring::THistogramPtr TxTotalTimeHgram; + NMonitoring::THistogramPtr TxPrepareSpreadHgram; + NMonitoring::THistogramPtr TxPrepareArriveSpreadHgram; + NMonitoring::THistogramPtr TxPrepareCompleteSpreadHgram; + NMonitoring::THistogramPtr TxExecSpreadHgram; + + NMonitoring::THistogramPtr TxPrepareSetProgramHgram; + NMonitoring::THistogramPtr TxPrepareResolveHgram; + NMonitoring::THistogramPtr TxPrepareBuildShardProgramsHgram; + NMonitoring::THistogramPtr TxPrepareSendShardProgramsHgram; + NMonitoring::TDynamicCounters::TCounterPtr MiniKQLResolveSentToShard; NMonitoring::TDynamicCounters::TCounterPtr MiniKQLWrongRequest; NMonitoring::TDynamicCounters::TCounterPtr ReadTableResolveSentToShard; NMonitoring::TDynamicCounters::TCounterPtr ReadTableWrongRequest; - NMonitoring::TDynamicCounters::TCounterPtr MiniKQLProgramSize; - NMonitoring::TDynamicCounters::TCounterPtr MiniKQLParamsSize; - + NMonitoring::TDynamicCounters::TCounterPtr MiniKQLProgramSize; + NMonitoring::TDynamicCounters::TCounterPtr MiniKQLParamsSize; + NMonitoring::TDynamicCounters::TCounterPtr ExecTimeout; NMonitoring::TDynamicCounters::TCounterPtr MarkShardError; NMonitoring::TDynamicCounters::TCounterPtr PrepareErrorTimeout; @@ -111,8 +111,8 @@ namespace NTxProxy { NMonitoring::TDynamicCounters::TCounterPtr TxResultError; NMonitoring::TDynamicCounters::TCounterPtr TxResultAborted; NMonitoring::TDynamicCounters::TCounterPtr TxResultFatal; - NMonitoring::TDynamicCounters::TCounterPtr TxResultShardOverloaded; - NMonitoring::TDynamicCounters::TCounterPtr TxResultShardTryLater; + NMonitoring::TDynamicCounters::TCounterPtr TxResultShardOverloaded; + NMonitoring::TDynamicCounters::TCounterPtr TxResultShardTryLater; NMonitoring::TDynamicCounters::TCounterPtr TxResultExecError; NMonitoring::TDynamicCounters::TCounterPtr TxResultResultUnavailable; NMonitoring::TDynamicCounters::TCounterPtr TxResultCancelled; @@ -128,7 +128,7 @@ namespace NTxProxy { TAlignedPagePoolCounters AllocPoolCounters; - TTxProxyMon(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters); + TTxProxyMon(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters); }; } // NTxProxy diff --git a/ydb/core/tx/tx_proxy/proxy.cpp b/ydb/core/tx/tx_proxy/proxy.cpp index 23a9a1953a..55962e7d06 100644 --- a/ydb/core/tx/tx_proxy/proxy.cpp +++ b/ydb/core/tx/tx_proxy/proxy.cpp @@ -1,13 +1,13 @@ #include "proxy.h" - -namespace NKikimr { - + +namespace NKikimr { + TActorId MakeTxProxyID() { return TActorId(0, TStringBuf("TxProxyServ")); } } - + TString NKikimr::TEvTxUserProxy::TEvProposeTransactionStatus::ToString() const { TStringStream str; diff --git a/ydb/core/tx/tx_proxy/proxy.h b/ydb/core/tx/tx_proxy/proxy.h index deca1f059f..86d4f1ac79 100644 --- a/ydb/core/tx/tx_proxy/proxy.h +++ b/ydb/core/tx/tx_proxy/proxy.h @@ -1,5 +1,5 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include "mon.h" #include <ydb/public/lib/base/defs.h> @@ -12,17 +12,17 @@ #include <ydb/core/scheme/scheme_tabledefs.h> #include <ydb/core/protos/tx_proxy.pb.h> -#include <util/generic/set.h> -#include <util/generic/hash.h> - -namespace NKikimr { - -namespace NMiniKQL { - struct TKeyDescriptionRange; - struct TKeyDescriptionSuffixItem; - struct TKeyDescription; -} - +#include <util/generic/set.h> +#include <util/generic/hash.h> + +namespace NKikimr { + +namespace NMiniKQL { + struct TKeyDescriptionRange; + struct TKeyDescriptionSuffixItem; + struct TKeyDescription; +} + namespace NTxProxy { struct TTxProxyServices { TActorId Proxy; @@ -32,16 +32,16 @@ namespace NTxProxy { }; } -struct TEvTxUserProxy { - enum EEv { - EvProposeTransaction = EventSpaceBegin(TKikimrEvents::ES_TX_USERPROXY), // reply would be with generic TEvTxProxy::TEvProposeTransactionStatus - EvNavigate, // --/-- TEvSchemeShard::TEvNavigateSchemePartResult - - EvProposeTransactionStatus = EvProposeTransaction + 1 * 512, - EvNavigateStatus, +struct TEvTxUserProxy { + enum EEv { + EvProposeTransaction = EventSpaceBegin(TKikimrEvents::ES_TX_USERPROXY), // reply would be with generic TEvTxProxy::TEvProposeTransactionStatus + EvNavigate, // --/-- TEvSchemeShard::TEvNavigateSchemePartResult + + EvProposeTransactionStatus = EvProposeTransaction + 1 * 512, + EvNavigateStatus, EvInvalidateTable, EvInvalidateTableResult, - + EvCancelBackupRequestDeprecated, EvCancelBackupResultDeprecated, @@ -61,27 +61,27 @@ struct TEvTxUserProxy { EvResolveTablesResponse, - EvEnd - }; - + EvEnd + }; + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_TX_USERPROXY), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_TX_USERPROXY)"); - - struct TEvProposeTransaction : public TEventPB<TEvProposeTransaction, NKikimrTxUserProxy::TEvProposeTransaction, EvProposeTransaction> { - enum EProxyFlags { - ProxyTrackWallClock = 1 << 0, - ProxyReportAccepted = 1 << 1, - ProxyReportResolved = 1 << 2, - ProxyReportPrepared = 1 << 3, - ProxyReportPlanned = 1 << 4, - }; - - TEvProposeTransaction() - {} - - TEvProposeTransaction(ui64 proxyFlags) - { - Record.SetProxyFlags(proxyFlags); - } + + struct TEvProposeTransaction : public TEventPB<TEvProposeTransaction, NKikimrTxUserProxy::TEvProposeTransaction, EvProposeTransaction> { + enum EProxyFlags { + ProxyTrackWallClock = 1 << 0, + ProxyReportAccepted = 1 << 1, + ProxyReportResolved = 1 << 2, + ProxyReportPrepared = 1 << 3, + ProxyReportPlanned = 1 << 4, + }; + + TEvProposeTransaction() + {} + + TEvProposeTransaction(ui64 proxyFlags) + { + Record.SetProxyFlags(proxyFlags); + } bool HasSchemeProposal() const { return HasModifyScheme() || HasTransactionalModification(); @@ -135,32 +135,32 @@ struct TEvTxUserProxy { return false; } - }; - - struct TEvNavigate : public TEventPB<TEvNavigate, NKikimrTxUserProxy::TEvNavigate, EvNavigate> { - TEvNavigate() - {} - }; - + }; + + struct TEvNavigate : public TEventPB<TEvNavigate, NKikimrTxUserProxy::TEvNavigate, EvNavigate> { + TEvNavigate() + {} + }; + using TResultStatus = NTxProxy::TResultStatus; - - struct TEvProposeTransactionStatus : public TEventPB<TEvProposeTransactionStatus, NKikimrTxUserProxy::TEvProposeTransactionStatus, EvProposeTransactionStatus> { - using EStatus = TResultStatus::EStatus; - - TEvProposeTransactionStatus() - {} - - TEvProposeTransactionStatus(EStatus status) { - Record.SetStatus(static_cast<ui32>(status)); - } - - EStatus Status() const { - return static_cast<EStatus>(Record.GetStatus()); - } + + struct TEvProposeTransactionStatus : public TEventPB<TEvProposeTransactionStatus, NKikimrTxUserProxy::TEvProposeTransactionStatus, EvProposeTransactionStatus> { + using EStatus = TResultStatus::EStatus; + + TEvProposeTransactionStatus() + {} + + TEvProposeTransactionStatus(EStatus status) { + Record.SetStatus(static_cast<ui32>(status)); + } + + EStatus Status() const { + return static_cast<EStatus>(Record.GetStatus()); + } TString ToString() const; - }; - + }; + struct TEvInvalidateTable : public TEventPB<TEvInvalidateTable, NKikimrTxUserProxy::TEvInvalidateTable, EvInvalidateTable> { TEvInvalidateTable() = default; TEvInvalidateTable(const TTableId& tableId) { @@ -219,44 +219,44 @@ struct TEvTxUserProxy { , Issues(issues) {} }; -}; - -struct TEvTxProxyReq { - enum EEv { - EvMakeRequest = EventSpaceBegin(TKikimrEvents::ES_TX_PROXY_REQ), - EvSchemeRequest, - EvNavigateScheme, - - EvEnd, - }; - +}; + +struct TEvTxProxyReq { + enum EEv { + EvMakeRequest = EventSpaceBegin(TKikimrEvents::ES_TX_PROXY_REQ), + EvSchemeRequest, + EvNavigateScheme, + + EvEnd, + }; + static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_TX_PROXY_REQ), "expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_TX_PROXY_REQ)"); - - struct TEvMakeRequest : public TEventLocal<TEvMakeRequest, EvMakeRequest> { - TEvTxUserProxy::TEvProposeTransaction::TPtr Ev; - - TEvMakeRequest(TEvTxUserProxy::TEvProposeTransaction::TPtr &ev) - : Ev(ev) - {} - }; - - struct TEvSchemeRequest : public TEventLocal<TEvSchemeRequest, EvSchemeRequest> { - TEvTxUserProxy::TEvProposeTransaction::TPtr Ev; - - TEvSchemeRequest(TEvTxUserProxy::TEvProposeTransaction::TPtr &ev) - : Ev(ev) - {} - }; - - struct TEvNavigateScheme : public TEventLocal<TEvNavigateScheme, EvNavigateScheme> { - TEvTxUserProxy::TEvNavigate::TPtr Ev; - - TEvNavigateScheme(TEvTxUserProxy::TEvNavigate::TPtr &ev) - : Ev(ev) - {} - }; -}; - + + struct TEvMakeRequest : public TEventLocal<TEvMakeRequest, EvMakeRequest> { + TEvTxUserProxy::TEvProposeTransaction::TPtr Ev; + + TEvMakeRequest(TEvTxUserProxy::TEvProposeTransaction::TPtr &ev) + : Ev(ev) + {} + }; + + struct TEvSchemeRequest : public TEventLocal<TEvSchemeRequest, EvSchemeRequest> { + TEvTxUserProxy::TEvProposeTransaction::TPtr Ev; + + TEvSchemeRequest(TEvTxUserProxy::TEvProposeTransaction::TPtr &ev) + : Ev(ev) + {} + }; + + struct TEvNavigateScheme : public TEventLocal<TEvNavigateScheme, EvNavigateScheme> { + TEvTxUserProxy::TEvNavigate::TPtr Ev; + + TEvNavigateScheme(TEvTxUserProxy::TEvNavigate::TPtr &ev) + : Ev(ev) + {} + }; +}; + namespace NTxProxy { using TTableColumnInfo = TSysTables::TTableColumnInfo; @@ -312,5 +312,5 @@ namespace NTxProxy { IActor* CreateTxProxy(const TVector<ui64> &allocators); TActorId MakeTxProxyID(); - -} + +} diff --git a/ydb/core/tx/tx_proxy/proxy_impl.cpp b/ydb/core/tx/tx_proxy/proxy_impl.cpp index 34371fccfd..20dc8cce17 100644 --- a/ydb/core/tx/tx_proxy/proxy_impl.cpp +++ b/ydb/core/tx/tx_proxy/proxy_impl.cpp @@ -12,12 +12,12 @@ #include <ydb/core/kqp/executer/kqp_executer.h> #include <ydb/core/tablet/tablet_pipe_client_cache.h> #include <ydb/core/protos/counters_tx_proxy.pb.h> - -namespace NKikimr { -using namespace NTabletFlatExecutor; - -namespace NTxProxy { - + +namespace NKikimr { +using namespace NTabletFlatExecutor; + +namespace NTxProxy { + template<class EventType> struct TDelayedQueue { typedef typename EventType::TPtr EventTypePtr; @@ -44,11 +44,11 @@ struct TDelayedQueue { }; class TTxProxy : public TActorBootstrapped<TTxProxy> { - TTxProxyServices Services; + TTxProxyServices Services; THolder<NTabletPipe::IClientCache> PipeClientCache; TTxAllocatorClient TxAllocatorClient; - + static const TDuration TimeoutDelayedRequest; typedef TDelayedQueue<TEvTxUserProxy::TEvProposeTransaction> TDelayedProposal; TDelayedProposal DelayedProposal; @@ -57,21 +57,21 @@ class TTxProxy : public TActorBootstrapped<TTxProxy> { typedef TDelayedQueue<TEvTxUserProxy::TEvAllocateTxId> TDelayedAllocateTxId; TDelayedAllocateTxId DelayedAllocateTxId; - TIntrusivePtr<NMonitoring::TDynamicCounters> CacheCounters; - TIntrusivePtr<TTxProxyMon> TxProxyMon; + TIntrusivePtr<NMonitoring::TDynamicCounters> CacheCounters; + TIntrusivePtr<TTxProxyMon> TxProxyMon; TRequestControls RequestControls; - - void Die(const TActorContext &ctx) override { - ctx.Send(Services.SchemeCache, new TEvents::TEvPoisonPill()); + + void Die(const TActorContext &ctx) override { + ctx.Send(Services.SchemeCache, new TEvents::TEvPoisonPill()); ctx.Send(Services.LeaderPipeCache, new TEvents::TEvPoisonPill()); ctx.Send(Services.FollowerPipeCache, new TEvents::TEvPoisonPill()); - + PipeClientCache->Detach(ctx); PipeClientCache.Destroy(); - + return TActor::Die(ctx); } - + void Handle(TEvents::TEvPoisonPill::TPtr &ev, const TActorContext &ctx) { LOG_NOTICE_S(ctx, NKikimrServices::TX_PROXY, "actor# " << SelfId() << @@ -79,7 +79,7 @@ class TTxProxy : public TActorBootstrapped<TTxProxy> { " from Sender# " << ev->Sender.ToString()); Die(ctx); } - + void ReplyDecline(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus status, const TEvTxUserProxy::TEvProposeTransaction::TPtr &ev, const TActorContext &ctx) { LOG_NOTICE_S(ctx, NKikimrServices::TX_PROXY, "actor# " << SelfId() << @@ -89,7 +89,7 @@ class TTxProxy : public TActorBootstrapped<TTxProxy> { ctx.Send(ev->Sender, new TEvTxUserProxy::TEvProposeTransactionStatus(status), 0, ev->Cookie); } - + void ReplyNotImplemented(const TEvTxUserProxy::TEvProposeTransaction::TPtr &ev, const TActorContext &ctx) { TxProxyMon->TxNotImplemented->Inc(); const NKikimrTxUserProxy::TTransaction &tx = ev->Get()->Record.GetTransaction(); @@ -100,7 +100,7 @@ class TTxProxy : public TActorBootstrapped<TTxProxy> { " RESPONSE Status# NotImplemented Type# Unknown"); return ReplyDecline(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::NotImplemented, ev, ctx); } - + void Decline(const TEvTxUserProxy::TEvProposeTransaction::TPtr &ev, const TActorContext &ctx) { if (ev->Get()->HasSchemeProposal()) { LOG_WARN_S(ctx, NKikimrServices::TX_PROXY, @@ -126,7 +126,7 @@ class TTxProxy : public TActorBootstrapped<TTxProxy> { ReplyNotImplemented(ev, ctx); } - + void DelayRequest(TEvTxUserProxy::TEvProposeTransaction::TPtr &ev, const TActorContext &ctx) { auto request = new TDelayedProposal::TRequest(ev, ctx.Now() + TimeoutDelayedRequest); DelayedProposal.Queue->Push(request); @@ -190,21 +190,21 @@ class TTxProxy : public TActorBootstrapped<TTxProxy> { .BackoffMultiplier = 5, }; return config; - } - + } + static const NTabletPipe::TClientConfig& GetPipeClientConfig() { static const NTabletPipe::TClientConfig config = InitPipeClientConfig(); return config; - } - + } + void Handle(TEvTxAllocator::TEvAllocateResult::TPtr &ev, const TActorContext &ctx) { if (!TxAllocatorClient.OnAllocateResult(ev, ctx)) { return; } PlayDelayed(ctx); - } - + } + void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx) { TEvTabletPipe::TEvClientConnected *msg = ev->Get(); LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, @@ -217,8 +217,8 @@ class TTxProxy : public TActorBootstrapped<TTxProxy> { TxAllocatorClient.SendRequest(msg->TabletId, ctx); return; } - } - + } + void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx) { TEvTabletPipe::TEvClientDestroyed *msg = ev->Get(); LOG_WARN_S(ctx, NKikimrServices::TX_PROXY, @@ -236,45 +236,45 @@ class TTxProxy : public TActorBootstrapped<TTxProxy> { "actor# " << SelfId() << " TxId# " << txid << " ProcessProposeTransaction"); - + RequestControls.Reqister(ctx); - // process scheme transactions + // process scheme transactions const NKikimrTxUserProxy::TTransaction &tx = ev->Get()->Record.GetTransaction(); if (ev->Get()->HasSchemeProposal()) { - // todo: in-fly and shutdown + // todo: in-fly and shutdown Y_VERIFY_DEBUG(txid != 0); ui64 cookie = ev->Cookie; const TString userRequestId = tx.GetUserRequestId(); TAutoPtr<TEvTxProxyReq::TEvSchemeRequest> request = new TEvTxProxyReq::TEvSchemeRequest(ev); const TActorId reqId = ctx.ExecutorThread.RegisterActor(CreateTxProxyFlatSchemeReq(Services, txid, request, TxProxyMon)); - TxProxyMon->SchemeRequest->Inc(); - LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, + TxProxyMon->SchemeRequest->Inc(); + LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, "actor# " << SelfId() << " Cookie# " << cookie << " userReqId# \"" << userRequestId << "\"" " txid# " << txid << " SEND to# " << reqId.ToString().data()); - return; - } - - // otherwise process data transaction + return; + } + + // otherwise process data transaction if (ev->Get()->HasMakeProposal()) { - // todo: in-fly and shutdown + // todo: in-fly and shutdown Y_VERIFY_DEBUG(txid != 0); const TActorId reqId = ctx.ExecutorThread.RegisterActor(CreateTxProxyDataReq(Services, txid, TxProxyMon, RequestControls)); - TxProxyMon->MakeRequest->Inc(); - LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, + TxProxyMon->MakeRequest->Inc(); + LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, "actor# " << SelfId() << " Cookie# " << (ui64)ev->Cookie << " userReqId# \"" << tx.GetUserRequestId() << "\"" << " txid# " << txid << " SEND to# " << reqId.ToString().data() << " DataReq marker# P0"); - ctx.Send(reqId, new TEvTxProxyReq::TEvMakeRequest(ev)); - return; - } - + ctx.Send(reqId, new TEvTxProxyReq::TEvMakeRequest(ev)); + return; + } + if (ev->Get()->HasSnapshotProposal()) { auto cookie = ev->Cookie; auto userReqId = tx.GetUserRequestId(); @@ -306,8 +306,8 @@ class TTxProxy : public TActorBootstrapped<TTxProxy> { } ReplyNotImplemented(ev, ctx); - } - + } + void Handle(TEvTxUserProxy::TEvProposeTransaction::TPtr &ev, const TActorContext &ctx) { const NKikimrTxUserProxy::TTransaction &tx = ev->Get()->Record.GetTransaction(); LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, @@ -395,23 +395,23 @@ class TTxProxy : public TActorBootstrapped<TTxProxy> { ctx.Send(ev->Sender, reply.Release(), 0, ev->Cookie); } - void Handle(TEvTxUserProxy::TEvNavigate::TPtr &ev, const TActorContext &ctx) { + void Handle(TEvTxUserProxy::TEvNavigate::TPtr &ev, const TActorContext &ctx) { TString path = ev->Get()->Record.GetDescribePath().GetPath(); LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, "actor# " << SelfId() << " Handle TEvNavigate " << " describe path " << path); - TxProxyMon->Navigate->Inc(); + TxProxyMon->Navigate->Inc(); TActorId reqId = ctx.ExecutorThread.RegisterActor(CreateTxProxyDescribeFlatSchemeReq(Services, TxProxyMon)); - ctx.Send(reqId, new TEvTxProxyReq::TEvNavigateScheme(ev)); - } - + ctx.Send(reqId, new TEvTxProxyReq::TEvNavigateScheme(ev)); + } + void Handle(TEvTxUserProxy::TEvInvalidateTable::TPtr &ev, const TActorContext &ctx) { LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, "actor# " << SelfId() << " HANDLE EvInvalidateTable"); - ctx.Send(Services.SchemeCache, new TEvTxProxySchemeCache::TEvInvalidateTable(TTableId(ev.Get()->Get()->Record.GetSchemeShardId(), ev.Get()->Get()->Record.GetTableId()), ev.Get()->Sender)); + ctx.Send(Services.SchemeCache, new TEvTxProxySchemeCache::TEvInvalidateTable(TTableId(ev.Get()->Get()->Record.GetSchemeShardId(), ev.Get()->Get()->Record.GetTableId()), ev.Get()->Sender)); } void Handle(TEvTxProxySchemeCache::TEvInvalidateTableResult::TPtr &ev, const TActorContext &ctx) { @@ -421,7 +421,7 @@ class TTxProxy : public TActorBootstrapped<TTxProxy> { ctx.Send(ev.Get()->Get()->Sender, new TEvTxUserProxy::TEvInvalidateTableResult); } -public: +public: TTxProxy(const TVector<ui64> &txAllocators) : PipeClientCache(NTabletPipe::CreateUnboundedClientCache(GetPipeClientConfig())) , TxAllocatorClient(NKikimrServices::TX_PROXY, PipeClientCache.Get(), txAllocators) @@ -451,20 +451,20 @@ public: LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, "actor# " << SelfId() << " Become StateWork"); - } - + } + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TX_PROXY_ACTOR; - } - - STFUNC(StateWork) { - switch (ev->GetTypeRewrite()) { + } + + STFUNC(StateWork) { + switch (ev->GetTypeRewrite()) { HFunc(TEvTabletPipe::TEvClientDestroyed, Handle); HFunc(TEvTabletPipe::TEvClientConnected, Handle); HFunc(TEvTxAllocator::TEvAllocateResult, Handle); HFunc(TEvTxUserProxy::TEvNavigate, Handle); - HFunc(TEvTxUserProxy::TEvProposeTransaction, Handle); + HFunc(TEvTxUserProxy::TEvProposeTransaction, Handle); HFunc(TEvTxUserProxy::TEvInvalidateTable, Handle); HFunc(TEvTxProxySchemeCache::TEvInvalidateTableResult, Handle); @@ -474,24 +474,24 @@ public: HFunc(TEvTxUserProxy::TEvGetProxyServicesRequest, Handle); - HFunc(TEvents::TEvPoisonPill, Handle); - default: + HFunc(TEvents::TEvPoisonPill, Handle); + default: LOG_ERROR_S(ctx, NKikimrServices::TX_PROXY, "actor# " << SelfId() << " IGNORING message type# " << ev->GetTypeRewrite() << " from Sender# " << ev->Sender.ToString() << " at StateWork"); - break; - } - } -}; - + break; + } + } +}; + const TDuration TTxProxy::TimeoutDelayedRequest = TDuration::Seconds(15); -} - +} + IActor* CreateTxProxy(const TVector<ui64> &allocators) { return new NTxProxy::TTxProxy(allocators); -} - -} +} + +} diff --git a/ydb/core/tx/tx_proxy/schemereq.cpp b/ydb/core/tx/tx_proxy/schemereq.cpp index 5a5215d45f..923fe381ae 100644 --- a/ydb/core/tx/tx_proxy/schemereq.cpp +++ b/ydb/core/tx/tx_proxy/schemereq.cpp @@ -9,13 +9,13 @@ #include <ydb/core/base/path.h> #include <ydb/library/aclib/aclib.h> - + #include <library/cpp/actors/core/hfunc.h> #include <util/string/cast.h> -namespace NKikimr { -namespace NTxProxy { - +namespace NKikimr { +namespace NTxProxy { + static constexpr TStringBuf DocApiRequestType = "_document_api_request"; static constexpr TStringBuf DocApiTableVersionAttribute = "__document_api_version"; @@ -26,44 +26,44 @@ struct TBaseSchemeReq: public TActorBootstrapped<TDerived> { using TEvSchemeShardPropose = NSchemeShard::TEvSchemeShard::TEvModifySchemeTransaction; const TTxProxyServices Services; - const ui64 TxId; + const ui64 TxId; THolder<TEvTxProxyReq::TEvSchemeRequest> SchemeRequest; - TIntrusivePtr<TTxProxyMon> TxProxyMon; - + TIntrusivePtr<TTxProxyMon> TxProxyMon; + TInstant WallClockStarted; TActorId Source; TActorId PipeClient; - + struct TPathToResolve { NKikimrSchemeOp::EOperationType OperationRelated; - + TVector<TString> Path; bool RequiredRedirect = true; ui32 RequiredAccess = NACLib::EAccessRights::NoAccess; std::optional<NKikimrSchemeOp::TModifyACL> RequiredGrandAccess; - + TPathToResolve(NKikimrSchemeOp::EOperationType opType) : OperationRelated(opType) { - } + } }; - + TVector<TPathToResolve> ResolveForACL; - + std::optional<NACLib::TUserToken> UserToken; TBaseSchemeReq(const TTxProxyServices &services, ui64 txid, TAutoPtr<TEvTxProxyReq::TEvSchemeRequest> request, const TIntrusivePtr<TTxProxyMon> &txProxyMon) : Services(services) - , TxId(txid) + , TxId(txid) , SchemeRequest(request) - , TxProxyMon(txProxyMon) + , TxProxyMon(txProxyMon) , Source(SchemeRequest->Ev->Sender) - { - ++*TxProxyMon->SchemeReqInFly; - } - + { + ++*TxProxyMon->SchemeReqInFly; + } + auto& GetRequestEv() { return *SchemeRequest->Ev->Get(); } auto& GetRequestProto() { return GetRequestEv().Record; } @@ -107,9 +107,9 @@ struct TBaseSchemeReq: public TActorBootstrapped<TDerived> { void ExtractUserToken() { if (!GetRequestProto().GetUserToken().empty()) { UserToken = NACLib::TUserToken(GetRequestProto().GetUserToken()); - } - } - + } + } + static TVector<TString> Merge(const TVector<TString>& l, TVector<TString>&& r) { TVector<TString> result = l; std::move(r.begin(), r.end(), std::back_inserter(result)); @@ -153,7 +153,7 @@ struct TBaseSchemeReq: public TActorBootstrapped<TDerived> { case NKikimrSchemeOp::ESchemeOpModifyACL: return *modifyScheme.MutableModifyACL()->MutableName(); - + case NKikimrSchemeOp::ESchemeOpSplitMergeTablePartitions: Y_FAIL("no implementation for ESchemeOpSplitMergeTablePartitions"); @@ -174,14 +174,14 @@ struct TBaseSchemeReq: public TActorBootstrapped<TDerived> { case NKikimrSchemeOp::ESchemeOpAlterBlockStoreVolume: return *modifyScheme.MutableAlterBlockStoreVolume()->MutableName(); - + case NKikimrSchemeOp::ESchemeOpAssignBlockStoreVolume: return *modifyScheme.MutableAssignBlockStoreVolume()->MutableName(); - + case NKikimrSchemeOp::ESchemeOpCreateKesus: case NKikimrSchemeOp::ESchemeOpAlterKesus: return *modifyScheme.MutableKesus()->MutableName(); - + case NKikimrSchemeOp::ESchemeOpCreateSolomonVolume: return *modifyScheme.MutableCreateSolomonVolume()->MutableName(); @@ -608,7 +608,7 @@ struct TBaseSchemeReq: public TActorBootstrapped<TDerived> { toResolve.RequiredAccess = NACLib::EAccessRights::SelectRow; ResolveForACL.push_back(toResolve); } - break; + break; } case NKikimrSchemeOp::ESchemeOpCreateIndexedTable: case NKikimrSchemeOp::ESchemeOpCreateColumnStore: @@ -825,7 +825,7 @@ struct TBaseSchemeReq: public TActorBootstrapped<TDerived> { case NSchemeCache::TSchemeCacheNavigate::KindSubdomain: case NSchemeCache::TSchemeCacheNavigate::KindExtSubdomain: return true; - default: + default: return false; } } @@ -1235,7 +1235,7 @@ void TSchemeTransactionalReq::Bootstrap(const TActorContext &ctx) { WallClockStarted = ctx.Now(); TBase::Bootstrap(ctx); - + for(auto& scheme: GetModifications()) { if (!ExamineTables(scheme, ctx)) { ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::NotImplemented, ctx); @@ -1256,22 +1256,22 @@ void TSchemeTransactionalReq::Bootstrap(const TActorContext &ctx) { if (!resolveRequest) { ReportStatus(TEvTxUserProxy::TEvProposeTransactionStatus::EStatus::ResolveError, ctx); TxProxyMon->ResolveKeySetWrongRequest->Inc(); - return Die(ctx); - } - + return Die(ctx); + } + LOG_DEBUG_S(ctx, NKikimrServices::TX_PROXY, "Actor# " << ctx.SelfID.ToString() << " txid# " << TxId << " TEvNavigateKeySet requested from SchemeCache"); ctx.Send(Services.SchemeCache, new TEvTxProxySchemeCache::TEvNavigateKeySet(resolveRequest)); Become(&TThis::StateWaitResolve); return; -} - +} + IActor* CreateTxProxyFlatSchemeReq(const TTxProxyServices &services, const ui64 txid, TAutoPtr<TEvTxProxyReq::TEvSchemeRequest> request, const TIntrusivePtr<NKikimr::NTxProxy::TTxProxyMon>& mon) { if (request->Ev->Get()->HasModifyScheme()) { return new TFlatSchemeReq(services, txid, request, mon); } else { return new TSchemeTransactionalReq(services, txid, request, mon); } -} - -} -} +} + +} +} diff --git a/ydb/core/tx/tx_proxy/storage_tenant_ut.cpp b/ydb/core/tx/tx_proxy/storage_tenant_ut.cpp index d1b8dcd732..c3b8e9921a 100644 --- a/ydb/core/tx/tx_proxy/storage_tenant_ut.cpp +++ b/ydb/core/tx/tx_proxy/storage_tenant_ut.cpp @@ -333,7 +333,7 @@ Y_UNIT_TEST_SUITE(TStorageTenantTest) { TIntrusivePtr<TTabletStorageInfo> info = TabletStorageInfoFromProto(storageInfo.GetInfo()); TActorId edge = runtime->AllocateEdgeActor(nodeIdx); - IActor* x = CreateTabletReqBlockBlobStorage(edge, info.Get(), Max<ui32>(), false); + IActor* x = CreateTabletReqBlockBlobStorage(edge, info.Get(), Max<ui32>(), false); runtime->Register(x, nodeIdx); // TAutoPtr<IEventHandle> handle; diff --git a/ydb/core/tx/ya.make b/ydb/core/tx/ya.make index 343ed8290a..5bfe4b3b86 100644 --- a/ydb/core/tx/ya.make +++ b/ydb/core/tx/ya.make @@ -1,20 +1,20 @@ -LIBRARY() - +LIBRARY() + OWNER( ddoarn g:kikimr ) - -SRCS( - defs.h + +SRCS( + defs.h message_seqno.h - tx.h + tx.h tx.cpp - tx_processing.h + tx_processing.h tx_proxy_schemereq.cpp -) - -PEERDIR( +) + +PEERDIR( library/cpp/actors/core ydb/core/base ydb/core/persqueue/config @@ -23,9 +23,9 @@ PEERDIR( ydb/core/tablet_flat ydb/core/util ydb/library/aclib -) - -END() +) + +END() RECURSE( balance_coverage diff --git a/ydb/core/util/cache_cache.h b/ydb/core/util/cache_cache.h index 0859cad738..a8ab10977d 100644 --- a/ydb/core/util/cache_cache.h +++ b/ydb/core/util/cache_cache.h @@ -1,46 +1,46 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include <ydb/core/util/queue_oneone_inplace.h> #include <library/cpp/monlib/counters/counters.h> #include <library/cpp/monlib/dynamic_counters/counters.h> -#include <util/generic/ptr.h> -#include <util/generic/intrlist.h> - -namespace NKikimr { - -struct TCacheCacheConfig : public TAtomicRefCount<TCacheCacheConfig> { - using TCounterPtr = NMonitoring::TDynamicCounters::TCounterPtr; - - enum ECacheGeneration { - CacheGenNone, - CacheGenEvicted, - CacheGenFresh, - CacheGenStaging, - CacheGenWarm, - }; - +#include <util/generic/ptr.h> +#include <util/generic/intrlist.h> + +namespace NKikimr { + +struct TCacheCacheConfig : public TAtomicRefCount<TCacheCacheConfig> { + using TCounterPtr = NMonitoring::TDynamicCounters::TCounterPtr; + + enum ECacheGeneration { + CacheGenNone, + CacheGenEvicted, + CacheGenFresh, + CacheGenStaging, + CacheGenWarm, + }; + ui64 Limit; - ui64 FreshLimit; - ui64 StagingLimit; - ui64 WarmLimit; - - TCounterPtr ReportedFresh; - TCounterPtr ReportedStaging; - TCounterPtr ReportedWarm; - - TCacheCacheConfig(ui64 limit, const TCounterPtr &reportedFresh, const TCounterPtr &reportedStaging, const TCounterPtr &reportedWarm) + ui64 FreshLimit; + ui64 StagingLimit; + ui64 WarmLimit; + + TCounterPtr ReportedFresh; + TCounterPtr ReportedStaging; + TCounterPtr ReportedWarm; + + TCacheCacheConfig(ui64 limit, const TCounterPtr &reportedFresh, const TCounterPtr &reportedStaging, const TCounterPtr &reportedWarm) : Limit(0) , FreshLimit(0) , StagingLimit(0) , WarmLimit(0) - , ReportedFresh(reportedFresh) - , ReportedStaging(reportedStaging) - , ReportedWarm(reportedWarm) + , ReportedFresh(reportedFresh) + , ReportedStaging(reportedStaging) + , ReportedWarm(reportedWarm) { SetLimit(limit); } - + void SetLimit(ui64 limit) { Limit = limit; @@ -49,206 +49,206 @@ struct TCacheCacheConfig : public TAtomicRefCount<TCacheCacheConfig> { WarmLimit = FreshLimit; } - template<typename TItem> - struct TDefaultWeight { - static ui64 Get(TItem *) { - return 1; - } - }; - - template<typename TItem> - struct TDefaultGeneration { - static ECacheGeneration Get(TItem *x) { - return static_cast<ECacheGeneration>(x->CacheGeneration); - } - static void Set(TItem *x, ECacheGeneration gen) { - x->CacheGeneration = gen; - } - }; -}; - -template <typename TItem - , typename TWeight = TCacheCacheConfig::TDefaultWeight<TItem> - , typename TGeneration = TCacheCacheConfig::TDefaultGeneration<TItem> - > -class TCacheCache { -public: - TCacheCache(const TCacheCacheConfig &config) - : Config(config) - , FreshWeight(0) - , StagingWeight(0) - , WarmWeight(0) - {} - - TItem* Touch(TItem *item) { // returns evicted elements as list - TIntrusiveListItem<TItem> *xitem = item; - - const TCacheCacheConfig::ECacheGeneration cacheGen = GenerationOp.Get(item); - switch (cacheGen) { - case TCacheCacheConfig::CacheGenNone: // place in fresh - case TCacheCacheConfig::CacheGenEvicted: // corner case: was evicted from staging and touched in same update - return AddToFresh(item); - case TCacheCacheConfig::CacheGenFresh: // just update inside fresh - xitem->Unlink(); - FreshList.PushFront(xitem); - return nullptr; - case TCacheCacheConfig::CacheGenStaging: // move to warm - return MoveToWarm(item); - case TCacheCacheConfig::CacheGenWarm: // just update inside warm - xitem->Unlink(); - WarmList.PushFront(xitem); - return nullptr; - default: + template<typename TItem> + struct TDefaultWeight { + static ui64 Get(TItem *) { + return 1; + } + }; + + template<typename TItem> + struct TDefaultGeneration { + static ECacheGeneration Get(TItem *x) { + return static_cast<ECacheGeneration>(x->CacheGeneration); + } + static void Set(TItem *x, ECacheGeneration gen) { + x->CacheGeneration = gen; + } + }; +}; + +template <typename TItem + , typename TWeight = TCacheCacheConfig::TDefaultWeight<TItem> + , typename TGeneration = TCacheCacheConfig::TDefaultGeneration<TItem> + > +class TCacheCache { +public: + TCacheCache(const TCacheCacheConfig &config) + : Config(config) + , FreshWeight(0) + , StagingWeight(0) + , WarmWeight(0) + {} + + TItem* Touch(TItem *item) { // returns evicted elements as list + TIntrusiveListItem<TItem> *xitem = item; + + const TCacheCacheConfig::ECacheGeneration cacheGen = GenerationOp.Get(item); + switch (cacheGen) { + case TCacheCacheConfig::CacheGenNone: // place in fresh + case TCacheCacheConfig::CacheGenEvicted: // corner case: was evicted from staging and touched in same update + return AddToFresh(item); + case TCacheCacheConfig::CacheGenFresh: // just update inside fresh + xitem->Unlink(); + FreshList.PushFront(xitem); + return nullptr; + case TCacheCacheConfig::CacheGenStaging: // move to warm + return MoveToWarm(item); + case TCacheCacheConfig::CacheGenWarm: // just update inside warm + xitem->Unlink(); + WarmList.PushFront(xitem); + return nullptr; + default: Y_VERIFY_DEBUG(false, "unknown/broken cache generation"); - return nullptr; - } - } - - // evict and erase differs on Evicted handling - void Evict(TItem *item) { - const TCacheCacheConfig::ECacheGeneration cacheGen = GenerationOp.Get(item); - switch (cacheGen) { - case TCacheCacheConfig::CacheGenNone: - case TCacheCacheConfig::CacheGenEvicted: - break; - case TCacheCacheConfig::CacheGenFresh: - Unlink(item, FreshWeight); - if (Config.ReportedFresh) - *Config.ReportedFresh = FreshWeight; - break; - case TCacheCacheConfig::CacheGenStaging: - Unlink(item, StagingWeight); - if (Config.ReportedStaging) - *Config.ReportedStaging = StagingWeight; - break; - case TCacheCacheConfig::CacheGenWarm: - Unlink(item, WarmWeight); - if (Config.ReportedWarm) - *Config.ReportedWarm = WarmWeight; - break; - default: + return nullptr; + } + } + + // evict and erase differs on Evicted handling + void Evict(TItem *item) { + const TCacheCacheConfig::ECacheGeneration cacheGen = GenerationOp.Get(item); + switch (cacheGen) { + case TCacheCacheConfig::CacheGenNone: + case TCacheCacheConfig::CacheGenEvicted: + break; + case TCacheCacheConfig::CacheGenFresh: + Unlink(item, FreshWeight); + if (Config.ReportedFresh) + *Config.ReportedFresh = FreshWeight; + break; + case TCacheCacheConfig::CacheGenStaging: + Unlink(item, StagingWeight); + if (Config.ReportedStaging) + *Config.ReportedStaging = StagingWeight; + break; + case TCacheCacheConfig::CacheGenWarm: + Unlink(item, WarmWeight); + if (Config.ReportedWarm) + *Config.ReportedWarm = WarmWeight; + break; + default: Y_VERIFY_DEBUG(false, "unknown cache generaton"); - } - } - - void Erase(TItem *item) { - const TCacheCacheConfig::ECacheGeneration cacheGen = GenerationOp.Get(item); - switch (cacheGen) { - case TCacheCacheConfig::CacheGenNone: - break; - case TCacheCacheConfig::CacheGenEvicted: - item->Unlink(); - GenerationOp.Set(item, TCacheCacheConfig::CacheGenNone); - break; - case TCacheCacheConfig::CacheGenFresh: - Unlink(item, FreshWeight); - if (Config.ReportedFresh) - *Config.ReportedFresh = FreshWeight; - break; - case TCacheCacheConfig::CacheGenStaging: - Unlink(item, StagingWeight); - if (Config.ReportedStaging) - *Config.ReportedStaging = StagingWeight; - break; - case TCacheCacheConfig::CacheGenWarm: - Unlink(item, WarmWeight); - if (Config.ReportedWarm) - *Config.ReportedWarm = WarmWeight; - break; - default: + } + } + + void Erase(TItem *item) { + const TCacheCacheConfig::ECacheGeneration cacheGen = GenerationOp.Get(item); + switch (cacheGen) { + case TCacheCacheConfig::CacheGenNone: + break; + case TCacheCacheConfig::CacheGenEvicted: + item->Unlink(); + GenerationOp.Set(item, TCacheCacheConfig::CacheGenNone); + break; + case TCacheCacheConfig::CacheGenFresh: + Unlink(item, FreshWeight); + if (Config.ReportedFresh) + *Config.ReportedFresh = FreshWeight; + break; + case TCacheCacheConfig::CacheGenStaging: + Unlink(item, StagingWeight); + if (Config.ReportedStaging) + *Config.ReportedStaging = StagingWeight; + break; + case TCacheCacheConfig::CacheGenWarm: + Unlink(item, WarmWeight); + if (Config.ReportedWarm) + *Config.ReportedWarm = WarmWeight; + break; + default: Y_VERIFY_DEBUG(false, "unknown cache generaton"); - } - } - - void UpdateCacheSize(ui64 cacheSize) { - if (cacheSize == 0) - cacheSize = Max<ui64>(); - + } + } + + void UpdateCacheSize(ui64 cacheSize) { + if (cacheSize == 0) + cacheSize = Max<ui64>(); + Config.SetLimit(cacheSize); - } -private: - void Unlink(TItem *item, ui64 &weight) { - item->Unlink(); - - const ui64 elementWeight = WeightOp.Get(item); + } +private: + void Unlink(TItem *item, ui64 &weight) { + item->Unlink(); + + const ui64 elementWeight = WeightOp.Get(item); Y_VERIFY_DEBUG(elementWeight <= weight); - weight -= elementWeight; - } - - TItem* AddToFresh(TItem *item) { - TItem *ret = nullptr; - while (FreshWeight > Config.FreshLimit) { + weight -= elementWeight; + } + + TItem* AddToFresh(TItem *item) { + TItem *ret = nullptr; + while (FreshWeight > Config.FreshLimit) { Y_VERIFY_DEBUG(!FreshList.Empty()); - TItem *x = FreshList.PopBack(); + TItem *x = FreshList.PopBack(); Y_VERIFY(GenerationOp.Get(x) == TCacheCacheConfig::CacheGenFresh, "malformed entry in fresh cache. %" PRIu32, (ui32)GenerationOp.Get(x)); - Unlink(x, FreshWeight); - ret = AddToStaging(x, ret); - } - item->Unlink(); - FreshWeight += WeightOp.Get(item); - FreshList.PushFront(item); - GenerationOp.Set(item, TCacheCacheConfig::CacheGenFresh); - - if (Config.ReportedStaging) - *Config.ReportedStaging = StagingWeight; - if (Config.ReportedFresh) - *Config.ReportedFresh = FreshWeight; - - return ret; - } - - TItem* MoveToWarm(TItem *item) { - TItem *ret = nullptr; - Unlink(item, StagingWeight); - while (WarmWeight > Config.WarmLimit) { + Unlink(x, FreshWeight); + ret = AddToStaging(x, ret); + } + item->Unlink(); + FreshWeight += WeightOp.Get(item); + FreshList.PushFront(item); + GenerationOp.Set(item, TCacheCacheConfig::CacheGenFresh); + + if (Config.ReportedStaging) + *Config.ReportedStaging = StagingWeight; + if (Config.ReportedFresh) + *Config.ReportedFresh = FreshWeight; + + return ret; + } + + TItem* MoveToWarm(TItem *item) { + TItem *ret = nullptr; + Unlink(item, StagingWeight); + while (WarmWeight > Config.WarmLimit) { Y_VERIFY_DEBUG(!WarmList.Empty()); - TItem *x = WarmList.PopBack(); + TItem *x = WarmList.PopBack(); Y_VERIFY(GenerationOp.Get(x) == TCacheCacheConfig::CacheGenWarm, "malformed entry in warm cache. %" PRIu32, (ui32)GenerationOp.Get(x)); - Unlink(x, WarmWeight); - ret = AddToStaging(x, ret); - } - WarmWeight += WeightOp.Get(item); - WarmList.PushFront(item); - GenerationOp.Set(item, TCacheCacheConfig::CacheGenWarm); - - if (Config.ReportedStaging) - *Config.ReportedStaging = StagingWeight; - if (Config.ReportedWarm) - *Config.ReportedWarm = WarmWeight; - - return ret; - } - - TItem* AddToStaging(TItem *item, TItem *ret) { - while (StagingWeight > Config.StagingLimit) { + Unlink(x, WarmWeight); + ret = AddToStaging(x, ret); + } + WarmWeight += WeightOp.Get(item); + WarmList.PushFront(item); + GenerationOp.Set(item, TCacheCacheConfig::CacheGenWarm); + + if (Config.ReportedStaging) + *Config.ReportedStaging = StagingWeight; + if (Config.ReportedWarm) + *Config.ReportedWarm = WarmWeight; + + return ret; + } + + TItem* AddToStaging(TItem *item, TItem *ret) { + while (StagingWeight > Config.StagingLimit) { Y_VERIFY_DEBUG(!StagingList.Empty()); - TItem *evicted = StagingList.PopBack(); + TItem *evicted = StagingList.PopBack(); Y_VERIFY(GenerationOp.Get(evicted) == TCacheCacheConfig::CacheGenStaging, "malformed entry in staging cache %" PRIu32, (ui32)GenerationOp.Get(evicted)); - Unlink(evicted, StagingWeight); - GenerationOp.Set(evicted, TCacheCacheConfig::CacheGenEvicted); - if (ret == nullptr) - ret = evicted; - else - evicted->LinkBefore(ret); - } - StagingWeight += WeightOp.Get(item); - StagingList.PushFront(item); - GenerationOp.Set(item, TCacheCacheConfig::CacheGenStaging); - return ret; - } -private: - TCacheCacheConfig Config; - - TIntrusiveList<TItem> FreshList; - TIntrusiveList<TItem> StagingList; - TIntrusiveList<TItem> WarmList; - - ui64 FreshWeight; - ui64 StagingWeight; - ui64 WarmWeight; - - TWeight WeightOp; - TGeneration GenerationOp; -}; - -} + Unlink(evicted, StagingWeight); + GenerationOp.Set(evicted, TCacheCacheConfig::CacheGenEvicted); + if (ret == nullptr) + ret = evicted; + else + evicted->LinkBefore(ret); + } + StagingWeight += WeightOp.Get(item); + StagingList.PushFront(item); + GenerationOp.Set(item, TCacheCacheConfig::CacheGenStaging); + return ret; + } +private: + TCacheCacheConfig Config; + + TIntrusiveList<TItem> FreshList; + TIntrusiveList<TItem> StagingList; + TIntrusiveList<TItem> WarmList; + + ui64 FreshWeight; + ui64 StagingWeight; + ui64 WarmWeight; + + TWeight WeightOp; + TGeneration GenerationOp; +}; + +} diff --git a/ydb/core/util/defs.h b/ydb/core/util/defs.h index 5883cc376d..77c876c9c1 100644 --- a/ydb/core/util/defs.h +++ b/ydb/core/util/defs.h @@ -1,19 +1,19 @@ -#pragma once +#pragma once // unique tag to fix pragma once gcc glueing: ./ydb/core/util/defs.h - + #include <library/cpp/actors/core/actor.h> #include <library/cpp/actors/core/hfunc.h> #include <library/cpp/actors/core/interconnect.h> #include <library/cpp/actors/interconnect/interconnect_common.h> -#include <util/system/defaults.h> +#include <util/system/defaults.h> #include <util/generic/bt_exception.h> -#include <util/generic/noncopyable.h> -#include <util/generic/ptr.h> +#include <util/generic/noncopyable.h> +#include <util/generic/ptr.h> #include <util/generic/string.h> -#include <util/generic/yexception.h> -#include <util/system/atomic.h> -#include <util/system/align.h> -#include <util/generic/vector.h> -#include <util/datetime/base.h> -#include <util/generic/ylimits.h> +#include <util/generic/yexception.h> +#include <util/system/atomic.h> +#include <util/system/align.h> +#include <util/generic/vector.h> +#include <util/datetime/base.h> +#include <util/generic/ylimits.h> diff --git a/ydb/core/util/intrusive_fixed_hash_set.h b/ydb/core/util/intrusive_fixed_hash_set.h index 3007cfa6c6..09a255b7d6 100644 --- a/ydb/core/util/intrusive_fixed_hash_set.h +++ b/ydb/core/util/intrusive_fixed_hash_set.h @@ -14,7 +14,7 @@ namespace NKikimr { // bool E(const T&) - equals function (returns true iff *this == T) // -template <class T, T* T::*N, ui64 (*H)(const T&), bool (*E)(const T&, const T&)> +template <class T, T* T::*N, ui64 (*H)(const T&), bool (*E)(const T&, const T&)> class TIntrusiveFixedHashSet { TVector<T*> Table; public: diff --git a/ydb/core/util/queue_oneone_inplace.h b/ydb/core/util/queue_oneone_inplace.h index 9a8aaaa597..499215b821 100644 --- a/ydb/core/util/queue_oneone_inplace.h +++ b/ydb/core/util/queue_oneone_inplace.h @@ -1,3 +1,3 @@ -#pragma once +#pragma once #include <library/cpp/actors/util/queue_oneone_inplace.h> - + diff --git a/ydb/core/util/queue_oneone_inplace_ut.cpp b/ydb/core/util/queue_oneone_inplace_ut.cpp index 0e7097ab5d..ac60a69f3d 100644 --- a/ydb/core/util/queue_oneone_inplace_ut.cpp +++ b/ydb/core/util/queue_oneone_inplace_ut.cpp @@ -1,84 +1,84 @@ #include <library/cpp/testing/unittest/registar.h> - -#include <util/generic/vector.h> + +#include <util/generic/vector.h> #include <library/cpp/threading/future/legacy_future.h> - -#include "queue_oneone_inplace.h" - + +#include "queue_oneone_inplace.h" + Y_UNIT_TEST_SUITE(TOneOneQueueTests) { - + Y_UNIT_TEST(TestSimpleEnqueueDequeue) { using TQueueType = TOneOneQueueInplace<ui64, 32>; // 3 values per chunk TQueueType queue; - - UNIT_ASSERT(queue.Pop() == 0); - UNIT_ASSERT(queue.Head() == 0); - - queue.Push(10); - queue.Push(11); - queue.Push(12); - queue.Push(13); - queue.Push(14); - - UNIT_ASSERT_EQUAL(queue.Head(), 10); - UNIT_ASSERT_EQUAL(queue.Pop(), 10); - UNIT_ASSERT_EQUAL(queue.Head(), 11); - UNIT_ASSERT_EQUAL(queue.Pop(), 11); - UNIT_ASSERT_EQUAL(queue.Head(), 12); - UNIT_ASSERT_EQUAL(queue.Pop(), 12); - UNIT_ASSERT_EQUAL(queue.Head(), 13); - UNIT_ASSERT_EQUAL(queue.Pop(), 13); - UNIT_ASSERT_EQUAL(queue.Head(), 14); - UNIT_ASSERT_EQUAL(queue.Pop(), 14); - - UNIT_ASSERT(queue.Pop() == 0); - } - + + UNIT_ASSERT(queue.Pop() == 0); + UNIT_ASSERT(queue.Head() == 0); + + queue.Push(10); + queue.Push(11); + queue.Push(12); + queue.Push(13); + queue.Push(14); + + UNIT_ASSERT_EQUAL(queue.Head(), 10); + UNIT_ASSERT_EQUAL(queue.Pop(), 10); + UNIT_ASSERT_EQUAL(queue.Head(), 11); + UNIT_ASSERT_EQUAL(queue.Pop(), 11); + UNIT_ASSERT_EQUAL(queue.Head(), 12); + UNIT_ASSERT_EQUAL(queue.Pop(), 12); + UNIT_ASSERT_EQUAL(queue.Head(), 13); + UNIT_ASSERT_EQUAL(queue.Pop(), 13); + UNIT_ASSERT_EQUAL(queue.Head(), 14); + UNIT_ASSERT_EQUAL(queue.Pop(), 14); + + UNIT_ASSERT(queue.Pop() == 0); + } + Y_UNIT_TEST(CleanInDestructor) { using TQueueType = TOneOneQueueInplace<std::shared_ptr<bool> *, 32>; - - + + std::shared_ptr<bool> p(new bool(true)); UNIT_ASSERT_VALUES_EQUAL(1u, p.use_count()); - - { + + { TAutoPtr<TQueueType, TQueueType::TPtrCleanDestructor> queue(new TQueueType()); queue->Push(new std::shared_ptr<bool>(p)); queue->Push(new std::shared_ptr<bool>(p)); queue->Push(new std::shared_ptr<bool>(p)); queue->Push(new std::shared_ptr<bool>(p)); - + UNIT_ASSERT_VALUES_EQUAL(5u, p.use_count()); - } - + } + UNIT_ASSERT_VALUES_EQUAL(1, p.use_count()); - } - + } + Y_UNIT_TEST(ReadIterator) { using TQueueType = TOneOneQueueInplace<int, 32>; TQueueType queue; - - queue.Push(10); - queue.Push(11); - queue.Push(12); - queue.Push(13); - queue.Push(14); - - auto it = queue.Iterator(); - while (it.Next()); - - UNIT_ASSERT_EQUAL(queue.Head(), 10); - UNIT_ASSERT_EQUAL(queue.Pop(), 10); - UNIT_ASSERT_EQUAL(queue.Head(), 11); - UNIT_ASSERT_EQUAL(queue.Pop(), 11); - UNIT_ASSERT_EQUAL(queue.Head(), 12); - UNIT_ASSERT_EQUAL(queue.Pop(), 12); - UNIT_ASSERT_EQUAL(queue.Head(), 13); - UNIT_ASSERT_EQUAL(queue.Pop(), 13); - UNIT_ASSERT_EQUAL(queue.Head(), 14); - UNIT_ASSERT_EQUAL(queue.Pop(), 14); - - UNIT_ASSERT(queue.Pop() == 0); - } -} + + queue.Push(10); + queue.Push(11); + queue.Push(12); + queue.Push(13); + queue.Push(14); + + auto it = queue.Iterator(); + while (it.Next()); + + UNIT_ASSERT_EQUAL(queue.Head(), 10); + UNIT_ASSERT_EQUAL(queue.Pop(), 10); + UNIT_ASSERT_EQUAL(queue.Head(), 11); + UNIT_ASSERT_EQUAL(queue.Pop(), 11); + UNIT_ASSERT_EQUAL(queue.Head(), 12); + UNIT_ASSERT_EQUAL(queue.Pop(), 12); + UNIT_ASSERT_EQUAL(queue.Head(), 13); + UNIT_ASSERT_EQUAL(queue.Pop(), 13); + UNIT_ASSERT_EQUAL(queue.Head(), 14); + UNIT_ASSERT_EQUAL(queue.Pop(), 14); + + UNIT_ASSERT(queue.Pop() == 0); + } +} diff --git a/ydb/core/util/ya.make b/ydb/core/util/ya.make index 4df0498f7f..4f325d8fcb 100644 --- a/ydb/core/util/ya.make +++ b/ydb/core/util/ya.make @@ -1,22 +1,22 @@ -LIBRARY() - +LIBRARY() + OWNER( ddoarn g:kikimr ) - -SRCS( + +SRCS( address_classifier.cpp cache.cpp cache.h - cache_cache.h + cache_cache.h circular_queue.h concurrent_rw_hash.cpp concurrent_rw_hash.h console.cpp console.h counted_leaky_bucket.h - defs.h + defs.h failure_injection.cpp failure_injection.h fast_tls.cpp @@ -40,7 +40,7 @@ SRCS( pb.h proto_duration.h queue_inplace.h - queue_oneone_inplace.h + queue_oneone_inplace.h simple_cache.h single_thread_ic_mock.cpp single_thread_ic_mock.h @@ -59,9 +59,9 @@ SRCS( ulid.h wildcard.h yverify_stream.h -) - -PEERDIR( +) + +PEERDIR( library/cpp/actors/interconnect/mock library/cpp/actors/util library/cpp/containers/stack_vector @@ -72,9 +72,9 @@ PEERDIR( library/cpp/random_provider ydb/core/base ydb/core/protos -) - -END() +) + +END() RECURSE_FOR_TESTS( btree_benchmark diff --git a/ydb/core/viewer/json_cluster.h b/ydb/core/viewer/json_cluster.h index a0ed37e70e..36b5362a45 100644 --- a/ydb/core/viewer/json_cluster.h +++ b/ydb/core/viewer/json_cluster.h @@ -64,7 +64,7 @@ public: void Die(const TActorContext& ctx) override { if (NodesInfo != nullptr) { for (const auto& ni : NodesInfo->Nodes) { - ctx.Send(TActivationContext::InterconnectProxy(ni.NodeId), new TEvents::TEvUnsubscribe()); + ctx.Send(TActivationContext::InterconnectProxy(ni.NodeId), new TEvents::TEvUnsubscribe()); } } TBase::Die(ctx); diff --git a/ydb/core/viewer/json_counters.h b/ydb/core/viewer/json_counters.h index 9bbdef1423..cac1e0885c 100644 --- a/ydb/core/viewer/json_counters.h +++ b/ydb/core/viewer/json_counters.h @@ -48,7 +48,7 @@ public: void Die(const TActorContext& ctx) override { if (NodesInfo != nullptr) { for (const auto& ni : NodesInfo->Nodes) { - ctx.Send(TActivationContext::InterconnectProxy(ni.NodeId), new TEvents::TEvUnsubscribe()); + ctx.Send(TActivationContext::InterconnectProxy(ni.NodeId), new TEvents::TEvUnsubscribe()); } } TBase::Die(ctx); diff --git a/ydb/library/wilson/ya.make b/ydb/library/wilson/ya.make index bde38a152a..e4daf898c7 100644 --- a/ydb/library/wilson/ya.make +++ b/ydb/library/wilson/ya.make @@ -1,8 +1,8 @@ LIBRARY() PEERDIR( library/cpp/actors/wilson - ) - + ) + OWNER(alexvru) END() - + diff --git a/ydb/library/yql/core/expr_nodes/yql_expr_nodes.h b/ydb/library/yql/core/expr_nodes/yql_expr_nodes.h index 4116a87358..01cc777118 100644 --- a/ydb/library/yql/core/expr_nodes/yql_expr_nodes.h +++ b/ydb/library/yql/core/expr_nodes/yql_expr_nodes.h @@ -108,10 +108,10 @@ public: return TCoAtom(node); } - TParent& Build() { + TParent& Build() { return this->NGenerated::TCoAtomBuilder<TParent>::Build(); - } - + } + TParent& Build(const TStringBuf& value, ui32 flags = TNodeFlags::ArbitraryContent) { this->ValueHolder = this->Ctx.AppendString(value); this->Flags = flags; diff --git a/ydb/library/yql/core/issue/protos/issue_id.proto b/ydb/library/yql/core/issue/protos/issue_id.proto index b82cb7852b..a2ed91d640 100644 --- a/ydb/library/yql/core/issue/protos/issue_id.proto +++ b/ydb/library/yql/core/issue/protos/issue_id.proto @@ -133,7 +133,7 @@ message TIssuesIds { YQL_DEPRECATED_LIST_FLATMAP_OPTIONAL = 4531; YQL_PROJECTION_ALIAS_IS_REFERENCED_IN_GROUP_BY = 4532; YQL_TABLE_BINDING_DUPLICATE = 4533; - + // yql parser errors YQL_NOT_ALLOWED_IN_DISCOVERY = 4600; @@ -171,8 +171,8 @@ message TIssuesIds { DQ_GATEWAY_ERROR = 6000; DQ_GATEWAY_NEED_FALLBACK_ERROR = 6001; -// range [200000, 399999) reserved for KiKiMR issue codes, do not use! - +// range [200000, 399999) reserved for KiKiMR issue codes, do not use! + } message TIssueId { diff --git a/ydb/library/yql/public/issue/yql_issue.h b/ydb/library/yql/public/issue/yql_issue.h index 3a85a53016..7b97674c9d 100644 --- a/ydb/library/yql/public/issue/yql_issue.h +++ b/ydb/library/yql/public/issue/yql_issue.h @@ -270,10 +270,10 @@ public: return Issues_.empty(); } - explicit operator bool() const noexcept { - return !Issues_.empty(); - } - + explicit operator bool() const noexcept { + return !Issues_.empty(); + } + inline size_t Size() const { return Issues_.size(); } @@ -298,10 +298,10 @@ public: Issues_.clear(); } - void Reserve(size_t capacity) { - Issues_.reserve(capacity); - } - + void Reserve(size_t capacity) { + Issues_.reserve(capacity); + } + private: TVector<TIssue> Issues_; }; diff --git a/ydb/library/yql/public/issue/yql_issue_message.cpp b/ydb/library/yql/public/issue/yql_issue_message.cpp index 04d8d47615..f9d512ca5a 100644 --- a/ydb/library/yql/public/issue/yql_issue_message.cpp +++ b/ydb/library/yql/public/issue/yql_issue_message.cpp @@ -46,14 +46,14 @@ TIssue IssueFromMessage(const TIssueMessage& issueMessage) { template<typename TIssueMessage> void IssuesFromMessage(const ::google::protobuf::RepeatedPtrField<TIssueMessage> &message, TIssues &issues) { - issues.Clear(); - if (message.size()) { - issues.Reserve(message.size()); - for (auto &x : message) - issues.AddIssue(IssueFromMessage(x)); - } -} - + issues.Clear(); + if (message.size()) { + issues.Reserve(message.size()); + for (auto &x : message) + issues.AddIssue(IssueFromMessage(x)); + } +} + template<typename TIssueMessage> void IssueToMessage(const TIssue& topIssue, TIssueMessage* issueMessage) { TDeque<std::pair<const TIssue*, TIssueMessage*>> queue; @@ -86,15 +86,15 @@ void IssueToMessage(const TIssue& topIssue, TIssueMessage* issueMessage) { template<typename TIssueMessage> void IssuesToMessage(const TIssues& issues, ::google::protobuf::RepeatedPtrField<TIssueMessage> *message) { - message->Clear(); - if (!issues) - return; - message->Reserve(issues.Size()); - for (const auto &issue : issues) { + message->Clear(); + if (!issues) + return; + message->Reserve(issues.Size()); + for (const auto &issue : issues) { IssueToMessage(issue, message->Add()); - } + } } - + template TIssue IssueFromMessage<Ydb::Issue::IssueMessage>(const Ydb::Issue::IssueMessage& issueMessage); template @@ -119,7 +119,7 @@ NIssue::NProto::IssueMessage IssueToMessage(const TIssue& topIssue) { NIssue::NProto::IssueMessage issueMessage; IssueToMessage(topIssue, &issueMessage); return issueMessage; -} +} TString IssueToBinaryMessage(const TIssue& issue) { TString result; diff --git a/ydb/public/api/grpc/ydb_discovery_v1.proto b/ydb/public/api/grpc/ydb_discovery_v1.proto index 34410d6abd..dc06a4f678 100644 --- a/ydb/public/api/grpc/ydb_discovery_v1.proto +++ b/ydb/public/api/grpc/ydb_discovery_v1.proto @@ -1,11 +1,11 @@ -syntax = "proto3"; - +syntax = "proto3"; + package Ydb.Discovery.V1; option java_package = "com.yandex.ydb.discovery.v1"; - + import "ydb/public/api/protos/ydb_discovery.proto"; - -service DiscoveryService { - rpc ListEndpoints(Ydb.Discovery.ListEndpointsRequest) returns (Ydb.Discovery.ListEndpointsResponse); + +service DiscoveryService { + rpc ListEndpoints(Ydb.Discovery.ListEndpointsRequest) returns (Ydb.Discovery.ListEndpointsResponse); rpc WhoAmI(Ydb.Discovery.WhoAmIRequest) returns (Ydb.Discovery.WhoAmIResponse); -} +} diff --git a/ydb/public/api/protos/ydb_discovery.proto b/ydb/public/api/protos/ydb_discovery.proto index f859032d8d..5577dafe36 100644 --- a/ydb/public/api/protos/ydb_discovery.proto +++ b/ydb/public/api/protos/ydb_discovery.proto @@ -1,27 +1,27 @@ -syntax = "proto3"; -option cc_enable_arenas = true; - -package Ydb.Discovery; +syntax = "proto3"; +option cc_enable_arenas = true; + +package Ydb.Discovery; option java_package = "com.yandex.ydb.discovery"; -option java_outer_classname = "DiscoveryProtos"; - +option java_outer_classname = "DiscoveryProtos"; + import "ydb/public/api/protos/ydb_operation.proto"; - -message ListEndpointsRequest { - string database = 1; - repeated string service = 2; - -// todo: feature flags + +message ListEndpointsRequest { + string database = 1; + repeated string service = 2; + +// todo: feature flags } - -message EndpointInfo { + +message EndpointInfo { // This is an address (usually fqdn) and port of this node's grpc endpoint - string address = 1; - uint32 port = 2; - float load_factor = 3; - bool ssl = 4; - repeated string service = 5; - string location = 6; + string address = 1; + uint32 port = 2; + float load_factor = 3; + bool ssl = 4; + repeated string service = 5; + string location = 6; uint32 node_id = 7; // Optional ipv4 and/or ipv6 addresses of the endpoint, which clients may @@ -36,13 +36,13 @@ message EndpointInfo { string ssl_target_name_override = 10; } -message ListEndpointsResult { - repeated EndpointInfo endpoints = 1; - string self_location = 2; +message ListEndpointsResult { + repeated EndpointInfo endpoints = 1; + string self_location = 2; } - -message ListEndpointsResponse { - Ydb.Operations.Operation operation = 1; + +message ListEndpointsResponse { + Ydb.Operations.Operation operation = 1; } message WhoAmIRequest { diff --git a/ydb/public/lib/base/defs.h b/ydb/public/lib/base/defs.h index aa6f7c27ed..97e933c93a 100644 --- a/ydb/public/lib/base/defs.h +++ b/ydb/public/lib/base/defs.h @@ -1,13 +1,13 @@ -#pragma once - +#pragma once + /// @note It must not depend on anything except util, library and propobufs #include <library/cpp/actors/core/actorid.h> #include <library/cpp/actors/core/actor.h> #include <library/cpp/deprecated/enum_codegen/enum_codegen.h> -namespace NKikimr { - +namespace NKikimr { + enum class EDataReqStatusExcerpt { Unknown, // must not happen Complete, // request success @@ -35,7 +35,7 @@ inline const char* EDataReqStatusExcerptStr(EDataReqStatusExcerpt status) { default: return "Unknown error"; } -} +} namespace NTxProxy { #define TXUSERPROXY_RESULT_STATUS_MAP(XX) \ diff --git a/ydb/public/lib/base/msgbus.h b/ydb/public/lib/base/msgbus.h index d7e255216c..f11bd9771f 100644 --- a/ydb/public/lib/base/msgbus.h +++ b/ydb/public/lib/base/msgbus.h @@ -1,5 +1,5 @@ -#pragma once -#include "defs.h" +#pragma once +#include "defs.h" #include "msgbus_status.h" #include <ydb/core/protos/msgbus.pb.h> #include <ydb/core/protos/msgbus_kv.pb.h> @@ -8,18 +8,18 @@ #include <library/cpp/messagebus/protobuf/ybusbuf.h> #include <library/cpp/messagebus/session_config.h> #include <library/cpp/messagebus/queue_config.h> - -namespace NKikimr { -namespace NMsgBusProxy { - -enum { - MTYPE_CLIENT_REQUEST = 10401, - MTYPE_CLIENT_RESPONSE = 10402, - MTYPE_CLIENT_FAKE_CONFIGDUMMY = 10403, - MTYPE_CLIENT_INSPECT = 10404, - MTYPE_CLIENT_SCHEME_INITROOT = 10405, - MTYPE_CLIENT_BSADM = 10406, - MTYPE_CLIENT_SCHEME_NAVIGATE = 10407, + +namespace NKikimr { +namespace NMsgBusProxy { + +enum { + MTYPE_CLIENT_REQUEST = 10401, + MTYPE_CLIENT_RESPONSE = 10402, + MTYPE_CLIENT_FAKE_CONFIGDUMMY = 10403, + MTYPE_CLIENT_INSPECT = 10404, + MTYPE_CLIENT_SCHEME_INITROOT = 10405, + MTYPE_CLIENT_BSADM = 10406, + MTYPE_CLIENT_SCHEME_NAVIGATE = 10407, MTYPE_CLIENT_TYPES_REQUEST = 10408, MTYPE_CLIENT_TYPES_RESPONSE = 10409, MTYPE_CLIENT_CREATE_TABLET_POOL = 10410, // deprecated @@ -43,7 +43,7 @@ enum { MTYPE_CLIENT_MESSAGE_BUS_TRACE_STATUS = 10428, MTYPE_CLIENT_TABLET_KILL_REQUEST = 10429, MTYPE_CLIENT_TABLET_STATE_REQUEST = 10430, - MTYPE_CLIENT_LOCAL_MINIKQL = 10431, + MTYPE_CLIENT_LOCAL_MINIKQL = 10431, MTYPE_CLIENT_FLAT_TX_REQUEST = 10432, MTYPE_CLIENT_FLAT_TX_STATUS_REQUEST = 10434, MTYPE_CLIENT_OLD_FLAT_DESCRIBE_REQUEST = 10435, // deprecated @@ -89,11 +89,11 @@ enum { MTYPE_CLIENT_TENANT_SLOT_BROKER_REQUEST = 10479, MTYPE_CLIENT_TENANT_SLOT_BROKER_RESPONSE = 10480, MTYPE_CLIENT_TEST_SHARD_CONTROL = 10481, -}; - +}; + template <typename InstanceType, class TBufferRecord, int MType> struct TBusMessage : NBus::TBusBufferMessage<TBufferRecord, MType> { NBus::TBusBufferBase* New() override { return new InstanceType; } }; - + // we had to define structs instead of typedef because we need to create real C++ type, so we could use RTTI names later in protocol registration struct TBusRequest : TBusMessage<TBusRequest, NKikimrClient::TRequest, MTYPE_CLIENT_REQUEST> {}; struct TBusResponse : TBusMessage<TBusResponse, NKikimrClient::TResponse, MTYPE_CLIENT_RESPONSE> {}; @@ -152,22 +152,22 @@ struct TBusConsoleRequest : TBusMessage<TBusConsoleRequest, NKikimrClient::TCons struct TBusConsoleResponse : TBusMessage<TBusConsoleResponse, NKikimrClient::TConsoleResponse, MTYPE_CLIENT_CONSOLE_RESPONSE> {}; struct TBusTestShardControlRequest : TBusMessage<TBusTestShardControlRequest, NKikimrClient::TTestShardControlRequest, MTYPE_CLIENT_TEST_SHARD_CONTROL> {}; -class TBusResponseStatus : public TBusResponse { -public: +class TBusResponseStatus : public TBusResponse { +public: TBusResponseStatus(EResponseStatus status, const TString& text = TString()) - { - Record.SetStatus(status); + { + Record.SetStatus(status); if (text) { Record.SetErrorReason(text); } - } -}; - -class TProtocol : public NBus::TBusBufferProtocol { + } +}; + +class TProtocol : public NBus::TBusBufferProtocol { protected: THashMap<TString, NBus::TBusBufferBase*> NameToType; -public: +public: static TString TrimMessageName(const TString& name) { std::size_t pos = name.rfind(':'); if (pos != TString::npos && pos + 5 <= name.size() && name.substr(pos + 1, 4) == "TBus") @@ -189,14 +189,14 @@ public: return nullptr; } - TProtocol(int port) - : NBus::TBusBufferProtocol("CLI_MB", port) - { - RegisterType(new TBusRequest); - RegisterType(new TBusResponse); - RegisterType(new TBusFakeConfigDummy); - RegisterType(new TBusSchemeInitRoot); - RegisterType(new TBusBSAdm); + TProtocol(int port) + : NBus::TBusBufferProtocol("CLI_MB", port) + { + RegisterType(new TBusRequest); + RegisterType(new TBusResponse); + RegisterType(new TBusFakeConfigDummy); + RegisterType(new TBusSchemeInitRoot); + RegisterType(new TBusBSAdm); RegisterType(new TBusTypesRequest); RegisterType(new TBusTypesResponse); RegisterType(new TBusMessageBusTraceRequest); @@ -214,7 +214,7 @@ public: RegisterType(new TBusTabletKillRequest); RegisterType(new TBusTabletStateRequest); RegisterType(new TBusTabletCountersRequest); - RegisterType(new TBusTabletLocalMKQL); + RegisterType(new TBusTabletLocalMKQL); RegisterType(new TBusTabletLocalSchemeTx); RegisterType(new TBusSchemeOperation); RegisterType(new TBusSchemeOperationStatus); @@ -246,20 +246,20 @@ public: RegisterType(new TBusConsoleRequest); RegisterType(new TBusConsoleResponse); RegisterType(new TBusTestShardControlRequest); - } - + } + const static ui32 DefaultPort = 2134; -}; - -class IMessageBusServer { -public: +}; + +class IMessageBusServer { +public: virtual NActors::IActor* CreateProxy() = 0; virtual NActors::IActor* CreateMessageBusTraceService() = 0; - virtual ~IMessageBusServer() {} -}; - + virtual ~IMessageBusServer() {} +}; + class IPersQueueGetReadSessionsInfoWorkerFactory; - + IMessageBusServer* CreateMsgBusServer( NBus::TBusMessageQueue *queue, const NBus::TBusServerSessionConfig &config, @@ -276,7 +276,7 @@ IMessageBusServer* CreateMsgBusTracingServer( inline NActors::TActorId CreateMsgBusProxyId() { return NActors::TActorId(0, "MsgBusProxy"); -} +} -} +} } diff --git a/ydb/public/lib/deprecated/client/msgbus_client.cpp b/ydb/public/lib/deprecated/client/msgbus_client.cpp index 9b59c497e8..4d5f2427eb 100644 --- a/ydb/public/lib/deprecated/client/msgbus_client.cpp +++ b/ydb/public/lib/deprecated/client/msgbus_client.cpp @@ -1,9 +1,9 @@ -#include "msgbus_client.h" -#include <util/system/event.h> - -namespace NKikimr { -namespace NMsgBusProxy { - +#include "msgbus_client.h" +#include <util/system/event.h> + +namespace NKikimr { +namespace NMsgBusProxy { + void TMsgBusClientConfig::CrackAddress(const TString& address, TString& hostname, ui32& port) { size_t first_colon_pos = address.find(':'); if (first_colon_pos != TString::npos) { @@ -45,23 +45,23 @@ struct TSyncMessageCookie : public TMessageCookie { TAutoPtr<NBus::TBusMessage> Reply; NBus::EMessageStatus ErrorStatus = NBus::MESSAGE_UNKNOWN; TManualEvent Ev; - + TSyncMessageCookie() : Ev() - {} - - void Wait() { - Ev.Wait(); - } - + {} + + void Wait() { + Ev.Wait(); + } + virtual void Signal(TAutoPtr<NBus::TBusMessage>& msg, NBus::EMessageStatus errorStatus, TAutoPtr<NBus::TBusMessage> reply) { Y_UNUSED(msg.Release()); ErrorStatus = errorStatus; Reply = reply; - Ev.Signal(); - } -}; - + Ev.Signal(); + } +}; + template <typename CallbackType> struct TAsyncMessageCookie : public TMessageCookie { @@ -91,89 +91,89 @@ void TAsyncMessageCookie<TMsgBusClient::TOnCallWithRequest>::Signal(TAutoPtr<NBu } -TMsgBusClientConfig::TMsgBusClientConfig() - : Ip("localhost") - , Port(NMsgBusProxy::TProtocol::DefaultPort) - , UseCompression(false) +TMsgBusClientConfig::TMsgBusClientConfig() + : Ip("localhost") + , Port(NMsgBusProxy::TProtocol::DefaultPort) + , UseCompression(false) {} - + void TMsgBusClientConfig::ConfigureLastGetopt(NLastGetopt::TOpts &opts, const TString& prefix) { BusSessionConfig.ConfigureLastGetopt(opts, prefix); BusQueueConfig.ConfigureLastGetopt(opts, prefix); -} - -TMsgBusClient::TMsgBusClient(const TMsgBusClientConfig &config) - : Config(config) - , Protocol(NMsgBusProxy::TProtocol::DefaultPort) -{} - -TMsgBusClient::~TMsgBusClient() { - Shutdown(); -} - -void TMsgBusClient::Init() { - NetAddr = new NBus::TNetAddr(Config.Ip, Config.Port); // could throw - Bus = NBus::CreateMessageQueue(Config.BusQueueConfig); - Session = NBus::TBusClientSession::Create(&Protocol, this, Config.BusSessionConfig, Bus); -} - -void TMsgBusClient::Shutdown() { - if (Bus) { +} + +TMsgBusClient::TMsgBusClient(const TMsgBusClientConfig &config) + : Config(config) + , Protocol(NMsgBusProxy::TProtocol::DefaultPort) +{} + +TMsgBusClient::~TMsgBusClient() { + Shutdown(); +} + +void TMsgBusClient::Init() { + NetAddr = new NBus::TNetAddr(Config.Ip, Config.Port); // could throw + Bus = NBus::CreateMessageQueue(Config.BusQueueConfig); + Session = NBus::TBusClientSession::Create(&Protocol, this, Config.BusSessionConfig, Bus); +} + +void TMsgBusClient::Shutdown() { + if (Bus) { if (Session) { Session->Shutdown(); } - Session.Drop(); - Bus.Drop(); - } -} - -NBus::EMessageStatus TMsgBusClient::SyncCall(TAutoPtr<NBus::TBusMessage> msg, TAutoPtr<NBus::TBusMessage> &reply) { + Session.Drop(); + Bus.Drop(); + } +} + +NBus::EMessageStatus TMsgBusClient::SyncCall(TAutoPtr<NBus::TBusMessage> msg, TAutoPtr<NBus::TBusMessage> &reply) { Y_VERIFY(!msg->Data); TAutoPtr<TSyncMessageCookie> cookie(new TSyncMessageCookie()); - msg->Data = cookie.Get(); - - // msgbus would recreate second TAutoPtr for our msg pointer (wut?!) Second copy terminates in OnRelease/OnError where we release it. - NBus::EMessageStatus status = Session->SendMessage(msg.Get(), NetAddr.Get(), true); - - if (status == NBus::MESSAGE_OK) { - cookie->Wait(); - reply = cookie->Reply; - return cookie->ErrorStatus; - } else { - return status; - } -} - + msg->Data = cookie.Get(); + + // msgbus would recreate second TAutoPtr for our msg pointer (wut?!) Second copy terminates in OnRelease/OnError where we release it. + NBus::EMessageStatus status = Session->SendMessage(msg.Get(), NetAddr.Get(), true); + + if (status == NBus::MESSAGE_OK) { + cookie->Wait(); + reply = cookie->Reply; + return cookie->ErrorStatus; + } else { + return status; + } +} + NBus::EMessageStatus TMsgBusClient::AsyncCall(TAutoPtr<NBus::TBusMessage> msg, TOnCall callback) { TAutoPtr<TMessageCookie> cookie(new TAsyncMessageCookie<TOnCall>(callback, msg->Data)); msg->Data = cookie.Get(); - + if (Config.UseCompression) { - msg->SetCompressed(true); + msg->SetCompressed(true); msg->SetCompressedResponse(true); } - + NBus::EMessageStatus status = Session->SendMessage(msg.Get(), NetAddr.Get(), false); - - if (status == NBus::MESSAGE_OK) { - // would be destructed in onresult/onerror + + if (status == NBus::MESSAGE_OK) { + // would be destructed in onresult/onerror Y_UNUSED(cookie.Release()); Y_UNUSED(msg.Release()); - } + } return status; -} - +} + NBus::EMessageStatus TMsgBusClient::AsyncCall(TAutoPtr<NBus::TBusMessage> msg, TOnCallWithRequest callback) { TAutoPtr<TMessageCookie> cookie(new TAsyncMessageCookie<TOnCallWithRequest>(callback, msg->Data)); msg->Data = cookie.Get(); - + if (Config.UseCompression) { - msg->SetCompressed(true); + msg->SetCompressed(true); msg->SetCompressedResponse(true); } - + NBus::EMessageStatus status = Session->SendMessage(msg.Get(), NetAddr.Get(), false); if (status == NBus::MESSAGE_OK) { @@ -193,42 +193,42 @@ void TMsgBusClient::OnReply(TAutoPtr<NBus::TBusMessage> pMessage, TAutoPtr<NBus: OnResult(pMessage, NBus::MESSAGE_OK, pReply); } -void TMsgBusClient::OnError(TAutoPtr<NBus::TBusMessage> pMessage, NBus::EMessageStatus status) { - if (status == NBus::MESSAGE_UNKNOWN) // timeouted request - return; - +void TMsgBusClient::OnError(TAutoPtr<NBus::TBusMessage> pMessage, NBus::EMessageStatus status) { + if (status == NBus::MESSAGE_UNKNOWN) // timeouted request + return; + OnResult(pMessage, status, TAutoPtr<NBus::TBusMessage>()); -} - +} + const TMsgBusClientConfig& TMsgBusClient::GetConfig() { return Config; } EDataReqStatusExcerpt ExtractDataRequestStatus(const NKikimrClient::TResponse *record) { if (!record) - return EDataReqStatusExcerpt::Unknown; + return EDataReqStatusExcerpt::Unknown; switch (record->GetStatus()) { - case MSTATUS_OK: - return EDataReqStatusExcerpt::Complete; - case MSTATUS_INPROGRESS: - return EDataReqStatusExcerpt::InProgress; - case MSTATUS_ERROR: - return EDataReqStatusExcerpt::Error; - case MSTATUS_TIMEOUT: - return EDataReqStatusExcerpt::LostInSpaceAndTime; - case MSTATUS_NOTREADY: - case MSTATUS_REJECTED: - return EDataReqStatusExcerpt::RejectedForNow; - case MSTATUS_INTERNALERROR: - return EDataReqStatusExcerpt::InternalError; - default: - return EDataReqStatusExcerpt::Unknown; - } -} - -} - + case MSTATUS_OK: + return EDataReqStatusExcerpt::Complete; + case MSTATUS_INPROGRESS: + return EDataReqStatusExcerpt::InProgress; + case MSTATUS_ERROR: + return EDataReqStatusExcerpt::Error; + case MSTATUS_TIMEOUT: + return EDataReqStatusExcerpt::LostInSpaceAndTime; + case MSTATUS_NOTREADY: + case MSTATUS_REJECTED: + return EDataReqStatusExcerpt::RejectedForNow; + case MSTATUS_INTERNALERROR: + return EDataReqStatusExcerpt::InternalError; + default: + return EDataReqStatusExcerpt::Unknown; + } +} + +} + void SetMsgBusDefaults(NBus::TBusSessionConfig& sessionConfig, NBus::TBusQueueConfig& queueConfig) { size_t memorySize = NSystemInfo::TotalMemorySize(); @@ -243,6 +243,6 @@ void SetMsgBusDefaults(NBus::TBusSessionConfig& sessionConfig, ((NSystemInfo::CachedNumberOfCpus() - 1) / 4 + 1); sessionConfig.TotalTimeout = TDuration::Minutes(5).MilliSeconds(); sessionConfig.ConnectTimeout = TDuration::Seconds(15).MilliSeconds(); -} +} } diff --git a/ydb/public/lib/deprecated/client/msgbus_client.h b/ydb/public/lib/deprecated/client/msgbus_client.h index 66dc1fbec1..7d721946d8 100644 --- a/ydb/public/lib/deprecated/client/msgbus_client.h +++ b/ydb/public/lib/deprecated/client/msgbus_client.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "msgbus_client_config.h" @@ -8,43 +8,43 @@ #include <functional> #include <util/system/info.h> #include <library/cpp/messagebus/ybus.h> - -namespace NKikimr { -namespace NMsgBusProxy { - -class TMsgBusClient : NBus::IBusClientHandler { + +namespace NKikimr { +namespace NMsgBusProxy { + +class TMsgBusClient : NBus::IBusClientHandler { TMsgBusClientConfig Config; - TProtocol Protocol; - TAutoPtr<NBus::TNetAddr> NetAddr; - NBus::TBusMessageQueuePtr Bus; - NBus::TBusClientSessionPtr Session; -private: - void OnReply(TAutoPtr<NBus::TBusMessage> pMessage, TAutoPtr<NBus::TBusMessage> pReply) override; - void OnError(TAutoPtr<NBus::TBusMessage> pMessage, NBus::EMessageStatus status) override; + TProtocol Protocol; + TAutoPtr<NBus::TNetAddr> NetAddr; + NBus::TBusMessageQueuePtr Bus; + NBus::TBusClientSessionPtr Session; +private: + void OnReply(TAutoPtr<NBus::TBusMessage> pMessage, TAutoPtr<NBus::TBusMessage> pReply) override; + void OnError(TAutoPtr<NBus::TBusMessage> pMessage, NBus::EMessageStatus status) override; void OnResult(TAutoPtr<NBus::TBusMessage> pMessage, NBus::EMessageStatus status, TAutoPtr<NBus::TBusMessage> pReply); -public: +public: typedef std::function<void (NBus::EMessageStatus status, TAutoPtr<NBus::TBusMessage> reply)> TOnCall; typedef std::function<void (NBus::EMessageStatus status, TAutoPtr<NBus::TBusMessage> message, TAutoPtr<NBus::TBusMessage> reply)> TOnCallWithRequest; - TMsgBusClient(const TMsgBusClientConfig &config); - ~TMsgBusClient(); - - NBus::EMessageStatus SyncCall(TAutoPtr<NBus::TBusMessage> msg, TAutoPtr<NBus::TBusMessage> &reply); + TMsgBusClient(const TMsgBusClientConfig &config); + ~TMsgBusClient(); + + NBus::EMessageStatus SyncCall(TAutoPtr<NBus::TBusMessage> msg, TAutoPtr<NBus::TBusMessage> &reply); NBus::EMessageStatus AsyncCall(TAutoPtr<NBus::TBusMessage> msg, TOnCall callback); NBus::EMessageStatus AsyncCall(TAutoPtr<NBus::TBusMessage> msg, TOnCallWithRequest callback); - void Init(); - void Shutdown(); + void Init(); + void Shutdown(); const TMsgBusClientConfig& GetConfig(); -}; - +}; + EDataReqStatusExcerpt ExtractDataRequestStatus(const NKikimrClient::TResponse *response); - + } // NMsgBusProxy void SetMsgBusDefaults(NBus::TBusSessionConfig& sessionConfig, NBus::TBusQueueConfig& queueConfig); -} +} diff --git a/ydb/public/lib/deprecated/client/msgbus_player.cpp b/ydb/public/lib/deprecated/client/msgbus_player.cpp index 4407b8a08a..befa19f73a 100644 --- a/ydb/public/lib/deprecated/client/msgbus_player.cpp +++ b/ydb/public/lib/deprecated/client/msgbus_player.cpp @@ -119,7 +119,7 @@ ui32 TMsgBusPlayer::PlayTrace(const TString &traceFile, ui32 maxInFlight, std::f if (read != sizeof(NBus::TBusHeader)) ythrow yexception() << "Error reading message header"; filePos += read; - NBus::TBusHeader messageHeader(::TArrayRef<char>(messageBuffer.Data(), messageBuffer.Size())); + NBus::TBusHeader messageHeader(::TArrayRef<char>(messageBuffer.Data(), messageBuffer.Size())); messageBuffer.Resize(messageHeader.Size - sizeof(NBus::TBusHeader)); if (!messageBuffer.Empty()) { read = stream->Load(messageBuffer.Data(), messageBuffer.Size()); @@ -128,7 +128,7 @@ ui32 TMsgBusPlayer::PlayTrace(const TString &traceFile, ui32 maxInFlight, std::f filePos += read; } if (replyKey == YBUS_KEYINVALID) { - TAutoPtr<NBus::TBusMessage> request = protocol.Deserialize(messageHeader.Type, ::TArrayRef<char>(messageBuffer.Data(), messageBuffer.Size())); + TAutoPtr<NBus::TBusMessage> request = protocol.Deserialize(messageHeader.Type, ::TArrayRef<char>(messageBuffer.Data(), messageBuffer.Size())); if (request == nullptr) ythrow yexception() << "Error deserializing message (" << DumpMessageHeader(messageHeader) << ")"; TBusKey requestKey = messageHeader.Id; diff --git a/ydb/public/lib/scheme_types/scheme_type_id.h b/ydb/public/lib/scheme_types/scheme_type_id.h index 9340fa1a24..22fada2a7d 100644 --- a/ydb/public/lib/scheme_types/scheme_type_id.h +++ b/ydb/public/lib/scheme_types/scheme_type_id.h @@ -72,7 +72,7 @@ static constexpr TTypeId YqlIds[] = { DyNumber, }; -// types must be defined in GetValueHash and CompareTypedCells +// types must be defined in GetValueHash and CompareTypedCells constexpr bool IsYqlTypeImpl(TTypeId typeId, ui32 i) { return i == Y_ARRAY_SIZE(YqlIds) ? false : YqlIds[i] == typeId ? true : IsYqlTypeImpl(typeId, i + 1); diff --git a/ydb/public/sdk/cpp/client/impl/ydb_stats/stats.h b/ydb/public/sdk/cpp/client/impl/ydb_stats/stats.h index 95c477a13b..cae4099682 100644 --- a/ydb/public/sdk/cpp/client/impl/ydb_stats/stats.h +++ b/ydb/public/sdk/cpp/client/impl/ydb_stats/stats.h @@ -362,8 +362,8 @@ public: case TSessionPoolStatCollector::EStatCollectorType::SETTLERPOOL: return TSessionPoolStatCollector(nullptr, SettlerSessions_.Get(), nullptr); } - - return TSessionPoolStatCollector(); + + return TSessionPoolStatCollector(); } TClientStatCollector GetClientStatCollector() { diff --git a/ydb/services/discovery/grpc_service.cpp b/ydb/services/discovery/grpc_service.cpp index c7ad95ffc5..010322b5d9 100644 --- a/ydb/services/discovery/grpc_service.cpp +++ b/ydb/services/discovery/grpc_service.cpp @@ -1,12 +1,12 @@ -#include "grpc_service.h" - +#include "grpc_service.h" + #include <ydb/core/grpc_services/grpc_helper.h> #include <ydb/core/grpc_services/grpc_request_proxy.h> #include <ydb/core/grpc_services/rpc_calls.h> - -namespace NKikimr { -namespace NGRpcService { - + +namespace NKikimr { +namespace NGRpcService { + static TString GetSdkBuildInfo(NGrpc::IRequestContextBase* reqCtx) { const auto& res = reqCtx->GetPeerMetaValues(NYdb::YDB_SDK_BUILD_INFO_HEADER); if (res.empty()) { @@ -15,55 +15,55 @@ static TString GetSdkBuildInfo(NGrpc::IRequestContextBase* reqCtx) { return TString{res[0]}; } -TGRpcDiscoveryService::TGRpcDiscoveryService(NActors::TActorSystem *system, - TIntrusivePtr<NMonitoring::TDynamicCounters> counters, +TGRpcDiscoveryService::TGRpcDiscoveryService(NActors::TActorSystem *system, + TIntrusivePtr<NMonitoring::TDynamicCounters> counters, NActors::TActorId id) - : ActorSystem_(system) - , Counters_(counters) - , GRpcRequestProxyId_(id) - { - } - + : ActorSystem_(system) + , Counters_(counters) + , GRpcRequestProxyId_(id) + { + } + void TGRpcDiscoveryService::InitService(grpc::ServerCompletionQueue *cq, NGrpc::TLoggerPtr logger) { - CQ_ = cq; + CQ_ = cq; SetupIncomingRequests(std::move(logger)); - } - + } + void TGRpcDiscoveryService::SetGlobalLimiterHandle(NGrpc::TGlobalLimiter *limiter) { - Limiter_ = limiter; - } - - bool TGRpcDiscoveryService::IncRequest() { - return Limiter_->Inc(); - } - - void TGRpcDiscoveryService::DecRequest() { - Limiter_->Dec(); - Y_ASSERT(Limiter_->GetCurrentInFlight() >= 0); - } - + Limiter_ = limiter; + } + + bool TGRpcDiscoveryService::IncRequest() { + return Limiter_->Inc(); + } + + void TGRpcDiscoveryService::DecRequest() { + Limiter_->Dec(); + Y_ASSERT(Limiter_->GetCurrentInFlight() >= 0); + } + void TGRpcDiscoveryService::SetupIncomingRequests(NGrpc::TLoggerPtr logger) { - auto getCounterBlock = CreateCounterCb(Counters_, ActorSystem_); - #ifdef ADD_REQUEST - #error ADD_REQUEST macro already defined - #endif - #define ADD_REQUEST(NAME, IN, OUT, ACTION) \ + auto getCounterBlock = CreateCounterCb(Counters_, ActorSystem_); + #ifdef ADD_REQUEST + #error ADD_REQUEST macro already defined + #endif + #define ADD_REQUEST(NAME, IN, OUT, ACTION) \ MakeIntrusive<TGRpcRequest<Ydb::Discovery::IN, Ydb::Discovery::OUT, TGRpcDiscoveryService>>(this, &Service_, CQ_, \ [this](NGrpc::IRequestContextBase *reqCtx) { \ NGRpcService::ReportGrpcReqToMon(*ActorSystem_, reqCtx->GetPeer(), GetSdkBuildInfo(reqCtx)); \ ACTION; \ }, &Ydb::Discovery::V1::DiscoveryService::AsyncService::Request ## NAME, \ #NAME, logger, getCounterBlock("discovery", #NAME))->Run(); - - ADD_REQUEST(ListEndpoints, ListEndpointsRequest, ListEndpointsResponse, { - ActorSystem_->Send(GRpcRequestProxyId_, new TEvListEndpointsRequest(reqCtx)); - }) + + ADD_REQUEST(ListEndpoints, ListEndpointsRequest, ListEndpointsResponse, { + ActorSystem_->Send(GRpcRequestProxyId_, new TEvListEndpointsRequest(reqCtx)); + }) ADD_REQUEST(WhoAmI, WhoAmIRequest, WhoAmIResponse, { ActorSystem_->Send(GRpcRequestProxyId_, new TEvWhoAmIRequest(reqCtx)); }) - - #undef ADD_REQUEST - } - -} // namespace NGRpcService -} // namespace NKikimr + + #undef ADD_REQUEST + } + +} // namespace NGRpcService +} // namespace NKikimr diff --git a/ydb/services/discovery/grpc_service.h b/ydb/services/discovery/grpc_service.h index 0b089400d7..c6cb25f0fd 100644 --- a/ydb/services/discovery/grpc_service.h +++ b/ydb/services/discovery/grpc_service.h @@ -1,38 +1,38 @@ -#pragma once - +#pragma once + #include <library/cpp/actors/core/actorsystem.h> - + #include <ydb/public/api/grpc/ydb_discovery_v1.grpc.pb.h> - + #include <library/cpp/grpc/server/grpc_server.h> - -namespace NKikimr { -namespace NGRpcService { - - class TGRpcDiscoveryService + +namespace NKikimr { +namespace NGRpcService { + + class TGRpcDiscoveryService : public NGrpc::TGrpcServiceBase<Ydb::Discovery::V1::DiscoveryService> - { - public: - TGRpcDiscoveryService(NActors::TActorSystem* system, - TIntrusivePtr<NMonitoring::TDynamicCounters> counters, + { + public: + TGRpcDiscoveryService(NActors::TActorSystem* system, + TIntrusivePtr<NMonitoring::TDynamicCounters> counters, NActors::TActorId id); - + void InitService(grpc::ServerCompletionQueue* cq, NGrpc::TLoggerPtr logger) override; void SetGlobalLimiterHandle(NGrpc::TGlobalLimiter* limiter) override; - - bool IncRequest(); - void DecRequest(); - - private: + + bool IncRequest(); + void DecRequest(); + + private: void SetupIncomingRequests(NGrpc::TLoggerPtr logger); - - NActors::TActorSystem* ActorSystem_; + + NActors::TActorSystem* ActorSystem_; grpc::ServerCompletionQueue* CQ_ = nullptr; - - TIntrusivePtr<NMonitoring::TDynamicCounters> Counters_; + + TIntrusivePtr<NMonitoring::TDynamicCounters> Counters_; NActors::TActorId GRpcRequestProxyId_; NGrpc::TGlobalLimiter* Limiter_ = nullptr; - }; - -} // namespace NGRpcService -} // namespace NKikimr + }; + +} // namespace NGRpcService +} // namespace NKikimr diff --git a/ydb/services/discovery/ya.make b/ydb/services/discovery/ya.make index abe915bbbb..a3aaae080e 100644 --- a/ydb/services/discovery/ya.make +++ b/ydb/services/discovery/ya.make @@ -1,17 +1,17 @@ -LIBRARY() - -OWNER(g:kikimr) - -SRCS( - grpc_service.cpp -) - -PEERDIR( +LIBRARY() + +OWNER(g:kikimr) + +SRCS( + grpc_service.cpp +) + +PEERDIR( library/cpp/grpc/server ydb/core/grpc_services ydb/core/mind ydb/public/api/grpc ydb/public/lib/operation_id -) - -END() +) + +END() diff --git a/ydb/services/ydb/ydb_dummy.cpp b/ydb/services/ydb/ydb_dummy.cpp index 32367c5b50..c628b0b3e4 100644 --- a/ydb/services/ydb/ydb_dummy.cpp +++ b/ydb/services/ydb/ydb_dummy.cpp @@ -64,9 +64,9 @@ class TBiStreamPingRequestRPC : public TActorBootstrapped<TBiStreamPingRequestRP TEvBiStreamPingRequest::TResponse>; public: - static constexpr NKikimrServices::TActivity::EType ActorActivityType() { - return NKikimrServices::TActivity::GRPC_REQ; - } + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { + return NKikimrServices::TActivity::GRPC_REQ; + } TBiStreamPingRequestRPC(TEvBiStreamPingRequest* msg) : Request_(msg) {} diff --git a/ydb/services/ydb/ydb_ut.cpp b/ydb/services/ydb/ydb_ut.cpp index 57119197bf..2d37063079 100644 --- a/ydb/services/ydb/ydb_ut.cpp +++ b/ydb/services/ydb/ydb_ut.cpp @@ -3323,7 +3323,7 @@ void InitConfigs(TKikimrWithGrpcAndRootSchema &server) { STORAGE_CONFIG1.MutableLog()->SetPreferredPoolKind("hdd"); STORAGE_CONFIG1.MutableData()->SetPreferredPoolKind("hdd"); STORAGE_CONFIG1.MutableExternal()->SetPreferredPoolKind("hdd"); - STORAGE_CONFIG1.SetExternalThreshold(Max<ui32>()); + STORAGE_CONFIG1.SetExternalThreshold(Max<ui32>()); } { @@ -4616,7 +4616,7 @@ Y_UNIT_TEST_SUITE(TTableProfileTests) { {TString("log"), TString("hdd")}, {TString("data"), TString("hdd")}, {TString("external"), TString("hdd")}, - {TString("external_threshold"), ToString(Max<ui32>())}, + {TString("external_threshold"), ToString(Max<ui32>())}, {TString("codec"), TString("lz4")}, {TString("in_memory"), TString("false")} }}); } else { diff --git a/ydb/tests/functional/tenants/test_storage_config.py b/ydb/tests/functional/tenants/test_storage_config.py index 97fda366b1..94f1789ed5 100644 --- a/ydb/tests/functional/tenants/test_storage_config.py +++ b/ydb/tests/functional/tenants/test_storage_config.py @@ -109,8 +109,8 @@ def case_0(): creation_options.ColumnStorage1Ext1, creation_options.ColumnCacheNone ) - creation_options.partition_config.with_partitioning_policy(0) # for now external blobs and autosplit not compatible - + creation_options.partition_config.with_partitioning_policy(0) # for now external blobs and autosplit not compatible + has_external = True scheme = lambda table_name: has_item( has_properties( @@ -143,8 +143,8 @@ def case_11(): creation_options.ColumnStorageTest_1_2_1k, creation_options.ColumnCacheNone ) - creation_options.partition_config.with_partitioning_policy(0) # for now external blobs and autosplit not compatible - + creation_options.partition_config.with_partitioning_policy(0) # for now external blobs and autosplit not compatible + has_external = True scheme = lambda table_name: has_item( has_properties( @@ -209,8 +209,8 @@ def case_12(): creation_options.ColumnStorage2, creation_options.ColumnCacheNone ) - creation_options.partition_config.with_partitioning_policy(0) # for now external blobs and autosplit not compatible - + creation_options.partition_config.with_partitioning_policy(0) # for now external blobs and autosplit not compatible + has_external = True scheme = lambda table_name: has_item( has_properties( @@ -305,8 +305,8 @@ def case_4(): storage_config.appoint_log('NotExist', True) storage_config.appoint_data('NotExist', True) storage_config.appoint_external('NotExist', True) - creation_options.partition_config.with_partitioning_policy(0) # for now external blobs and autosplit not compatible - + creation_options.partition_config.with_partitioning_policy(0) # for now external blobs and autosplit not compatible + has_external = True scheme = lambda table_name: has_item( has_properties( @@ -339,8 +339,8 @@ def case_5(): storage_config.appoint_log('hdd1') storage_config.appoint_data('hdd') storage_config.appoint_external('hdd2') - creation_options.partition_config.with_partitioning_policy(0) # for now external blobs and autosplit not compatible - + creation_options.partition_config.with_partitioning_policy(0) # for now external blobs and autosplit not compatible + has_external = True scheme = lambda table_name: has_item( has_properties( @@ -373,7 +373,7 @@ def case_6(): storage_config.appoint_log('hdd1') storage_config.appoint_data('hdd2') storage_config.appoint_external('hdd2') - creation_options.partition_config.with_partitioning_policy(0) # for now external blobs and autosplit not compatible + creation_options.partition_config.with_partitioning_policy(0) # for now external blobs and autosplit not compatible has_external = True scheme = lambda table_name: has_item( @@ -407,7 +407,7 @@ def case_7(): storage_config.appoint_log('hdd1') storage_config.appoint_data('hdd2', threshold=12200) storage_config.appoint_external('hdd2', threshold=524200) - creation_options.partition_config.with_partitioning_policy(0) # for now external blobs and autosplit not compatible + creation_options.partition_config.with_partitioning_policy(0) # for now external blobs and autosplit not compatible has_external = True scheme = lambda table_name: has_item( @@ -474,8 +474,8 @@ def case_9(): storage_config.appoint_log('hdd') storage_config.appoint_data('hdd', threshold=12288) storage_config.appoint_external('hdd', threshold=524288) - creation_options.partition_config.with_partitioning_policy(0) # for now external blobs and autosplit not compatible - + creation_options.partition_config.with_partitioning_policy(0) # for now external blobs and autosplit not compatible + has_external = True scheme = lambda table_name: has_item( has_properties( @@ -508,7 +508,7 @@ def case_10(): storage_config.appoint_log('hdd') storage_config.appoint_data('hdd', threshold=12288) storage_config.appoint_external('hdd', threshold=2*1024*1024+1) - creation_options.partition_config.with_partitioning_policy(0) # for now external blobs and autosplit not compatible + creation_options.partition_config.with_partitioning_policy(0) # for now external blobs and autosplit not compatible has_external = False scheme = lambda table_name: has_item( |