#include <so_5/all.hpp>
class service_provider_t final : public so_5::agent_t
{
public:
struct ask_service final : public so_5::signal_t {};
struct service_ack final : public so_5::signal_t {};
service_provider_t(
context_t ctx,
const std::string & service_name)
: so_5::agent_t(std::move(ctx))
{
const auto service_mbox = so_environment().create_mbox(service_name);
so_subscribe(service_mbox).event([service_mbox](mhood_t<ask_service>) {
so_5::send<service_ack>(service_mbox);
});
}
};
class customer_t final : public so_5::agent_t
{
public:
customer_t(context_t ctx) :
so_5::agent_t(
std::move(ctx)) {}
virtual void so_evt_start() override
{
initiate_async_op_for("alpha");
initiate_async_op_for("beta");
}
private:
int m_acks_received = 0;
void initiate_async_op_for(const std::string & service_name)
{
const auto service_mbox = so_environment().create_mbox(service_name);
service_mbox,
so_default_state(),
[this, service_name](mhood_t<service_provider_t::service_ack>) {
std::cout << "ack from a service provider: " << service_name << std::endl;
++m_acks_received;
if(2 == m_acks_received)
so_deregister_agent_coop_normally();
})
.activate([&]{
so_5::send<service_provider_t::ask_service>(service_mbox);
});
}
};
int main()
{
try
{
so_5::launch([](so_5::environment_t & env) {
using namespace so_5::disp::thread_pool;
env.introduce_coop(
bind_params_t{}.fifo(fifo_t::individual)),
[](so_5::coop_t & coop) {
coop.make_agent<service_provider_t>("alpha");
coop.make_agent<service_provider_t>("beta");
coop.make_agent<customer_t>();
});
});
return 0;
}
catch(const std::exception & ex)
{
std::cerr << "Exception caught: " << ex.what() << std::endl;
}
return 2;
}