Vishal Kumar Vishal Kumar - 11 days ago 9
C++ Question

Server hangs for while after 16000 requests

I am new to boost::asio. Trying to run

ab -n 20000 -c 5 -r http://127.0.0.1:9999/

Test gets stuck after 16000 request every time. But it does complete. Also I get lots of failed request.


What code is doing :

A. Create Service

B. Create Acceptor

C. Bind and listen

D. Create Socket

F. Do async_connect

G. In async_connect handler close socket. Create New One And do async_connect with same handler.

Code follows :

#include <iostream>
#include <functional>
#include <string>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <memory>

//global variable for service and acceptor
boost::asio::io_service ioService;
boost::asio::ip::tcp::acceptor accp(ioService);

//callback for accept
void onAccept(const boost::system::error_code& ec,shared_ptr<boost::asio::ip::tcp::socket> soc){
using boost::asio::ip::tcp;
soc->send(boost::asio::buffer("In Accept"));
soc->shutdown(boost::asio::ip::tcp::socket::shutdown_send);
soc.reset(new tcp::socket(ioService));
accp.async_accept(*soc, [=](const boost::system::error_code& ec){
onAccept(ec, soc);
});
}

int main( int argc, char * argv[] )
{
using boost::asio::ip::tcp;
boost::asio::ip::tcp::resolver resolver(ioService );
try{
boost::asio::ip::tcp::resolver::query query(
"127.0.0.1",
boost::lexical_cast< std::string >( 9999 )
);
boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve( query );
accp.open( endpoint.protocol() );
accp.set_option( boost::asio::ip::tcp::acceptor::reuse_address( true ) );
accp.bind( endpoint );
cout << "Ready to accept @ 9999" << endl;
auto t1 = boost::thread([&](){
ioService.run();
});
accp.listen( boost::asio::socket_base::max_connections );
std::shared_ptr<tcp::socket> soc = make_shared<tcp::socket>(ioService);
accp.async_accept(*soc, [=](const boost::system::error_code& ec){
onAccept(ec, soc);
});
t1.join();
}catch(std::exception & ex){
std::cout << "[" << boost::this_thread::get_id()
<< "] Exception: " << ex.what() << std::endl;
}
}


For completeness :

1. I changed my code as per @Arunmu

2. I used docker with linux because of socket problem suggested by @david-schwartz

3. Server never hangs now.

4. Single Thread - 6045 req per sec

2 Threads - 5849 req per sec

5. Using async_write

Answer

You're running out of local sockets. You should not be testing by generating all your load from a single IP address. (Also, your load generator should be smart enough to detect and work around this condition, but alas many aren't.)