| Author: | Евгений Охотников |
|---|---|
| Contact: | eao197 at intervale dot ru; eao197 at yahoo dot com |
| Version: | 1.0 |
| Date: | 2007.09.15 |
Начиная с версии 4.2.6 контроль за интенсивностью входящего трафика (как raw, так и sop) в SObjectizer выполняется с помощью т.н. порогов ввода-вывода. Порог -- это пара значений <количество пакетов, объем пакетов>. Транспортный агент подсчитывает, сколько пакетов он извлек из канала и их суммарный объем. Как только какое-то из этих значений превышает соответствующее значение в заданном для канала пороге объявляется, что порог входящих данных превышен и канал блокируется. Чтение из канала останавливается до разблокирования канала, которое кто-то должен выполнить посредством отсылки сообщения msg_unblock_channel транспортному агенту. После разблокирования канала транспортный агент обнуляет свои счетчики и возобновляет операции чтения.
В версиях до 4.4.0-beta3 (включительно) контроль за входящим трафиком осуществлялся следующим образом:
Подход за контролем интенсивности входящего SOP-трафика в предшествующих версиях SObjectizer был не самым удачным, поскольку агент-коммуникатор мог разбирать входящие пакеты быстрее, чем прикладные агенты успевали бы обрабатывать содержащиеся в них сообщения. Но это было хоть что-то.
В очередной бета-версии 4.4.0 транспортная подсистема SObjectizer очень серьезно перестраивается. Так, теперь транспортные агенты сами будут разбирать входящие пакеты и генерировать содержащиеся в них сообщения. Соответственно, агент-коммуникатор уже не сможет управлять интенсивностью входящего SOP-трафика, поскольку транспортный агент даже не сможет никому сказать, что канал оказался заблокированным. А это ведет к том, что при интенсивном входящем SOP-трафике транспортный агент, работающий на отдельной нити (активный или член активной группы) способен вычитывать и разбирать входящие пакеты быстрее, чем прикладные агенты будут обрабатывать содержащиеся в этих пакетах сообщения.
Таким образом требуется найти хороший и прозрачный способ управления интенсивностью входящего трафика.
Предлагаемое решение заключается в следующем:
Данный способ позволяет гарантировать, что входящий SOP-трафик из конкретного канала будет остановлен до тех пор, пока приложение не обработает или не проигнорирует все ранее прочитанные входящие сообщения из этого канала.
Отложенные и периодические сообщения не учитываются, что оставляет потенциальную возможность перегрузить приложение, если во входящем трафике будет содержаться большое количество подобных сообщений.
Реализовать данную схему можно добавив в SObjectizer интерфейс:
class msg_destroy_notificator_t
{
public :
virtual void
on_destroy() = 0;
};
И позволив назначение реализующих данный интерфейс объектов экземплярам класса so_4::rt::msg_data_t (или so_4::rt::impl::msg_data_impl_t). Например, таким образом:
class msg_data_t
{
private :
...
std::auto_ptr< msg_destroy_notificator_t > m_destroy_notificator;
public :
...
~msg_data_t()
{
if( m_destroy_notificator.get() )
m_destroy_notificator->on_destroy();
}
...
void
set_destroy_notificator(
std::auto_ptr< msg_destroy_notificator_t > destroy_notificator )
{
m_destroy_notificator = destroy_notificator;
}
...
};
Таким образом обеспечивается автоматическое задействование объекта-уведомителя при разрушении экземпляра msg_data_t (т.е. сразу после завершения обработки сообщения всеми его подписчиками).