diff --git a/src/aria2.cpp b/src/aria2.cpp index e58b2bd67..206a3032e 100644 --- a/src/aria2.cpp +++ b/src/aria2.cpp @@ -4,6 +4,7 @@ #include "xmlrpc.h" #include #include +#include #include #include #include @@ -29,6 +30,31 @@ namespace kiwix { +namespace { + +void pauseAnyActiveDownloads(const std::string& ariaSessionFilePath) +{ + std::ifstream inputFile(ariaSessionFilePath); + if ( !inputFile ) + return; + + std::ostringstream ss; + std::string line; + while ( std::getline(inputFile, line) ) { + if ( !startsWith(line, " pause=") ) { + ss << line << "\n"; + } + if ( !line.empty() && line[0] != ' ' && line[0] != '#' ) { + ss << " pause=true\n"; + } + } + + std::ofstream outputFile(ariaSessionFilePath); + outputFile << ss.str(); +} + +} // unnamed namespace + Aria2::Aria2(): mp_aria(nullptr), m_port(42042), @@ -41,6 +67,7 @@ Aria2::Aria2(): std::string rpc_port = "--rpc-listen-port=" + to_string(m_port); std::string download_dir = "--dir=" + getDataDirectory(); std::string session_file = appendToDirectory(getDataDirectory(), "kiwix.session"); + pauseAnyActiveDownloads(session_file); std::string session = "--save-session=" + session_file; std::string inputFile = "--input-file=" + session_file; // std::string log_dir = "--log=\"" + logDir + "\""; @@ -97,20 +124,30 @@ Aria2::Aria2(): curl_easy_setopt(p_curl, CURLOPT_PORT, m_port); curl_easy_setopt(p_curl, CURLOPT_POST, 1L); curl_easy_setopt(p_curl, CURLOPT_ERRORBUFFER, curlErrorBuffer); + curl_easy_setopt(p_curl, CURLOPT_TIMEOUT_MS, 100); + + typedef std::chrono::duration Seconds; - int watchdog = 50; - 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); curlErrorBuffer[0] = 0; - auto res = curl_easy_perform(p_curl); + res = curl_easy_perform(p_curl); if (res == CURLE_OK) { break; - } else if (watchdog == 1) { - LOG_ARIA_ERROR(); } + + const auto dt = std::chrono::steady_clock::now() - t0; + const double elapsedTime = std::chrono::duration_cast(dt).count(); + maxWaitingTimeWasExceeded = elapsedTime > MAX_WAITING_TIME_SECONDS; } 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); } } diff --git a/src/downloader.cpp b/src/downloader.cpp index 25dfc1e95..5193c51de 100644 --- a/src/downloader.cpp +++ b/src/downloader.cpp @@ -151,11 +151,20 @@ Downloader::Downloader() : /* Destructor */ Downloader::~Downloader() { + close(); } void Downloader::close() { - mp_aria->close(); + if ( mp_aria ) { + try { + mp_aria->close(); + } catch (const std::exception& err) { + std::cerr << "ERROR: Failed to save the downloader state: " + << err.what() << std::endl; + } + mp_aria.reset(); + } } std::vector Downloader::getDownloadIds() const {