Ejemplo n.º 1
0
actor_base<Protocol>::actor_base(context_t& context, io::dispatch_ptr_t prototype) :
    m_context(context),
    m_log(context.log("core/asio", {{"service", prototype->name()}})),
    metrics(new metrics_t{
        context.metrics_hub().counter<std::int64_t>(cocaine::format("{}.connections.accepted", prototype->name())),
        context.metrics_hub().counter<std::int64_t>(cocaine::format("{}.connections.rejected", prototype->name()))
    }),
    m_prototype(std::move(prototype))
{}
Ejemplo n.º 2
0
std::shared_ptr<session_t>
execution_unit_t::attach(const std::shared_ptr<Socket>& ptr, const io::dispatch_ptr_t& dispatch) {
    int socket;

    if((socket = ::dup(ptr->native_handle())) == -1) {
        throw std::system_error(errno, std::system_category(), "unable to clone client's socket");
    }

    std::shared_ptr<session_t> session;

    try {
        // Local endpoint address of the socket to be cloned.
        const auto endpoint = ptr->local_endpoint();

        // Copy the socket into the new reactor.
        auto channel = std::make_unique<io::channel<generic::stream_protocol>>(
                           std::make_unique<generic::stream_protocol::socket>(
                               *m_asio,
                               endpoint.protocol(),
                               socket
                           )
                       );

        if (std::is_same<typename Socket::protocol_type, ip::tcp>::value) {
            // Disable Nagle's algorithm, since most of the service clients do not send or receive
            // more than a couple of kilobytes of data.
            channel->socket->set_option(tcp::no_delay(true));
        }

        auto session_log = std::make_unique<logging::log_t>(*m_log, attribute::set_t({
            attribute::make("endpoint", endpoint_traits<typename Socket::endpoint_type>::path(
                std::is_same<typename Socket::protocol_type, ip::tcp>::value ?
                ptr->remote_endpoint() :
                endpoint
            )),
            attribute::make("service",  dispatch ? dispatch->name() : "<none>"),
        }));

        COCAINE_LOG_DEBUG(session_log, "attached connection to engine, load: %.2f%%", utilization() * 100);

        // Create a new inactive session.
        session = std::make_shared<session_t>(std::move(session_log), std::move(channel), dispatch);
    } catch(const std::system_error& e) {
        throw std::system_error(e.code(), "client has disappeared while creating session");
    }

    m_asio->dispatch([=]() mutable {
        (m_sessions[socket] = std::move(session))->pull();
    });

    return session;
}