#include <iostream>
#include <chrono>
#include <cstdlib>
#if defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
#endif
struct msg_do_hardwork
{
unsigned int m_index;
unsigned int m_milliseconds;
};
struct msg_hardwork_done
{
unsigned int m_index;
};
struct msg_check_hardwork
{
unsigned int m_index;
unsigned int m_milliseconds;
};
struct msg_hardwork_checked
{
unsigned int m_index;
};
{
public :
a_manager_t(
context_t ctx,
unsigned int requests,
unsigned int milliseconds )
, m_worker_mbox(
std::move(worker_mbox) )
, m_checker_mbox(
std::move(checker_mbox) )
, m_requests( requests )
, m_milliseconds( milliseconds )
{}
{
.
event( &a_manager_t::evt_hardwork_done )
.event( &a_manager_t::evt_hardwork_checked );
}
{
m_start_time = std::chrono::steady_clock::now();
for( unsigned int i = 0; i != m_requests; ++i )
{
m_worker_mbox,
i, m_milliseconds );
}
}
void evt_hardwork_done( const msg_hardwork_done & evt )
{
m_checker_mbox,
evt.m_index, m_milliseconds );
}
void evt_hardwork_checked( const msg_hardwork_checked & )
{
++m_processed;
if( m_processed == m_requests )
{
auto finish_time = std::chrono::steady_clock::now();
auto duration = double(
std::chrono::duration_cast< std::chrono::milliseconds >(
finish_time - m_start_time ).count()
) / 1000.0;
std::cout << "Working time: " << duration << "s" << std::endl;
}
}
private :
const unsigned int m_requests;
unsigned int m_processed = 0;
const unsigned int m_milliseconds;
std::chrono::steady_clock::time_point m_start_time;
};
create_test_coop(
unsigned int requests,
unsigned int milliseconds )
{
public :
[&manager]( mhood_t<msg_do_hardwork> cmd ) {
std::this_thread::sleep_for(
std::chrono::milliseconds( cmd->m_milliseconds ) );
},
}
};
public :
[&manager]( mhood_t<msg_check_hardwork> cmd ) {
std::this_thread::sleep_for(
std::chrono::milliseconds( cmd->m_milliseconds ) );
},
}
};
auto c = env.
make_coop( std::move( disp_binder ) );
auto checker = c->make_agent< checker_t >();
auto manager = c->make_agent< a_manager_t >(
worker->so_direct_mbox(),
checker->so_direct_mbox(),
requests,
milliseconds );
worker->bind_to( *manager );
checker->bind_to( *manager );
return c;
}
using dispatcher_factory_t = std::function<
dispatcher_factory_t
make_dispatcher_factory( std::string_view type )
{
dispatcher_factory_t res;
if( "active_obj" == type )
{
};
}
else if( "thread_pool" == type )
{
};
}
else if( "adv_thread_pool" == type )
{
};
}
else if( "one_thread" == type )
{
};
}
else
throw std::runtime_error(
"unknown type of dispatcher: " + std::string{ type } );
return res;
}
struct config_t
{
dispatcher_factory_t m_factory;
unsigned int m_requests;
unsigned int m_milliseconds;
};
config_t
parse_params( int argc, char ** argv )
{
if( 1 == argc )
throw std::runtime_error( "no arguments given!\n\n"
"usage:\n\n"
"sample.so_5.hardwork_imit <disp_type> [requests] [worktime_ms]" );
config_t r {
make_dispatcher_factory( argv[ 1 ] ),
200,
15
};
if( 2 < argc )
r.m_requests = static_cast< unsigned int >( std::atoi( argv[ 2 ] ) );
if( 3 < argc )
r.m_milliseconds = static_cast< unsigned int >( std::atoi( argv[ 3 ] ) );
std::cout << "Config:\n"
"\t" "dispatcher: " << argv[ 1 ] << "\n"
"\t" "requests: " << r.m_requests << "\n"
"\t" "worktime (ms): " << r.m_milliseconds << std::endl;
return r;
}
int main( int argc, char ** argv )
{
try
{
const config_t config = parse_params( argc, argv );
{
create_test_coop(
env,
config.m_factory( env ),
config.m_requests,
config.m_milliseconds ) );
} );
return 0;
}
catch( const std::exception & x )
{
std::cerr << "Exception: " << x.what() << std::endl;
}
return 2;
}
A helper header file for including all public SObjectizer stuff.
virtual void so_define_agent()
Hook on define agent for SObjectizer.
subscription_bind_t so_subscribe_self()
Initiate subscription to agent's direct mbox.
agent_t(environment_t &env)
Constructor.
environment_t & so_environment() const noexcept
Access to the SObjectizer Environment which this agent is belong.
virtual void so_evt_start()
Hook on agent start inside SObjectizer.
Agent * make_agent(Args &&... args)
Helper method for simplification of agents creation.
A special type that plays role of unique_ptr for coop.
disp_binder_shptr_t binder(nonempty_name_t group_name) const
Get a binder for that dispatcher.
Parameters for binding agents to adv_thread_pool dispatcher.
bind_params_t & fifo(fifo_t v)
Set FIFO type.
Parameters for binding agents to thread_pool dispatcher.
bind_params_t & fifo(fifo_t v)
Set FIFO type.
coop_unique_holder_t make_coop()
Create a cooperation.
void stop() noexcept
Send a shutdown signal to the Run-Time.
coop_handle_t register_coop(coop_unique_holder_t agent_coop)
Register a cooperation.
std::enable_if< details::is_agent_method_pointer< details::method_arity::unary, Method_Pointer >::value, subscription_bind_t & >::type event(Method_Pointer pfn, thread_safety_t thread_safety=not_thread_safe)
Make subscription to the message.
SO_5_FUNC dispatcher_handle_t make_dispatcher(environment_t &env, const std::string_view data_sources_name_base, disp_params_t params)
Create an instance of active_group dispatcher.
Active objects dispatcher.
Advanced thread pool dispatcher.
Dispatcher with single working thread.
Private part of message limit implementation.
void launch(Init_Routine &&init_routine)
Launch a SObjectizer Environment with default parameters.
const thread_safety_t thread_safe
Shorthand for thread safety indicator.
void send(Target &&to, Args &&... args)
A utility function for creating and delivering a message or a signal.
std::shared_ptr< disp_binder_t > disp_binder_shptr_t
Typedef for the disp_binder smart pointer.