diff options
author | Arsentiy Milchakov <milcars@mapswithme.com> | 2021-03-29 13:26:27 +0300 |
---|---|---|
committer | Aleksandr Zatsepin <alexander.zatsepin@mail.ru> | 2021-03-30 13:59:46 +0300 |
commit | 3fa87adcaf9815d3f37b257084cab166aece8bb1 (patch) | |
tree | 9750013cfe7fa59b7e3edb109e637f30c537328d | |
parent | 29882b4dbeb0b7c7d3305fceb316328f6bd954b0 (diff) |
[downloader] server with shortest response time is used first during map downloading.
-rw-r--r-- | storage/pinger.cpp | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/storage/pinger.cpp b/storage/pinger.cpp index 0bc9f5971f..0fabc407f2 100644 --- a/storage/pinger.cpp +++ b/storage/pinger.cpp @@ -10,16 +10,21 @@ #include "3party/Alohalytics/src/alohalytics.h" +#include <chrono> +#include <map> #include <sstream> #include <utility> using namespace std; +using namespace std::chrono; namespace { auto constexpr kTimeoutInSeconds = 5.0; -void DoPing(string const & url, size_t index, vector<string> & readyUrls) +using ResponseTimeAndUrl = pair<int32_t, string>; + +void DoPing(string const & url, size_t index, vector<ResponseTimeAndUrl> & responseTimeAndUrls) { if (url.empty()) { @@ -30,9 +35,12 @@ void DoPing(string const & url, size_t index, vector<string> & readyUrls) platform::HttpClient request(url); request.SetHttpMethod("HEAD"); request.SetTimeout(kTimeoutInSeconds); + auto begin = high_resolution_clock::now(); if (request.RunHttpRequest() && !request.WasRedirected() && request.ErrorCode() == 200) { - readyUrls[index] = url; + auto end = high_resolution_clock::now(); + auto responseTime = duration_cast<milliseconds>(end - begin).count(); + responseTimeAndUrls[index] = {responseTime, url}; } else { @@ -56,19 +64,26 @@ namespace storage // static Pinger::Endpoints Pinger::ExcludeUnavailableEndpoints(Endpoints const & urls) { + using base::thread_pool::delayed::ThreadPool; + auto const size = urls.size(); CHECK_GREATER(size, 0, ()); - vector<string> readyUrls(size); + vector<ResponseTimeAndUrl> responseTimeAndUrls(size); { - base::thread_pool::delayed::ThreadPool t(size); + ThreadPool t(size, ThreadPool::Exit::ExecPending); for (size_t i = 0; i < size; ++i) - t.Push([url = urls[i], &readyUrls, i] { DoPing(url, i, readyUrls); }); + t.Push([url = urls[i], &responseTimeAndUrls, i] { DoPing(url, i, responseTimeAndUrls); }); + } - t.Shutdown(base::thread_pool::delayed::ThreadPool::Exit::ExecPending); + sort(responseTimeAndUrls.begin(), responseTimeAndUrls.end()); + + vector<string> readyUrls; + for (auto & [_, url] : responseTimeAndUrls) + { + readyUrls.push_back(move(url)); } - base::EraseIf(readyUrls, [](auto const & url) { return url.empty(); }); SendStatistics(readyUrls.size()); return readyUrls; } |