开发者

boost asio "A non-recoverable error occurred during database lookup"

开发者 https://www.devze.com 2023-04-02 13:01 出处:网络
I\'m currently stress testing my server. sometimes I get \"A non-recoverable error occurred during database lookup\" Error

I'm currently stress testing my server.

sometimes I get "A non-recoverable error occurred during database lookup" Error coming from error.message()

error is sent to my handling function by boost::asio::placeholders::error called on the asy开发者_如何学Gonc_read method.

I have no idea what this error means, and I am not able to reproduce purposely this error, it only happen sometimes and seems to be random (of course it is not, but it seems)

Does anyone have ever got this error message, and if so, know where it came from ?


EDIT 1

Here's what I found on the boost library, the error is :

no_recovery = BOOST_ASIO_NETDB_ERROR(NO_RECOVERY)

But can't figure out what this is...


EDIT 2

Just so you know everything about my problem, here the design :

I have only one io_service. Everytime a user is connecting, an async_read is starting, waiting for something to read. When it reads something, most of the time, it is doing some work on a thread (coming from a pool), and write something synchronously back to the user. (using boost write). Even since boost 1.37 claims that synchronous write is thread safe, I'm really worried about the fact that it is coming from this.

If the user sends different message really quick, it can happen that async_read and write are called simultaneously, can it does any harm ?


EDIT 3

Here's some portion of my code asked by Dave S :

    void TCPConnection::listenForCMD() {
    boost::asio::async_read(m_socket,
                            boost::asio::buffer(m_inbound_data, 3),
                            boost::asio::transfer_at_least(3),
                            boost::bind(&TCPConnection::handle_cmd,
                                        shared_from_this(),
                                        boost::asio::placeholders::error)
                            );
  }

      void TCPConnection::handle_cmd(const boost::system::error_code& error) {
        if (error) {
          std::cout << "ERROR READING : " << error.message() << std::endl;
    return;
        }                                                                                                                                                                                                                              
          std::string str1(m_inbound_data);
          std::string str = str1.substr(0,3);

          std::cout << "COMMAND FUNCTION: " << str << std::endl;

          a_fact func = CommandFactory::getInstance()->getFunction(str);

          if (func == NULL) {
            std::cout << "command doesn't exist: " << str << std::endl;
            return;
          }

          protocol::in::Command::pointer cmd = func(m_socket, client);

          cmd->setCallback(boost::bind(&TCPConnection::command_is_done,
                                       shared_from_this()));
          cmd->parse();                                                                                                                                                                                                                                   
      }

m_inbound_data is a char[3]

Once cmd->parse() is done, it will call a callback command_is_done

  void TCPConnection::command_is_done() {                                                                                                                                                                                                                   
    m_inbound_data[0] = '0';
    m_inbound_data[1] = '0';
    m_inbound_data[2] = '0';

    listenForCMD();
  }

The error occurs in the handle_cmd when checking for error at the first line.

As I said before, the cmd->parse() will parse the command it just got, sometime lauching blocking code in a thread coming from a pool. On this thread it sends back data to the client with a synchronous write.

IMPORTANT THING : The callback command_is_done will always be called before the said thread is launched. this means that listenForCMD is already called when the thread may send something back to the client in synchronous write. Therefore my first worries.


When it reads something, most of the time, it is doing some work on a thread (coming from a pool), and write something synchronously back to the user. (using boost write). Even since boost 1.37 claims that synchronous write is thread safe, I'm really worried about the fact that it is coming from this.

Emphasis added by me, this is incorrect. A single boost::asio::tcp::socket is not thread safe, the documentation is very clear

Thread Safety

Distinct objects: Safe.

Shared objects: Unsafe.

It is also very odd to mix async_read() with a blocking write().

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号