socket_server should accept and drop connections when it hits the limit. This relieves the operating system from managing listening socket overflow. (#2929)
The existing implementation didn't attempt to evict stale connections before testing if after an overflow occurred, possibly needlessly disconnecting a connection. After an overflow, the listening socket also wouldn't accept connections for 2 seconds, regardless of whether a connection goes stale during that time.
This commit is contained in:
parent
aa5c5fd5ce
commit
97afc803b3
2 changed files with 16 additions and 30 deletions
|
@ -325,7 +325,7 @@ size_t nano::socket::get_max_write_queue_size () const
|
|||
}
|
||||
|
||||
nano::server_socket::server_socket (std::shared_ptr<nano::node> node_a, boost::asio::ip::tcp::endpoint local_a, size_t max_connections_a, nano::socket::concurrency concurrency_a) :
|
||||
socket (node_a, std::chrono::seconds::max (), concurrency_a), acceptor (node_a->io_ctx), local (local_a), deferred_accept_timer (node_a->io_ctx), max_inbound_connections (max_connections_a), concurrency_new_connections (concurrency_a)
|
||||
socket (node_a, std::chrono::seconds::max (), concurrency_a), acceptor (node_a->io_ctx), local (local_a), max_inbound_connections (max_connections_a), concurrency_new_connections (concurrency_a)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -367,14 +367,15 @@ void nano::server_socket::on_connection (std::function<bool(std::shared_ptr<nano
|
|||
{
|
||||
if (this_l->acceptor.is_open ())
|
||||
{
|
||||
if (this_l->connections.size () < this_l->max_inbound_connections)
|
||||
{
|
||||
// Prepare new connection
|
||||
auto new_connection (std::make_shared<nano::socket> (node_l->shared (), boost::none, this_l->concurrency_new_connections));
|
||||
this_l->acceptor.async_accept (new_connection->tcp_socket, new_connection->remote,
|
||||
boost::asio::bind_executor (this_l->strand,
|
||||
[this_l, new_connection, callback_a](boost::system::error_code const & ec_a) {
|
||||
if (auto node_l = this_l->node.lock ())
|
||||
// Prepare new connection
|
||||
auto new_connection (std::make_shared<nano::socket> (node_l->shared (), boost::none, this_l->concurrency_new_connections));
|
||||
this_l->acceptor.async_accept (new_connection->tcp_socket, new_connection->remote,
|
||||
boost::asio::bind_executor (this_l->strand,
|
||||
[this_l, new_connection, callback_a](boost::system::error_code const & ec_a) {
|
||||
this_l->evict_dead_connections ();
|
||||
if (auto node_l = this_l->node.lock ())
|
||||
{
|
||||
if (this_l->connections.size () < this_l->max_inbound_connections)
|
||||
{
|
||||
if (!ec_a)
|
||||
{
|
||||
|
@ -384,7 +385,6 @@ void nano::server_socket::on_connection (std::function<bool(std::shared_ptr<nano
|
|||
new_connection->start_timer (node_l->network_params.network.is_dev_network () ? std::chrono::seconds (2) : node_l->network_params.node.idle_timeout);
|
||||
node_l->stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_accept_success, nano::stat::dir::in);
|
||||
this_l->connections.push_back (new_connection);
|
||||
this_l->evict_dead_connections ();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -401,28 +401,15 @@ void nano::server_socket::on_connection (std::function<bool(std::shared_ptr<nano
|
|||
node_l->logger.try_log ("Stopping to accept connections");
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
this_l->evict_dead_connections ();
|
||||
node_l->stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_accept_failure, nano::stat::dir::in);
|
||||
this_l->deferred_accept_timer.expires_after (std::chrono::seconds (2));
|
||||
this_l->deferred_accept_timer.async_wait ([this_l, callback_a](const boost::system::error_code & ec_a) {
|
||||
if (!ec_a)
|
||||
{
|
||||
// Try accepting again
|
||||
std::static_pointer_cast<nano::server_socket> (this_l)->on_connection (callback_a);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto node_l = this_l->node.lock ())
|
||||
{
|
||||
node_l->logger.try_log ("Unable to accept connection (deferred): ", ec_a.message ());
|
||||
}
|
||||
node_l->stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_accept_failure, nano::stat::dir::in);
|
||||
boost::asio::post (this_l->strand, boost::asio::bind_executor (this_l->strand, [this_l, callback_a]() {
|
||||
this_l->on_connection (callback_a);
|
||||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}));
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
|
|
@ -132,7 +132,6 @@ private:
|
|||
std::vector<std::weak_ptr<nano::socket>> connections;
|
||||
boost::asio::ip::tcp::acceptor acceptor;
|
||||
boost::asio::ip::tcp::endpoint local;
|
||||
boost::asio::steady_timer deferred_accept_timer;
|
||||
size_t max_inbound_connections;
|
||||
/** Concurrency setting for new connections */
|
||||
concurrency concurrency_new_connections;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue