link_server.h 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #pragma once
  2. //
  3. // Copyright (c) 2019-2020 Ivan Baidakou (basiliscos) (the dot dmol at gmail dot com)
  4. //
  5. // Distributed under the MIT Software License
  6. //
  7. #include "plugin_base.h"
  8. #include <string>
  9. #include <unordered_set>
  10. #include <functional>
  11. #include <optional>
  12. namespace rotor::plugin {
  13. /** \struct link_server_plugin_t
  14. *
  15. * \brief allows actor to have passive (server) role in linking
  16. *
  17. * The plugin keeps records of connected clients. When actor is
  18. * going to shutdown it will block shutdown process until all
  19. * connected clients will send unlink confirmation (or until
  20. * timeout will trigger).
  21. *
  22. */
  23. struct link_server_plugin_t : public plugin_base_t {
  24. using plugin_base_t::plugin_base_t;
  25. /** The plugin unique identity to allow further static_cast'ing*/
  26. static const void *class_identity;
  27. const void *identity() const noexcept override;
  28. void activate(actor_base_t *actor) noexcept override;
  29. /** \brief reaction upon link request */
  30. virtual void on_link_request(message::link_request_t &message) noexcept;
  31. /** \brief reaction upon link unlink response */
  32. virtual void on_unlink_response(message::unlink_response_t &message) noexcept;
  33. /** \brief reaction upon link unlink notify */
  34. virtual void on_unlink_notify(message::unlink_notify_t &message) noexcept;
  35. bool handle_shutdown(message::shutdown_request_t *message) noexcept override;
  36. void handle_start(message::start_trigger_t *message) noexcept override;
  37. /** \brief returns true if there is any connected client */
  38. virtual bool has_clients() noexcept { return !linked_clients.empty(); }
  39. /** \brief generic non-public fields accessor */
  40. template <typename T> auto &access() noexcept;
  41. private:
  42. enum class link_state_t { PENDING, OPERATIONAL, UNLINKING };
  43. using link_request_ptr_t = intrusive_ptr_t<message::link_request_t>;
  44. using request_option_t = std::optional<request_id_t>;
  45. struct link_info_t {
  46. link_info_t(link_state_t state_, link_request_ptr_t request_) noexcept : state{state_}, request{request_} {}
  47. link_state_t state;
  48. link_request_ptr_t request;
  49. request_option_t unlink_request;
  50. };
  51. using linked_clients_t = std::unordered_map<address_ptr_t, link_info_t>;
  52. linked_clients_t linked_clients;
  53. };
  54. } // namespace rotor::plugin