Proper handling of DNS issues (#197)
* Fixed dns resolver issues * fixed supported-variants in login
This commit is contained in:
parent
0d2f4d1c7a
commit
6687d56910
5 changed files with 53 additions and 9 deletions
|
@ -65,7 +65,7 @@ public:
|
||||||
m_socket.connect(endpointIterator, boost::bind(&BoostConnection::handleConnect, this->shared_from_this(),
|
m_socket.connect(endpointIterator, boost::bind(&BoostConnection::handleConnect, this->shared_from_this(),
|
||||||
boost::asio::placeholders::error));
|
boost::asio::placeholders::error));
|
||||||
} else {
|
} else {
|
||||||
notifyError(std::string("[DNS resolve] ") + error.message());
|
notifyDNSError(std::string("[DNS resolve] ") + error.message());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
|
||||||
uv_async_init(uv_default_loop(), &onConnectedAsync, Client::onConnected);
|
uv_async_init(uv_default_loop(), &onConnectedAsync, Client::onConnected);
|
||||||
uv_async_init(uv_default_loop(), &onReceivedAsync, Client::onReceived);
|
uv_async_init(uv_default_loop(), &onReceivedAsync, Client::onReceived);
|
||||||
uv_async_init(uv_default_loop(), &onErrorAsync, Client::onError);
|
uv_async_init(uv_default_loop(), &onErrorAsync, Client::onError);
|
||||||
|
uv_async_init(uv_default_loop(), &onDNSErrorAsync, Client::onDNSError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -96,7 +97,7 @@ void Client::connect(const Url *url)
|
||||||
|
|
||||||
void Client::connect()
|
void Client::connect()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("connect");
|
LOG_DEBUG("[%d] connect", m_id);
|
||||||
|
|
||||||
m_connection = establishConnection(shared_from_this(),
|
m_connection = establishConnection(shared_from_this(),
|
||||||
m_url.useTls() ? CONNECTION_TYPE_TLS : CONNECTION_TYPE_TCP,
|
m_url.useTls() ? CONNECTION_TYPE_TLS : CONNECTION_TYPE_TCP,
|
||||||
|
@ -106,13 +107,15 @@ void Client::connect()
|
||||||
|
|
||||||
void Client::disconnect()
|
void Client::disconnect()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("disconnect");
|
LOG_DEBUG("[%d] disconnect", m_id);
|
||||||
|
|
||||||
uv_timer_stop(&m_keepAliveTimer);
|
uv_timer_stop(&m_keepAliveTimer);
|
||||||
|
|
||||||
m_expire = 0;
|
m_expire = 0;
|
||||||
m_failures = -1;
|
m_failures = -1;
|
||||||
|
|
||||||
|
LOG_DEBUG("[%d] disconnect set m_failure to -1", m_id);
|
||||||
|
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,7 +333,7 @@ int64_t Client::send(char* buf, size_t size)
|
||||||
|
|
||||||
void Client::close()
|
void Client::close()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("close");
|
LOG_DEBUG("[%d] close", m_id);
|
||||||
|
|
||||||
if (m_connection) {
|
if (m_connection) {
|
||||||
m_connection->disconnect();
|
m_connection->disconnect();
|
||||||
|
@ -364,7 +367,8 @@ void Client::login()
|
||||||
|
|
||||||
rapidjson::Value supportedPowVariantsList(rapidjson::kArrayType);
|
rapidjson::Value supportedPowVariantsList(rapidjson::kArrayType);
|
||||||
for (auto& supportedPowVariant : getSupportedPowVariants()) {
|
for (auto& supportedPowVariant : getSupportedPowVariants()) {
|
||||||
supportedPowVariantsList.PushBack(rapidjson::StringRef(supportedPowVariant.c_str()), allocator);
|
rapidjson::Value val(supportedPowVariant.c_str(), allocator);
|
||||||
|
supportedPowVariantsList.PushBack(val, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
params.AddMember("supported-variants", supportedPowVariantsList, allocator);
|
params.AddMember("supported-variants", supportedPowVariantsList, allocator);
|
||||||
|
@ -517,7 +521,9 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap
|
||||||
return reconnect();
|
return reconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG("[%d] login set m_failure to 0", m_id);
|
||||||
m_failures = 0;
|
m_failures = 0;
|
||||||
|
|
||||||
m_listener->onLoginSuccess(this);
|
m_listener->onLoginSuccess(this);
|
||||||
m_listener->onJobReceived(this, m_job);
|
m_listener->onJobReceived(this, m_job);
|
||||||
return;
|
return;
|
||||||
|
@ -553,7 +559,7 @@ void Client::ping()
|
||||||
|
|
||||||
void Client::reconnect()
|
void Client::reconnect()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("reconnect");
|
LOG_DEBUG("[%d] reconnect", m_id);
|
||||||
|
|
||||||
close();
|
close();
|
||||||
|
|
||||||
|
@ -562,11 +568,12 @@ void Client::reconnect()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_failures == -1) {
|
if (m_failures == -1) {
|
||||||
LOG_DEBUG("reconnect -> m_failures == -1");
|
LOG_DEBUG("[%d] reconnect -> m_failures == -1", m_id);
|
||||||
return m_listener->onClose(this, -1);
|
return m_listener->onClose(this, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_failures++;
|
m_failures++;
|
||||||
|
LOG_DEBUG("[%d] increment m_failures to: %d", m_id, m_failures);
|
||||||
m_listener->onClose(this, (int) m_failures);
|
m_listener->onClose(this, (int) m_failures);
|
||||||
|
|
||||||
m_expire = uv_now(uv_default_loop()) + m_retryPause;
|
m_expire = uv_now(uv_default_loop()) + m_retryPause;
|
||||||
|
@ -636,10 +643,9 @@ void Client::scheduleOnReceived(char* data, std::size_t size)
|
||||||
|
|
||||||
void Client::onError(uv_async_t *handle)
|
void Client::onError(uv_async_t *handle)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("onError");
|
|
||||||
|
|
||||||
auto client = getClient(handle->data);
|
auto client = getClient(handle->data);
|
||||||
if (client) {
|
if (client) {
|
||||||
|
LOG_DEBUG("[%d] onError", client->m_id);
|
||||||
client->reconnect();
|
client->reconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -655,3 +661,28 @@ void Client::scheduleOnError(const std::string &error)
|
||||||
onErrorAsync.data = this;
|
onErrorAsync.data = this;
|
||||||
uv_async_send(&onErrorAsync);
|
uv_async_send(&onErrorAsync);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::onDNSError(uv_async_t *handle)
|
||||||
|
{
|
||||||
|
auto client = getClient(handle->data);
|
||||||
|
if (client) {
|
||||||
|
if (client->m_failures == -1) {
|
||||||
|
client->m_failures = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG("[%d] onDNSError", client->m_id);
|
||||||
|
client->reconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::scheduleOnDNSError(const std::string &error)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("scheduleOnDNSError");
|
||||||
|
|
||||||
|
if (!m_quiet) {
|
||||||
|
LOG_ERR("[%s:%u] DNS Error: \"%s\"", m_url.host(), m_url.port(), error.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
onDNSErrorAsync.data = this;
|
||||||
|
uv_async_send(&onDNSErrorAsync);
|
||||||
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@ public:
|
||||||
static void onConnected(uv_async_t *handle);
|
static void onConnected(uv_async_t *handle);
|
||||||
static void onReceived(uv_async_t *handle);
|
static void onReceived(uv_async_t *handle);
|
||||||
static void onError(uv_async_t *handle);
|
static void onError(uv_async_t *handle);
|
||||||
|
static void onDNSError(uv_async_t *handle);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isCriticalError(const char *message);
|
bool isCriticalError(const char *message);
|
||||||
|
@ -92,6 +93,7 @@ private:
|
||||||
virtual void scheduleOnConnected();
|
virtual void scheduleOnConnected();
|
||||||
virtual void scheduleOnReceived(char *data, size_t size);
|
virtual void scheduleOnReceived(char *data, size_t size);
|
||||||
virtual void scheduleOnError(const std::string &error);
|
virtual void scheduleOnError(const std::string &error);
|
||||||
|
virtual void scheduleOnDNSError(const std::string &error);
|
||||||
|
|
||||||
static inline Client *getClient(void *data) { return static_cast<Client*>(data); }
|
static inline Client *getClient(void *data) { return static_cast<Client*>(data); }
|
||||||
|
|
||||||
|
@ -122,6 +124,7 @@ private:
|
||||||
uv_async_t onConnectedAsync;
|
uv_async_t onConnectedAsync;
|
||||||
uv_async_t onReceivedAsync;
|
uv_async_t onReceivedAsync;
|
||||||
uv_async_t onErrorAsync;
|
uv_async_t onErrorAsync;
|
||||||
|
uv_async_t onDNSErrorAsync;
|
||||||
|
|
||||||
uv_timer_t m_keepAliveTimer;
|
uv_timer_t m_keepAliveTimer;
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,14 @@ void Connection::notifyError(const std::string& error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Connection::notifyDNSError(const std::string& error)
|
||||||
|
{
|
||||||
|
ConnectionListener::Ptr listener = listener_.lock();
|
||||||
|
if (listener)
|
||||||
|
{
|
||||||
|
listener->scheduleOnDNSError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Connection::Ptr establishConnection(const ConnectionListener::Ptr& listener,
|
Connection::Ptr establishConnection(const ConnectionListener::Ptr& listener,
|
||||||
ConnectionType type, const std::string& host, uint16_t port)
|
ConnectionType type, const std::string& host, uint16_t port)
|
||||||
|
|
|
@ -39,6 +39,7 @@ public:
|
||||||
virtual void scheduleOnConnected() = 0;
|
virtual void scheduleOnConnected() = 0;
|
||||||
virtual void scheduleOnReceived(char *data, std::size_t size) = 0;
|
virtual void scheduleOnReceived(char *data, std::size_t size) = 0;
|
||||||
virtual void scheduleOnError(const std::string &error) = 0;
|
virtual void scheduleOnError(const std::string &error) = 0;
|
||||||
|
virtual void scheduleOnDNSError(const std::string &error) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Connection : private boost::noncopyable
|
class Connection : private boost::noncopyable
|
||||||
|
@ -61,6 +62,7 @@ public:
|
||||||
void notifyConnected();
|
void notifyConnected();
|
||||||
void notifyRead(char* data, size_t size);
|
void notifyRead(char* data, size_t size);
|
||||||
void notifyError(const std::string& error);
|
void notifyError(const std::string& error);
|
||||||
|
void notifyDNSError(const std::string& error);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConnectionListener::WeakPtr listener_;
|
ConnectionListener::WeakPtr listener_;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue