ping-pong-req.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. //
  2. // Copyright (c) 2019-2021 Ivan Baidakou (basiliscos) (the dot dmol at gmail dot com)
  3. //
  4. // Distributed under the MIT Software License
  5. //
  6. #include <rotor/ev.hpp>
  7. #include <iostream>
  8. #include <random>
  9. namespace payload {
  10. struct pong_t {};
  11. struct ping_t {
  12. using response_t = pong_t;
  13. };
  14. } // namespace payload
  15. namespace message {
  16. using ping_t = rotor::request_traits_t<payload::ping_t>::request::message_t;
  17. using pong_t = rotor::request_traits_t<payload::ping_t>::response::message_t;
  18. } // namespace message
  19. struct pinger_t : public rotor::actor_base_t {
  20. using rotor::actor_base_t::actor_base_t;
  21. void set_ponger_addr(const rotor::address_ptr_t &addr) { ponger_addr = addr; }
  22. void configure(rotor::plugin::plugin_base_t &plugin) noexcept override {
  23. rotor::actor_base_t::configure(plugin);
  24. plugin.with_casted<rotor::plugin::starter_plugin_t>([](auto &p) { p.subscribe_actor(&pinger_t::on_pong); });
  25. }
  26. void on_start() noexcept override {
  27. rotor::actor_base_t::on_start();
  28. request<payload::ping_t>(ponger_addr).send(rotor::pt::seconds(1));
  29. }
  30. void on_pong(message::pong_t &msg) noexcept {
  31. auto &ec = msg.payload.ee;
  32. if (!msg.payload.ee) {
  33. std::cout << "pong received\n";
  34. } else {
  35. std::cout << "pong was NOT received: " << ec->message() << "\n";
  36. }
  37. supervisor->do_shutdown();
  38. }
  39. rotor::address_ptr_t ponger_addr;
  40. };
  41. struct ponger_t : public rotor::actor_base_t {
  42. using generator_t = std::mt19937;
  43. using distrbution_t = std::uniform_real_distribution<double>;
  44. std::random_device rd;
  45. generator_t gen;
  46. distrbution_t dist;
  47. explicit ponger_t(config_t &cfg) : rotor::actor_base_t(cfg), gen(rd()) {}
  48. void configure(rotor::plugin::plugin_base_t &plugin) noexcept override {
  49. rotor::actor_base_t::configure(plugin);
  50. plugin.with_casted<rotor::plugin::starter_plugin_t>([](auto &p) { p.subscribe_actor(&ponger_t::on_ping); });
  51. }
  52. void on_ping(message::ping_t &req) noexcept {
  53. auto dice = dist(gen);
  54. std::cout << "pong, dice = " << dice << std::endl;
  55. if (dice > 0.5) {
  56. reply_to(req);
  57. }
  58. }
  59. };
  60. int main() {
  61. try {
  62. auto *loop = ev_loop_new(0);
  63. auto system_context = rotor::ev::system_context_ptr_t{new rotor::ev::system_context_ev_t()};
  64. auto timeout = boost::posix_time::milliseconds{10};
  65. auto sup = system_context->create_supervisor<rotor::ev::supervisor_ev_t>()
  66. .loop(loop)
  67. .loop_ownership(true) /* let supervisor takes ownership on the loop */
  68. .timeout(timeout)
  69. .finish();
  70. auto pinger = sup->create_actor<pinger_t>().timeout(timeout).finish();
  71. auto ponger = sup->create_actor<ponger_t>().timeout(timeout).finish();
  72. pinger->set_ponger_addr(ponger->get_address());
  73. sup->start();
  74. ev_run(loop);
  75. } catch (const std::exception &ex) {
  76. std::cout << "exception : " << ex.what();
  77. }
  78. std::cout << "exiting...\n";
  79. return 0;
  80. }