mirror of https://github.com/kiwix/libkiwix.git
Defense against non-responsive aria RPC on startup
Downloader constructor may get stuck if the check for the aria2c RPC being up gets stuck due to curl_easy_perform() never returning (or, at least, taking longer than I was willing to wait). Currently it may happen, for example, after an application crashes with active downloads being saved to slow media. Then the next creation of a Downloader object will deal with aria2c immediately resuming those downloads and becoming unresponsive as it struggles flushing incoming data to slow storage (or because of some other unfortunate timing of the RPC request being received while it cannot yet be served).
This commit is contained in:
parent
e8afcbe6ae
commit
42295c9010
|
@ -97,20 +97,30 @@ Aria2::Aria2():
|
||||||
curl_easy_setopt(p_curl, CURLOPT_PORT, m_port);
|
curl_easy_setopt(p_curl, CURLOPT_PORT, m_port);
|
||||||
curl_easy_setopt(p_curl, CURLOPT_POST, 1L);
|
curl_easy_setopt(p_curl, CURLOPT_POST, 1L);
|
||||||
curl_easy_setopt(p_curl, CURLOPT_ERRORBUFFER, curlErrorBuffer);
|
curl_easy_setopt(p_curl, CURLOPT_ERRORBUFFER, curlErrorBuffer);
|
||||||
|
curl_easy_setopt(p_curl, CURLOPT_TIMEOUT_MS, 100);
|
||||||
|
|
||||||
int watchdog = 50;
|
typedef std::chrono::duration<double> Seconds;
|
||||||
while(--watchdog) {
|
|
||||||
|
const double MAX_WAITING_TIME_SECONDS = 0.5;
|
||||||
|
const auto t0 = std::chrono::steady_clock::now();
|
||||||
|
bool maxWaitingTimeWasExceeded = false;
|
||||||
|
|
||||||
|
CURLcode res = CURLE_OK;
|
||||||
|
while ( !maxWaitingTimeWasExceeded ) {
|
||||||
sleep(10);
|
sleep(10);
|
||||||
curlErrorBuffer[0] = 0;
|
curlErrorBuffer[0] = 0;
|
||||||
auto res = curl_easy_perform(p_curl);
|
res = curl_easy_perform(p_curl);
|
||||||
if (res == CURLE_OK) {
|
if (res == CURLE_OK) {
|
||||||
break;
|
break;
|
||||||
} else if (watchdog == 1) {
|
|
||||||
LOG_ARIA_ERROR();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto dt = std::chrono::steady_clock::now() - t0;
|
||||||
|
const double elapsedTime = std::chrono::duration_cast<Seconds>(dt).count();
|
||||||
|
maxWaitingTimeWasExceeded = elapsedTime > MAX_WAITING_TIME_SECONDS;
|
||||||
}
|
}
|
||||||
curl_easy_cleanup(p_curl);
|
curl_easy_cleanup(p_curl);
|
||||||
if (!watchdog) {
|
if ( maxWaitingTimeWasExceeded ) {
|
||||||
|
LOG_ARIA_ERROR();
|
||||||
throw std::runtime_error("Cannot connect to aria2c rpc. Aria2c launch cmd : " + launchCmd);
|
throw std::runtime_error("Cannot connect to aria2c rpc. Aria2c launch cmd : " + launchCmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue