diff options
author | xenoxeno <xeno@ydb.tech> | 2023-03-09 12:10:01 +0300 |
---|---|---|
committer | xenoxeno <xeno@ydb.tech> | 2023-03-09 12:10:01 +0300 |
commit | ad607bb887619f321dec03b02df8220e01b7f5aa (patch) | |
tree | 7d5c87352cbe835b56bb2bdac93b37cbdf8ead21 /library/cpp/actors/core/actor.h | |
parent | 6324d075a5e80b6943b5de6b465b775050fe83df (diff) | |
download | ydb-ad607bb887619f321dec03b02df8220e01b7f5aa.tar.gz |
light events for actor system
Diffstat (limited to 'library/cpp/actors/core/actor.h')
-rw-r--r-- | library/cpp/actors/core/actor.h | 229 |
1 files changed, 214 insertions, 15 deletions
diff --git a/library/cpp/actors/core/actor.h b/library/cpp/actors/core/actor.h index 0e109da819..08a3beb2bf 100644 --- a/library/cpp/actors/core/actor.h +++ b/library/cpp/actors/core/actor.h @@ -59,6 +59,12 @@ namespace NActors { template <ESendingType SendingType = ESendingType::Common> static bool Send(std::unique_ptr<IEventHandle> &&ev); + template <ESendingType SendingType = ESendingType::Common> + static bool Forward(TAutoPtr<IEventHandle>& ev, const TActorId& recipient); + + template <ESendingType SendingType = ESendingType::Common> + static bool Forward(THolder<IEventHandle>& ev, const TActorId& recipient); + /** * Schedule one-shot event that will be send at given time point in the future. * @@ -132,10 +138,16 @@ namespace NActors { template <ESendingType SendingType = ESendingType::Common> bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const; template <ESendingType SendingType = ESendingType::Common> + bool Send(const TActorId& recipient, IEventHandleLight* ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const; + template <ESendingType SendingType = ESendingType::Common> bool Send(const TActorId& recipient, THolder<IEventBase> ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const { return Send<SendingType>(recipient, ev.Release(), flags, cookie, std::move(traceId)); } template <ESendingType SendingType = ESendingType::Common> + bool Send(const TActorId& recipient, THolder<IEventHandleLight> ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const { + return Send<SendingType>(recipient, ev.Release(), flags, cookie, std::move(traceId)); + } + template <ESendingType SendingType = ESendingType::Common> bool Send(const TActorId& recipient, std::unique_ptr<IEventBase> ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const { return Send<SendingType>(recipient, ev.release(), flags, cookie, std::move(traceId)); } @@ -145,6 +157,15 @@ namespace NActors { bool Send(std::unique_ptr<IEventHandle> &&ev) const { return Send<SendingType>(TAutoPtr<IEventHandle>(ev.release())); } + template <ESendingType SendingType = ESendingType::Common> + bool Forward(TAutoPtr<IEventHandle>& ev, const TActorId& recipient) const; + template <ESendingType SendingType = ESendingType::Common> + bool Forward(THolder<IEventHandle>& ev, const TActorId& recipient) const; + template <ESendingType SendingType = ESendingType::Common, typename TEventHandle> + bool Forward(TAutoPtr<TEventHandle>& ev, const TActorId& recipient) const { + TAutoPtr<IEventHandle> evi(ev.Release()); + return Forward(evi, recipient); + } TInstant Now() const; TMonotonic Monotonic() const; @@ -206,6 +227,15 @@ namespace NActors { template <ESendingType SendingType = ESendingType::Common> bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const; + template <ESendingType SendingType = ESendingType::Common> + bool Send(const TActorId& recipient, IEventHandleLight* ev) const; + template <ESendingType SendingType = ESendingType::Common> + bool Send(const TActorId& recipient, IEventHandleLight* ev, ui32 flags) const; + template <ESendingType SendingType = ESendingType::Common> + bool Send(const TActorId& recipient, IEventHandleLight* ev, ui32 flags, ui64 cookie) const; + template <ESendingType SendingType = ESendingType::Common> + bool Send(const TActorId& recipient, IEventHandleLight* ev, ui32 flags, ui64 cookie, NWilson::TTraceId traceId) const; + bool SendWithContinuousExecution(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; @@ -253,7 +283,7 @@ namespace NActors { class TActorVirtualBehaviour { public: - static void Receive(IActor* actor, std::unique_ptr<IEventHandle> ev); + static void Receive(IActor* actor, std::unique_ptr<IEventHandleFat> ev); public: }; @@ -262,8 +292,7 @@ namespace NActors { using TBase = IActor; friend class TDecorator; public: - typedef void (IActor::* TReceiveFunc)(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx); - + using TReceiveFunc = void (IActor::*)(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx); private: TReceiveFunc StateFunc = nullptr; public: @@ -303,6 +332,8 @@ namespace NActors { friend void DoActorInit(TActorSystem*, IActor*, const TActorId&, const TActorId&); friend class TDecorator; protected: + using TReceiveFuncLight = void (IActor::*)(TAutoPtr<IEventHandle>& ev); + TReceiveFuncLight StateFuncLight = nullptr; TActorCallbackBehaviour CImpl; public: using TReceiveFunc = TActorCallbackBehaviour::TReceiveFunc; @@ -476,19 +507,28 @@ namespace NActors { TActorIdentity SelfId() const { return SelfActorId; } - void Receive(TAutoPtr<IEventHandle>& ev, const TActorContext& /*ctx*/) { + // void Receive(TAutoPtr<IEventHandle> ev, const TActorContext& /*ctx*/) { + // Receive(ev); + // } + void Receive(TAutoPtr<IEventHandle>& ev) { ++HandledEvents; - if (CImpl.Initialized()) { + if (StateFuncLight) { + (this->*StateFuncLight)(ev); + } else if (CImpl.Initialized()) { CImpl.Receive(this, ev); } else { - TActorVirtualBehaviour::Receive(this, std::unique_ptr<IEventHandle>(ev.Release())); + TActorVirtualBehaviour::Receive(this, std::unique_ptr<IEventHandleFat>(IEventHandleFat::MakeFat(ev).Release())); } } 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; - bool Send(const TActorId& recipient, THolder<IEventBase> ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const { + bool Send(const TActorId& recipient, IEventHandleLight* ev) const noexcept; + bool Send(const TActorId& recipient, IEventHandleLight* ev, ui32 flags) const noexcept; + bool Send(const TActorId& recipient, IEventHandleLight* ev, ui32 flags, ui64 cookie) const noexcept; + bool Send(const TActorId& recipient, IEventHandleLight* ev, ui32 flags, ui64 cookie, NWilson::TTraceId traceId) const noexcept; + bool Send(const TActorId& recipient, THolder<IEventBase> ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const{ return Send(recipient, ev.Release(), flags, cookie, std::move(traceId)); } bool Send(const TActorId& recipient, std::unique_ptr<IEventBase> ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const { @@ -511,6 +551,20 @@ namespace NActors { return Send(recipient, ev.release(), flags, cookie, std::move(traceId)); } + bool Forward(TAutoPtr<IEventHandle>& ev, const TActorId& recipient) { + return TActivationContext::Forward(ev, recipient); + } + + bool Forward(THolder<IEventHandle>& ev, const TActorId& recipient) { + return TActivationContext::Forward(ev, recipient); + } + + template <typename TEventHandle> + bool Forward(TAutoPtr<TEventHandle>& ev, const TActorId& recipient) const { + TAutoPtr<IEventHandle> evi(ev.Release()); + return Forward(evi, recipient); + } + 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; @@ -574,8 +628,78 @@ namespace NActors { } }; + template<typename TDerived> + class TActorCallback : public IActorCallback { + public: + using TFatReceiveFunc = void (TDerived::*)(TAutoPtr<IEventHandle>&, const TActorContext&); + using TLightReceiveFunc = void (TDerived::*)(TAutoPtr<IEventHandle>&); + + private: + void BecomeFat(TFatReceiveFunc stateFunc) { + IActorCallback::Become(stateFunc); + } + + template<typename... TArgs> + void BecomeFat(TFatReceiveFunc stateFunc, const TActorContext& ctx, TArgs&&... args) { + IActorCallback::Become(stateFunc, ctx, std::forward<TArgs>(args)...); + } + + template<typename... TArgs> + void BecomeFat(TFatReceiveFunc stateFunc, TArgs&&... args) { + IActorCallback::Become(stateFunc, std::forward<TArgs>(args)...); + } + + void BecomeLight(TLightReceiveFunc stateFuncLight) { + StateFuncLight = static_cast<TReceiveFuncLight>(stateFuncLight); + } + + public: + TActorCallback(TFatReceiveFunc stateFunc, ui32 activityType = OTHER) + : IActorCallback(static_cast<TReceiveFunc>(stateFunc), activityType) + { + } + + TActorCallback(TLightReceiveFunc stateFunc, ui32 activityType = OTHER) + : IActorCallback(nullptr, activityType) + { + Become(stateFunc); + } + + template<typename T> + void Become(T stateFunc) { + IActorCallback::Become(stateFunc); + } + + template<typename T, typename... TArgs> + void Become(T stateFunc, const TActorContext&, TArgs&&... args) { + IActorCallback::Become(stateFunc); + Schedule(std::forward<TArgs>(args)...); + } + + template<typename T, typename... TArgs> + void Become(T stateFunc, TArgs&&... args) { + IActorCallback::Become(stateFunc); + Schedule(std::forward<TArgs>(args)...); + } + + template<> + void Become<TLightReceiveFunc>(TLightReceiveFunc stateFunc) { + BecomeLight(stateFunc); + } + + template<> + void Become<TFatReceiveFunc>(TFatReceiveFunc stateFunc) { + BecomeFat(stateFunc); + } + + template<typename... TArgs> + void Become(TFatReceiveFunc stateFunc, const TActorContext& ctx, TArgs&&... args) { + BecomeFat(stateFunc, ctx, std::forward<TArgs>(args)...); + } + }; + template <typename TDerived> - class TActor: public IActorCallback { + class TActor: public TActorCallback<TDerived> { private: template <typename T, typename = const char*> struct HasActorName: std::false_type { }; @@ -601,14 +725,20 @@ namespace NActors { protected: //* Comment this function to find unmarked activities static constexpr IActor::EActivityType ActorActivityType() { - return EActorActivity::OTHER; + return IActorCallback::EActorActivity::OTHER; } //*/ // static constexpr char ActorName[] = "UNNAMED"; - TActor(void (TDerived::*func)(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx), ui32 activityType = GetActivityTypeIndex()) - : IActorCallback(static_cast<TReceiveFunc>(func), activityType) - { } + TActor(typename TActorCallback<TDerived>::TFatReceiveFunc func, ui32 activityType = GetActivityTypeIndex()) + : TActorCallback<TDerived>(func, activityType) + { + } + + TActor(typename TActorCallback<TDerived>::TLightReceiveFunc func, ui32 activityType = GetActivityTypeIndex()) + : TActorCallback<TDerived>(func, activityType) + { + } public: typedef TDerived TThis; @@ -617,8 +747,10 @@ namespace NActors { #define STFUNC_SIG TAutoPtr< ::NActors::IEventHandle>&ev, const ::NActors::TActorContext &ctx #define STATEFN_SIG TAutoPtr<::NActors::IEventHandle>& ev +#define LIGHTFN_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 LIGHTFN(funcName) void funcName(TAutoPtr<::NActors::IEventHandle>& ev) #define STFUNC_STRICT_UNHANDLED_MSG_HANDLER Y_VERIFY_DEBUG(false, "%s: unexpected message type 0x%08" PRIx32, __func__, etype); @@ -630,13 +762,26 @@ namespace NActors { UNHANDLED_MSG_HANDLER \ } +#define LIGHTFN_BODY(HANDLERS, UNHANDLED_MSG_HANDLER) \ + switch (const ui32 etype = ev->GetTypeRewrite()) { \ + HANDLERS \ + default: \ + UNHANDLED_MSG_HANDLER \ + } + #define STRICT_STFUNC_BODY(HANDLERS) STFUNC_BODY(HANDLERS, STFUNC_STRICT_UNHANDLED_MSG_HANDLER) +#define STRICT_LIGHTFN_BODY(HANDLERS) LIGHTFN_BODY(HANDLERS, STFUNC_STRICT_UNHANDLED_MSG_HANDLER) #define STRICT_STFUNC(NAME, HANDLERS) \ void NAME(STFUNC_SIG) { \ STRICT_STFUNC_BODY(HANDLERS) \ } +#define STRICT_LIGHTFN(NAME, HANDLERS) \ + void NAME(LIGHTFN_SIG) { \ + STRICT_LIGHTFN_BODY(HANDLERS) \ + } + #define STRICT_STFUNC_EXC(NAME, HANDLERS, EXCEPTION_HANDLERS) \ void NAME(STFUNC_SIG) { \ try { \ @@ -681,7 +826,7 @@ namespace NActors { STFUNC(State) { if (DoBeforeReceiving(ev, ctx)) { - Actor->Receive(ev, ctx); + Actor->Receive(ev); DoAfterReceiving(ctx); } } @@ -777,8 +922,26 @@ namespace NActors { } template <ESendingType SendingType> + bool TActivationContext::Forward(TAutoPtr<IEventHandle>& ev, const TActorId& recipient) { + IEventHandle::Forward(ev, recipient); + return Send(ev); + } + + template <ESendingType SendingType> + bool TActivationContext::Forward(THolder<IEventHandle>& ev, const TActorId& recipient) { + IEventHandle::Forward(ev, recipient); + return Send(ev); + } + + template <ESendingType SendingType> bool TActorContext::Send(const TActorId& recipient, IEventBase* ev, ui32 flags, ui64 cookie, NWilson::TTraceId traceId) const { - return Send<SendingType>(new IEventHandle(recipient, SelfID, ev, flags, cookie, nullptr, std::move(traceId))); + return Send<SendingType>(new IEventHandleFat(recipient, SelfID, ev, flags, cookie, nullptr, std::move(traceId))); + } + + template <ESendingType SendingType> + bool TActorContext::Send(const TActorId& recipient, IEventHandleLight* ev, ui32 flags, ui64 cookie, NWilson::TTraceId traceId) const { + ev->PrepareSend(recipient, SelfID, flags, cookie, std::move(traceId)); + return Send<SendingType>(ev); } template <ESendingType SendingType> @@ -787,6 +950,18 @@ namespace NActors { } template <ESendingType SendingType> + bool TActorContext::Forward(TAutoPtr<IEventHandle>& ev, const TActorId& recipient) const { + IEventHandle::Forward(ev, recipient); + return ExecutorThread.Send<SendingType>(ev); + } + + template <ESendingType SendingType> + bool TActorContext::Forward(THolder<IEventHandle>& ev, const TActorId& recipient) const { + IEventHandle::Forward(ev, recipient); + return ExecutorThread.Send<SendingType>(ev); + } + + template <ESendingType SendingType> TActorId TActivationContext::Register(IActor* actor, TActorId parentId, TMailboxType::EType mailboxType, ui32 poolId) { return TlsActivationContext->ExecutorThread.RegisterActor<SendingType>(actor, mailboxType, poolId, parentId); } @@ -798,7 +973,31 @@ namespace NActors { template <ESendingType SendingType> bool TActorIdentity::Send(const TActorId& recipient, IEventBase* ev, ui32 flags, ui64 cookie, NWilson::TTraceId traceId) const { - return TActivationContext::Send<SendingType>(new IEventHandle(recipient, *this, ev, flags, cookie, nullptr, std::move(traceId))); + return TActivationContext::Send<SendingType>(new IEventHandleFat(recipient, *this, ev, flags, cookie, nullptr, std::move(traceId))); + } + + template <ESendingType SendingType> + bool TActorIdentity::Send(const TActorId& recipient, IEventHandleLight* ev) const { + ev->PrepareSend(recipient, *this); + return TActivationContext::Send<SendingType>(ev); + } + + template <ESendingType SendingType> + bool TActorIdentity::Send(const TActorId& recipient, IEventHandleLight* ev, ui32 flags) const { + ev->PrepareSend(recipient, *this, flags); + return TActivationContext::Send<SendingType>(ev); + } + + template <ESendingType SendingType> + bool TActorIdentity::Send(const TActorId& recipient, IEventHandleLight* ev, ui32 flags, ui64 cookie) const { + ev->PrepareSend(recipient, *this, flags, cookie); + return TActivationContext::Send<SendingType>(ev); + } + + template <ESendingType SendingType> + bool TActorIdentity::Send(const TActorId& recipient, IEventHandleLight* ev, ui32 flags, ui64 cookie, NWilson::TTraceId traceId) const { + ev->PrepareSend(recipient, *this, flags, cookie, std::move(traceId)); + return TActivationContext::Send<SendingType>(ev); } template <ESendingType SendingType> |