11 #include <so_5_extra/error_ranges.hpp> 13 #include <so_5/rt/h/disp_binder.hpp> 14 #include <so_5/rt/h/send_functions.hpp> 16 #include <so_5/disp/reuse/h/work_thread_activity_tracking.hpp> 17 #include <so_5/disp/reuse/h/disp_binder_helpers.hpp> 18 #include <so_5/disp/reuse/h/data_source_prefix_helpers.hpp> 20 #include <so_5/rt/stats/h/repository.hpp> 21 #include <so_5/rt/stats/h/messages.hpp> 22 #include <so_5/rt/stats/h/std_names.hpp> 23 #include <so_5/rt/stats/impl/h/activity_tracking.hpp> 25 #include <so_5/details/h/invoke_noexcept_code.hpp> 26 #include <so_5/details/h/rollback_on_exception.hpp> 27 #include <so_5/details/h/abort_on_fatal_error.hpp> 29 #include <so_5/h/outliving.hpp> 31 #include <asio/io_context.hpp> 32 #include <asio/io_context_strand.hpp> 33 #include <asio/post.hpp> 90 std::swap( a.m_thread_count, b.m_thread_count );
91 std::swap( a.m_io_context, b.m_io_context );
115 m_thread_count = count;
123 return m_thread_count;
145 ::asio::io_context & service )
147 m_io_context = std::shared_ptr< ::asio::io_context >(
148 std::addressof( service ),
150 [](::asio::io_context *) {} );
162 std::shared_ptr< ::asio::io_context > service )
164 m_io_context = std::move(service);
178 m_io_context = std::make_shared< ::asio::io_context >();
359 on_demand( execution_demand_t demand )
noexcept = 0;
380 template<
typename Derived,
typename... Args >
386 ::asio::io_context & io_svc,
408 log_stream <<
"An exception caught in work thread " 409 "of so_5::extra::disp::asio_thread_pool dispatcher." 419 log_stream <<
"An unknown exception caught in work thread " 420 "of so_5::extra::disp::asio_thread_pool dispatcher." 431 ptr()->on_demand( std::move(demand) );
453 on_demand( execution_demand_t demand )
noexcept override 455 demand.call_handler( thread_id() );
494 m_thread_id = std::move(tid);
512 m_work_activity.start();
521 m_work_activity.stop();
530 ::so_5::stats::work_thread_activity_stats_t result;
531 result.m_working_stats = m_work_activity.take_stats();
555 outliving_reference_t< work_thread_activity_collector_t > activity_stats )
559 m_activity_stats.get().setup_thread_id( thread_id() );
566 on_demand( execution_demand_t demand )
noexcept override 568 m_activity_stats.get().activity_started();
570 demand.call_handler( thread_id() );
572 m_activity_stats.get().activity_finished();
605 start( environment_t & env )
override 607 data_source().start( outliving_mutable(env.stats_repository()) );
609 ::so_5::details::do_with_rollback_on_exception(
610 [&] { launch_work_threads(env); },
611 [
this] { data_source().stop(); } );
617 ::so_5::details::invoke_noexcept_code( [
this] {
619 m_io_context->stop();
626 ::so_5::details::invoke_noexcept_code( [
this] {
630 data_source().stop();
636 const std::string & name_base )
override 638 data_source().set_data_sources_name_base( name_base );
656 return m_demands_counter;
677 #if defined(__clang__
) 678 #pragma clang diagnostic push 679 #pragma clang diagnostic ignored "-Wnon-virtual-dtor" 710 const auto agents_count = m_dispatcher.m_agents_bound.load(
711 std::memory_order_acquire );
713 const auto demands_count = m_dispatcher.m_demands_counter.load(
714 std::memory_order_acquire );
716 send< ::so_5::stats::messages::quantity< std::size_t > >(
719 ::so_5::stats::suffixes::agent_count(),
725 send< ::so_5::stats::messages::quantity< std::size_t > >(
728 ::so_5::stats::suffixes::work_thread_queue_size(),
734 const std::string & name_base )
736 using namespace ::so_5::disp::reuse;
738 m_base_prefix = make_disp_prefix(
745 #if defined(__clang__
) 746 #pragma clang diagnostic pop 766 environment_t & env ) = 0;
811 ::asio::io_context & io_svc,
815 work_thread_t::run< work_thread_without_activity_tracking_t >(
844 #if defined(__clang__
) 845 #pragma clang diagnostic push 846 #pragma clang diagnostic ignored "-Wnon-virtual-dtor" 867 std::size_t thread_count )
871 for(
auto & c : m_collectors )
872 c = std::make_unique< work_thread_activity_collector_t >();
878 disp_data_source_t::distribute( mbox );
880 for( std::size_t i = 0; i != m_collectors.size(); ++i )
881 distribute_stats_for_work_thread_at( mbox, i );
890 return *(m_collectors[index]);
899 std::ostringstream ss;
900 ss << base_prefix().c_str() <<
"/wt-" << index;
902 const ::so_5::stats::prefix_t prefix{ ss.str() };
903 auto & collector = collector_at( index );
905 so_5::send< ::so_5::stats::messages::work_thread_activity >(
908 ::so_5::stats::suffixes::work_thread_activity(),
909 collector.thread_id(),
910 collector.take_activity_stats() );
914 #if defined(__clang__
) 915 #pragma clang diagnostic pop 935 ::asio::io_context & io_svc,
941 work_thread_t::run< work_thread_with_activity_tracking_t >(
945 self.m_actual_data_source.collector_at(index) ) );
972 typename Basic_Skeleton >
976 using Basic_Skeleton::Basic_Skeleton;
980 using thread_t =
typename Traits::thread_type;
989 environment_t & env )
override 1062 class pseudo_event_queue_t
final :
public event_queue_t
1071 outliving_reference_t< demands_counter_t > demands_counter,
1073 outliving_reference_t< ::asio::io_context::strand > strand )
1079 push( execution_demand_t demand )
override 1081 demands_counter_t * counter = &(m_demands_counter.get());
1085 asio::post( m_strand.get(),
1086 [d = std::move(demand), counter]()
mutable {
1092 work_thread_t::handle_demand( std::move(d) );
1122 outliving_reference_t< demands_counter_t > demands_counter,
1123 outliving_reference_t< ::asio::io_context::strand > strand )
1132 auto result = [agent, &disp,
this]() {
1135 ::so_5::details::invoke_noexcept_code( [&] {
1136 agent->so_bind_to_dispatcher( m_event_queue );
1192 typename Basic_Skeleton >
1196 using actual_dispatcher_t =
1205 environment_t & env,
1208 const std::string & data_sources_name_base,
1263 auto c = std::thread::hardware_concurrency();
1384 "io_context is not set in disp_params" );
Ranges for error codes of each submodules.