XDL 的网络流程

时间秒杀一切 提交于 2020-01-10 14:18:40

在xdl中会在每个核心运行SeastarServer::Start函数(函数代码位于https://github.com/alibaba/x-deeplearning/blob/master/xdl/third_party/seastar/service/server.cc,22行。

void SeastarServer::Start()
{
seastar::listen_options lo;
lo.reuse_address = true;
mListener = seastar::engine().listen(seastar::make_ipv4_address({mPort}), lo);

// Poll() will be start in reactor
//seastar::engine().GetQueuePoller().Poll();

// accept and read
seastar::keep_doing([this]
{
    return mListener->accept().then_wrapped([this] (auto&& f) mutable
    {
        try
        {
            std::tuple<seastar::connected_socket, seastar::socket_address> data = f.get();
            seastar::connected_socket fd = std::move(get<0>(data));
            if (this->GetTcpNoDelayOn())
            {
                fd.set_nodelay(true);
            }

            if (this->GetTcpKeepAliveIdle() > 0) {
                seastar::net::tcp_keepalive_params keep_alive;
                keep_alive.idle = std::chrono::seconds(this->GetTcpKeepAliveIdle());
                keep_alive.interval = std::chrono::seconds(this->GetTcpKeepAliveInterval());
                keep_alive.count = this->GetTcpKeepAliveCnt();
                fd.set_keepalive(true);
                fd.set_keepalive_parameters(keep_alive);
            }

            seastar::socket_address addr = get<1>(data);
            auto conn = new ServerConnection(RoleType::Server, std::move(fd), addr, *this);

            this->Process(conn).finally([conn]
            {
                return conn->mOut.close().finally([conn]
                {
                    //cout << "client disconnect..." << endl;
                    conn->DeleteSessionContext();
                });
            });
       }

它里面会调用seastar::engine().listen的函数listen(socket_address sa, listen_options opt)

server_socket
reactor::listen(socket_address sa, listen_options opt) {
return server_socket(_network_stack->listen(sa, opt));
}
其中network_stack会调用posix_network_stack::listen

server_socket
posix_network_stack::listen(socket_address sa, listen_options opt) {
if (opt.proto == transport::TCP) {
return _reuseport ?
server_socket(std::make_unique<posix_reuseport_server_tcp_socket_impl>(sa, engine().posix_listen(sa, opt)))
:
server_socket(std::make_unique<posix_server_tcp_socket_impl>(sa, engine().posix_listen(sa, opt)));
} else {
return _reuseport ?
server_socket(std::make_unique<posix_reuseport_server_sctp_socket_impl>(sa, engine().posix_listen(sa, opt)))
:
server_socket(std::make_unique<posix_server_sctp_socket_impl>(sa, engine().posix_listen(sa, opt)));
}
}
里面调用engine().posix_listen(sa, opt)来自于

pollable_fd
reactor::posix_listen(socket_address sa, listen_options opts) {
file_desc fd = file_desc::socket(sa.u.sa.sa_family, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, int(opts.proto));
if (opts.reuse_address) {
fd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1);
}
if (_reuseport)
fd.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1);

fd.bind(sa.u.sa, sizeof(sa.u.sas));
fd.listen(100);
return pollable_fd(std::move(fd));

}
这个里面会调用

static file_desc socket(int family, int type, int protocol = 0) {
int fd = ::socket(family, type, protocol);
throw_system_error_on(fd == -1, “socket”);
return file_desc(fd);
}

void bind(sockaddr& sa, socklen_t sl) {
auto r = ::bind(_fd, &sa, sl);
throw_system_error_on(r == -1, “bind”);
}
创建socket套接字。然后代码逻辑是把它绑定到_fd

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!