-
Notifications
You must be signed in to change notification settings - Fork 5
so5extra 1.3 Enveloped Msg Sending
Sending an enveloped message/signal is not an easy task without special tools. SObjectizer Core doesn't provide ready-to-use tools for simplification of sending of enveloped messages. Reimplementation of send()
functions (like it is done for Revocable Messages and Revocable Timers) is a boring and complex task. Because of that, there is a need for some tool(s) that allows to:
- creation of message to be sent as payload inside an envelope;
- creation of an envelope with this message inside;
- sending this envelope to an appropriate destination (including
send_delayed
andsend_periodic
functionality).
Since v.1.2.0 so5extra provides a family of make()
-envelope()
-send_to()
functions those can be used as such tools.
The stuff described below is defined in so_5_extra/enveloped_msg/send_functions.hpp
header file. So to use this functionality it is necessary to include that file and so_5/all.hpp
file:
#include <so_5_extra/enveloped_msg/send_functions.hpp>
#include <so_5/all.hpp>
To make, envelope and then send an enveloped message it is necessary to use chain of make()
, envelope()
and send_to()
functions. For example:
// Create message of type my_message, envelop it into my_envelope
// and then send it to the mbox mb1.
so_5::mbox_t mb1 = ...;
so_5::extra::enveloped_msg::make<my_message>(...)
.envelope<my_envelope>(...)
.send_to(mb1);
This chains creates an instance of my_message
class (this is performed by make()
call). Then the message created is enveloped into a new envelope of type my_envelope
(this is performed by envelope()
call). And then the envelope is sent to mbox mb1
.
There are several forms of send_to()
functions, including send_delayed_to()
and send_periodic_to()
:
// Create message of type my_message, envelop it into my_envelope
// and then send it to the mchain ch1.
so_5::mchain_t ch1 = ...;
so_5::extra::enveloped_msg::make<my_message>(...)
.envelope<my_envelope>(...)
.send_to(ch1);
// Create message of type my_message, envelop it into my_envelope
// and then send it to the direct mbox of the agent a1.
so_5::agent_t & a1 = ...;
so_5::extra::enveloped_msg::make<my_message>(...)
.envelope<my_envelope>(...)
.send_to(a1);
// Create message of type my_message, envelop it into my_envelope
// and then send it to the mbox mb1 as delayed message.
so_5::mbox_t mb1 = ...;
so_5::extra::enveloped_msg::make<my_message>(...)
.envelope<my_envelope>(...)
.send_delayed_to(mb1, 10s);
// Create message of type my_message, envelop it into my_envelope
// and then send it to the mchain ch1 as delayed message.
so_5::mchain_t ch1 = ...;
so_5::extra::enveloped_msg::make<my_message>(...)
.envelope<my_envelope>(...)
.send_delayed_to(ch1, 10s);
// Create message of type my_message, envelop it into my_envelope
// and then send it to the direct mbox of the agent a1 as delayed message.
so_5::agent_t & a1 = ...;
so_5::extra::enveloped_msg::make<my_message>(...)
.envelope<my_envelope>(...)
.send_delayed_to(a1, 10s);
// Create message of type my_message, envelop it into my_envelope
// and then send it to the mbox mb1 as periodic message.
so_5::mbox_t mb1 = ...;
auto timer_id = so_5::extra::enveloped_msg::make<my_message>(...)
.envelope<my_envelope>(...)
.send_periodic_to(mb1, 10s, 30s);
// Create message of type my_message, envelop it into my_envelope
// and then send it to the mchain ch1 as delayed message.
so_5::mchain_t ch1 = ...;
auto timer_id = so_5::extra::enveloped_msg::make<my_message>(...)
.envelope<my_envelope>(...)
.send_periodic_to(ch1, 10s, 30s);
// Create message of type my_message, envelop it into my_envelope
// and then send it to the direct mbox of the agent a1 as delayed message.
so_5::agent_t & a1 = ...;
auto timer_id = so_5::extra::enveloped_msg::make<my_message>(...)
.envelope<my_envelope>(...)
.send_periodic_to(a1, 10s, 30s);
There can be several calls to envelope()
. It allows to envelop an envelope into another envelope:
so_5::extra::enveloped_msg::make<my_message>(...)
.envelope<inner_envelope_type>(...)
.envelope<outer_envelope_type>(...)
.send_to(mbox);
In that case, an instance of my_message
will be enveloped into an envelope of type inner_envelope_type
. And envelope of type inner_envelope_type
will be enveloped into an envelope of type outer_envelope_type
.
There is a requirement for envelope's constructors: the first argument of a constructor should be of type so_5::message_ref_t
or const so_5::message_ref_t&
. This argument is used to passing the payload into an envelope. All other arguments of a constructor can be arbitrary, but they should match to arguments passed to envelope()
method.
For example:
class my_envelope final : public so_5::extra::enveloped_msg::just_envelope_t {
using base_type = so_5::extra::enveloped_msg::just_envelope_t;
std::chrono::steady_clock::time_point not_before_;
std::chrono::steady_clock::time_point not_after_;
public:
my_envelope(
so_5::message_ref_t payload,
std::chrono::steady_clock::time_point not_before,
std::chrono::steady_clock::time_point not_after)
: base_type{std::move(payload)}
, not_before_{not_before}, not_after_{not_after}
{}
...
};
...
const auto now = std::chrono::steady_clock::now();
so_5::extra::enveloped_msg::make<my_message>(...)
.envelope<my_envelope>(now+10s, now+1m)
.send_to(mbox);