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 (т.е. сразу после завершения обработки сообщения всеми его подписчиками).