ask.cpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #include "ask.h"
  2. #include "actor_bootstrapped.h"
  3. #include "actorid.h"
  4. #include "event.h"
  5. #include "hfunc.h"
  6. namespace NActors {
  7. namespace {
  8. class TAskActor: public TActorBootstrapped<TAskActor> {
  9. enum {
  10. Timeout = EventSpaceBegin(TEvents::ES_PRIVATE),
  11. };
  12. // We can't use the standard timeout event because recipient may send us one.
  13. struct TTimeout: public TEventLocal<TTimeout, Timeout> {
  14. };
  15. public:
  16. TAskActor(
  17. TMaybe<ui32> expectedEventType,
  18. TActorId recipient,
  19. THolder<IEventBase> event,
  20. TDuration timeout,
  21. const NThreading::TPromise<THolder<IEventBase>>& promise)
  22. : ExpectedEventType_(expectedEventType)
  23. , Recipient_(recipient)
  24. , Event_(std::move(event))
  25. , Timeout_(timeout)
  26. , Promise_(promise)
  27. {
  28. }
  29. public:
  30. void Bootstrap() {
  31. Send(Recipient_, std::move(Event_));
  32. Become(&TAskActor::Waiting);
  33. if (Timeout_ != TDuration::Max()) {
  34. Schedule(Timeout_, new TTimeout);
  35. }
  36. }
  37. STATEFN(Waiting) {
  38. if (ev->GetTypeRewrite() == TTimeout::EventType) {
  39. Promise_.SetException(std::make_exception_ptr(yexception() << "ask timeout"));
  40. } else if (!ExpectedEventType_ || ev->GetTypeRewrite() == ExpectedEventType_) {
  41. Promise_.SetValue(ev->ReleaseBase());
  42. } else {
  43. Promise_.SetException(std::make_exception_ptr(yexception() << "received unexpected response " << ev->GetBase()->ToString()));
  44. }
  45. PassAway();
  46. }
  47. public:
  48. TMaybe<ui32> ExpectedEventType_;
  49. TActorId Recipient_;
  50. THolder<IEventBase> Event_;
  51. TDuration Timeout_;
  52. NThreading::TPromise<THolder<IEventBase>> Promise_;
  53. };
  54. }
  55. THolder<IActor> MakeAskActor(
  56. TMaybe<ui32> expectedEventType,
  57. TActorId recipient,
  58. THolder<IEventBase> event,
  59. TDuration timeout,
  60. const NThreading::TPromise<THolder<IEventBase>>& promise)
  61. {
  62. return MakeHolder<TAskActor>(expectedEventType, std::move(recipient), std::move(event), timeout, promise);
  63. }
  64. }