Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArsentiy Milchakov <milcars@mapswithme.com>2016-10-07 12:35:43 +0300
committerArsentiy Milchakov <milcars@mapswithme.com>2016-10-10 18:14:45 +0300
commit53da4259b42ee24fc5c662514cb533529939ad1b (patch)
tree303df93a9f376a2a0895ec79b6ed27c8c30f6b9c /partners_api
parent4e99e7b9fc17d0a527c8598e22912046bf612869 (diff)
async changed to detached threads
Diffstat (limited to 'partners_api')
-rw-r--r--partners_api/partners_api_tests/uber_tests.cpp55
-rw-r--r--partners_api/uber_api.cpp148
-rw-r--r--partners_api/uber_api.hpp35
3 files changed, 131 insertions, 107 deletions
diff --git a/partners_api/partners_api_tests/uber_tests.cpp b/partners_api/partners_api_tests/uber_tests.cpp
index ea2e9cbdea..850f1333d7 100644
--- a/partners_api/partners_api_tests/uber_tests.cpp
+++ b/partners_api/partners_api_tests/uber_tests.cpp
@@ -1,10 +1,8 @@
#include "testing/testing.hpp"
-#include "geometry/latlon.hpp"
-
#include "partners_api/uber_api.hpp"
-#include "base/logging.hpp"
+#include "geometry/latlon.hpp"
#include "3party/jansson/myjansson.hpp"
@@ -23,7 +21,7 @@ UNIT_TEST(Uber_GetTimes)
auto const timesArray = json_object_get(timeRoot.get(), "times");
TEST(json_is_array(timesArray), ());
- TEST(json_array_size(timesArray) > 0, ());
+ TEST_GREATER(json_array_size(timesArray), 0, ());
auto const timeSize = json_array_size(timesArray);
for (size_t i = 0; i < timeSize; ++i)
@@ -39,7 +37,7 @@ UNIT_TEST(Uber_GetTimes)
}
catch (my::Json::Exception const & e)
{
- LOG(LERROR, (e.Msg()));
+ TEST(false, (e.Msg()));
}
string estimated = strings::to_string(estimatedTime);
@@ -58,7 +56,7 @@ UNIT_TEST(Uber_GetPrices)
auto const pricesArray = json_object_get(priceRoot.get(), "prices");
TEST(json_is_array(pricesArray), ());
- TEST(json_array_size(pricesArray) > 0, ());
+ TEST_GREATER(json_array_size(pricesArray), 0, ());
auto const pricesSize = json_array_size(pricesArray);
for (size_t i = 0; i < pricesSize; ++i)
@@ -85,7 +83,7 @@ UNIT_TEST(Uber_GetPrices)
}
catch (my::Json::Exception const & e)
{
- LOG(LERROR, (e.Msg()));
+ TEST(false, (e.Msg()));
}
TEST(!productId.empty(), ());
@@ -94,34 +92,39 @@ UNIT_TEST(Uber_GetPrices)
}
}
-UNIT_TEST(Uber_SmokeTest)
+UNIT_TEST(Uber_ProductMaker)
{
+ size_t reqId = 1;
ms::LatLon from(38.897724, -77.036531);
ms::LatLon to(38.862416, -76.883316);
- uber::Api uberApi;
- size_t reqId = 0;
- size_t returnedId = 0;
- vector<uber::Product> returnedProducts;
- reqId = uberApi.GetAvailableProducts(
- from, to, [&returnedId, &returnedProducts](vector<uber::Product> const & products, size_t const requestId)
+ uber::ProductMaker maker;
+
+ maker.Reset(reqId);
+ maker.SetTimes(reqId, uber::RawApi::GetEstimatedTime(from));
+ maker.SetPrices(reqId, uber::RawApi::GetEstimatedPrice(from, to));
+ maker.MakeProducts(reqId, [reqId](vector<uber::Product> const & products, size_t const requestId)
{
- returnedId = requestId;
- returnedProducts = products;
+ TEST(!products.empty(), ());
+ TEST_EQUAL(requestId, reqId, ());
- testing::StopEventLoop();
+ for (auto const & product : products)
+ {
+ TEST(!product.m_productId.empty() &&
+ !product.m_name.empty() &&
+ !product.m_time.empty() &&
+ !product.m_price.empty(),());
+ }
});
- testing::RunEventLoop();
+ ++reqId;
- TEST(!returnedProducts.empty(), ());
- TEST_EQUAL(returnedId, reqId, ());
+ maker.Reset(reqId);
+ maker.SetTimes(reqId, uber::RawApi::GetEstimatedTime(from));
+ maker.SetPrices(reqId, uber::RawApi::GetEstimatedPrice(from, to));
- for (auto const & product : returnedProducts)
+ maker.MakeProducts(reqId + 1, [reqId](vector<uber::Product> const & products, size_t const requestId)
{
- TEST(!product.m_productId.empty() &&
- !product.m_name.empty() &&
- !product.m_time.empty() &&
- !product.m_price.empty(),());
- }
+ TEST(false, ());
+ });
}
diff --git a/partners_api/uber_api.cpp b/partners_api/uber_api.cpp
index edb8908e3c..22e1b6388d 100644
--- a/partners_api/uber_api.cpp
+++ b/partners_api/uber_api.cpp
@@ -6,6 +6,7 @@
#include "base/assert.hpp"
#include "base/logging.hpp"
+#include "base/thread.hpp"
#include "std/chrono.hpp"
#include "std/future.hpp"
@@ -18,8 +19,6 @@ using namespace platform;
namespace
{
-uint32_t const kHttpMinWait = 10;
-
string RunSimpleHttpRequest(string const & url)
{
HttpClient request(url);
@@ -98,49 +97,6 @@ void FillProducts(json_t const * time, json_t const * price, vector<uber::Produc
p.m_price.empty();
}), products.end());
}
-
-void GetAvailableProductsAsync(ms::LatLon const from, ms::LatLon const to,
- size_t const requestId, atomic<bool> const & runFlag,
- uber::ProductsCallback const fn)
-{
- auto time = async(launch::async, uber::RawApi::GetEstimatedTime, ref(from));
- auto price = async(launch::async, uber::RawApi::GetEstimatedPrice, ref(from), ref(to));
-
- vector<uber::Product> products;
-
- if (!WaitForFeature(time, kHttpMinWait, runFlag) || !WaitForFeature(price, kHttpMinWait, runFlag))
- {
- return;
- }
-
- try
- {
- string timeStr = time.get();
- string priceStr = price.get();
-
- if (timeStr.empty() || priceStr.empty())
- {
- LOG(LWARNING, ("Time or price is empty, time:", timeStr, "; price:", priceStr));
- return;
- }
-
- my::Json timeRoot(timeStr.c_str());
- my::Json priceRoot(priceStr.c_str());
- auto const timesArray = json_object_get(timeRoot.get(), "times");
- auto const pricesArray = json_object_get(priceRoot.get(), "prices");
- if (CheckUberAnswer(timesArray) && CheckUberAnswer(pricesArray))
- {
- FillProducts(timesArray, pricesArray, products);
- }
- }
- catch (my::Json::Exception const & e)
- {
- LOG(LERROR, (e.Msg()));
- products.clear();
- }
-
- fn(products, requestId);
-}
} // namespace
namespace uber
@@ -176,21 +132,92 @@ string RawApi::GetEstimatedPrice(ms::LatLon const & from, ms::LatLon const & to)
return RunSimpleHttpRequest(url.str());
}
-Api::~Api()
+void ProductMaker::Reset(size_t const requestId)
+{
+ lock_guard<mutex> lock(m_mutex);
+
+ m_requestId = requestId;
+ m_times.reset();
+ m_prices.reset();
+}
+
+void ProductMaker::SetTimes(size_t const requestId, string const & times)
{
- ResetThread();
+ lock_guard<mutex> lock(m_mutex);
+
+ if (requestId != m_requestId)
+ return;
+
+ m_times = make_unique<string>(times);
+}
+
+void ProductMaker::SetPrices(size_t const requestId, string const & prices)
+{
+ lock_guard<mutex> lock(m_mutex);
+
+ if (requestId != m_requestId)
+ return;
+
+ m_prices = make_unique<string>(prices);
+}
+
+void ProductMaker::MakeProducts(size_t const requestId, ProductsCallback const & fn)
+{
+ lock_guard<mutex> lock(m_mutex);
+
+ if (requestId != m_requestId || !m_times || !m_prices)
+ return;
+
+ vector<uber::Product> products;
+
+ if (m_times->empty() || m_prices->empty())
+ {
+ LOG(LWARNING, ("Time or price is empty, time:", *m_times, "; price:", *m_prices));
+ fn(products, m_requestId);
+ return;
+ }
+
+ try
+ {
+ my::Json timesRoot(m_times->c_str());
+ my::Json pricesRoot(m_prices->c_str());
+ auto const timesArray = json_object_get(timesRoot.get(), "times");
+ auto const pricesArray = json_object_get(pricesRoot.get(), "prices");
+ if (CheckUberAnswer(timesArray) && CheckUberAnswer(pricesArray))
+ {
+ FillProducts(timesArray, pricesArray, products);
+ }
+ }
+ catch (my::Json::Exception const & e)
+ {
+ LOG(LERROR, (e.Msg()));
+ products.clear();
+ }
+
+ fn(products, requestId);
}
size_t Api::GetAvailableProducts(ms::LatLon const & from, ms::LatLon const & to,
ProductsCallback const & fn)
{
static size_t requestId = 0;
- ResetThread();
- m_runFlag = true;
- m_thread = make_unique<threads::SimpleThread>(GetAvailableProductsAsync, from, to,
- ++requestId, ref(m_runFlag), fn);
+ size_t reqId = ++requestId;
- return requestId;
+ m_maker->Reset(reqId);
+
+ threads::SimpleThread([this, from, reqId, fn]()
+ {
+ m_maker->SetTimes(reqId, uber::RawApi::GetEstimatedTime(from));
+ m_maker->MakeProducts(reqId, fn);
+ }).detach();
+
+ threads::SimpleThread([this, from, to, reqId, fn]()
+ {
+ m_maker->SetPrices(reqId, uber::RawApi::GetEstimatedPrice(from, to));
+ m_maker->MakeProducts(reqId, fn);
+ }).detach();
+
+ return reqId;
}
// static
@@ -199,22 +226,9 @@ string Api::GetRideRequestLink(string const & productId, ms::LatLon const & from
{
stringstream url;
url << "uber://?client_id=" << UBER_CLIENT_ID << "&action=setPickup&product_id=" << productId
- << "&pickup[latitude]=" << static_cast<float>(from.lat)
- << "&pickup[longitude]=" << static_cast<float>(from.lon)
- << "&dropoff[latitude]=" << static_cast<float>(to.lat)
- << "&dropoff[longitude]=" << static_cast<float>(to.lon);
+ << "&pickup[latitude]=" << from.lat << "&pickup[longitude]=" << from.lon
+ << "&dropoff[latitude]=" << to.lat << "&dropoff[longitude]=" << to.lon;
return url.str();
}
-
-void Api::ResetThread()
-{
- m_runFlag = false;
-
- if (m_thread)
- {
- m_thread->join();
- m_thread.reset();
- }
-}
} // namespace uber
diff --git a/partners_api/uber_api.hpp b/partners_api/uber_api.hpp
index d16144caa1..faf5fc5292 100644
--- a/partners_api/uber_api.hpp
+++ b/partners_api/uber_api.hpp
@@ -1,22 +1,20 @@
#pragma once
-#include "base/thread.hpp"
-
-#include "std/atomic.hpp"
#include "std/function.hpp"
#include "std/mutex.hpp"
+#include "std/shared_ptr.hpp"
#include "std/string.hpp"
#include "std/unique_ptr.hpp"
#include "std/vector.hpp"
namespace ms
{
- class LatLon;
+class LatLon;
} // namespace ms
namespace downloader
{
- class HttpRequest;
+class HttpRequest;
} // namespace downloader
namespace uber
@@ -54,25 +52,34 @@ struct Product
/// @requestId - identificator which was provided to GetAvailableProducts to identify request.
using ProductsCallback = function<void(vector<Product> const & products, size_t const requestId)>;
+/// Class which used for making products from http requests results.
+class ProductMaker
+{
+public:
+ void Reset(size_t const requestId);
+ void SetTimes(size_t const requestId, string const & times);
+ void SetPrices(size_t const requestId, string const & prices);
+ void MakeProducts(size_t const requestId, ProductsCallback const & fn);
+
+private:
+ size_t m_requestId;
+ unique_ptr<string> m_times;
+ unique_ptr<string> m_prices;
+ mutex m_mutex;
+};
+
class Api
{
public:
- ~Api();
/// Requests list of available products from Uber. Returns request identificator immediately.
size_t GetAvailableProducts(ms::LatLon const & from, ms::LatLon const & to,
- ProductsCallback const & fn);
+ ProductsCallback const & fn);
/// Returns link which allows you to launch the Uber app.
static string GetRideRequestLink(string const & productId, ms::LatLon const & from,
ms::LatLon const & to);
private:
- void ResetThread();
- unique_ptr<threads::SimpleThread> m_thread;
-
- atomic<bool> m_runFlag;
+ shared_ptr<ProductMaker> m_maker = make_shared<ProductMaker>();
};
} // namespace uber
-
-
-