diff options
| author | Devtools Arcadia <[email protected]> | 2022-02-07 18:08:42 +0300 |
|---|---|---|
| committer | Devtools Arcadia <[email protected]> | 2022-02-07 18:08:42 +0300 |
| commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
| tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/actors/core/ask.cpp | |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/actors/core/ask.cpp')
| -rw-r--r-- | library/cpp/actors/core/ask.cpp | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/library/cpp/actors/core/ask.cpp b/library/cpp/actors/core/ask.cpp new file mode 100644 index 00000000000..0054c9a906c --- /dev/null +++ b/library/cpp/actors/core/ask.cpp @@ -0,0 +1,74 @@ +#include "ask.h" + +#include "actor_bootstrapped.h" +#include "actorid.h" +#include "event.h" +#include "hfunc.h" + +namespace NActors { + namespace { + class TAskActor: public TActorBootstrapped<TAskActor> { + enum { + Timeout = EventSpaceBegin(TEvents::ES_PRIVATE), + }; + + // We can't use the standard timeout event because recipient may send us one. + struct TTimeout: public TEventLocal<TTimeout, Timeout> { + }; + + public: + TAskActor( + TMaybe<ui32> expectedEventType, + TActorId recipient, + THolder<IEventBase> event, + TDuration timeout, + const NThreading::TPromise<THolder<IEventBase>>& promise) + : ExpectedEventType_(expectedEventType) + , Recipient_(recipient) + , Event_(std::move(event)) + , Timeout_(timeout) + , Promise_(promise) + { + } + + public: + void Bootstrap() { + Send(Recipient_, std::move(Event_)); + Become(&TAskActor::Waiting); + + if (Timeout_ != TDuration::Max()) { + Schedule(Timeout_, new TTimeout); + } + } + + STATEFN(Waiting) { + if (ev->GetTypeRewrite() == TTimeout::EventType) { + Promise_.SetException(std::make_exception_ptr(yexception() << "ask timeout")); + } else if (!ExpectedEventType_ || ev->GetTypeRewrite() == ExpectedEventType_) { + Promise_.SetValue(ev->ReleaseBase()); + } else { + Promise_.SetException(std::make_exception_ptr(yexception() << "received unexpected response " << ev->GetBase()->ToString())); + } + + PassAway(); + } + + public: + TMaybe<ui32> ExpectedEventType_; + TActorId Recipient_; + THolder<IEventBase> Event_; + TDuration Timeout_; + NThreading::TPromise<THolder<IEventBase>> Promise_; + }; + } + + THolder<IActor> MakeAskActor( + TMaybe<ui32> expectedEventType, + TActorId recipient, + THolder<IEventBase> event, + TDuration timeout, + const NThreading::TPromise<THolder<IEventBase>>& promise) + { + return MakeHolder<TAskActor>(expectedEventType, std::move(recipient), std::move(event), timeout, promise); + } +} |
