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();
			}
Example #2
0
		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() );
		} );
}
Example #9
0
		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();
				} );
		}
Example #10
0
		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 ) );
		}
Example #11
0
	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 );
	}
Example #12
0
	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 );
	}
Example #14
0
		virtual void
		so_evt_start()
		{
			so_direct_mbox()->deliver_signal< msg_tick >();
		}