Exemplo n.º 1
0
        void asio_rpc_session::connect()
        {
            if (try_connecting())
            {
                boost::asio::ip::tcp::endpoint ep(
                    boost::asio::ip::address_v4(_remote_addr.ip()), _remote_addr.port());

                add_ref();
                _socket->async_connect(ep, [this](boost::system::error_code ec)
                {
                    if (!ec)
                    {
                        dinfo("client session %s connected",
                            _remote_addr.to_string()
                            );

                        set_options();
                        set_connected();
                        on_send_completed();
                        do_read();
                    }
                    else
                    {
                        derror("client session connect to %s failed, error = %s",
                            _remote_addr.to_string(),
                            ec.message().c_str()
                            );
                        on_failure();
                    }
                    release_ref();
                });
            }
        }   
Exemplo n.º 2
0
        void asio_rpc_session::write(uint64_t signature)
        {
            std::vector<boost::asio::const_buffer> buffers2;
            int bcount = (int)_sending_buffers.size();
            
            // prepare buffers
            buffers2.resize(bcount);            
            for (int i = 0; i < bcount; i++)
            {
                buffers2[i] = boost::asio::const_buffer(_sending_buffers[i].buf, _sending_buffers[i].sz);
            }

            add_ref();
            boost::asio::async_write(*_socket, buffers2,
                [this, signature](boost::system::error_code ec, std::size_t length)
            {
                if (!!ec)
                {
                    derror("asio write failed: %s", ec.message().c_str());
                    on_failure();
                }
                else
                {
                    on_send_completed(signature);
                }

                release_ref();
            });
        }
Exemplo n.º 3
0
void hpc_rpc_session::connect()
{
    if (!try_connecting())
        return;

    _connect_event.callback = [this](int err, uint32_t io_size, uintptr_t lpolp)
    {
        //dinfo("ConnectEx completed, err = %d, size = %u", err, io_size);
        if (err != ERROR_SUCCESS)
        {
            dwarn("ConnectEx failed, err = %d", err);
            this->on_failure();
        }
        else
        {
            dinfo("client session %s:%hu connected",
                  _remote_addr.name(),
                  _remote_addr.port()
                 );

            set_connected();
            on_send_completed(nullptr);
            do_read();
        }
        this->release_ref(); // added before ConnectEx
    };
    memset(&_connect_event.olp, 0, sizeof(_connect_event.olp));

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(_remote_addr.ip());
    addr.sin_port = htons(_remote_addr.port());

    this->add_ref(); // released in _connect_event.callback
    BOOL rt = s_lpfnConnectEx(
                  _socket,
                  (struct sockaddr*)&addr,
                  (int)sizeof(addr),
                  0,
                  0,
                  0,
                  &_connect_event.olp
              );

    if (!rt && (WSAGetLastError() != ERROR_IO_PENDING))
    {
        dwarn("ConnectEx failed, err = %d", ::WSAGetLastError());
        this->release_ref();

        on_failure();
    }
}
Exemplo n.º 4
0
    void sim_server_session::send(uint64_t sig)
    {
        for (auto& msg : _sending_msgs)
        {
            message_ex* recv_msg = virtual_send_message(msg);

            {
                node_scoper ns(_client->net().node());

                _client->on_recv_reply(recv_msg->header->id, recv_msg,
                    recv_msg->to_address == recv_msg->from_address ?
                    0 : (static_cast<sim_network_provider*>(&_net))->net_delay_milliseconds()
                    );
            }
        }        

        on_send_completed(sig);
    }
Exemplo n.º 5
0
    void sim_client_session::send(uint64_t sig)
    {
        for (auto& msg : _sending_msgs)
        {
            sim_network_provider* rnet = nullptr;
            if (!s_switch[task_spec::get(msg->local_rpc_code)->rpc_call_channel][msg->hdr_format].get(remote_address(), rnet))
            {
                derror("cannot find destination node %s in simulator",
                    remote_address().to_string()
                    );
                //on_disconnected();  // disable this to avoid endless resending
            }
            else
            {
                auto server_session = rnet->get_server_session(_net.address());
                if (nullptr == server_session)
                {
                    rpc_session_ptr cptr = this;
                    message_parser_ptr parser(_net.new_message_parser(msg->hdr_format));
                    server_session = new sim_server_session(*rnet, _net.address(), 
                        cptr, parser);
                    rnet->on_server_session_accepted(server_session);
                }

                message_ex* recv_msg = virtual_send_message(msg);

                {
                    node_scoper ns(rnet->node());

                    bool ret = server_session->on_recv_message(recv_msg,
                        recv_msg->to_address == recv_msg->header->from_address ?
                        0 : rnet->net_delay_milliseconds()
                        );
                    dassert(ret, "");
                }
            }
        }

        on_send_completed(sig);
    }
Exemplo n.º 6
0
        void hpc_rpc_session::do_safe_write(message_ex* msg)
        {
            utils::auto_lock<utils::ex_lock_nr> l(_send_lock);

            if (nullptr == msg)
            {
                if (_sending_msg)
                {
                    do_write(_sending_msg);
                }
                else
                {
                    _send_lock.unlock(); // avoid recursion
                    on_send_completed(nullptr); // send next msg if there is.
                    _send_lock.lock();
                }
            }
            else
            {
                do_write(msg);
            }
        }
