JobClient: resolve endpoint only once
The JobClient now resolves the server IP once (lazily, when needed) instead on each connect attempt, reducing the amount of DNS requests sent out. Change-Id: I9804048d3252da333cb3addbe94a01fdf3c707c8
This commit is contained in:
@ -3,6 +3,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
#include <boost/optional.hpp>
|
||||||
#include <boost/array.hpp>
|
#include <boost/array.hpp>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
|
|
||||||
@ -16,6 +17,7 @@ namespace fail {
|
|||||||
struct JobClient::impl {
|
struct JobClient::impl {
|
||||||
io_service ios;
|
io_service ios;
|
||||||
ip::tcp::socket socket;
|
ip::tcp::socket socket;
|
||||||
|
boost::optional<ip::tcp::endpoint> endpoint;
|
||||||
|
|
||||||
impl() : socket(ios) {}
|
impl() : socket(ios) {}
|
||||||
};
|
};
|
||||||
@ -46,32 +48,41 @@ bool JobClient::connectToServer()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::asio::ip::tcp::resolver resolver(m_d->ios);
|
|
||||||
boost::asio::ip::tcp::resolver::query query(
|
|
||||||
m_server, std::to_string(m_server_port));
|
|
||||||
|
|
||||||
// random engine for backoff.
|
// random engine for backoff.
|
||||||
std::mt19937_64 engine(time(NULL));
|
std::mt19937_64 engine(time(NULL));
|
||||||
|
|
||||||
for (int tries = CLIENT_RETRY_COUNT + 1; tries > 0; --tries) {
|
for (int tries = CLIENT_RETRY_COUNT + 1; tries > 0; --tries) {
|
||||||
for (ip::tcp::resolver::iterator end,
|
// resolve endpoint lazily
|
||||||
addrs = resolver.resolve(query);
|
if (!m_d->endpoint) {
|
||||||
addrs != end; ++addrs) {
|
boost::asio::ip::tcp::resolver resolver(m_d->ios);
|
||||||
// server listens on IPv4 endpoint only, skip IPv6 endpoints
|
boost::asio::ip::tcp::resolver::query query(
|
||||||
if (!addrs->endpoint().address().is_v4()) {
|
m_server, std::to_string(m_server_port));
|
||||||
|
|
||||||
|
for (ip::tcp::resolver::iterator end,
|
||||||
|
addrs = resolver.resolve(query);
|
||||||
|
addrs != end; ++addrs) {
|
||||||
|
// server listens on IPv4 endpoint only, skip IPv6 endpoints
|
||||||
|
if (addrs->endpoint().address().is_v4()) {
|
||||||
|
m_d->endpoint = addrs->endpoint();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_d->endpoint) {
|
||||||
|
cerr << "[Client] Failed to resolve " << m_server << endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
boost::system::error_code error;
|
|
||||||
m_d->socket.connect(addrs->endpoint(), error);
|
|
||||||
if (!error) {
|
|
||||||
cout << "[Client] Connection established!"
|
|
||||||
<< endl;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
perror("[Client@connect()]");
|
|
||||||
m_d->socket.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::system::error_code error;
|
||||||
|
m_d->socket.connect(*m_d->endpoint, error);
|
||||||
|
if (!error) {
|
||||||
|
cout << "[Client] Connection established!" << endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
perror("[Client@connect()]");
|
||||||
|
m_d->socket.close();
|
||||||
|
|
||||||
std::uniform_real_distribution<> distribution(
|
std::uniform_real_distribution<> distribution(
|
||||||
CLIENT_RAND_BACKOFF_TSTART, CLIENT_RAND_BACKOFF_TEND);
|
CLIENT_RAND_BACKOFF_TSTART, CLIENT_RAND_BACKOFF_TEND);
|
||||||
const auto delay = std::chrono::duration<double>(distribution(engine));
|
const auto delay = std::chrono::duration<double>(distribution(engine));
|
||||||
|
|||||||
Reference in New Issue
Block a user