-
Notifications
You must be signed in to change notification settings - Fork 5
so5extra 1.5 Enveloped Msg Time Limited Delivery
The time-limited message delivery can be necessary in cases where the processing of a message has sense only if that processing will be performed before some deadline. For example:
class request_handler final : public so_5::agent_t {
struct deadline final : public so_5::signal_t {};
...
void so_evt_start() override {
// Limit request-processing time.
so_5::send_delayed<deadline>(*this, 10s);
...
// Request some action from another agent.
so_5::send<check_user>(user_checker_, ...);
}
...
void on_deadline(mhood_t<deadline>) {
... // Send negative response.
// Finish work.
so_deregister_agent_coop_normally();
}
};
In this example, a message check_user
should be processed in 10s. Otherwise, the processing of that message has no sense. But because the message was sent it will be processed sometime in the future, even if there is no sender anymore.
We can use revocable message in that case (see Revocable Messages for more details):
class request_handler final : public so_5::agent_t {
struct deadline final : public so_5::signal_t {};
...
so_5::extra::revocable_msg::delivery_id_t check_user_msg_id_;
...
void so_evt_start() override {
// Limit request-processing time.
so_5::send_delayed<deadline>(*this, 10s);
...
// Request some action from another agent.
check_user_msg_id_ = so_5::extra::revocable_msg::send<check_user>(user_checker_, ...);
}
...
void on_deadline(mhood_t<deadline>) {
// Remove check_user message because it processing is not needed anymore.
check_user_msg_id_.revoke();
... // Send negative response.
// Finish work.
so_deregister_agent_coop_normally();
}
};
But there is a more easy way: the usage of time-limited delivery:
class request_handler final : public so_5::agent_t {
struct deadline final : public so_5::signal_t {};
...
void so_evt_start() override {
// Limit request-processing time.
so_5::send_delayed<deadline>(*this, 10s);
...
// Request some action from another agent.
so_5::extra::enveloped_msg::make<check_user>(...)
.envelope<so_5::extra::enveloped_msg::time_limited_delivery_t>(10s)
.send_to(user_checker_);
}
...
void on_deadline(mhood_t<deadline>) {
... // Send negative response.
// Finish work.
so_deregister_agent_coop_normally();
}
};
The message check_user
will be automatically ignored if it is not delivered in 10s.
The stuff described below is defined in so_5_extra/enveloped_msg/time_limited_delivery.hpp
header file. And header file so_5_extra/enveloped_msg/send_functions.hpp
may be necessary for sending time-limited message. So to use this functionality it is necessary to include several header files:
#include <so_5_extra/enveloped_msg/time_limited_delivery.hpp>
#include <so_5_extra/enveloped_msg/send_functions.hpp>
#include <so_5/all.hpp>
The simplest way of sending a message with time-limited delivery is to use make()
-envelope()
-send_to()
chain (see Sending of Envelopes for more details):
so_5::extra::enveloped_msg::make<my_message>(...)
.envelope<so_5::extra::enveloped_msg::time_limited_delivery>(deadline_point)
.send_to(mbox);
There are two ways to specify a deadline for time-limited delivery:
As an absolute (wallclock) time point:
so_5::extra::enveloped_msg::make<my_message>(...)
.envelope<so_5::extra::enveloped_msg::time_limited_delivery>(
std::chrono::steady_clock::now() + 20s)
.send_to(mbox);
As a time interval from the current time point. The example above can be rewritten this way:
so_5::extra::enveloped_msg::make<my_message>(...)
.envelope<so_5::extra::enveloped_msg::time_limited_delivery>(20s)
.send_to(mbox);