Возможность получения мониторинговой информации о том, что происходит внутри SObjectizer Environment была добавлена довольно давно, еще в версии 5.5.4. Работает этот механизм на потактовой основе: пользователь может задать темп, с которым он хочет получать мониторинговую информацию. Например, раз в 250ms. И SObjectizer каждые 250ms будет отсылать на специальный mbox целую пачку сообщений с текущими значениями.
Со временем у этого механизма выявился небольшой недостаток: для ряда сценариев обработки мониторинговой информации было очень желательно знать, что очередной такт раздачи данных начался или закончился. В версии 5.5.18 этот недостаток был устранен. В пространство имен so_5::stats::messages добавлены новые сообщения distribution_started и distribution_finished. Сообщение distribution_started отсылается в начале каждого такта раздачи очередной порции мониторинговой информации. Фактически, это сообщение первое, которое отсылается stats_controller-ом в начале такта. Затем уже следуют сообщения от всех источников данных внутри SObjectizer Environment. А закрывает такт сообщение distribution_finished. Это последнее сообщение, после которого уже не будет никаких сообщений, относящихся к только что закончившемуся такту.
Два эти сообщения упрощают обработку сценариев, для которых требуется иметь информацию о моментах начала/завершения тактов. Например, для обновления информации на графиках или для фиксации транзакций с очередной порцией свежих данных в БД.
Под катом пример агента, который инициирует раздачу мониторинговой информации три раза в секунду, после чего обрабатывает только сообщения с данными о длине очередей заявок на рабочих нитях запущенных в SObjectizer Environment диспетчеров (для фильтрации нужных сообщений используется механизм delivery filters).
// Agent for receiving run-time monitoring information. class a_stats_listener_t : public so_5::agent_t { public : a_stats_listener_t( // Environment to work in. context_t ctx, // Address of logger. so_5::mbox_t logger ) : so_5::agent_t( ctx ) , m_logger( std::move( logger ) ) {} virtual void so_define_agent() override { using namespace so_5::stats; auto & controller = so_environment().stats_controller(); // Set up a filter for messages with run-time monitoring information. so_set_delivery_filter( // Message box to which delivery filter must be set. controller.mbox(), // Delivery predicate. []( const messages::quantity< std::size_t > & msg ) { // Process only messages related to dispatcher's queue sizes. return suffixes::work_thread_queue_size() == msg.m_suffix; } ); // We must receive messages from run-time monitor. so_default_state() .event( // This is mbox to that run-time statistic will be sent. controller.mbox(), &a_stats_listener_t::evt_quantity ) .event( controller.mbox(), [this]( const messages::distribution_started & ) { so_5::send< log_message >( m_logger, "--- DISTRIBUTION STARTED ---" ); } ) .event( controller.mbox(), [this]( const messages::distribution_finished & ) { so_5::send< log_message >( m_logger, "--- DISTRIBUTION FINISHED ---" ); } ); } virtual void so_evt_start() override { // Change the speed of run-time monitor updates. so_environment().stats_controller().set_distribution_period( std::chrono::milliseconds( 330 ) ); // Turn the run-timer monitoring on. so_environment().stats_controller().turn_on(); } private : const so_5::mbox_t m_logger; void evt_quantity( const so_5::stats::messages::quantity< std::size_t > & evt ) { std::ostringstream ss; ss << "stats: '" << evt.m_prefix << evt.m_suffix << "': " << evt.m_value; so_5::send< log_message >( m_logger, ss.str() ); } }; |
Комментариев нет:
Отправить комментарий