Esempio n. 1
0
multicast_t::multicast_t(context_t& context, interface& locator, const std::string& name, const dynamic_t& args):
    category_type(context, locator, name, args),
    m_context(context),
    m_log(context.log(name)),
    m_locator(locator),
    m_cfg(args.to<multicast_cfg_t>()),
    m_socket(locator.asio()),
    m_timer(locator.asio())
{
    m_socket.open(m_cfg.endpoint.protocol());
    m_socket.set_option(socket_base::reuse_address(true));

    if(m_cfg.endpoint.address().is_v4()) {
        m_socket.bind(udp::endpoint(address_v4::any(), m_cfg.endpoint.port()));
    } else {
        m_socket.bind(udp::endpoint(address_v6::any(), m_cfg.endpoint.port()));
    }

    if(args.as_object().count("interface")) {
        auto interface = args.as_object().at("interface");

        if(m_cfg.endpoint.address().is_v4()) {
            m_socket.set_option(multicast::outbound_interface(interface.to<ip::address>().to_v4()));
        } else {
            m_socket.set_option(multicast::outbound_interface(interface.as_uint()));
        }
    }

    m_socket.set_option(multicast::enable_loopback(args.as_object().at("loopback", false).as_bool()));
    m_socket.set_option(multicast::hops(args.as_object().at("hops", 1u).as_uint()));

    COCAINE_LOG_INFO(m_log, "joining multicast group '%s'", m_cfg.endpoint)(
        "uuid", m_locator.uuid()
    );

    m_socket.set_option(multicast::join_group(m_cfg.endpoint.address()));

    const auto announce = std::make_shared<announce_t>();

    m_socket.async_receive_from(buffer(announce->buffer.data(), announce->buffer.size()),
        announce->endpoint,
        std::bind(&multicast_t::on_receive, this, ph::_1, ph::_2, announce)
    );

    m_signals = std::make_shared<dispatch<context_tag>>(name);
    m_signals->on<context::prepared>(std::bind(&multicast_t::on_publish, this, std::error_code()));

    context.listen(m_signals, m_locator.asio());
}
Esempio n. 2
0
node_t::node_t(context_t& context, asio::io_service& asio, const std::string& name, const dynamic_t& args):
    category_type(context, asio, name, args),
    dispatch<io::node_tag>(name),
    context(context),
    log(context.log(name))
{
    on<io::node::start_app>(std::bind(&node_t::start_app, this, ph::_1, ph::_2));
    on<io::node::pause_app>(std::bind(&node_t::pause_app, this, ph::_1));
    on<io::node::list>     (std::bind(&node_t::list, this));
    on<io::node::info>     (std::bind(&node_t::info, this, ph::_1, ph::_2));

    // Context signal/slot.
    signal = std::make_shared<dispatch<io::context_tag>>(name);
    signal->on<io::context::shutdown>(std::bind(&node_t::on_context_shutdown, this));

    const auto runname = args.as_object().at("runlist", "").as_string();

    if(runname.empty()) {
        context.listen(signal, asio);
        return;
    }

    COCAINE_LOG_INFO(log, "reading '%s' runlist", runname);

    typedef std::map<std::string, std::string> runlist_t;
    runlist_t runlist;

    const auto storage = api::storage(context, "core");

    try {
        // TODO: Perform request to a special service, like "storage->runlist(runname)".
        runlist = storage->get<runlist_t>("runlists", runname);
    } catch(const std::system_error& err) {
        COCAINE_LOG_WARNING(log, "unable to read '%s' runlist: %s", runname, err.what());
    }

    if(runlist.empty()) {
        context.listen(signal, asio);
        return;
    }

    COCAINE_LOG_INFO(log, "starting %d app(s)", runlist.size());

    std::vector<std::string> errored;

    for(auto it = runlist.begin(); it != runlist.end(); ++it) {
        blackhole::scoped_attributes_t scope(*log, {{ "app", it->first }});

        try {
            start_app(it->first, it->second);
        } catch(const std::exception& e) {
            COCAINE_LOG_WARNING(log, "unable to initialize app: %s", e.what());
            errored.push_back(it->first);
        }
    }

    if(!errored.empty()) {
        std::ostringstream stream;
        std::ostream_iterator<char> builder(stream);

        boost::spirit::karma::generate(builder, boost::spirit::karma::string % ", ", errored);

        COCAINE_LOG_WARNING(log, "couldn't start %d app(s): %s", errored.size(), stream.str());
    }

    context.listen(signal, asio);
}