9 #ifndef EAGINE_MESSAGE_BUS_SERVICE_PING_PONG_HPP
10 #define EAGINE_MESSAGE_BUS_SERVICE_PING_PONG_HPP
12 #include "../../bool_aggregate.hpp"
13 #include "../../maybe_unused.hpp"
14 #include "../serialize.hpp"
15 #include "../subscriber.hpp"
21 template <
typename Base = subscriber>
22 class pingable :
public Base {
23 using This = pingable;
35 virtual auto respond_to_ping(
39 EAGINE_MAYBE_UNUSED(pinger_id);
44 auto _handle_ping(
const message_context&, stored_message& message) ->
bool {
48 this->verify_bits(message))) {
49 this->
bus().respond_to(message, EAGINE_MSGBUS_ID(pong), {});
55 template <
typename Base = subscriber>
58 ,
protected std::chrono::steady_clock {
62 std::vector<std::tuple<identifier_t, message_sequence_t, timeout>>
75 static constexpr
auto ping_msg_id() noexcept {
76 return EAGINE_MSGBUS_ID(ping);
79 void query_pingables() {
80 this->
bus().query_subscribers_of(ping_msg_id());
83 void ping(
identifier_t pingable_id, std::chrono::milliseconds max_time) {
85 auto msg_id{EAGINE_MSGBUS_ID(ping)};
86 message.set_target_id(pingable_id);
88 this->
bus().set_next_sequence_id(msg_id, message);
89 this->
bus().post(msg_id, message);
90 _pending.emplace_back(
message.target_id,
message.sequence_no, max_time);
94 ping(pingable_id, std::chrono::milliseconds{5000});
98 some_true something_done{};
99 something_done(Base::update());
105 [
this, &something_done](
auto& entry) {
106 auto& [pingable_id, sequence_no, ping_time] = entry;
107 if(ping_time.is_expired()) {
111 std::chrono::duration_cast<std::chrono::microseconds>(
112 ping_time.elapsed_time()));
119 return something_done;
122 auto has_pending_pings() const noexcept ->
bool {
123 return !_pending.empty();
126 virtual void on_ping_response(
129 std::chrono::microseconds age,
132 virtual void on_ping_timeout(
135 std::chrono::microseconds age) = 0;
138 auto _handle_pong(
const message_context&, stored_message& message) ->
bool {
143 [
this, &message](
auto& entry) {
144 auto& [pingable_id, sequence_no, ping_time] = entry;
145 const bool is_response = (message.source_id == pingable_id) &&
146 (message.sequence_no == sequence_no);
151 std::chrono::duration_cast<std::chrono::microseconds>(
152 ping_time.elapsed_time()),
153 this->verify_bits(message));
165 #endif // EAGINE_MESSAGE_BUS_SERVICE_PING_PONG_HPP