Exemplo n.º 7
0
void hpc_rpc_session::do_write(message_ex* msg)
{
    add_ref();

    _write_event.callback = [this](int err, uint32_t length, uintptr_t lolp)
    {
        dassert((LPOVERLAPPED)lolp == &_write_event.olp, "must be exact this overlapped");
        if (err != ERROR_SUCCESS)
        {
            dwarn("WSASend failed, err = %d", err);
            on_failure();
        }
        else
        {
            int len = (int)length;
            int buf_i = _sending_buffer_start_index;
            while (len > 0)
            {
                auto& buf = _sending_buffers[buf_i];
                if (len >= (int)buf.sz)
                {
                    buf_i++;
                    len -= (int)buf.sz;
                }
                else
                {
                    buf.buf = (char*)buf.buf + len;
                    buf.sz -= (uint32_t)len;
                    break;
                }
            }
            _sending_buffer_start_index = buf_i;

            // message completed, continue next message
            if (_sending_buffer_start_index == (int)_sending_buffers.size())
            {
                dassert(len == 0, "buffer must be sent completely");
                auto lmsg = _sending_msg;
                _sending_msg = nullptr;
                on_send_completed(lmsg);
            }
            else
                do_write(_sending_msg);
        }

        release_ref();
    };
    memset(&_write_event.olp, 0, sizeof(_write_event.olp));

    // new msg
    if (_sending_msg != msg)
    {
        dassert(_sending_msg == nullptr, "only one sending msg is possible");
        _sending_msg = msg;
        _sending_buffer_start_index = 0;
    }

    // continue old msg
    else
    {
        // nothing to do
    }

    int buffer_count = (int)_sending_buffers.size() - _sending_buffer_start_index;
    static_assert (sizeof(dsn_message_parser::send_buf) == sizeof(WSABUF), "make sure they are compatible");

    DWORD bytes = 0;
    int rt = WSASend(
                 _socket,
                 (LPWSABUF)&_sending_buffers[_sending_buffer_start_index],
                 (DWORD)buffer_count,
                 &bytes,
                 0,
                 &_write_event.olp,
                 NULL
             );

    if (SOCKET_ERROR == rt && (WSAGetLastError() != ERROR_IO_PENDING))
    {
        dwarn("WSASend failed, err = %d", ::WSAGetLastError());
        release_ref();
        on_failure();
    }

    //dinfo("WSASend called, err = %d", rt);
}
Exemplo n.º 8
0
        void hpc_rpc_session::do_write(message_ex* msg)
        {
            static_assert (sizeof(dsn_message_parser::send_buf) == sizeof(struct iovec), 
                "make sure they are compatible");

            dbg_dassert(msg != nullptr, "cannot send empty msg");
                        
            // new msg
            if (_sending_msg == nullptr)
            {
                _sending_msg = msg;
                _sending_buffer_start_index = 0;
            }

            // continue old msg
            else
            {
                dassert(_sending_msg == msg, "only one sending msg is possible");
            }

            // prepare send buffer, make sure header is already in the buffer
            while (true)
            {
                int buffer_count = (int)_sending_buffers.size() - _sending_buffer_start_index;
                struct msghdr hdr;
                memset((void*)&hdr, 0, sizeof(hdr));
                hdr.msg_name = (void*)&_peer_addr;
                hdr.msg_namelen = (socklen_t)sizeof(_peer_addr);
                hdr.msg_iov = (struct iovec*)&_sending_buffers[_sending_buffer_start_index];
                hdr.msg_iovlen = (size_t)buffer_count;

                int sz = sendmsg(_socket, &hdr, MSG_NOSIGNAL);
                int err = errno;
                dinfo("(s = %d) call sendmsg on %s:%hu, return %d, err = %s",
                    _socket,
                    _remote_addr.name(),
                    _remote_addr.port(),
                    sz,
                    strerror(err)
                    );

                if (sz < 0)
                {
                    if (err != EAGAIN && err != EWOULDBLOCK)
                    {
                        derror("(s = %d) sendmsg failed, err = %s", _socket, strerror(err));
                        on_failure();                        
                    }
                    else
                    {
                        // wait for epoll_wait notification
                    }
                    return;
                }
                else
                {
                    int len = (int)sz;
                    int buf_i = _sending_buffer_start_index;
                    while (len > 0)
                    {
                        auto& buf = _sending_buffers[buf_i];
                        if (len >= (int)buf.sz)
                        {
                            buf_i++;
                            len -= (int)buf.sz;
                        }
                        else
                        {
                            buf.buf = (char*)buf.buf + len;
                            buf.sz -= len;
                            break;
                        }
                    }
                    _sending_buffer_start_index = buf_i;

                    // message completed, continue next message
                    if (_sending_buffer_start_index == (int)_sending_buffers.size())
                    {
                        dassert(len == 0, "buffer must be sent completely");
                        _sending_msg = nullptr;

                        _send_lock.unlock(); // avoid recursion
                        // try next msg recursively
                        on_send_completed(msg);
                        _send_lock.lock();
                        return;
                    }

                    else
                    {
                        // try next while(true) loop to continue sending current msg
                    }
                }
            }
        }