so_4: Версия 4.2.6. Диспетчер с активными группами

В v.4.2.6 в SObjectizer добавлен новый тип диспетчера -- диспетчер с активными группами. От диспетчера с активными объектами новый диспетчер отличается тем, что отдельная рабочая нить и очередь событий выделяется не одному агенту, а группе агентов, называемой активной группой.

Необходимость в диспетчере с активными группами возникла в результате практического использования SObjectizer-а. Довольно часто необходимо было создавать кооперации агентов, занимающихся ретрансляцией какой-либо информации. Например, агент A должен был установить исходящее HTTP соединение с узлом U1, а затем передать полученные данные агенту B. Который, в свою очередь, устанавливает исходящее HTTPS соединение с узлом U2 и передает полученные данные на этот узел. За успешностью выполнения этих действий следит агент C, который может указать агенту A устанавливать соединение не с узлом U1, а с U3. Либо может заставить агент B повторить доставку на узел U2, если предыдущая доставка завершилась неудачно.

Поскольку выполнение запросов по исходящим HTTP (HTTPS) соединениям является синхронной операцией, необходимо, чтобы агенты A и B обладали собственными рабочими нитями. Но агенты A и B никогда не работают одновременно, т.к. агенту B необходим результат выполнения операции агентом A. Поэтому не выгодно делать агенты A и B активными объектами и выделять каждому из них отдельную нить.

В этом случае выгоднее использовать активную группу, которая обязательно будет содержать агентов A, B и, возможно, агента C. Все эти агенты будут работать на контексте свой нити, что позволит им осуществлять свои HTTP (HTTPS) взаимодействия не оказывая влияния на остальных агентов приложения. При этом используется всего одна рабочая нить, а не две, как в случае с активными объектами.

Диспетчер с активными группами не требует, чтобы все агенты группы входили в одну кооперацию SObjectizer-а -- членами активной группы могут быть агенты, входящие в различные кооперации.

Не требуется, чтобы члены активной группы появлялись и исчезали в SObjectizer Run-Time одновременно. Ресурсы для новой активной группы диспетчер создает как только в SObjectizer Run-Time появляется первый агент группы и уничтожает ресурсы, как только из SObjectizer Run-Time исчезает последний агент этой группы.

Создание диспетчера

Диспетчер с активными группами не является полностью самодостаточным диспетчером. Он обрабатывает события только агентов, которые входят в активные группы. Для обработки событий остальных агентов, а так же отложенных и переодических сообщений, необходим дополнительный, т.н. подчиненный диспетчер, который передается как параметр при создании диспетчера с активными группами.

Это позволяет объединять диспетчер с активными группами с любыми другими диспетчерами. Например, в качестве подчиненного можно указать диспетчер с одной рабочей нитью. Тогда все агенты, не принадлежащие активным группам, будут работать на контексте одной нити.

Можно в качестве подчиненного указать диспетчер с активными объектами. Тогда члены активных групп будут работать на своих нитях, активные агенты на своих, а все остальные агенты -- на одной общей нити. Такое сочетание диспетчера с активными группами и диспетчера с активными объектами может оказаться очень удобным для перевода уже существующих приложений на новую версию SObjectizer-а, поскольку диспетчер с активными агентами уже используется очень широко.

Вот пример кода, который создает диспетчер с активными группами, указывая ему в качестве подчиненного диспетчер с активными объектами:

so_4::disp::active_group::create_disp(
  so_4::disp::active_obj::create_disp(
    // Таймер будет уничтожен диспетчером.
    so_4::timer_thread::simple::create_timer_thread(),
    so_4::auto_destroy_timer ) );

Включение агента в активную группу

Для того, чтобы агент включить в какую-либо активную группу необходимо до регистрации агента включить в список его свойств свойство, возвращаемое функцией so_4::disp::active_group::create_active_group_traits(), передав ей в качестве параметра имя активной группы. Например,
class my_agent_t : public so_4::rt::agent_t
{
  typedef so_4::rt::agent_t base_type_t;
  public :
    my_agent_t( const char * agent_name ) :
      base_type_t( agent_name )
    {
      so_add_destroyable_traits(
        so_4::disp::active_group::create_active_group_traits(
          "my_active_group" ) );
    }
  ...
};

Внимание:
Функция so_4::disp::active_group::create_active_group_traits() возвращает указатель на динамически созданный объект-свойство. Поэтому этот объект должен добавляться в список свойств агента только с использованием метода so_4::rt::agent_t::so_add_destroyable_traits().

Документация по SObjectizer v.4.4 'Тебуломста'. Последние изменения: Thu Sep 18 10:26:48 2008. Создано системой  doxygen1.5.6 Intervale SourceForge.net Logo