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)) {}
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; }