void so_evt_start() { ensure_counter_value( m_message_counter, 0 ); m_id1 = so_environment().schedule_timer( make_message_object(), so_direct_mbox(), 6000, 0 ); m_id2 = so_environment().schedule_timer( make_message_object(), so_direct_mbox(), 6000, 1000 ); m_id3 = so_environment().schedule_timer( make_message_object(), so_direct_mbox(), 6000, 0 ); m_id4 = so_environment().schedule_timer( make_message_object(), so_direct_mbox(), 6000, 1000 ); m_id1.release(); m_id2.release(); ensure_counter_value( m_message_counter, 2 ); so_deregister_agent_coop_normally(); }
virtual void so_define_agent() { so_subscribe( so_direct_mbox() ) .in( so_default_state() ) .event( &a_ordinary_t::some_handler ); so_direct_mbox()->deliver_signal< some_message >(); }
void evt_three( const so_5::event_data_t< msg_three > & ) { m_sequence += "e3:"; so_drop_subscription( so_direct_mbox(), &a_test_t::evt_one ); so_subscribe( so_direct_mbox() ).event( &a_test_t::evt_two ); }
void so_define_agent() { so_subscribe( so_direct_mbox() ) .event( &a_test_t::evt_one ); so_subscribe( so_direct_mbox() ) .event( &a_test_t::evt_three ); so_subscribe( so_direct_mbox() ) .event( &a_test_t::evt_four ); }
void create_new_child_coop() { // The cooperation will use active_obj dispatcher. auto disp = so_5::disp::active_obj::create_private_disp( so_environment() ); auto coop = so_5::create_child_coop( // This agent will be parent for new cooperation. *this, // Name for the cooperation will be generated automatically. so_5::autoname, // The main dispatcher for the new cooperation is // the private active_obj dispatcher. disp->binder() ); // We should receive notification about complete // child cooperation deregistration. coop->add_dereg_notificator( so_5::make_coop_dereg_notificator( so_direct_mbox() ) ); auto first_mbox = fill_coop( *coop ); so_environment().register_coop( std::move( coop ) ); // Initial message must be sent to the first chain's member. so_5::send< a_chain_member_t::msg_your_turn >( first_mbox ); }
// Filling the cooperation with the agents. // Return the mbox of the first member in the chain. so_5::mbox_t fill_coop( so_5::coop_t & coop ) { const std::size_t agent_count = 8; // Those containers are necessary for building agents chain. std::vector< so_5::mbox_t > mboxes; mboxes.reserve( agent_count ); std::vector< a_chain_member_t * > agents; agents.reserve( agent_count ); // Create all agents of child cooperation. for( std::size_t i = 0; i != agent_count; ++i ) { auto a = coop.make_agent< a_chain_member_t >(); agents.push_back( a ); mboxes.push_back( a->so_direct_mbox() ); } // Connect all agents to the chain. for( std::size_t i = 0; i != agent_count - 1; ++i ) agents[ i ]->set_next( mboxes[ i + 1 ] ); return mboxes[ 0 ]; }
int main() { try { std::string sequence; so_5::launch( [&sequence]( so_5::environment_t & env ) { auto coop = env.create_coop( "test", so_5::disp::active_obj::create_disp_binder( "active_obj" ) ); auto a_test = new a_test_t( env, sequence ); const so_5::mbox_t mbox = a_test->so_direct_mbox(); coop->add_agent( a_test ); coop->define_agent() .on_start( [mbox]() { mbox->deliver_signal< msg_one >(); mbox->deliver_signal< msg_two >(); mbox->run_one() .wait_for( std::chrono::seconds(1) ) .sync_get< msg_three >(); mbox->deliver_signal< msg_one >(); mbox->deliver_signal< msg_two >(); mbox->deliver_signal< msg_four >(); } ); env.register_coop( std::move( coop ) ); }, []( so_5::environment_params_t & params ) { params.add_named_dispatcher( "active_obj", so_5::disp::active_obj::create_disp() ); } ); const std::string expected = "e1:e3:e2:e4:"; if( sequence != expected ) throw std::runtime_error( "sequence mismatch! " "expected: '" + expected + "', actual: '" + sequence + "'" ); } catch( const std::exception & ex ) { std::cerr << "Error: " << ex.what() << std::endl; return 1; } return 0; }
void init( so_5::environment_t & env ) { env.introduce_coop( so_5::disp::active_obj::create_private_disp( env )->binder(), []( so_5::coop_t & coop ) { auto a_test = coop.make_agent< a_test_t >(); coop.make_agent< a_request_initator_t >( a_test->so_direct_mbox() ); } ); }
virtual void so_define_agent() { so_subscribe_self().event< msg_tick >( [=] { m_ticks += 1; if( m_ticks < 15 ) so_direct_mbox()->deliver_signal< msg_tick >(); else so_deregister_agent_coop_normally(); } ); }
void try_start_new_iteration() { if( m_iterations_left <= 0 ) { std::cout << "COMPLETED!" << std::endl; so_environment().stop(); return; } std::cout << m_iterations_left << " iterations left...\r" << std::flush; m_state = state_t::awaiting_creation; m_acks_received = 0; m_destroy_received = 0; m_child_mboxes = std::vector< so_5::rt::mbox_t >(); m_child_mboxes.reserve( m_max_agents ); auto coop = so_environment().create_coop( "child" ); coop->set_parent_coop_name( so_coop_name() ); coop->add_reg_notificator( so_5::rt::make_coop_reg_notificator( so_direct_mbox() ) ); coop->add_dereg_notificator( so_5::rt::make_coop_dereg_notificator( so_direct_mbox() ) ); for( std::size_t i = 0; i != m_max_agents; ++i ) { std::unique_ptr< so_5::rt::agent_t > agent( new a_child_t( so_environment(), so_direct_mbox() ) ); m_child_mboxes.push_back( agent->so_direct_mbox() ); coop->add_agent( std::move( agent ) ); } so_environment().register_coop( std::move( coop ) ); }
virtual void so_evt_start() override { so_5::introduce_child_coop( *this, [this]( so_5::coop_t & coop ) { coop.add_dereg_notificator( so_5::make_coop_dereg_notificator( so_direct_mbox() ) ); coop.make_agent< a_child_t >( m_data_mbox ); } ); so_5::send< data >( m_data_mbox, 0 ); so_5::send< data >( m_data_mbox, 1 ); so_5::send< data >( m_data_mbox, 2 ); }
void so_evt_start() override { auto coop = so_5::rt::create_child_coop( *this, "child" ); // Add necessary cooperation notificators for coop. coop->add_reg_notificator( so_5::rt::make_coop_reg_notificator( so_direct_mbox() ) ); coop->add_reg_notificator( normal_coop_reg_notificator ); coop->add_reg_notificator( invalid_coop_reg_notificator ); // A cooperation agent. coop->define_agent() .on_start( []() { std::cout << "Child started!" << std::endl; } ); std::cout << "registering coop: " << coop->query_coop_name() << std::endl; // Registering cooperation. so_environment().register_coop( std::move( coop ) ); }
// An event for next attempt to send another requests. void evt_send_next() { if( m_requests_left ) { // Send can wait on full mchain. Mark the start time to // calculate send call duration later. const auto started_at = steady_clock::now(); try { // Send another request. // Note: this call can wait on full mchain. so_5::send< request >( m_consumer_mbox, so_direct_mbox(), m_name + "_request_" + std::to_string( m_requests_left ) ); // How much time the send take? const auto ms = std::chrono::duration_cast< std::chrono::milliseconds >( steady_clock::now() - started_at ).count(); m_logger_mbox <<= msg_maker() << m_name << ": request sent in " << ms << "ms"; } catch( const so_5::exception_t & ex ) { // Log the reason of send request failure. m_logger_mbox <<= msg_maker() << m_name << ": request NOT SENT, " << ex.what(); // Initiate next send attempt. so_5::send< send_next >( *this ); } } else // No more requests to send. Shutdowner must known about it. shutdowner::producer_finished( *this ); }
virtual void so_evt_start() { so_direct_mbox()->deliver_signal< msg_tick >(); }