forked from organicmaps/organicmaps
async changed to detached threads
This commit is contained in:
parent
4e99e7b9fc
commit
53da4259b4
4 changed files with 134 additions and 109 deletions
|
@ -2561,7 +2561,8 @@ void Framework::AllowAutoZoom(bool allowAutoZoom)
|
|||
bool const isPedestrianRoute = m_currentRouterType == RouterType::Pedestrian;
|
||||
bool const isUberRoute = m_currentRouterType == RouterType::Uber;
|
||||
|
||||
CallDrapeFunction(bind(&df::DrapeEngine::AllowAutoZoom, _1, allowAutoZoom && !isPedestrianRoute && !isUberRoute));
|
||||
CallDrapeFunction(bind(&df::DrapeEngine::AllowAutoZoom, _1,
|
||||
allowAutoZoom && !isPedestrianRoute && !isUberRoute));
|
||||
}
|
||||
|
||||
void Framework::SaveAutoZoom(bool allowAutoZoom)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
returnedId = requestId;
|
||||
returnedProducts = products;
|
||||
uber::ProductMaker maker;
|
||||
|
||||
testing::StopEventLoop();
|
||||
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)
|
||||
{
|
||||
TEST(!products.empty(), ());
|
||||
TEST_EQUAL(requestId, reqId, ());
|
||||
|
||||
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, ());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
ResetThread();
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue