You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Historically the standard SObjectizer's timers are not truly cancel-able (revocable): a user can call timer_id_t::release() method, but if a message is already in an event_queue then it will be delivered to the receiver anyway.
After addition of enveloped messages functionality there is a way to implement almost truly cancel-able messages that can be revocable messages. It is used in so5extra's revocable timers: a delayed/periodic message is wrapped into a special envelope with an atomic flag inside, when timer is cancelled this atomic flag is dropped and the payload of an envelope is hidden (not delivered to) from the receiver. It looks like canceling the message delivery.
So the idea is: replace the default SObjectizer's implementation of delayed/periodic messages with so5extra's revocable timers.
It should not be hard because so5extra's revocable timers were designed as a drop-in replacement for standard SObjectizer's timers.
But there are some tricky moments.
The standard so_5::send_delayed doesn't return timer_id, so delivering of the delayed message won't be canceled if a user writes code like that:
But so_5::extra::revocable_timer::send_delayed returns the timer_id and if this value won't be stored then the delayed delivery will be canceled:
usingnamespaceso_5::extra::revocable_timer;
std::ignore = send_delayed<msg_check_status>(*this, 125ms); // The message will be canceled automatically.
So I see a possible solution this way:
usingnamespaceso_5::extra::revocable_timer;// Have to call `detach` method on returned timer_id_t.
send_delayed<msg_check_status>(*this, 125ms).detach(); // Now message becomes non-revocable.
Or this way
usingnamespaceso_5::extra::revocable_timer;// Have to assign the returned timer_id_t to a special "variable".
detached = send_delayed<msg_check_status>(*this, 125ms);
The second way looks more attractive for me.
Even so5extra's revocable timers are not truly revocable if multi-consumer delivery happens :(
For example:
const so_5::mbox_t mpmc_mbox = env.create_mbox(); // Ordinary MPMC mbox.
... // Several agents make subscription for a message from mpmc_mbox.auto id = so_5::extra::revocable_timer::send_delayed<msg_shutdown_the_computer>(mpmc_mbox, 500ms);
...
id.release(); // (1) Canceling the delayed delivery.
At the point (1) we can find ourselves in a case where msg_shutdown_the_computer is already pushed into receivers' event_queues. And some receivers have already received it. Canceling the delivery prevents the message from being processed by the remaining receivers, but several receivers have already processed the message and we can't revert it :(
Because implementation of such an idea may break compatibility it has to be postponed to version 5.9 (at least).
The text was updated successfully, but these errors were encountered:
Historically the standard SObjectizer's timers are not truly cancel-able (revocable): a user can call
timer_id_t::release()
method, but if a message is already in an event_queue then it will be delivered to the receiver anyway.After addition of enveloped messages functionality there is a way to implement almost truly cancel-able messages that can be revocable messages. It is used in so5extra's revocable timers: a delayed/periodic message is wrapped into a special envelope with an atomic flag inside, when timer is cancelled this atomic flag is dropped and the payload of an envelope is hidden (not delivered to) from the receiver. It looks like canceling the message delivery.
So the idea is: replace the default SObjectizer's implementation of delayed/periodic messages with so5extra's revocable timers.
It should not be hard because so5extra's revocable timers were designed as a drop-in replacement for standard SObjectizer's timers.
But there are some tricky moments.
The standard
so_5::send_delayed
doesn't return timer_id, so delivering of the delayed message won't be canceled if a user writes code like that:so_5::send_delayed<msg_check_status>(*this, 125ms);
But
so_5::extra::revocable_timer::send_delayed
returns the timer_id and if this value won't be stored then the delayed delivery will be canceled:So I see a possible solution this way:
Or this way
The second way looks more attractive for me.
Even so5extra's revocable timers are not truly revocable if multi-consumer delivery happens :(
For example:
At the point (1) we can find ourselves in a case where
msg_shutdown_the_computer
is already pushed into receivers' event_queues. And some receivers have already received it. Canceling the delivery prevents the message from being processed by the remaining receivers, but several receivers have already processed the message and we can't revert it :(Because implementation of such an idea may break compatibility it has to be postponed to version 5.9 (at least).
The text was updated successfully, but these errors were encountered: