コード例 #1
0
ipvs_t::ipvs_t(context_t& context, const std::string& name, const dynamic_t& args):
    category_type(context, name, args),
    m_context(context),
    m_log(new logging::log_t(context, name)),
    m_default_scheduler(args.as_object().at("scheduler", "wlc").to<std::string>()),
    m_default_weight(args.as_object().at("weight", 1).to<unsigned int>())
{
    if(::ipvs_init() != 0) {
        throw std::system_error(errno, ipvs_category(), "unable to initialize IPVS");
    }

    COCAINE_LOG_INFO(m_log, "using IPVS version %d", ::ipvs_version());

    if(args["port-range"].empty()) {
        throw cocaine::error_t("no port ranges have been specified");
    }

    uint16_t min = args["port-range"][0].asUInt(),
             max = args["port-range"][1].asUInt();

    COCAINE_LOG_INFO(m_log, "%u gateway ports available, %u through %u", max - min, min, max);

    while(min != max) {
        m_ports.push(--max);
    }

    ::ipvs_flush();
}
コード例 #2
0
ファイル: context.cpp プロジェクト: lucciano/cocaine-core
 static
 result_type
 convert(const dynamic_t& from) {
     return cocaine::config_t::component_t {
         from.as_object().at("type", "unspecified").as_string(),
         from.as_object().at("args", dynamic_t::empty_object)
     };
 }
コード例 #3
0
ファイル: multicast.cpp プロジェクト: b-xiang/cocaine-core
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());
}
コード例 #4
0
ファイル: process.cpp プロジェクト: myutwo/cocaine-core
process_t::process_t(context_t& context, const std::string& name, const dynamic_t& args):
    category_type(context, name, args),
    m_context(context),
    m_log(context.log(name)),
    m_name(name),
    m_working_directory(fs::path(args.as_object().at("spool", "/var/spool/cocaine").as_string()) / name)
{
#ifdef COCAINE_ALLOW_CGROUPS
    int rv = 0;

    if((rv = cgroup_init()) != 0) {
        throw std::system_error(rv, cgroup_category(), "unable to initialize cgroups");
    }

    m_cgroup = cgroup_new_cgroup(m_name.c_str());

    // NOTE: Looks like if this is not done, then libcgroup will chown everything as root.
    cgroup_set_uid_gid(m_cgroup, getuid(), getgid(), getuid(), getgid());

    for(auto type = args.as_object().begin(); type != args.as_object().end(); ++type) {
        if(!type->second.is_object() || type->second.as_object().empty()) {
            continue;
        }

        cgroup_controller* ptr = cgroup_add_controller(m_cgroup, type->first.c_str());

        for(auto it = type->second.as_object().begin(); it != type->second.as_object().end(); ++it) {
            COCAINE_LOG_INFO(m_log, "setting cgroup controller '%s' parameter '%s' to '%s'",
                type->first, it->first, boost::lexical_cast<std::string>(it->second)
            );

            try {
                it->second.apply(cgroup_configurator_t(ptr, it->first.c_str()));
            } catch(const cocaine::error_t& e) {
                COCAINE_LOG_ERROR(m_log, "unable to set cgroup controller '%s' parameter '%s' - %s",
                    type->first, it->first, e.what()
                );
            }
        }
    }

    if((rv = cgroup_create_cgroup(m_cgroup, false)) != 0) {
        cgroup_free(&m_cgroup);

        throw std::system_error(rv, cgroup_category(), "unable to create cgroup");
    }
#endif
}
コード例 #5
0
ファイル: cache.cpp プロジェクト: toshic/cocaine-plugins
cache_t::cache_t(context_t& context, io::reactor_t& reactor, const std::string& name, const dynamic_t& args):
    service_t(context, reactor, name, args),
    implements<io::cache_tag>(name),
	cache_(args.as_object().at("max-size", 1000000).to<size_t>())
{
    on<io::cache::get>(std::bind(&cache_t::get, this, _1));
    on<io::cache::put>(std::bind(&cache_t::put, this, _1, _2));
}
コード例 #6
0
darkmetrics_t::darkmetrics_t(context_t& context, peers_t& peers, const dynamic_t& args)
    : unicorn_name_(args.as_object().at("unicorn", dynamic_t::empty_string).as_string())
    , unicorn_prefix_(args.as_object().at("unicorn_prefix", dynamic_t::empty_string).as_string())
    , unicorn_retry_after_(args.as_object().at("unicorn_retry_after_s", 20U).as_uint())
    , enabled_(args.as_object().at("enabled", false).as_bool())
    , ttl_(args.as_object().at("ttl_s", 300U).as_uint())
    , logger_(context.log("vicodyn/darkmetrics"))
    , peers_(peers) {

    if (enabled_) {
        if (unicorn_name_.empty() || unicorn_prefix_.empty()) {
            throw error_t("invalid configuration of darkmetrics: `unicorn` and `unicorn_prefix` are required");
        }
        unicorn_ = api::unicorn(context, unicorn_name_);
    }
    COCAINE_LOG_INFO(logger_, "balancing by system weights is {}", enabled_ ? "on" : "off");
}
コード例 #7
0
ファイル: multicast.cpp プロジェクト: b-xiang/cocaine-core
    static
    result_type
    convert(const dynamic_t& source) {
        result_type result;

        try {
            result.endpoint = udp::endpoint(
                source.as_object().at("group").to<ip::address>(),
                source.as_object().at("port", 10053u).as_uint()
            );
        } catch(std::out_of_range& e) {
            throw cocaine::error_t("no multicast group has been specified");
        }

        result.interval = boost::posix_time::seconds(
            source.as_object().at("interval", 5u).as_uint()
        );

        return result;
    }
コード例 #8
0
ファイル: storage.cpp プロジェクト: ApelSYN/cocaine-core
storage_t::storage_t(context_t& context, reactor_t& reactor, const std::string& name, const dynamic_t& args):
    api::service_t(context, reactor, name, args),
    implements<io::storage_tag>(context, name)
{
    auto storage = api::storage(context, args.as_object().at("backend", "core").as_string());

    on<io::storage::read>(std::bind(&api::storage_t::read, storage, _1, _2));
    on<io::storage::write>(std::bind(&api::storage_t::write, storage, _1, _2, _3, _4));
    on<io::storage::remove>(std::bind(&api::storage_t::remove, storage, _1, _2));
    on<io::storage::find>(std::bind(&api::storage_t::find, storage, _1, _2));
}
コード例 #9
0
ファイル: files.cpp プロジェクト: ApelSYN/cocaine-core
files_t::files_t(const config_t& config, const dynamic_t& args):
    category_type(config, args),
    m_file(nullptr)
{
    const std::string path = args.as_object()["path"].as_string();

    m_file = std::fopen(path.c_str(), "a");

    if(m_file == nullptr) {
        throw std::system_error(errno, std::system_category(), cocaine::format("unable to open '%s'", path));
    }
}
コード例 #10
0
ファイル: service.cpp プロジェクト: 3Hren/elliptics
elliptics_service_t::elliptics_service_t(context_t &context, asio::io_service &reactor, const std::string &name, const dynamic_t &args) :
	api::service_t(context, reactor, name, args),
	dispatch<io::elliptics_tag>(name),
	m_storage(api::storage(context, args.as_object().at("source", "core").as_string())),
	m_elliptics(dynamic_cast<storage::elliptics_storage_t*>(m_storage.get()))
{
	debug() << m_elliptics << std::endl;

	if (!m_elliptics) {
		throw std::system_error(-1, std::generic_category(), "to be able to use elliptics service, storage must be also elliptics");
	}

	on<io::storage::read  >(std::bind(&elliptics_service_t::read,   this, ph::_1, ph::_2));
	on<io::storage::write >(std::bind(&elliptics_service_t::write,  this, ph::_1, ph::_2, ph::_3, ph::_4));
	on<io::storage::remove>(std::bind(&elliptics_service_t::remove, this, ph::_1, ph::_2));
	on<io::storage::find  >(std::bind(&elliptics_service_t::find,   this, ph::_1, ph::_2));
	on<io::elliptics::cache_read >(std::bind(&elliptics_service_t::cache_read,  this, ph::_1, ph::_2));
	on<io::elliptics::cache_write>(std::bind(&elliptics_service_t::cache_write, this, ph::_1, ph::_2, ph::_3, ph::_4));
	on<io::elliptics::bulk_read  >(std::bind(&elliptics_service_t::bulk_read,   this, ph::_1, ph::_2));
	on<io::elliptics::read_latest>(std::bind(&elliptics_service_t::read_latest, this, ph::_1, ph::_2));
}
コード例 #11
0
ファイル: context.cpp プロジェクト: lucciano/cocaine-core
    static
    result_type
    convert(const dynamic_t& from) {
        result_type component;
        const auto& logging = from.as_object();

        for(auto it = logging.begin(); it != logging.end(); ++it) {
            using namespace blackhole::repository;

            auto object = it->second.as_object();
            auto loggers = object.at("loggers", dynamic_t::empty_array);

            config_t::logging_t::logger_t log {
                logmask(object.at("verbosity", defaults::log_verbosity).as_string()),
                object.at("timestamp", defaults::log_timestamp).as_string(),
                config::parser_t<dynamic_t, blackhole::log_config_t>::parse(it->first, loggers)
            };

            component.loggers[it->first] = log;
        }

        return component;
    }
