executelater.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #pragma once
  2. #include "actor_bootstrapped.h"
  3. #include <utility>
  4. namespace NActors {
  5. template <typename TCallback>
  6. class TExecuteLater: public TActorBootstrapped<TExecuteLater<TCallback>> {
  7. public:
  8. static constexpr IActor::EActivityType ActorActivityType() {
  9. return IActor::ACTORLIB_COMMON;
  10. }
  11. TExecuteLater(
  12. TCallback&& callback,
  13. IActor::EActivityType activityType,
  14. ui32 channel = 0,
  15. ui64 cookie = 0,
  16. const TActorId& reportCompletionTo = TActorId(),
  17. const TActorId& reportExceptionTo = TActorId()) noexcept
  18. : Callback(std::move(callback))
  19. , Channel(channel)
  20. , Cookie(cookie)
  21. , ReportCompletionTo(reportCompletionTo)
  22. , ReportExceptionTo(reportExceptionTo)
  23. {
  24. this->SetActivityType(activityType);
  25. }
  26. void Bootstrap(const TActorContext& ctx) noexcept {
  27. try {
  28. {
  29. /* RAII, Callback should be destroyed right before sending
  30. TEvCallbackCompletion */
  31. auto local = std::move(Callback);
  32. using T = decltype(local);
  33. if constexpr (std::is_invocable_v<T, const TActorContext&>) {
  34. local(ctx);
  35. } else {
  36. local();
  37. }
  38. }
  39. if (ReportCompletionTo) {
  40. ctx.Send(ReportCompletionTo,
  41. new TEvents::TEvCallbackCompletion(ctx.SelfID),
  42. Channel, Cookie);
  43. }
  44. } catch (...) {
  45. if (ReportExceptionTo) {
  46. const TString msg = CurrentExceptionMessage();
  47. ctx.Send(ReportExceptionTo,
  48. new TEvents::TEvCallbackException(ctx.SelfID, msg),
  49. Channel, Cookie);
  50. }
  51. }
  52. this->Die(ctx);
  53. }
  54. private:
  55. TCallback Callback;
  56. const ui32 Channel;
  57. const ui64 Cookie;
  58. const TActorId ReportCompletionTo;
  59. const TActorId ReportExceptionTo;
  60. };
  61. template <typename T>
  62. IActor* CreateExecuteLaterActor(
  63. T&& func,
  64. IActor::EActivityType activityType,
  65. ui32 channel = 0,
  66. ui64 cookie = 0,
  67. const TActorId& reportCompletionTo = TActorId(),
  68. const TActorId& reportExceptionTo = TActorId()) noexcept {
  69. return new TExecuteLater<T>(std::forward<T>(func),
  70. activityType,
  71. channel,
  72. cookie,
  73. reportCompletionTo,
  74. reportExceptionTo);
  75. }
  76. }