SObjectizer-5 | SObjectizer-4 |
---|---|
class a_processor_t : public so_sysconf_3::agent_with_fatal_state_t { public : /*! * \name Типы сообщений, которыми владеет данный агент. * \{ */ //! Принудительная переконфигурация агента. struct reconfigure_t { std::string m_cfg_file_name }; /*! * \} */ /*! * \name Домены сообщений этого агента. * \{ */ // Пояснение: домены определяют сообщения, которыми владеет // данный агент. Т.е. либо их отсылает он сам, либо их // отсылают от его имени. // // Пояснение: поскольку ряд сообщений не передают данных, // а являются сигналами, то для них не нужно определять // каких-либо пустых структур (как в SO4). И для декларации // их домена используется специальный тип signal_domain_t. //! Сигнал о необходимости сборки мусора. so5::signal_domain_t msg_garbage_collection; //! Сигнал о необходимости контроля за дочерними процессами. so5::signal_domain_t msg_control_child_processes; //! Сигнал о необходимости обновления мониторинговой информации. so5::signal_domain_t msg_update_gemont_data; //! Сообщение о необходимости переконфигурировать агента. so5::message_domain_t< reconfigure_t > msg_reconfigure; /*! * \} */ /*! * \name Слоты сообщений этого агента. */ // Пояснение: слоты определяют сообщения, которые будет // получать данный агент. // // Пояснение: для сообщений-сигналов используется // специальный тип signal_slot_t. so5::signal_slot_t slot_garbage_collection; so5::signal_slot_t slot_control_child_processes; so5::signal_slot_t slot_update_gemont_data; so5::message_slot_t< reconfigure_t > slot_reconfigure; so5::message_slot_t< a_child_iface_t::hello_t > slot_child_hello; so5::message_slot_t< a_communicator_t::client_disconnected_t > slot_client_disconnected; so5::message_slot_t< a_request_producer_t::phase_c_t > slot_phase_c; so5::message_slot_t< a_child_iface_t::phase_c_result_t > slot_phase_c_result; so5::message_slot_t< a_request_producer_t::phase_p_t > slot_phase_p; so5::message_slot_t< a_child_iface_t::phase_p_result_t > slot_phase_p_result; /*! * \} */ /*! * \name Состояния данного агента. * \{ */ //! Единственное собственное состояние. so5::state_t st_normal; /*! * \} */ //! В конструкторе все домены, слоты и состояния должны //! быть проинициализированны. a_processor_t( /* какие-то параметры */ ) : // Инициализация базового типа и каких-то других атрибутов. // Инициализация доменов сообщений. Каждый домен должен // быть связан с агентом. , msg_garbage_collection( so_self() ) , msg_control_child_processes( so_self() ) , msg_update_gemont_data( so_self() ) , msg_reconfigure( so_self() ) // Инициализация слотов сообщений. // Часть слотов сразу связывается с конкретными доменами. , slot_garbage_collection( so_self(), msg_garbage_collection ) , slot_control_child_processes( so_self(), msg_control_child_processes ) , slot_update_gemont_data( so_self(), msg_update_gemont_data ) , slot_reconfigure( so_self(), msg_reconfigure ) // Остальные слоты будут связаны с сообщениями позже. , slot_child_hello( so_self() ) , slot_client_disconnected( so_self() ) , slot_phase_c( so_self() ) , slot_phase_c_result( so_self() ) , slot_phase_p( so_self() ) , slot_phase_p_result( so_self() ) // Инициализация состояний. , st_normal( so_self() ) {} //! Описание агента для SObjectizer. virtual void so_define_agent() { // Начальным состояние должно быть состояние st_normal. // Если этого не сказать, то начальным будет унаследованное // из agent_with_fatal_state_t состояние st_fatal. so_initial_state( st_normal ); // Определение состояние st_normal. st_normal .on( slot_garbage_collection, &a_processor_t::evt_garbage_collection ) .on( slot_control_child_processes, &a_processor_t::evt_control_child_processes ) .on( slot_update_gemont_data, &a_processor_t::evt_update_gemont_data ) .on( slot_reconfigure, &a_processor_t::evt_reconfigure ) .on( slot_child_hello, &a_processor_t::evt_child_hello ) .on( slot_client_disconnected, &a_processor_t::evt_client_disconnected ) .on( slot_phase_c, &a_processor_t::evt_phase_c ) .on( slot_phase_c_result, &a_processor_t::evt_phase_c_result ) .on( slot_phase_p, &a_processor_t::evt_phase_p ) .on( slot_phase_p_result, &a_processor_t::evt_phase_p_result ); // Определение состояния st_fatal. // В нем должны быть определены реакции на новые сообщения // (которых не было у агента agent_with_fatal_state_t). st_fatal .on( slot_garbage_collection, SO_IGNORE_MESSAGE ) .on( slot_control_child_processes, SO_IGNORE_MESSAGE ) .on( slot_update_gemont_data, SO_IGNORE_MESSAGE ) .on( slot_reconfigure, SO_IGNORE_MESSAGE ) .on( slot_child_hello, SO_IGNORE_MESSAGE ) .on( slot_client_disconnected, SO_IGNORE_MESSAGE ) .on( slot_phase_c, SO_IGNORE_MESSAGE ) .on( slot_phase_c_result, SO_IGNORE_MESSAGE ) .on( slot_phase_p, SO_IGNORE_MESSAGE ) .on( slot_phase_p_result, SO_IGNORE_MESSAGE ); // Поскольку несколько слотов сообщения связаны с // чужими сообщениями, то их сейчас нужно подписать. so5::agent_reference_t< a_child_iface_t > child_iface( so5::lockup_agent< a_child_iface_t >( "a_child_iface" ) ); slot_child_hello.connect( child_iface->msg_hello ); slot_phase_c_result.connect( child_iface->msg_phase_c_result ); slot_phase_p_result.connect( child_iface->msg_phase_p_result ); so5::agent_reference_t< a_request_producer_t > producer( so5::lockup_agent< a_request_producer_t >( "a_producer" ) ); slot_phase_c.connect( producer->msg_phase_c ); slot_phase_p.connect( producer->msg_phase_p ); slot_client_disconnected.connect( so5::lockup_agent< a_communicator_t >( "a_communicator" )-> msg_client_disconnected ); } /*! * \name Обработчики событий. * \{ */ void evt_garbage_collection(); void evt_control_child_processes(); void evt_update_gemont_data(); void evt_reconfigure( const reconfigure_t & ); void evt_child_hello( const so5::event_data_t &, const a_child_iface_t::hello_t & ); void evt_client_disconnected( const a_communicator_t::client_disconnected_t & ); void evt_phase_c( const a_request_producer_t::phase_c_t & ); void evt_phase_c_result( const so5::event_data_t &, const a_child_iface_t::phase_c_result_t & ); void evt_phase_p( const a_request_producer_t::phase_p_t & ); void evt_phase_p_result( const so5::event_data_t &, const a_child_iface_t::phase_c_result_t & ); /*! * \} */ }; |
class a_processor_t : public so_sysconf_2::agent_with_fatal_state_t { public : /*! * \name Сообщения агента. * \{ */ //! Периодическое сообщение о необходимости сборки мусора. struct msg_garbage_collection {}; //! Периодическое сообщение для проверки того, что дочерние //! процессы работают. struct msg_control_child_processes {}; //! Периодическое сообщение для обновления мониторинговой информации. struct msg_update_gemont_data {}; //! Сообщение для перезагрузки конфигурации. struct msg_reconfigure { std::string m_cfg_file_name; }; /*! * \} */ //! Конструктор агента. a_processor_t( /* какие-то параметры */ ) : // Инициализация базового типа и каких-то других атрибутов. {} // Этот метод должен быть задекларирован, // но его реализация спрятана в макросах SOL4_CLASS_*. virtual const char * so_query_type() const; //! Подписка событий агента. virtual void so_on_subscription() { so_4::api::make_global_agent( a_child_iface_t::agent_name(), a_child_iface_t::agent_type() ); so_subscribe( "evt_start", so_4::rt::sobjectizer_agent_name(), "msg_start" ); so_subscribe( "evt_child_process_hello", a_child_iface_t::agent_name(), "msg_hello" ); so_subscribe( "evt_client_disconnected", so_4::rt::comm::communicator_agent_name(), "msg_client_disconnected" ); so_subscribe( "evt_phase_c", a_request_producer_t::agent_name(), "msg_phase_c" ); so_subscribe( "evt_phase_c_result_received", a_child_iface_t::agent_name(), "msg_phase_c_result" ); so_subscribe( "evt_phase_p", a_request_producer_t::agent_name(), "msg_phase_p" ); so_subscribe( "evt_phase_p_result_received", a_child_iface_t::agent_name(), "msg_phase_p_result" ); so_subscribe( "evt_control_child_processes", "msg_control_child_processes" ); so_subscribe( "evt_garbage_collection", "msg_garbage_collection" ); so_subscribe( "evt_update_gemont_data", "msg_update_gemont_data" ); so_subscribe( "evt_reconfigure", "msg_reconfigure" ); } /*! * \name Обработчики событий. * \{ */ void evt_start(); void evt_child_process_hello( const so_4::rt::event_data_t & event_data, const a_child_iface_t::msg_hello & cmd ); void evt_client_disconnected( const so_4::rt::comm::msg_client_disconnected & cmd ); void evt_phase_c( const a_request_producer_t::msg_phase_c & cmd ); void evt_phase_c_result_received( const so_4::rt::event_data_t & event_data, const a_child_iface_t::msg_phase_c_result & cmd ); void evt_phase_p( const a_request_producer_t::msg_phase_p & cmd ); void evt_phase_p_result_received( const so_4::rt::event_data_t & event_data, const a_child_iface_t::msg_phase_p_result & cmd ); void evt_control_child_processes(); void evt_garbage_collection(); void evt_update_gemont_data(); void evt_reconfigure( const msg_reconfigure & cmd ); /*! * \} */ }; // Описание класса агента для SObjectizer. // Должна быть сделана в .cpp файле с помощью макрсов. SOL4_CLASS_START( sample_project::child_processor::processor::a_processor_t ) SOL4_SUPER_CLASS( so_sysconf_2::agent_with_fatal_state_t ) SOL4_MSG_START( msg_garbage_collection, sample_project::child_processor::processor::a_processor_t:: msg_garbage_collection ) SOL4_MSG_FINISH() SOL4_MSG_START( msg_control_child_processes, sample_project::child_processor::processor::a_processor_t:: msg_control_child_processes ) SOL4_MSG_FINISH() SOL4_MSG_START( msg_update_gemont_data, sample_project::child_processor::processor::a_processor_t:: msg_update_gemont_data ) SOL4_MSG_FINISH() SOL4_MSG_START( msg_reconfigure, sample_project::child_processor::processor::a_processor_t:: msg_reconfigure ) SOL4_MSG_FIELD( m_cfg_file_name ) SOL4_MSG_FINISH() SOL4_EVENT( evt_start ) SOL4_EVENT_STC( evt_child_process_hello, sample_project::child_processor::child_iface::a_child_iface_t:: msg_hello ) SOL4_EVENT_STC( evt_phase_c, a_request_producer_t::msg_phase_c ) SOL4_EVENT_STC( evt_phase_c_result_received, sample_project::child_processor::child_iface::a_child_iface_t:: msg_phase_c_result ) SOL4_EVENT_STC( evt_client_disconnected, so_4::rt::comm::msg_client_disconnected ) SOL4_EVENT_STC( evt_phase_p, a_request_producer_t::msg_phase_p ) SOL4_EVENT_STC( evt_phase_p_result_received, sample_project::child_processor::child_iface::a_child_iface_t:: msg_phase_p_result ) SOL4_EVENT( evt_control_child_processes ) SOL4_EVENT( evt_garbage_collection ) SOL4_EVENT( evt_update_gemont_data ) SOL4_EVENT_STC( evt_reconfigure, sample_project::child_processor::processor::a_processor_t:: msg_reconfigure ) SOL4_INITIAL_STATE( st_normal ) SOL4_STATE_START( st_normal ) SOL4_STATE_EVENT( evt_start ) SOL4_STATE_EVENT( evt_child_process_hello ) SOL4_STATE_EVENT( evt_client_disconnected ) SOL4_STATE_EVENT( evt_phase_c ) SOL4_STATE_EVENT( evt_phase_c_result_received ) SOL4_STATE_EVENT( evt_phase_p ) SOL4_STATE_EVENT( evt_phase_p_result_received ) SOL4_STATE_EVENT( evt_control_child_processes ) SOL4_STATE_EVENT( evt_garbage_collection ) SOL4_STATE_EVENT( evt_update_gemont_data ) SOL4_STATE_EVENT( evt_reconfigure ) SOL4_STATE_FINISH() SOL4_CLASS_FINISH() |