Advertisement
eao197

Пример для обсуждения SO-5.5.0 на LOR-е

Oct 3rd, 2014
282
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.23 KB | None | 0 0
  1. // Псевдокод event-loop-а, в котором принимаются новые подключения,
  2. // читаются данные, отслеживаются моменты отключения клиентов.
  3. void event_loop( handle_t fd, ... )
  4. {
  5.     // Окружение, в рамках которого работают агенты.
  6.     so_5::rt::environment_t & env = ...;
  7.  
  8.     // Для осуществления связи между каналами и агентами.
  9.     std::unordered_map< handle_t, so_5::rt::mbox_ref_t > channels;
  10.  
  11.     if( <новое подключение> )
  12.     {
  13.         // Создаем для него агента-обработчика.
  14.         std::unique_ptr< a_parser_t > parser{ new a_parser_t( ... ) };
  15.         // Нам нужно запомнить mbox этого агента, чтобы
  16.         // отсылать ему данные для разбора.
  17.         auto mbox = parser->so_direct_mbox();
  18.         // Агент должен быть зарегистрирован.
  19.         env->register_agent_as_coop(
  20.                 // У кооперации должно быть уникальное имя.
  21.                 // Формируем его каким-то образом.
  22.                 create_new_coop_name(...),
  23.                 // За судьбу агента отвечает SObjectizer.
  24.                 std::move( parser ) );
  25.         // Сохраняем связь между каналами и агентами.
  26.         channels.emplace( fd, mbox );
  27.     }
  28.     else if( <готовность к приему данных> )
  29.     {
  30.         // Буфер для чтения.
  31.         std::unique_ptr< msg_in_data > data{ new msg_in_data( ... ) };
  32.         // Читаем данные + какой-то контроль ошибок I/O.
  33.         read_data( fd, msg_in_data->m_buffer );
  34.         if( <чтение прошло успешно> )
  35.             // Отсылаем прочитанные данные агенту для обработки.
  36.             channels[ fd ]->deliver_message( std::move( data ) );
  37.         else
  38.         {
  39.             // Считаем, что канал закрыт.
  40.             // Агент должен завершить свою работу.
  41.             channels[ fd ]->deliver_signal< msg_channel_closed >();
  42.             // Про канал нужно забыть.
  43.             channels.erase( fd );
  44.         }
  45.     }
  46. }
  47.  
  48. // Cообщения, необходимые для агента-парсера.
  49.  
  50. // Сообщение об очередной порции данных.
  51. struct msg_in_data : public so_5::rt::message_t
  52. {
  53.     std::vector< std::uint8_t > m_data;
  54.     ... // Какой-то конструктор(ы)
  55. };
  56.  
  57. // Сигнал о том, что канал закрылся удаленной строной.
  58. struct msg_channel_closed : public so_5::rt::signal_t {};
  59.  
  60. //
  61. // Сам агент-парсер.
  62. //
  63. class a_parser_t : public so_5::rt::agent_t
  64. {
  65. public :
  66.     // Конструктор.
  67.     a_parser_t(
  68.         // Это обязательный параметр. Без него никак.
  69.         // Агент должен быть связан с тем окружением,
  70.         // в котором он будет работать.
  71.         so_5::rt::environment_t & env,
  72.         // Возможно, еще какой-то набор параметров.
  73.         ... )
  74.         :   so_5::rt::agent_t( env )
  75.         ...
  76.     {}
  77.  
  78.     // Подготовка агента к работе внутри SObjectizer.
  79.     // В данном случае только подписка на сообщения,
  80.     // которые приходят на собственный почтовый ящик агента.
  81.     virtual void so_define_agent() override
  82.     {
  83.         so_subscribe( so_direct_mbox() ).event( &a_parser_t::evt_in_data );
  84.  
  85.         so_subscribe( so_direct_mbox() )
  86.             .event( so_5::signal< msg_channel_closed >,
  87.                     &a_parser_t::evt_channel_closed );
  88.         ... // Возможно, подписка еще на какие-то сообщения.
  89.     }
  90.  
  91.     // Реакция на поступление входящих данных.
  92.     void evt_in_data( const msg_in_data & evt )
  93.     {
  94.         // Попытка разбора.
  95.         ...
  96.         if( <получены данные для zip-ования> )
  97.             // Отсылаем их следующему агенту.
  98.             m_zipper->deliver_message( new msg_data_to_zip( ... ) );
  99.     }
  100.  
  101.     // Реакция на закрытие канала.
  102.     void evt_channel_closed()
  103.     {
  104.         // Какие-то действия (логирование, отчистка ресурсов...).
  105.         ...
  106.         // Мы больше не нужны, завершаем свою работу.
  107.         so_deregister_agent_coop_normally();
  108.     }
  109.  
  110. private :
  111.     ... // Какие-то атрибуты, необходимые для разбора входящих данных.
  112.     // Почтовый ящик агента, который занимается zip-ованием.
  113.     const so_5::rt::mbox_ref_t m_zipper;
  114. };
  115.  
  116. // Сообщение о необходимости зазиповать данные.
  117. struct msg_data_to_zip : public so_5::rt::message_t
  118. {
  119.     ... // Какие-то потроха: сами данные, информация о том,
  120.         // куда их отсылать дальше и т.д.
  121.         // + Конструктор(ы).
  122. };
  123.  
  124. //
  125. // Агент для зипования данных.
  126. //
  127. class a_zipper_t : public so_5::rt::agent_t
  128. {
  129. public :
  130.     // Опять же нужен конструктор.
  131.     a_zipper_t( so_5::rt::environment_t & env,
  132.         // + какие-то параметры для агента.
  133.         ... )
  134.         :   so_5::rt::agent_t( env )
  135.         ...
  136.     {}
  137.  
  138.     // Настройка агента для работы внутри SObjectizer.
  139.     virtual void so_define_agent() override
  140.     {
  141.         // Подписываемся на сообщение для собственного почтового ящика.
  142.         // При этом считаем, что zip-ование -- это stateless процедура,
  143.         // поэтому указываем, что обработчик thread-safe и он может
  144.         // задействоваться для параллельной обработки событий.
  145.         so_subscribe( so_direct_mbox() )
  146.             .event( &a_zipper_t::evt_zip_data, so_5::thread_safe );
  147.         ...
  148.     }
  149.  
  150.     // Выполнение зипования данных и их последующая отсылка куда-то.
  151.     void evt_zip_data( const msg_data_to_zip & evt )
  152.     {
  153.         ...
  154.     }
  155. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement