|
SObjectizer
5.5
|
A new feature was introduced in v.5.5.23: envelopes with messages inside. This feature allows to send a message or signal that enveloped in a special object called envelope. An envelope can carry some additional information and can perform some actions when message/signal is delivered to a receiver.
This new feature is a low-level feature that intended to be used by SObjectizer's developers and those developers who want to extend SObjectizer functionality. It seems that ordinary users will be protected from envelope-related details by some high-level code (something like a special tools from so_5_extra).
Because of that the sense of reading the following text exists only if you want to write your own type of an envelope.
An envelope is a special case of a message. An envelope carries a message or signal (or another envelope) inside. An envelope is implemented as class derived from so_5::enveloped_msg::envelope_t.
Because an envelope is a message the delivery of an envelope is almost the same. For example, dispatchers have no knowledge about envelopes at all – they see just instances of so_5::message_t type.
Key differences in delivery process can be found in two places:
limit_then_transform).A new method has been added to so_5::abstract_message_box_t type: do_deliver_enveloped_msg. This method has the same semantic as do_deliver_message and do_deliver_service_request, but intended to be used with enveloped messages only.
If you want to send an envelope you have to pass your envelope to do_deliver_enveloped_msg method. For example:
New method do_deliver_enveloped_msg requires msg_type argument. This is a type of envelope's payload, not a type of envelope itself. For example:
There are several points in message delivery process where the payload should be extracted from an envelope:
limit_then_transform is used for overload control and count of messages of some type is exceeded the specified limit then the payload of envelope should be extracted and transformed to another message or signal;To extract the payload the corresponding evelope's hook is called.
An envelope can decide should the payload be extracted or not. It is possible that an envelope won't provide access to the payload for some reason. In that case the payload will be ignored. It means that if an envelope is delivered to a receiver but don't provide access to the payload then an event handler for the receiver won't be called (as if message was lost). The same is for transformation case: if an envelope don't provide access to the payload for limit_then_transform then message won't be transformed and will be simple thrown out.
This is the main feature of an envelope: the possibility to "hide" the payload from a receiver (or transformation procedure).
The access_hook() is called when SObjectizer need to access the payload of an enveloped message.
access_hook() can be called in different cases: when a message is delivered to a receiver, when overload reaction must be performed, when a delivery filter has to analyze the message and so on. The context of access_hook() call is identified by context argument of access_hook(). That argument can have the following values:
access_context_t::handler_found. It means that an enveloped message is delivered to a receiver and tha payload is necessary to call an event handler;access_context_t::transformation. It means that the payload of an enveloped message should be transformed to another representation. For example in the case of limit_then_transform overload reaction;access_context_t::inspection. It means that the payload of an enveloped message should be analyzed. For example, by a delivery filter.If the envelope decided that the access to the payload can be provided it should call invoke() method for invoker object (the invoker object is passed as argument to access_hook()):
Please note that access_hook() is marked as noexcept. It must not allow exceptions to leave the hook.
If an enveloped is passed to MPMC-mbox then hook methods can be called more than once. It is because here can be several receivers of the message inside the envelope.
Because envelopes can be sent to MPMC-mboxes there is a possibility that envelope's hooks will be called at the same time on different threads.
It means that envelope classes should be thread safe and should allow invocation of hooks on several threads simultaneously.
Message limits know almost nothing about envelopes. Strictly speaking only limit_then_transform knows that envelopes exist and knows how to extract of envelope's payload from an envelope. But no more.
It means that behaviour of an envelope have no influence on message limits.
For example let's consider an envelope that allows to revoke a message. Something like:
If revoke() method is called when message is waiting in receiver's queue then the message won't be delivered to the receiver (because envelope won't provide access to the payload). But the calling to revoke() do not decrement the quantity of messages on type my_message in receiver's queue. Quantity of messages will be decremented only after extraction of an envelope from receiver's queue.
It means that revoke() have no influence on message limits.
It is possible to create envelopes that holds another envelopes.
There is no need to know a type of the payload. For example this simple envelope can hold envelopes as well as messages or signals:
This is because the standard implementations of handler_invoker_t check the kind of payload. And if a payload is another envelope these implementation call appropriate hook for that envelope recursively.
An user should take care of payload kind only if he or she implements own handler_invoker_t class. In that case so_5::message_t::kind_t and so_5::message_kind() should be used.
SObjectizer v.5.5.23 doesn't provide ready to use envelopes. SObjectizer core only implements basic functionality for envelopes.
Ready to use envelopes can be found in so_5_extra library that is built on top of SObjectizer.
1.8.14