Don't block all requests to switch data

This switchtes the data even if there are requests still running on the
old data. osrm-datastore then waits until all of these old requests have
finished before freeing the old regions.

This also means that osrm-datastore will return with an error if there
is a data update currenlty in progress.
This commit is contained in:
Patrick Niklaus
2016-10-08 01:52:47 +02:00
committed by Patrick Niklaus
parent 1557ff81bc
commit c69545c47a
6 changed files with 150 additions and 85 deletions
+9 -25
View File
@@ -22,7 +22,6 @@
#include <boost/interprocess/sync/named_condition.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/sharable_lock.hpp>
#include <boost/thread/lock_types.hpp>
#include <algorithm>
#include <fstream>
@@ -36,28 +35,15 @@ namespace
// Works the same for every plugin.
template <typename ParameterT, typename PluginT, typename ResultT>
osrm::engine::Status
RunQuery(const std::unique_ptr<osrm::storage::SharedBarriers> &lock,
osrm::engine::DataWatchdog& watchdog,
RunQuery(const std::unique_ptr<osrm::engine::DataWatchdog>& watchdog,
std::shared_ptr<osrm::engine::datafacade::BaseDataFacade> &facade,
const ParameterT &parameters,
PluginT &plugin,
ResultT &result)
{
if (!lock)
if (watchdog && watchdog->HasNewRegion())
{
return plugin.HandleRequest(facade, parameters, result);
}
BOOST_ASSERT(lock);
// this locks aquires shared ownership of the query mutex: other requets are allowed
// to run, but data updates need to wait for all queries to finish until they can aquire an
// exclusive lock
boost::interprocess::sharable_lock<boost::interprocess::named_sharable_mutex> query_lock(
lock->query_mutex);
if (watchdog.HasNewRegion())
{
watchdog.MaybeLoadNewRegion(facade);
watchdog->MaybeLoadNewRegion(facade);
}
osrm::engine::Status status = plugin.HandleRequest(facade, parameters, result);
@@ -84,14 +70,12 @@ Engine::Engine(const EngineConfig &config)
"No shared memory blocks found, have you forgotten to run osrm-datastore?");
}
facade_update_mutex = std::make_unique<std::mutex>();
watchdog = std::make_unique<DataWatchdog>();
// this will always either return a value or throw an exception
// in the initial run
watchdog->MaybeLoadNewRegion(query_data_facade);
BOOST_ASSERT(query_data_facade);
BOOST_ASSERT(watchdog);
BOOST_ASSERT(lock);
}
else
{
@@ -120,32 +104,32 @@ Engine &Engine::operator=(Engine &&) noexcept = default;
Status Engine::Route(const api::RouteParameters &params, util::json::Object &result) const
{
return RunQuery(lock, *watchdog, query_data_facade, params, *route_plugin, result);
return RunQuery(watchdog, query_data_facade, params, *route_plugin, result);
}
Status Engine::Table(const api::TableParameters &params, util::json::Object &result) const
{
return RunQuery(lock, *watchdog, query_data_facade, params, *table_plugin, result);
return RunQuery(watchdog, query_data_facade, params, *table_plugin, result);
}
Status Engine::Nearest(const api::NearestParameters &params, util::json::Object &result) const
{
return RunQuery(lock, *watchdog, query_data_facade, params, *nearest_plugin, result);
return RunQuery(watchdog, query_data_facade, params, *nearest_plugin, result);
}
Status Engine::Trip(const api::TripParameters &params, util::json::Object &result) const
{
return RunQuery(lock, *watchdog, query_data_facade, params, *trip_plugin, result);
return RunQuery(watchdog, query_data_facade, params, *trip_plugin, result);
}
Status Engine::Match(const api::MatchParameters &params, util::json::Object &result) const
{
return RunQuery(lock, *watchdog, query_data_facade, params, *match_plugin, result);
return RunQuery(watchdog, query_data_facade, params, *match_plugin, result);
}
Status Engine::Tile(const api::TileParameters &params, std::string &result) const
{
return RunQuery(lock, *watchdog, query_data_facade, params, *tile_plugin, result);
return RunQuery(watchdog, query_data_facade, params, *tile_plugin, result);
}
} // engine ns