コード例 #12
0
ファイル: storage.cpp プロジェクト: kazan417/cocaine-plugins
mongo_storage_t::mongo_storage_t(context_t& context, const std::string& name, const dynamic_t& args):
    category_type(context, name, args),
    m_log(context.log(name)),
    m_client(connect(args.as_object().at("uri", "<unspecified>").to<std::string>()))
{ }
コード例 #13
0
ファイル: raft.cpp プロジェクト: andrusha97/cocaine-core
control_service_t::control_service_t(context_t& context,
                                     io::reactor_t& reactor,
                                     const std::string& name,
                                     const dynamic_t& args):
    api::service_t(context, reactor, name, args),
    dispatch<io::raft_control_tag<msgpack::object, msgpack::object>>(name),
    m_context(context),
    m_log(context.log(name))
{
    using namespace std::placeholders;

    typedef io::raft_control<msgpack::object, msgpack::object> protocol;

    on<protocol::insert>(std::bind(&control_service_t::insert, this, _1, _2));
    on<protocol::erase>(std::bind(&control_service_t::erase, this, _1, _2));
    on<protocol::lock>(std::bind(&control_service_t::lock, this, _1));
    on<protocol::reset>(std::bind(&control_service_t::reset, this, _1, _2));
    on<protocol::dump>(std::bind(&control_service_t::dump, this));
    on<protocol::status>(std::bind(&control_service_t::status, this, _1));
    on<protocol::leader>(std::bind(&control_service_t::leader, this, _1));

    options_t options;

    // The format of the name is "service/<name of service from the config>".
    // So here we drop "service/" part to determine the raft control service name.
    // TODO: Make the context to pass the names to services without "service/" part.
    options.control_service_name = name.substr(8, std::string::npos);
    options.node_service_name = "raft_node";
    options.configuration_machine_name = "configuration";
    options.some_nodes = args.as_object().at("some_nodes", dynamic_t::empty_array).to<std::set<node_id_t>>();
    options.election_timeout = args.as_object().at("election_timeout", 500).to<unsigned int>();
    options.heartbeat_timeout = args.as_object().at("heartbeat_timeout", options.election_timeout / 2).to<unsigned int>();
    options.snapshot_threshold = args.as_object().at("snapshot_threshold", 100000).to<unsigned int>();
    options.message_size = args.as_object().at("message_size", 1000).to<unsigned int>();

    m_context.raft().set_options(options);
    m_context.raft().activate();

    if(m_context.config.create_raft_cluster) {
        typedef log_entry<configuration_machine_t> entry_type;
        typedef configuration<configuration_machine_t> config_type;
        typedef log_traits<configuration_machine_t, config_type::cluster_type>::snapshot_type
                snapshot_type;

        config_type config(m_context,
                           m_context.raft().options().configuration_machine_name,
                           cluster_config_t {std::set<node_id_t>(), boost::none});

        configuration_machine_t config_machine(m_context, *m_context.raft().m_reactor, *this);

        config.log().push(entry_type());
        config.log().push(entry_type());

        std::map<std::string, lockable_config_t> config_snapshot;

        config_snapshot[m_context.raft().options().configuration_machine_name] = lockable_config_t {
            false,
            cluster_config_t {
                std::set<node_id_t>({m_context.raft().id()}),
                boost::none
            }
        };

        config_machine.consume(config_snapshot);
        config.log().set_snapshot(1, 1, snapshot_type(std::move(config_snapshot), config.cluster()));

        config.set_current_term(std::max<uint64_t>(1, config.current_term()));
        config.set_commit_index(1);
        config.set_last_applied(1);

        m_config_actor = m_context.raft().create_cluster(
            m_context.raft().options().configuration_machine_name,
            std::move(config_machine),
            std::move(config)
        );
    } else {
        m_config_actor = m_context.raft().insert(
            m_context.raft().options().configuration_machine_name,
            configuration_machine_t(m_context, *m_context.raft().m_reactor, *this)
        );
    }

    // Run Raft node service.
    auto node_service_reactor = std::make_shared<io::reactor_t>();

    std::unique_ptr<api::service_t> node_service(std::make_unique<node_service_t>(
        m_context,
        *m_context.raft().m_reactor,
        std::string("service/") + m_context.raft().options().node_service_name
    ));

    std::unique_ptr<actor_t> node_service_actor(
        new actor_t(m_context, m_context.raft().m_reactor, std::move(node_service))
    );

    m_context.insert(m_context.raft().options().node_service_name,
                     std::move(node_service_actor));
}
コード例 #14
0
ファイル: uniresis.cpp プロジェクト: cocaine/cocaine-plugins
uniresis_t::uniresis_t(context_t& context, asio::io_service& loop, const std::string& name, const dynamic_t& args) :
    api::service_t(context, loop, name, args),
    dispatch<io::uniresis_tag>(name),
    uuid(context.uuid()),
    resources(),
    updater(nullptr),
    log(context.log("uniresis"))
{
    if (resources.cpu == 0) {
        throw std::system_error(uniresis::uniresis_errc::failed_calculate_cpu_count);
    }

    if (resources.mem == 0) {
        throw std::system_error(uniresis::uniresis_errc::failed_calculate_system_memory);
    }

    auto restrictions = args.as_object().at("restrictions", dynamic_t::empty_object).as_object();

    auto cpu_restricted = std::min(
        resources.cpu,
        static_cast<uint>(restrictions.at("cpu", resources.cpu).as_uint())
    );

    if (resources.cpu != cpu_restricted) {
        resources.cpu = cpu_restricted;
        COCAINE_LOG_INFO(log, "restricted available CPU count to {}", resources.cpu);
    }

    auto mem_restricted = std::min(
        resources.mem,
        static_cast<std::uint64_t>(restrictions.at("mem", resources.mem).as_uint())
    );

    if (resources.mem != mem_restricted) {
        resources.mem = mem_restricted;
        COCAINE_LOG_INFO(log, "restricted available system memory to {}", resources.mem);
    }

    auto prefix = args.as_object().at("prefix", defaults::resources_path).as_string();
    auto path = format("{}/{}", prefix, uuid);

    auto hostname = context.config().network().hostname();
    auto endpoints = resolve(hostname);
    dynamic_t::object_t extra;
    if (auto locator = context.config().services().get("locator")) {
        extra = dynamic_converter<dynamic_t::object_t>::convert(
            locator->args().as_object().at("extra_param", dynamic_t::empty_object)
        );
    }
    auto unicorn = api::unicorn(context, args.as_object().at("unicorn", defaults::unicorn_name).as_string());
    updater = std::make_shared<updater_t>(
        std::move(path),
        std::move(hostname),
        std::move(endpoints),
        std::move(extra),
        resources,
        std::move(unicorn),
        log
    );
    updater->notify();

    on<io::uniresis::cpu_count>([&] {
        return resources.cpu;
    });

    on<io::uniresis::memory_count>([&] {
        return resources.mem;
    });

    on<io::uniresis::uuid>([&] {
        return uuid;
    });
}
コード例 #15
0
ファイル: context.cpp プロジェクト: lucciano/cocaine-core
config_t::config_t(const std::string& config_path) {
    path.config = config_path;

    const auto config_file_status = fs::status(path.config);

    if(!fs::exists(config_file_status) || !fs::is_regular_file(config_file_status)) {
        throw cocaine::error_t("the configuration file path is invalid");
    }

    fs::ifstream stream(path.config);

    if(!stream) {
        throw cocaine::error_t("unable to read the configuration file");
    }

    rapidjson::MemoryPoolAllocator<> json_allocator;
    rapidjson::Reader json_reader(&json_allocator);
    rapidjson_ifstream_t config_stream(&stream);
    dynamic_reader_t config_constructor;

    if(!json_reader.Parse<rapidjson::kParseDefaultFlags>(config_stream, config_constructor)) {
        if(json_reader.HasParseError()) {
            throw cocaine::error_t("the configuration file is corrupted - %s", json_reader.GetParseError());
        } else {
            throw cocaine::error_t("the configuration file is corrupted");
        }
    }

    const dynamic_t root(config_constructor.Result());

    const auto &path_config    = root.as_object().at("paths", dynamic_t::empty_object).as_object();
    const auto &locator_config = root.as_object().at("locator", dynamic_t::empty_object).as_object();
    const auto &network_config = root.as_object().at("network", dynamic_t::empty_object).as_object();

    // Validation

    if(root.as_object().at("version", 0).to<unsigned int>() != 2) {
        throw cocaine::error_t("the configuration file version is invalid");
    }

    // Paths

    path.plugins = path_config.at("plugins", defaults::plugins_path).as_string();
    path.runtime = path_config.at("runtime", defaults::runtime_path).as_string();

    const auto runtime_path_status = fs::status(path.runtime);

    if(!fs::exists(runtime_path_status)) {
        throw cocaine::error_t("the %s directory does not exist", path.runtime);
    } else if(!fs::is_directory(runtime_path_status)) {
        throw cocaine::error_t("the %s path is not a directory", path.runtime);
    }

    // Hostname configuration

    char hostname[256];

    if(gethostname(hostname, 256) != 0) {
        throw std::system_error(errno, std::system_category(), "unable to determine the hostname");
    }

    addrinfo hints,
             *result = nullptr;

    std::memset(&hints, 0, sizeof(addrinfo));

    hints.ai_flags = AI_CANONNAME;

    const int rv = getaddrinfo(hostname, nullptr, &hints, &result);

    if(rv != 0) {
        throw std::system_error(rv, gai_category(), "unable to determine the hostname");
    }

    network.hostname = locator_config.at("hostname", std::string(result->ai_canonname)).as_string();
    network.uuid     = unique_id_t().string();

    freeaddrinfo(result);

    // Locator configuration

    network.endpoint = locator_config.at("endpoint", defaults::endpoint).as_string();
    network.locator  = locator_config.at("port", defaults::locator_port).to<uint16_t>();

    // WARNING: Now only arrays of two items are allowed.
    auto ports = locator_config.find("port-range");

    if(ports != locator_config.end()) {
        network.ports = ports->second.to<std::tuple<uint16_t, uint16_t>>();
    }

    // Cluster configuration

    if(!network_config.empty()) {
        if(network_config.count("group") == 1) {
            network.group = network_config["group"].as_string();
        }

        if(network_config.count("gateway") == 1) {
            network.gateway = {
                network_config["gateway"].as_object().at("type", "adhoc").as_string(),
                network_config["gateway"].as_object().at("args", dynamic_t::empty_object)
            };
        }
    }

#ifdef COCAINE_ALLOW_RAFT
    create_raft_cluster = false;
#endif

    // Component configuration
    logging  = root.as_object().at("logging" , dynamic_t::empty_object).to<config_t::logging_t>();
    services = root.as_object().at("services", dynamic_t::empty_object).to<config_t::component_map_t>();
    storages = root.as_object().at("storages", dynamic_t::empty_object).to<config_t::component_map_t>();
}
コード例 #16
0
ファイル: node.cpp プロジェクト: nail-lian/cocaine-core
node_t::node_t(context_t& context, boost::asio::io_service& asio, const std::string& name, const dynamic_t& args):
    category_type(context, asio, name, args),
    dispatch<node_tag>(name),
    m_context(context),
    m_log(context.log(name))
{
    using namespace std::placeholders;

    on<node::start_app>(std::bind(&node_t::on_start_app, this, _1, _2));
    on<node::pause_app>(std::bind(&node_t::on_pause_app, this, _1));
    on<node::list>(std::bind(&node_t::on_list, this));

    const auto runlist_id = args.as_object().at("runlist", "default").as_string();
    const auto storage = api::storage(m_context, "core");

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

    runlist_t runlist;

    {
        blackhole::scoped_attributes_t attributes(*m_log, {
            blackhole::attribute::make("runlist", runlist_id)
        });

        COCAINE_LOG_INFO(m_log, "reading runlist");

        try {
            runlist = storage->get<runlist_t>("runlists", runlist_id);
        } catch(const storage_error_t& e) {
            COCAINE_LOG_WARNING(m_log, "unable to read runlist: %s", e.what());
        }
    }

    if(runlist.empty()) {
        return;
    }

    COCAINE_LOG_INFO(m_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 attributes(*m_log, {
            blackhole::attribute::make("app", it->first)
        });

        try {
            on_start_app(it->first, it->second);
        } catch(const std::exception& e) {
            COCAINE_LOG_ERROR(m_log, "unable to initialize app: %s", e.what());
            errored.push_back(it->first);
        } catch(...) {
            COCAINE_LOG_ERROR(m_log, "unable to initialize app");
            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::stream % ", ", errored);

        COCAINE_LOG_ERROR(m_log, "couldn't start %d app(s): %s", errored.size(), stream.str());
    }
}
コード例 #17
0
ファイル: node.cpp プロジェクト: borislitv/cocaine-plugins
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);
}
コード例 #18
0
ファイル: files.cpp プロジェクト: b-xiang/cocaine-core
files_t::files_t(context_t& context, const std::string& name, const dynamic_t& args):
    category_type(context, name, args),
    m_log(context.log(name)),
    m_parent_path(args.as_object().at("path").as_string())
{ }