mirror of https://gitee.com/bigwinds/arangodb
issue 374.3: use a reference to vocbase instead of a pointer in DatabaseGuard
This commit is contained in:
parent
d3626dd5c8
commit
f392925903
|
@ -45,10 +45,14 @@
|
||||||
using namespace arangodb;
|
using namespace arangodb;
|
||||||
using namespace arangodb::aql;
|
using namespace arangodb::aql;
|
||||||
|
|
||||||
QueryResultCursor::QueryResultCursor(TRI_vocbase_t* vocbase, CursorId id,
|
QueryResultCursor::QueryResultCursor(
|
||||||
|
TRI_vocbase_t& vocbase,
|
||||||
|
CursorId id,
|
||||||
aql::QueryResult&& result,
|
aql::QueryResult&& result,
|
||||||
size_t batchSize, double ttl,
|
size_t batchSize,
|
||||||
bool hasCount)
|
double ttl,
|
||||||
|
bool hasCount
|
||||||
|
)
|
||||||
: Cursor(id, batchSize, ttl, hasCount),
|
: Cursor(id, batchSize, ttl, hasCount),
|
||||||
_guard(vocbase),
|
_guard(vocbase),
|
||||||
_result(std::move(result)),
|
_result(std::move(result)),
|
||||||
|
@ -140,11 +144,15 @@ Result QueryResultCursor::dump(VPackBuilder& builder) {
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryStreamCursor::QueryStreamCursor(TRI_vocbase_t* vocbase, CursorId id,
|
QueryStreamCursor::QueryStreamCursor(
|
||||||
|
TRI_vocbase_t& vocbase,
|
||||||
|
CursorId id,
|
||||||
std::string const& query,
|
std::string const& query,
|
||||||
std::shared_ptr<VPackBuilder> bindVars,
|
std::shared_ptr<VPackBuilder> bindVars,
|
||||||
std::shared_ptr<VPackBuilder> opts,
|
std::shared_ptr<VPackBuilder> opts,
|
||||||
size_t batchSize, double ttl)
|
size_t batchSize,
|
||||||
|
double ttl
|
||||||
|
)
|
||||||
: Cursor(id, batchSize, ttl, /*hasCount*/ false),
|
: Cursor(id, batchSize, ttl, /*hasCount*/ false),
|
||||||
_guard(vocbase),
|
_guard(vocbase),
|
||||||
_queryString(query) {
|
_queryString(query) {
|
||||||
|
@ -152,11 +160,17 @@ QueryStreamCursor::QueryStreamCursor(TRI_vocbase_t* vocbase, CursorId id,
|
||||||
auto prevLockHeaders = CollectionLockState::_noLockHeaders;
|
auto prevLockHeaders = CollectionLockState::_noLockHeaders;
|
||||||
TRI_DEFER(CollectionLockState::_noLockHeaders = prevLockHeaders);
|
TRI_DEFER(CollectionLockState::_noLockHeaders = prevLockHeaders);
|
||||||
|
|
||||||
_query = std::make_unique<Query>(false, _guard.database(),
|
_query = std::make_unique<Query>(
|
||||||
|
false,
|
||||||
|
&(_guard.database()),
|
||||||
aql::QueryString(_queryString.c_str(), _queryString.length()),
|
aql::QueryString(_queryString.c_str(), _queryString.length()),
|
||||||
std::move(bindVars), std::move(opts), arangodb::aql::PART_MAIN);
|
std::move(bindVars),
|
||||||
|
std::move(opts),
|
||||||
|
arangodb::aql::PART_MAIN
|
||||||
|
);
|
||||||
_query->prepare(QueryRegistryFeature::QUERY_REGISTRY, aql::Query::DontCache);
|
_query->prepare(QueryRegistryFeature::QUERY_REGISTRY, aql::Query::DontCache);
|
||||||
TRI_ASSERT(_query->state() == aql::QueryExecutionState::ValueType::EXECUTION);
|
TRI_ASSERT(_query->state() == aql::QueryExecutionState::ValueType::EXECUTION);
|
||||||
|
|
||||||
// If we have set _noLockHeaders, we need to unset it:
|
// If we have set _noLockHeaders, we need to unset it:
|
||||||
if (CollectionLockState::_noLockHeaders != nullptr &&
|
if (CollectionLockState::_noLockHeaders != nullptr &&
|
||||||
CollectionLockState::_noLockHeaders == _query->engine()->lockedShards()) {
|
CollectionLockState::_noLockHeaders == _query->engine()->lockedShards()) {
|
||||||
|
@ -184,8 +198,9 @@ Result QueryStreamCursor::dump(VPackBuilder& builder) {
|
||||||
TRI_DEFER(CollectionLockState::_noLockHeaders = prevLockHeaders);
|
TRI_DEFER(CollectionLockState::_noLockHeaders = prevLockHeaders);
|
||||||
|
|
||||||
// we do have a query string... pass query to WorkMonitor
|
// we do have a query string... pass query to WorkMonitor
|
||||||
AqlWorkStack work(_guard.database(), _query->id(), _queryString.data(),
|
AqlWorkStack work(
|
||||||
_queryString.size());
|
&(_guard.database()), _query->id(), _queryString.data(), _queryString.size()
|
||||||
|
);
|
||||||
LOG_TOPIC(TRACE, Logger::QUERIES) << "executing query " << _id << ": '"
|
LOG_TOPIC(TRACE, Logger::QUERIES) << "executing query " << _id << ": '"
|
||||||
<< _queryString.substr(1024) << "'";
|
<< _queryString.substr(1024) << "'";
|
||||||
|
|
||||||
|
|
|
@ -39,12 +39,17 @@ class Query;
|
||||||
/// Should be used in conjunction with the RestCursorHandler
|
/// Should be used in conjunction with the RestCursorHandler
|
||||||
class QueryResultCursor final : public arangodb::Cursor {
|
class QueryResultCursor final : public arangodb::Cursor {
|
||||||
public:
|
public:
|
||||||
QueryResultCursor(TRI_vocbase_t*, CursorId, aql::QueryResult&&, size_t,
|
QueryResultCursor(
|
||||||
double ttl, bool hasCount);
|
TRI_vocbase_t& vocbase,
|
||||||
|
CursorId id,
|
||||||
|
aql::QueryResult&& result,
|
||||||
|
size_t batchSize,
|
||||||
|
double ttl,
|
||||||
|
bool hasCount
|
||||||
|
);
|
||||||
|
|
||||||
~QueryResultCursor() = default;
|
~QueryResultCursor() = default;
|
||||||
|
|
||||||
public:
|
|
||||||
aql::QueryResult const* result() const { return &_result; }
|
aql::QueryResult const* result() const { return &_result; }
|
||||||
|
|
||||||
CursorType type() const override final { return CURSOR_VPACK; }
|
CursorType type() const override final { return CURSOR_VPACK; }
|
||||||
|
@ -79,14 +84,18 @@ class QueryResultCursor final : public arangodb::Cursor {
|
||||||
/// cursor is deleted (or query exhausted)
|
/// cursor is deleted (or query exhausted)
|
||||||
class QueryStreamCursor final : public arangodb::Cursor {
|
class QueryStreamCursor final : public arangodb::Cursor {
|
||||||
public:
|
public:
|
||||||
QueryStreamCursor(TRI_vocbase_t*, CursorId, std::string const& query,
|
QueryStreamCursor(
|
||||||
|
TRI_vocbase_t& vocbase,
|
||||||
|
CursorId id,
|
||||||
|
std::string const& query,
|
||||||
std::shared_ptr<velocypack::Builder> bindVars,
|
std::shared_ptr<velocypack::Builder> bindVars,
|
||||||
std::shared_ptr<velocypack::Builder> opts, size_t,
|
std::shared_ptr<velocypack::Builder> opts,
|
||||||
double ttl);
|
size_t batchSize,
|
||||||
|
double ttl
|
||||||
|
);
|
||||||
|
|
||||||
~QueryStreamCursor();
|
~QueryStreamCursor();
|
||||||
|
|
||||||
public:
|
|
||||||
CursorType type() const override final { return CURSOR_VPACK; }
|
CursorType type() const override final { return CURSOR_VPACK; }
|
||||||
|
|
||||||
size_t count() const override final { return 0; }
|
size_t count() const override final { return 0; }
|
||||||
|
|
|
@ -58,10 +58,9 @@ DBServerAgencySyncResult DBServerAgencySync::execute() {
|
||||||
LOG_TOPIC(DEBUG, Logger::HEARTBEAT) << "DBServerAgencySync::execute starting";
|
LOG_TOPIC(DEBUG, Logger::HEARTBEAT) << "DBServerAgencySync::execute starting";
|
||||||
DatabaseFeature* database =
|
DatabaseFeature* database =
|
||||||
ApplicationServer::getFeature<DatabaseFeature>("Database");
|
ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||||
|
|
||||||
TRI_vocbase_t* const vocbase = database->systemDatabase();
|
TRI_vocbase_t* const vocbase = database->systemDatabase();
|
||||||
|
|
||||||
DBServerAgencySyncResult result;
|
DBServerAgencySyncResult result;
|
||||||
|
|
||||||
if (vocbase == nullptr) {
|
if (vocbase == nullptr) {
|
||||||
LOG_TOPIC(DEBUG, Logger::HEARTBEAT)
|
LOG_TOPIC(DEBUG, Logger::HEARTBEAT)
|
||||||
<< "DBServerAgencySync::execute no vocbase";
|
<< "DBServerAgencySync::execute no vocbase";
|
||||||
|
@ -71,9 +70,7 @@ DBServerAgencySyncResult DBServerAgencySync::execute() {
|
||||||
auto clusterInfo = ClusterInfo::instance();
|
auto clusterInfo = ClusterInfo::instance();
|
||||||
auto plan = clusterInfo->getPlan();
|
auto plan = clusterInfo->getPlan();
|
||||||
auto current = clusterInfo->getCurrent();
|
auto current = clusterInfo->getCurrent();
|
||||||
|
DatabaseGuard guard(*vocbase);
|
||||||
DatabaseGuard guard(vocbase);
|
|
||||||
|
|
||||||
double startTime = TRI_microtime();
|
double startTime = TRI_microtime();
|
||||||
V8Context* context = V8DealerFeature::DEALER->enterContext(vocbase, true, V8DealerFeature::ANY_CONTEXT_OR_PRIORITY);
|
V8Context* context = V8DealerFeature::DEALER->enterContext(vocbase, true, V8DealerFeature::ANY_CONTEXT_OR_PRIORITY);
|
||||||
|
|
||||||
|
@ -85,6 +82,7 @@ DBServerAgencySyncResult DBServerAgencySync::execute() {
|
||||||
TRI_DEFER(V8DealerFeature::DEALER->exitContext(context));
|
TRI_DEFER(V8DealerFeature::DEALER->exitContext(context));
|
||||||
|
|
||||||
double now = TRI_microtime();
|
double now = TRI_microtime();
|
||||||
|
|
||||||
if (now - startTime > 5.0) {
|
if (now - startTime > 5.0) {
|
||||||
LOG_TOPIC(WARN, arangodb::Logger::HEARTBEAT) << "DBServerAgencySync::execute took " << Logger::FIXED(now - startTime) << " to get free V8 context, starting handlePlanChange now";
|
LOG_TOPIC(WARN, arangodb::Logger::HEARTBEAT) << "DBServerAgencySync::execute took " << Logger::FIXED(now - startTime) << " to get free V8 context, starting handlePlanChange now";
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,11 +597,9 @@ void MMFilesCollectorThread::clearQueuedOperations() {
|
||||||
for (auto const& cache : operations) {
|
for (auto const& cache : operations) {
|
||||||
{
|
{
|
||||||
arangodb::DatabaseGuard dbGuard(cache->databaseId);
|
arangodb::DatabaseGuard dbGuard(cache->databaseId);
|
||||||
TRI_vocbase_t* vocbase = dbGuard.database();
|
arangodb::CollectionGuard collectionGuard(
|
||||||
TRI_ASSERT(vocbase != nullptr);
|
&(dbGuard.database()), cache->collectionId, true
|
||||||
|
);
|
||||||
arangodb::CollectionGuard collectionGuard(vocbase, cache->collectionId,
|
|
||||||
true);
|
|
||||||
arangodb::LogicalCollection* collection = collectionGuard.collection();
|
arangodb::LogicalCollection* collection = collectionGuard.collection();
|
||||||
|
|
||||||
TRI_ASSERT(collection != nullptr);
|
TRI_ASSERT(collection != nullptr);
|
||||||
|
@ -732,10 +730,10 @@ void MMFilesCollectorThread::processCollectionMarker(
|
||||||
/// @brief process all operations for a single collection
|
/// @brief process all operations for a single collection
|
||||||
int MMFilesCollectorThread::processCollectionOperations(MMFilesCollectorCache* cache) {
|
int MMFilesCollectorThread::processCollectionOperations(MMFilesCollectorCache* cache) {
|
||||||
arangodb::DatabaseGuard dbGuard(cache->databaseId);
|
arangodb::DatabaseGuard dbGuard(cache->databaseId);
|
||||||
TRI_vocbase_t* vocbase = dbGuard.database();
|
auto& vocbase = dbGuard.database();
|
||||||
TRI_ASSERT(vocbase != nullptr);
|
arangodb::CollectionGuard collectionGuard(
|
||||||
|
&vocbase, cache->collectionId, true
|
||||||
arangodb::CollectionGuard collectionGuard(vocbase, cache->collectionId, true);
|
);
|
||||||
arangodb::LogicalCollection* collection = collectionGuard.collection();
|
arangodb::LogicalCollection* collection = collectionGuard.collection();
|
||||||
|
|
||||||
TRI_ASSERT(collection != nullptr);
|
TRI_ASSERT(collection != nullptr);
|
||||||
|
@ -983,10 +981,9 @@ int MMFilesCollectorThread::transferMarkers(MMFilesWalLogfile* logfile,
|
||||||
|
|
||||||
// prepare database and collection
|
// prepare database and collection
|
||||||
arangodb::DatabaseGuard dbGuard(databaseId);
|
arangodb::DatabaseGuard dbGuard(databaseId);
|
||||||
TRI_vocbase_t* vocbase = dbGuard.database();
|
arangodb::CollectionGuard collectionGuard(
|
||||||
TRI_ASSERT(vocbase != nullptr);
|
&(dbGuard.database()), collectionId, true
|
||||||
|
);
|
||||||
arangodb::CollectionGuard collectionGuard(vocbase, collectionId, true);
|
|
||||||
arangodb::LogicalCollection* collection = collectionGuard.collection();
|
arangodb::LogicalCollection* collection = collectionGuard.collection();
|
||||||
TRI_ASSERT(collection != nullptr);
|
TRI_ASSERT(collection != nullptr);
|
||||||
|
|
||||||
|
@ -1006,6 +1003,7 @@ int MMFilesCollectorThread::transferMarkers(MMFilesWalLogfile* logfile,
|
||||||
int res = TRI_ERROR_INTERNAL;
|
int res = TRI_ERROR_INTERNAL;
|
||||||
|
|
||||||
uint64_t numBytesTransferred = 0;
|
uint64_t numBytesTransferred = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto en = static_cast<MMFilesEngine*>(engine);
|
auto en = static_cast<MMFilesEngine*>(engine);
|
||||||
res = en->transferMarkers(collection, cache.get(), operations, numBytesTransferred);
|
res = en->transferMarkers(collection, cache.get(), operations, numBytesTransferred);
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include <velocypack/Options.h>
|
#include <velocypack/Options.h>
|
||||||
#include <velocypack/velocypack-aliases.h>
|
#include <velocypack/velocypack-aliases.h>
|
||||||
|
|
||||||
using namespace arangodb;
|
namespace arangodb {
|
||||||
|
|
||||||
MMFilesExportCursor::MMFilesExportCursor(TRI_vocbase_t* vocbase, CursorId id,
|
MMFilesExportCursor::MMFilesExportCursor(TRI_vocbase_t* vocbase, CursorId id,
|
||||||
arangodb::MMFilesCollectionExport* ex, size_t batchSize,
|
arangodb::MMFilesCollectionExport* ex, size_t batchSize,
|
||||||
|
@ -73,7 +73,7 @@ VPackSlice MMFilesExportCursor::next() {
|
||||||
size_t MMFilesExportCursor::count() const { return _size; }
|
size_t MMFilesExportCursor::count() const { return _size; }
|
||||||
|
|
||||||
Result MMFilesExportCursor::dump(VPackBuilder& builder) {
|
Result MMFilesExportCursor::dump(VPackBuilder& builder) {
|
||||||
auto ctx = transaction::StandaloneContext::Create(_guard.database());
|
auto ctx = transaction::StandaloneContext::Create(&(_guard.database()));
|
||||||
VPackOptions const* oldOptions = builder.options;
|
VPackOptions const* oldOptions = builder.options;
|
||||||
|
|
||||||
builder.options = ctx->getVPackOptions();
|
builder.options = ctx->getVPackOptions();
|
||||||
|
@ -144,5 +144,7 @@ Result MMFilesExportCursor::dump(VPackBuilder& builder) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<transaction::Context> MMFilesExportCursor::context() const {
|
std::shared_ptr<transaction::Context> MMFilesExportCursor::context() const {
|
||||||
return transaction::StandaloneContext::Create(_guard.database()); // likely not used
|
return transaction::StandaloneContext::Create(&(_guard.database())); // likely not used
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // arangodb
|
||||||
|
|
|
@ -51,10 +51,14 @@ using namespace arangodb::basics;
|
||||||
const char* arangodb::pregel::ExecutionStateNames[6] = {
|
const char* arangodb::pregel::ExecutionStateNames[6] = {
|
||||||
"none", "running", "done", "canceled", "in error", "recovering"};
|
"none", "running", "done", "canceled", "in error", "recovering"};
|
||||||
|
|
||||||
Conductor::Conductor(uint64_t executionNumber, TRI_vocbase_t* vocbase,
|
Conductor::Conductor(
|
||||||
|
uint64_t executionNumber,
|
||||||
|
TRI_vocbase_t& vocbase,
|
||||||
std::vector<CollectionID> const& vertexCollections,
|
std::vector<CollectionID> const& vertexCollections,
|
||||||
std::vector<CollectionID> const& edgeCollections,
|
std::vector<CollectionID> const& edgeCollections,
|
||||||
std::string const& algoName, VPackSlice const& config)
|
std::string const& algoName,
|
||||||
|
VPackSlice const& config
|
||||||
|
)
|
||||||
: _vocbaseGuard(vocbase),
|
: _vocbaseGuard(vocbase),
|
||||||
_executionNumber(executionNumber),
|
_executionNumber(executionNumber),
|
||||||
_algorithm(AlgoRegistry::createAlgorithm(algoName, config)),
|
_algorithm(AlgoRegistry::createAlgorithm(algoName, config)),
|
||||||
|
@ -243,12 +247,15 @@ void Conductor::finishedWorkerStartup(VPackSlice const& data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_computationStartTimeSecs = TRI_microtime();
|
_computationStartTimeSecs = TRI_microtime();
|
||||||
|
|
||||||
if (_startGlobalStep()) {
|
if (_startGlobalStep()) {
|
||||||
// listens for changing primary DBServers on each collection shard
|
// listens for changing primary DBServers on each collection shard
|
||||||
RecoveryManager* mngr = PregelFeature::instance()->recoveryManager();
|
RecoveryManager* mngr = PregelFeature::instance()->recoveryManager();
|
||||||
|
|
||||||
if (mngr) {
|
if (mngr) {
|
||||||
mngr->monitorCollections(_vocbaseGuard.database()->name(),
|
mngr->monitorCollections(
|
||||||
_vertexCollections, this);
|
_vocbaseGuard.database().name(), _vertexCollections, this
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -523,7 +530,7 @@ int Conductor::_initializeWorkers(std::string const& suffix,
|
||||||
_callbackMutex.assertLockedByCurrentThread();
|
_callbackMutex.assertLockedByCurrentThread();
|
||||||
|
|
||||||
std::string const path =
|
std::string const path =
|
||||||
Utils::baseUrl(_vocbaseGuard.database()->name(), Utils::workerPrefix) +
|
Utils::baseUrl(_vocbaseGuard.database().name(), Utils::workerPrefix) +
|
||||||
suffix;
|
suffix;
|
||||||
|
|
||||||
// int64_t vertexCount = 0, edgeCount = 0;
|
// int64_t vertexCount = 0, edgeCount = 0;
|
||||||
|
@ -534,12 +541,22 @@ int Conductor::_initializeWorkers(std::string const& suffix,
|
||||||
|
|
||||||
// resolve plan id's and shards on the servers
|
// resolve plan id's and shards on the servers
|
||||||
for (CollectionID const& collectionID : _vertexCollections) {
|
for (CollectionID const& collectionID : _vertexCollections) {
|
||||||
resolveInfo(_vocbaseGuard.database(), collectionID, collectionPlanIdMap,
|
resolveInfo(
|
||||||
vertexMap, shardList); // store or
|
&(_vocbaseGuard.database()),
|
||||||
|
collectionID,
|
||||||
|
collectionPlanIdMap,
|
||||||
|
vertexMap,
|
||||||
|
shardList
|
||||||
|
); // store or
|
||||||
}
|
}
|
||||||
for (CollectionID const& collectionID : _edgeCollections) {
|
for (CollectionID const& collectionID : _edgeCollections) {
|
||||||
resolveInfo(_vocbaseGuard.database(), collectionID, collectionPlanIdMap,
|
resolveInfo(
|
||||||
edgeMap, shardList); // store or
|
&(_vocbaseGuard.database()),
|
||||||
|
collectionID,
|
||||||
|
collectionPlanIdMap,
|
||||||
|
edgeMap,
|
||||||
|
shardList
|
||||||
|
); // store or
|
||||||
}
|
}
|
||||||
|
|
||||||
_dbServers.clear();
|
_dbServers.clear();
|
||||||
|
@ -610,22 +627,23 @@ int Conductor::_initializeWorkers(std::string const& suffix,
|
||||||
if (ServerState::instance()->getRole() == ServerState::ROLE_SINGLE) {
|
if (ServerState::instance()->getRole() == ServerState::ROLE_SINGLE) {
|
||||||
TRI_ASSERT(vertexMap.size() == 1);
|
TRI_ASSERT(vertexMap.size() == 1);
|
||||||
PregelFeature* feature = PregelFeature::instance();
|
PregelFeature* feature = PregelFeature::instance();
|
||||||
|
|
||||||
std::shared_ptr<IWorker> worker = feature->worker(_executionNumber);
|
std::shared_ptr<IWorker> worker = feature->worker(_executionNumber);
|
||||||
|
|
||||||
if (worker) {
|
if (worker) {
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||||
"a worker with this execution number already exists.");
|
"a worker with this execution number already exists.");
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_vocbase_t* vocbase = _vocbaseGuard.database();
|
auto created =
|
||||||
auto created = AlgoRegistry::createWorker(vocbase, b.slice());
|
AlgoRegistry::createWorker(&(_vocbaseGuard.database()), b.slice());
|
||||||
|
|
||||||
TRI_ASSERT(created.get() != nullptr);
|
TRI_ASSERT(created.get() != nullptr);
|
||||||
PregelFeature::instance()->addWorker(std::move(created), _executionNumber);
|
PregelFeature::instance()->addWorker(std::move(created), _executionNumber);
|
||||||
worker = PregelFeature::instance()->worker(_executionNumber);
|
worker = PregelFeature::instance()->worker(_executionNumber);
|
||||||
TRI_ASSERT (worker);
|
TRI_ASSERT (worker);
|
||||||
worker->setupWorker();
|
worker->setupWorker();
|
||||||
return TRI_ERROR_NO_ERROR;
|
|
||||||
|
|
||||||
|
return TRI_ERROR_NO_ERROR;
|
||||||
} else {
|
} else {
|
||||||
auto body = std::make_shared<std::string const>(b.toJson());
|
auto body = std::make_shared<std::string const>(b.toJson());
|
||||||
requests.emplace_back("server:" + server, rest::RequestType::POST, path,
|
requests.emplace_back("server:" + server, rest::RequestType::POST, path,
|
||||||
|
@ -744,16 +762,20 @@ int Conductor::_sendToAllDBServers(std::string const& path,
|
||||||
if (ServerState::instance()->isRunningInCluster() == false) {
|
if (ServerState::instance()->isRunningInCluster() == false) {
|
||||||
if (handle) {
|
if (handle) {
|
||||||
VPackBuilder response;
|
VPackBuilder response;
|
||||||
PregelFeature::handleWorkerRequest(_vocbaseGuard.database(), path,
|
|
||||||
message.slice(), response);
|
PregelFeature::handleWorkerRequest(
|
||||||
|
&(_vocbaseGuard.database()), path, message.slice(), response
|
||||||
|
);
|
||||||
handle(response.slice());
|
handle(response.slice());
|
||||||
} else {
|
} else {
|
||||||
TRI_ASSERT(SchedulerFeature::SCHEDULER != nullptr);
|
TRI_ASSERT(SchedulerFeature::SCHEDULER != nullptr);
|
||||||
rest::Scheduler* scheduler = SchedulerFeature::SCHEDULER;
|
rest::Scheduler* scheduler = SchedulerFeature::SCHEDULER;
|
||||||
scheduler->post([this, path, message] {
|
scheduler->post([this, path, message] {
|
||||||
VPackBuilder response;
|
VPackBuilder response;
|
||||||
PregelFeature::handleWorkerRequest(_vocbaseGuard.database(), path,
|
|
||||||
message.slice(), response);
|
PregelFeature::handleWorkerRequest(
|
||||||
|
&(_vocbaseGuard.database()), path, message.slice(), response
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
|
@ -761,14 +783,17 @@ int Conductor::_sendToAllDBServers(std::string const& path,
|
||||||
|
|
||||||
// cluster case
|
// cluster case
|
||||||
std::shared_ptr<ClusterComm> cc = ClusterComm::instance();
|
std::shared_ptr<ClusterComm> cc = ClusterComm::instance();
|
||||||
|
|
||||||
if (_dbServers.size() == 0) {
|
if (_dbServers.size() == 0) {
|
||||||
LOG_TOPIC(WARN, Logger::PREGEL) << "No servers registered";
|
LOG_TOPIC(WARN, Logger::PREGEL) << "No servers registered";
|
||||||
return TRI_ERROR_FAILED;
|
return TRI_ERROR_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string base =
|
std::string base =
|
||||||
Utils::baseUrl(_vocbaseGuard.database()->name(), Utils::workerPrefix);
|
Utils::baseUrl(_vocbaseGuard.database().name(), Utils::workerPrefix);
|
||||||
auto body = std::make_shared<std::string const>(message.toJson());
|
auto body = std::make_shared<std::string const>(message.toJson());
|
||||||
std::vector<ClusterCommRequest> requests;
|
std::vector<ClusterCommRequest> requests;
|
||||||
|
|
||||||
for (auto const& server : _dbServers) {
|
for (auto const& server : _dbServers) {
|
||||||
requests.emplace_back("server:" + server, rest::RequestType::POST,
|
requests.emplace_back("server:" + server, rest::RequestType::POST,
|
||||||
base + path, body);
|
base + path, body);
|
||||||
|
|
|
@ -106,10 +106,14 @@ class Conductor {
|
||||||
void finishedRecoveryStep(VPackSlice const& data);
|
void finishedRecoveryStep(VPackSlice const& data);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Conductor(uint64_t executionNumber, TRI_vocbase_t* vocbase,
|
Conductor(
|
||||||
|
uint64_t executionNumber,
|
||||||
|
TRI_vocbase_t& vocbase,
|
||||||
std::vector<CollectionID> const& vertexCollections,
|
std::vector<CollectionID> const& vertexCollections,
|
||||||
std::vector<CollectionID> const& edgeCollections,
|
std::vector<CollectionID> const& edgeCollections,
|
||||||
std::string const& algoName, VPackSlice const& userConfig);
|
std::string const& algoName,
|
||||||
|
VPackSlice const& userConfig
|
||||||
|
);
|
||||||
|
|
||||||
~Conductor();
|
~Conductor();
|
||||||
|
|
||||||
|
|
|
@ -336,13 +336,16 @@ std::unique_ptr<transaction::Methods> GraphStore<V, E>::_createTransaction() {
|
||||||
transaction::Options transactionOptions;
|
transaction::Options transactionOptions;
|
||||||
transactionOptions.waitForSync = false;
|
transactionOptions.waitForSync = false;
|
||||||
transactionOptions.allowImplicitCollections = true;
|
transactionOptions.allowImplicitCollections = true;
|
||||||
auto ctx = transaction::StandaloneContext::Create(_vocbaseGuard.database());
|
auto ctx =
|
||||||
|
transaction::StandaloneContext::Create(&(_vocbaseGuard.database()));
|
||||||
std::unique_ptr<transaction::Methods> trx(
|
std::unique_ptr<transaction::Methods> trx(
|
||||||
new transaction::UserTransaction(ctx, {}, {}, {}, transactionOptions));
|
new transaction::UserTransaction(ctx, {}, {}, {}, transactionOptions));
|
||||||
Result res = trx->begin();
|
Result res = trx->begin();
|
||||||
|
|
||||||
if (!res.ok()) {
|
if (!res.ok()) {
|
||||||
THROW_ARANGO_EXCEPTION(res);
|
THROW_ARANGO_EXCEPTION(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
return trx;
|
return trx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,27 +507,39 @@ void GraphStore<V, E>::_storeVertices(std::vector<ShardID> const& globalShards,
|
||||||
if (it->shard() != currentShard) {
|
if (it->shard() != currentShard) {
|
||||||
if (trx) {
|
if (trx) {
|
||||||
res = trx->finish(res);
|
res = trx->finish(res);
|
||||||
|
|
||||||
if (!res.ok()) {
|
if (!res.ok()) {
|
||||||
THROW_ARANGO_EXCEPTION(res);
|
THROW_ARANGO_EXCEPTION(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
currentShard = it->shard();
|
currentShard = it->shard();
|
||||||
|
|
||||||
ShardID const& shard = globalShards[currentShard];
|
ShardID const& shard = globalShards[currentShard];
|
||||||
transaction::Options transactionOptions;
|
transaction::Options transactionOptions;
|
||||||
|
|
||||||
transactionOptions.waitForSync = false;
|
transactionOptions.waitForSync = false;
|
||||||
transactionOptions.allowImplicitCollections = false;
|
transactionOptions.allowImplicitCollections = false;
|
||||||
trx.reset(new transaction::UserTransaction(
|
trx.reset(new transaction::UserTransaction(
|
||||||
transaction::StandaloneContext::Create(_vocbaseGuard.database()), {},
|
transaction::StandaloneContext::Create(&(_vocbaseGuard.database())),
|
||||||
{shard}, {}, transactionOptions));
|
{},
|
||||||
|
{shard},
|
||||||
|
{},
|
||||||
|
transactionOptions
|
||||||
|
));
|
||||||
res = trx->begin();
|
res = trx->begin();
|
||||||
|
|
||||||
if (!res.ok()) {
|
if (!res.ok()) {
|
||||||
THROW_ARANGO_EXCEPTION(res);
|
THROW_ARANGO_EXCEPTION(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction::BuilderLeaser b(trx.get());
|
transaction::BuilderLeaser b(trx.get());
|
||||||
|
|
||||||
b->openArray();
|
b->openArray();
|
||||||
|
|
||||||
size_t buffer = 0;
|
size_t buffer = 0;
|
||||||
|
|
||||||
while (it != it.end() && it->shard() == currentShard && buffer < 1000) {
|
while (it != it.end() && it->shard() == currentShard && buffer < 1000) {
|
||||||
// This loop will fill a buffer of vertices until we run into a new
|
// This loop will fill a buffer of vertices until we run into a new
|
||||||
// collection
|
// collection
|
||||||
|
|
|
@ -62,14 +62,20 @@ using namespace arangodb::rest;
|
||||||
|
|
||||||
size_t const DatabaseInitialSyncer::MaxChunkSize = 10 * 1024 * 1024;
|
size_t const DatabaseInitialSyncer::MaxChunkSize = 10 * 1024 * 1024;
|
||||||
|
|
||||||
DatabaseInitialSyncer::DatabaseInitialSyncer(TRI_vocbase_t* vocbase,
|
DatabaseInitialSyncer::DatabaseInitialSyncer(
|
||||||
ReplicationApplierConfiguration const& configuration)
|
TRI_vocbase_t& vocbase,
|
||||||
: InitialSyncer(configuration),
|
ReplicationApplierConfiguration const& configuration
|
||||||
_vocbase(vocbase),
|
): InitialSyncer(configuration),
|
||||||
|
_vocbase(&vocbase),
|
||||||
_hasFlushed(false) {
|
_hasFlushed(false) {
|
||||||
_vocbases.emplace(vocbase->name(), DatabaseGuard(vocbase));
|
_vocbases.emplace(
|
||||||
|
std::piecewise_construct,
|
||||||
|
std::forward_as_tuple(vocbase.name()),
|
||||||
|
std::forward_as_tuple(vocbase)
|
||||||
|
);
|
||||||
|
|
||||||
if (configuration._database.empty()) {
|
if (configuration._database.empty()) {
|
||||||
_databaseName = vocbase->name();
|
_databaseName = vocbase.name();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,10 +78,10 @@ class DatabaseInitialSyncer : public InitialSyncer {
|
||||||
} sync_phase_e;
|
} sync_phase_e;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DatabaseInitialSyncer(TRI_vocbase_t*,
|
DatabaseInitialSyncer(
|
||||||
ReplicationApplierConfiguration const&);
|
TRI_vocbase_t& vocbase,
|
||||||
|
ReplicationApplierConfiguration const& configuration
|
||||||
public:
|
);
|
||||||
|
|
||||||
/// @brief run method, performs a full synchronization
|
/// @brief run method, performs a full synchronization
|
||||||
Result run(bool incremental) override {
|
Result run(bool incremental) override {
|
||||||
|
@ -114,7 +114,7 @@ class DatabaseInitialSyncer : public InitialSyncer {
|
||||||
|
|
||||||
TRI_vocbase_t* vocbase() const {
|
TRI_vocbase_t* vocbase() const {
|
||||||
TRI_ASSERT(vocbases().size() == 1);
|
TRI_ASSERT(vocbases().size() == 1);
|
||||||
return vocbases().begin()->second.database();
|
return &(vocbases().begin()->second.database());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief check whether the initial synchronization should be aborted
|
/// @brief check whether the initial synchronization should be aborted
|
||||||
|
|
|
@ -42,17 +42,19 @@
|
||||||
#include <velocypack/Slice.h>
|
#include <velocypack/Slice.h>
|
||||||
#include <velocypack/velocypack-aliases.h>
|
#include <velocypack/velocypack-aliases.h>
|
||||||
|
|
||||||
using namespace arangodb;
|
namespace arangodb {
|
||||||
|
|
||||||
/// @brief replication applier for a single database, without configuration
|
/// @brief replication applier for a single database, without configuration
|
||||||
DatabaseReplicationApplier::DatabaseReplicationApplier(TRI_vocbase_t* vocbase)
|
DatabaseReplicationApplier::DatabaseReplicationApplier(TRI_vocbase_t& vocbase)
|
||||||
: DatabaseReplicationApplier(ReplicationApplierConfiguration(), vocbase) {}
|
: DatabaseReplicationApplier(ReplicationApplierConfiguration(), vocbase) {}
|
||||||
|
|
||||||
/// @brief replication applier for a single database, with configuration
|
/// @brief replication applier for a single database, with configuration
|
||||||
DatabaseReplicationApplier::DatabaseReplicationApplier(ReplicationApplierConfiguration const& configuration,
|
DatabaseReplicationApplier::DatabaseReplicationApplier(
|
||||||
TRI_vocbase_t* vocbase)
|
ReplicationApplierConfiguration const& configuration,
|
||||||
: ReplicationApplier(configuration, std::string("database '") + vocbase->name() + "'"),
|
TRI_vocbase_t& vocbase
|
||||||
_vocbase(vocbase) {}
|
): ReplicationApplier(configuration, std::string("database '") + vocbase.name() + "'"),
|
||||||
|
_vocbase(vocbase) {
|
||||||
|
}
|
||||||
|
|
||||||
DatabaseReplicationApplier::~DatabaseReplicationApplier() {
|
DatabaseReplicationApplier::~DatabaseReplicationApplier() {
|
||||||
try {
|
try {
|
||||||
|
@ -62,7 +64,7 @@ DatabaseReplicationApplier::~DatabaseReplicationApplier() {
|
||||||
|
|
||||||
/// @brief execute the check condition
|
/// @brief execute the check condition
|
||||||
bool DatabaseReplicationApplier::applies() const {
|
bool DatabaseReplicationApplier::applies() const {
|
||||||
return (_vocbase->type() == TRI_VOCBASE_TYPE_NORMAL);
|
return (_vocbase.type() == TRI_VOCBASE_TYPE_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief configure the replication applier
|
/// @brief configure the replication applier
|
||||||
|
@ -88,16 +90,21 @@ void DatabaseReplicationApplier::forget() {
|
||||||
removeState();
|
removeState();
|
||||||
|
|
||||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||||
engine->removeReplicationApplierConfiguration(_vocbase);
|
|
||||||
|
engine->removeReplicationApplierConfiguration(&_vocbase);
|
||||||
_configuration.reset();
|
_configuration.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief factory function for creating a database-specific replication applier
|
/// @brief factory function for creating a database-specific replication applier
|
||||||
DatabaseReplicationApplier* DatabaseReplicationApplier::create(TRI_vocbase_t* vocbase) {
|
/*static*/ DatabaseReplicationApplier* DatabaseReplicationApplier::create(
|
||||||
|
TRI_vocbase_t& vocbase
|
||||||
|
) {
|
||||||
std::unique_ptr<DatabaseReplicationApplier> applier;
|
std::unique_ptr<DatabaseReplicationApplier> applier;
|
||||||
|
|
||||||
if (vocbase->type() == TRI_VOCBASE_TYPE_NORMAL) {
|
if (vocbase.type() == TRI_VOCBASE_TYPE_NORMAL) {
|
||||||
applier = std::make_unique<DatabaseReplicationApplier>(DatabaseReplicationApplier::loadConfiguration(vocbase), vocbase);
|
applier = std::make_unique<DatabaseReplicationApplier>(
|
||||||
|
DatabaseReplicationApplier::loadConfiguration(&vocbase), vocbase
|
||||||
|
);
|
||||||
applier->loadState();
|
applier->loadState();
|
||||||
} else {
|
} else {
|
||||||
applier = std::make_unique<DatabaseReplicationApplier>(vocbase);
|
applier = std::make_unique<DatabaseReplicationApplier>(vocbase);
|
||||||
|
@ -131,6 +138,7 @@ void DatabaseReplicationApplier::storeConfiguration(bool doSync) {
|
||||||
}
|
}
|
||||||
|
|
||||||
VPackBuilder builder;
|
VPackBuilder builder;
|
||||||
|
|
||||||
builder.openObject();
|
builder.openObject();
|
||||||
_configuration.toVelocyPack(builder, true, true);
|
_configuration.toVelocyPack(builder, true, true);
|
||||||
builder.close();
|
builder.close();
|
||||||
|
@ -138,7 +146,9 @@ void DatabaseReplicationApplier::storeConfiguration(bool doSync) {
|
||||||
LOG_TOPIC(DEBUG, Logger::REPLICATION) << "storing applier configuration " << builder.slice().toJson() << " for " << _databaseName;
|
LOG_TOPIC(DEBUG, Logger::REPLICATION) << "storing applier configuration " << builder.slice().toJson() << " for " << _databaseName;
|
||||||
|
|
||||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||||
int res = engine->saveReplicationApplierConfiguration(_vocbase, builder.slice(), doSync);
|
int res = engine->saveReplicationApplierConfiguration(
|
||||||
|
&_vocbase, builder.slice(), doSync
|
||||||
|
);
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
THROW_ARANGO_EXCEPTION(res);
|
THROW_ARANGO_EXCEPTION(res);
|
||||||
|
@ -157,5 +167,10 @@ std::unique_ptr<TailingSyncer> DatabaseReplicationApplier::buildTailingSyncer(TR
|
||||||
|
|
||||||
std::string DatabaseReplicationApplier::getStateFilename() const {
|
std::string DatabaseReplicationApplier::getStateFilename() const {
|
||||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||||
return arangodb::basics::FileUtils::buildFilename(engine->databasePath(_vocbase), "REPLICATION-APPLIER-STATE");
|
|
||||||
|
return arangodb::basics::FileUtils::buildFilename(
|
||||||
|
engine->databasePath(&_vocbase), "REPLICATION-APPLIER-STATE"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // arangodb
|
||||||
|
|
|
@ -31,16 +31,19 @@
|
||||||
struct TRI_vocbase_t;
|
struct TRI_vocbase_t;
|
||||||
|
|
||||||
namespace arangodb {
|
namespace arangodb {
|
||||||
|
|
||||||
/// @brief replication applier for a single database
|
/// @brief replication applier for a single database
|
||||||
class DatabaseReplicationApplier final : public ReplicationApplier {
|
class DatabaseReplicationApplier final : public ReplicationApplier {
|
||||||
friend class DatabaseTailingSyncer;
|
friend class DatabaseTailingSyncer;
|
||||||
friend class RestReplicationHandler;
|
friend class RestReplicationHandler;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DatabaseReplicationApplier(TRI_vocbase_t* vocbase);
|
explicit DatabaseReplicationApplier(TRI_vocbase_t& vocbase);
|
||||||
|
|
||||||
DatabaseReplicationApplier(ReplicationApplierConfiguration const& configuration,
|
DatabaseReplicationApplier(
|
||||||
TRI_vocbase_t* vocbase);
|
ReplicationApplierConfiguration const& configuration,
|
||||||
|
TRI_vocbase_t& vocbase
|
||||||
|
);
|
||||||
|
|
||||||
~DatabaseReplicationApplier();
|
~DatabaseReplicationApplier();
|
||||||
|
|
||||||
|
@ -60,7 +63,7 @@ class DatabaseReplicationApplier final : public ReplicationApplier {
|
||||||
void storeConfiguration(bool doSync) override;
|
void storeConfiguration(bool doSync) override;
|
||||||
|
|
||||||
/// @brief factory function for creating a database-specific replication applier
|
/// @brief factory function for creating a database-specific replication applier
|
||||||
static DatabaseReplicationApplier* create(TRI_vocbase_t* vocbase);
|
static DatabaseReplicationApplier* create(TRI_vocbase_t& vocbase);
|
||||||
|
|
||||||
/// @brief load a persisted configuration for the applier
|
/// @brief load a persisted configuration for the applier
|
||||||
static ReplicationApplierConfiguration loadConfiguration(TRI_vocbase_t* vocbase);
|
static ReplicationApplierConfiguration loadConfiguration(TRI_vocbase_t* vocbase);
|
||||||
|
@ -72,7 +75,7 @@ protected:
|
||||||
std::string getStateFilename() const override;
|
std::string getStateFilename() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TRI_vocbase_t* _vocbase;
|
TRI_vocbase_t& _vocbase;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,15 +56,27 @@ using namespace arangodb::httpclient;
|
||||||
using namespace arangodb::rest;
|
using namespace arangodb::rest;
|
||||||
|
|
||||||
DatabaseTailingSyncer::DatabaseTailingSyncer(
|
DatabaseTailingSyncer::DatabaseTailingSyncer(
|
||||||
TRI_vocbase_t* vocbase,
|
TRI_vocbase_t& vocbase,
|
||||||
ReplicationApplierConfiguration const& configuration,
|
ReplicationApplierConfiguration const& configuration,
|
||||||
TRI_voc_tick_t initialTick, bool useTick, TRI_voc_tick_t barrierId)
|
TRI_voc_tick_t initialTick,
|
||||||
: TailingSyncer(vocbase->replicationApplier(),
|
bool useTick,
|
||||||
configuration, initialTick, useTick, barrierId),
|
TRI_voc_tick_t barrierId
|
||||||
_vocbase(vocbase) {
|
): TailingSyncer(
|
||||||
_vocbases.emplace(vocbase->name(), DatabaseGuard(vocbase));
|
vocbase.replicationApplier(),
|
||||||
|
configuration,
|
||||||
|
initialTick,
|
||||||
|
useTick,
|
||||||
|
barrierId
|
||||||
|
),
|
||||||
|
_vocbase(&vocbase) {
|
||||||
|
_vocbases.emplace(
|
||||||
|
std::piecewise_construct,
|
||||||
|
std::forward_as_tuple(vocbase.name()),
|
||||||
|
std::forward_as_tuple(vocbase)
|
||||||
|
);
|
||||||
|
|
||||||
if (configuration._database.empty()) {
|
if (configuration._database.empty()) {
|
||||||
_databaseName = vocbase->name();
|
_databaseName = vocbase.name();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,12 +33,13 @@ class DatabaseReplicationApplier;
|
||||||
|
|
||||||
class DatabaseTailingSyncer : public TailingSyncer {
|
class DatabaseTailingSyncer : public TailingSyncer {
|
||||||
public:
|
public:
|
||||||
DatabaseTailingSyncer(TRI_vocbase_t*,
|
DatabaseTailingSyncer(
|
||||||
ReplicationApplierConfiguration const&,
|
TRI_vocbase_t& vocbase,
|
||||||
TRI_voc_tick_t initialTick, bool useTick,
|
ReplicationApplierConfiguration const& configuration,
|
||||||
TRI_voc_tick_t barrierId);
|
TRI_voc_tick_t initialTick,
|
||||||
|
bool useTick,
|
||||||
public:
|
TRI_voc_tick_t barrierId
|
||||||
|
);
|
||||||
|
|
||||||
TRI_vocbase_t* resolveVocbase(velocypack::Slice const&) override { return _vocbase; }
|
TRI_vocbase_t* resolveVocbase(velocypack::Slice const&) override { return _vocbase; }
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ class DatabaseTailingSyncer : public TailingSyncer {
|
||||||
|
|
||||||
TRI_vocbase_t* vocbase() const {
|
TRI_vocbase_t* vocbase() const {
|
||||||
TRI_ASSERT(vocbases().size() == 1);
|
TRI_ASSERT(vocbases().size() == 1);
|
||||||
return vocbases().begin()->second.database();
|
return &(vocbases().begin()->second.database());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -158,6 +158,7 @@ Result GlobalInitialSyncer::runInternal(bool incremental) {
|
||||||
VPackSlice const nameSlice = it.get("name");
|
VPackSlice const nameSlice = it.get("name");
|
||||||
VPackSlice const idSlice = it.get("id");
|
VPackSlice const idSlice = it.get("id");
|
||||||
VPackSlice const collections = it.get("collections");
|
VPackSlice const collections = it.get("collections");
|
||||||
|
|
||||||
if (!nameSlice.isString() ||
|
if (!nameSlice.isString() ||
|
||||||
!idSlice.isString() ||
|
!idSlice.isString() ||
|
||||||
!collections.isArray()) {
|
!collections.isArray()) {
|
||||||
|
@ -166,6 +167,7 @@ Result GlobalInitialSyncer::runInternal(bool incremental) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_vocbase_t* vocbase = resolveVocbase(nameSlice);
|
TRI_vocbase_t* vocbase = resolveVocbase(nameSlice);
|
||||||
|
|
||||||
if (vocbase == nullptr) {
|
if (vocbase == nullptr) {
|
||||||
return Result(TRI_ERROR_INTERNAL, "vocbase not found");
|
return Result(TRI_ERROR_INTERNAL, "vocbase not found");
|
||||||
}
|
}
|
||||||
|
@ -174,12 +176,14 @@ Result GlobalInitialSyncer::runInternal(bool incremental) {
|
||||||
|
|
||||||
// change database name in place
|
// change database name in place
|
||||||
auto configurationCopy = _configuration;
|
auto configurationCopy = _configuration;
|
||||||
|
|
||||||
configurationCopy._database = nameSlice.copyString();
|
configurationCopy._database = nameSlice.copyString();
|
||||||
|
|
||||||
DatabaseInitialSyncer syncer(vocbase, configurationCopy);
|
DatabaseInitialSyncer syncer(*vocbase, configurationCopy);
|
||||||
|
|
||||||
syncer.useAsChildSyncer(_masterInfo, _barrierId, _barrierUpdateTime,
|
syncer.useAsChildSyncer(_masterInfo, _barrierId, _barrierUpdateTime,
|
||||||
_batchId, _batchUpdateTime);
|
_batchId, _batchUpdateTime);
|
||||||
|
|
||||||
// run the syncer with the supplied inventory collections
|
// run the syncer with the supplied inventory collections
|
||||||
Result r = syncer.runWithInventory(false, collections);
|
Result r = syncer.runWithInventory(false, collections);
|
||||||
if (r.fail()) {
|
if (r.fail()) {
|
||||||
|
@ -193,7 +197,6 @@ Result GlobalInitialSyncer::runInternal(bool incremental) {
|
||||||
sendExtendBatch();
|
sendExtendBatch();
|
||||||
sendExtendBarrier();
|
sendExtendBarrier();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
return Result(TRI_ERROR_INTERNAL, "caught an unexpected exception");
|
return Result(TRI_ERROR_INTERNAL, "caught an unexpected exception");
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,16 +37,13 @@ namespace arangodb {
|
||||||
class ReplicationTransaction : public transaction::Methods {
|
class ReplicationTransaction : public transaction::Methods {
|
||||||
public:
|
public:
|
||||||
/// @brief create the transaction
|
/// @brief create the transaction
|
||||||
explicit ReplicationTransaction(TRI_vocbase_t* vocbase)
|
explicit ReplicationTransaction(TRI_vocbase_t& vocbase)
|
||||||
: transaction::Methods(transaction::StandaloneContext::Create(vocbase)),
|
: transaction::Methods(transaction::StandaloneContext::Create(&vocbase)),
|
||||||
_guard(vocbase) {
|
_guard(vocbase) {
|
||||||
|
|
||||||
TRI_ASSERT(_state != nullptr);
|
TRI_ASSERT(_state != nullptr);
|
||||||
_state->setType(AccessMode::Type::EXCLUSIVE);
|
_state->setType(AccessMode::Type::EXCLUSIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// @brief get a collection by id
|
/// @brief get a collection by id
|
||||||
/// this will automatically add the collection to the transaction
|
/// this will automatically add the collection to the transaction
|
||||||
/*inline TransactionCollection* trxCollection(TRI_voc_cid_t cid, AccessMode::Type) const override {
|
/*inline TransactionCollection* trxCollection(TRI_voc_cid_t cid, AccessMode::Type) const override {
|
||||||
|
|
|
@ -356,6 +356,7 @@ TRI_vocbase_t* Syncer::resolveVocbase(VPackSlice const& slice) {
|
||||||
} else if (slice.isString()) {
|
} else if (slice.isString()) {
|
||||||
name = slice.copyString();
|
name = slice.copyString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_REPLICATION_INVALID_RESPONSE,
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_REPLICATION_INVALID_RESPONSE,
|
||||||
"could not resolve vocbase id / name");
|
"could not resolve vocbase id / name");
|
||||||
|
@ -363,17 +364,24 @@ TRI_vocbase_t* Syncer::resolveVocbase(VPackSlice const& slice) {
|
||||||
|
|
||||||
// will work with either names or id's
|
// will work with either names or id's
|
||||||
auto const& it = _vocbases.find(name);
|
auto const& it = _vocbases.find(name);
|
||||||
|
|
||||||
if (it == _vocbases.end()) {
|
if (it == _vocbases.end()) {
|
||||||
// automatically checks for id in string
|
// automatically checks for id in string
|
||||||
TRI_vocbase_t* vocbase = DatabaseFeature::DATABASE->lookupDatabase(name);
|
TRI_vocbase_t* vocbase = DatabaseFeature::DATABASE->lookupDatabase(name);
|
||||||
|
|
||||||
if (vocbase != nullptr) {
|
if (vocbase != nullptr) {
|
||||||
_vocbases.emplace(name, DatabaseGuard(vocbase));
|
_vocbases.emplace(
|
||||||
|
std::piecewise_construct,
|
||||||
|
std::forward_as_tuple(name),
|
||||||
|
std::forward_as_tuple(*vocbase)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
LOG_TOPIC(DEBUG, Logger::REPLICATION) << "could not find database '" << name << "'";
|
LOG_TOPIC(DEBUG, Logger::REPLICATION) << "could not find database '" << name << "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
return vocbase;
|
return vocbase;
|
||||||
} else {
|
} else {
|
||||||
return it->second.database();
|
return &(it->second.database());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -444,7 +444,7 @@ Result TailingSyncer::startTransaction(VPackSlice const& slice) {
|
||||||
LOG_TOPIC(TRACE, Logger::REPLICATION) << "starting replication transaction "
|
LOG_TOPIC(TRACE, Logger::REPLICATION) << "starting replication transaction "
|
||||||
<< tid;
|
<< tid;
|
||||||
|
|
||||||
auto trx = std::make_unique<ReplicationTransaction>(vocbase);
|
auto trx = std::make_unique<ReplicationTransaction>(*vocbase);
|
||||||
Result res = trx->begin();
|
Result res = trx->begin();
|
||||||
|
|
||||||
if (res.ok()) {
|
if (res.ok()) {
|
||||||
|
|
|
@ -1755,13 +1755,15 @@ void RestReplicationHandler::handleCommandSync() {
|
||||||
|
|
||||||
TRI_ASSERT(!config._skipCreateDrop);
|
TRI_ASSERT(!config._skipCreateDrop);
|
||||||
std::unique_ptr<InitialSyncer> syncer;
|
std::unique_ptr<InitialSyncer> syncer;
|
||||||
|
|
||||||
if (isGlobal) {
|
if (isGlobal) {
|
||||||
syncer.reset(new GlobalInitialSyncer(config));
|
syncer.reset(new GlobalInitialSyncer(config));
|
||||||
} else {
|
} else {
|
||||||
syncer.reset(new DatabaseInitialSyncer(&_vocbase, config));
|
syncer.reset(new DatabaseInitialSyncer(_vocbase, config));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result r = syncer->run(config._incremental);
|
Result r = syncer->run(config._incremental);
|
||||||
|
|
||||||
if (r.fail()) {
|
if (r.fail()) {
|
||||||
LOG_TOPIC(ERR, Logger::REPLICATION)
|
LOG_TOPIC(ERR, Logger::REPLICATION)
|
||||||
<< "failed to sync: " << r.errorMessage();
|
<< "failed to sync: " << r.errorMessage();
|
||||||
|
|
|
@ -107,8 +107,9 @@ VPackSlice RocksDBExportCursor::next() {
|
||||||
size_t RocksDBExportCursor::count() const { return _size; }
|
size_t RocksDBExportCursor::count() const { return _size; }
|
||||||
|
|
||||||
Result RocksDBExportCursor::dump(VPackBuilder& builder) {
|
Result RocksDBExportCursor::dump(VPackBuilder& builder) {
|
||||||
auto ctx = transaction::StandaloneContext::Create(_guard.database());
|
auto ctx = transaction::StandaloneContext::Create(&(_guard.database()));
|
||||||
VPackOptions const* oldOptions = builder.options;
|
VPackOptions const* oldOptions = builder.options;
|
||||||
|
|
||||||
builder.options = ctx->getVPackOptions();
|
builder.options = ctx->getVPackOptions();
|
||||||
|
|
||||||
TRI_ASSERT(_iter.get() != nullptr);
|
TRI_ASSERT(_iter.get() != nullptr);
|
||||||
|
|
|
@ -102,10 +102,12 @@ uint64_t RocksDBReplicationContext::count() const {
|
||||||
|
|
||||||
TRI_vocbase_t* RocksDBReplicationContext::vocbase() const {
|
TRI_vocbase_t* RocksDBReplicationContext::vocbase() const {
|
||||||
MUTEX_LOCKER(locker, _contextLock);
|
MUTEX_LOCKER(locker, _contextLock);
|
||||||
|
|
||||||
if (!_guard) {
|
if (!_guard) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return _guard->database();
|
|
||||||
|
return &(_guard->database());
|
||||||
}
|
}
|
||||||
|
|
||||||
// creates new transaction/snapshot
|
// creates new transaction/snapshot
|
||||||
|
@ -116,7 +118,7 @@ void RocksDBReplicationContext::bind(TRI_vocbase_t* vocbase) {
|
||||||
|
|
||||||
void RocksDBReplicationContext::internalBind(TRI_vocbase_t* vocbase,
|
void RocksDBReplicationContext::internalBind(TRI_vocbase_t* vocbase,
|
||||||
bool allowChange) {
|
bool allowChange) {
|
||||||
if (!_trx || !_guard || (_guard->database() != vocbase)) {
|
if (!_trx || !_guard || (&(_guard->database()) != vocbase)) {
|
||||||
TRI_ASSERT(allowChange);
|
TRI_ASSERT(allowChange);
|
||||||
rocksdb::Snapshot const* snap = nullptr;
|
rocksdb::Snapshot const* snap = nullptr;
|
||||||
if (_trx) {
|
if (_trx) {
|
||||||
|
@ -177,7 +179,8 @@ int RocksDBReplicationContext::bindCollection(
|
||||||
int RocksDBReplicationContext::chooseDatabase(TRI_vocbase_t* vocbase) {
|
int RocksDBReplicationContext::chooseDatabase(TRI_vocbase_t* vocbase) {
|
||||||
TRI_ASSERT(_users > 0);
|
TRI_ASSERT(_users > 0);
|
||||||
MUTEX_LOCKER(locker, _contextLock);
|
MUTEX_LOCKER(locker, _contextLock);
|
||||||
if (_guard->database() == vocbase) {
|
|
||||||
|
if (&(_guard->database()) == vocbase) {
|
||||||
return TRI_ERROR_NO_ERROR; // nothing to do here
|
return TRI_ERROR_NO_ERROR; // nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,17 +245,23 @@ RocksDBReplicationResult RocksDBReplicationContext::dump(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
TRI_DEFER(release());
|
TRI_DEFER(release());
|
||||||
|
|
||||||
{
|
{
|
||||||
MUTEX_LOCKER(writeLocker, _contextLock);
|
MUTEX_LOCKER(writeLocker, _contextLock);
|
||||||
TRI_ASSERT(vocbase != nullptr);
|
TRI_ASSERT(vocbase != nullptr);
|
||||||
if (!_trx || !_guard || (_guard->database() != vocbase)) {
|
|
||||||
|
if (!_trx || !_guard || (&(_guard->database()) != vocbase)) {
|
||||||
return RocksDBReplicationResult(TRI_ERROR_BAD_PARAMETER, _lastTick);
|
return RocksDBReplicationResult(TRI_ERROR_BAD_PARAMETER, _lastTick);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_voc_cid_t const id{::normalizeIdentifier(*_trx, collectionName)};
|
TRI_voc_cid_t const id{::normalizeIdentifier(*_trx, collectionName)};
|
||||||
|
|
||||||
if (0 == id) {
|
if (0 == id) {
|
||||||
return RocksDBReplicationResult{TRI_ERROR_BAD_PARAMETER, _lastTick};
|
return RocksDBReplicationResult{TRI_ERROR_BAD_PARAMETER, _lastTick};
|
||||||
}
|
}
|
||||||
|
|
||||||
collection = getCollectionIterator(id);
|
collection = getCollectionIterator(id);
|
||||||
|
|
||||||
if (!collection) {
|
if (!collection) {
|
||||||
return RocksDBReplicationResult(TRI_ERROR_BAD_PARAMETER, _lastTick);
|
return RocksDBReplicationResult(TRI_ERROR_BAD_PARAMETER, _lastTick);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,15 +55,22 @@ bool WalAccessContext::shouldHandleCollection(TRI_voc_tick_t dbid,
|
||||||
TRI_vocbase_t* WalAccessContext::loadVocbase(TRI_voc_tick_t dbid) {
|
TRI_vocbase_t* WalAccessContext::loadVocbase(TRI_voc_tick_t dbid) {
|
||||||
TRI_ASSERT(dbid != 0);
|
TRI_ASSERT(dbid != 0);
|
||||||
auto const& it = _vocbases.find(dbid);
|
auto const& it = _vocbases.find(dbid);
|
||||||
|
|
||||||
if (it == _vocbases.end()) {
|
if (it == _vocbases.end()) {
|
||||||
TRI_vocbase_t* vocbase = DatabaseFeature::DATABASE->useDatabase(dbid);
|
TRI_vocbase_t* vocbase = DatabaseFeature::DATABASE->useDatabase(dbid);
|
||||||
|
|
||||||
if (vocbase != nullptr) {
|
if (vocbase != nullptr) {
|
||||||
TRI_DEFER(vocbase->release());
|
TRI_DEFER(vocbase->release());
|
||||||
_vocbases.emplace(dbid, DatabaseGuard(vocbase));
|
_vocbases.emplace(
|
||||||
|
std::piecewise_construct,
|
||||||
|
std::forward_as_tuple(dbid),
|
||||||
|
std::forward_as_tuple(*vocbase)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return vocbase;
|
return vocbase;
|
||||||
} else {
|
} else {
|
||||||
return it->second.database();
|
return &(it->second.database());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ size_t const CursorRepository::MaxCollectCount = 32;
|
||||||
/// @brief create a cursor repository
|
/// @brief create a cursor repository
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
CursorRepository::CursorRepository(TRI_vocbase_t* vocbase)
|
CursorRepository::CursorRepository(TRI_vocbase_t& vocbase)
|
||||||
: _vocbase(vocbase), _lock(), _cursors() {
|
: _vocbase(vocbase), _lock(), _cursors() {
|
||||||
_cursors.reserve(64);
|
_cursors.reserve(64);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
struct TRI_vocbase_t;
|
struct TRI_vocbase_t;
|
||||||
|
|
||||||
namespace arangodb {
|
namespace arangodb {
|
||||||
|
|
||||||
namespace velocypack {
|
namespace velocypack {
|
||||||
class Builder;
|
class Builder;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +47,7 @@ class CursorRepository {
|
||||||
/// @brief create a cursors repository
|
/// @brief create a cursors repository
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
explicit CursorRepository(TRI_vocbase_t*);
|
explicit CursorRepository(TRI_vocbase_t& vocbase);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief destroy a cursors repository
|
/// @brief destroy a cursors repository
|
||||||
|
@ -54,8 +55,6 @@ class CursorRepository {
|
||||||
|
|
||||||
~CursorRepository();
|
~CursorRepository();
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief stores a cursor in the registry
|
/// @brief stores a cursor in the registry
|
||||||
/// the repository will take ownership of the cursor
|
/// the repository will take ownership of the cursor
|
||||||
|
@ -121,7 +120,7 @@ class CursorRepository {
|
||||||
/// @brief vocbase
|
/// @brief vocbase
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TRI_vocbase_t* _vocbase;
|
TRI_vocbase_t& _vocbase;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief mutex for the cursors repository
|
/// @brief mutex for the cursors repository
|
||||||
|
@ -141,6 +140,7 @@ class CursorRepository {
|
||||||
|
|
||||||
static size_t const MaxCollectCount;
|
static size_t const MaxCollectCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -26,32 +26,48 @@
|
||||||
#include "Basics/Exceptions.h"
|
#include "Basics/Exceptions.h"
|
||||||
#include "RestServer/DatabaseFeature.h"
|
#include "RestServer/DatabaseFeature.h"
|
||||||
|
|
||||||
using namespace arangodb;
|
namespace {
|
||||||
|
|
||||||
/// @brief create the guard, using a database id
|
template<typename T>
|
||||||
DatabaseGuard::DatabaseGuard(TRI_voc_tick_t id) : _vocbase(nullptr) {
|
TRI_vocbase_t& vocbase(T& id) {
|
||||||
DatabaseFeature* databaseFeature = DatabaseFeature::DATABASE;
|
auto* databaseFeature = arangodb::DatabaseFeature::DATABASE;
|
||||||
_vocbase = databaseFeature->useDatabase(id);
|
|
||||||
|
|
||||||
if (_vocbase == nullptr) {
|
if (!databaseFeature) {
|
||||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_ASSERT(!_vocbase->isDangling());
|
auto* vocbase = databaseFeature->useDatabase(id);
|
||||||
|
|
||||||
|
if (!vocbase) {
|
||||||
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
return *vocbase;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
TRI_vocbase_t& vocbase(TRI_vocbase_t*& vocbase) {
|
||||||
|
// check from the original constructor of DatabaseGuard
|
||||||
|
TRI_ASSERT(vocbase != nullptr);
|
||||||
|
|
||||||
|
return *vocbase;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace arangodb {
|
||||||
|
|
||||||
|
DatabaseGuard::DatabaseGuard(TRI_vocbase_t* ptr): DatabaseGuard(vocbase(ptr)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief create the guard, using a database id
|
||||||
|
DatabaseGuard::DatabaseGuard(TRI_voc_tick_t id): _vocbase(vocbase(id)) {
|
||||||
|
TRI_ASSERT(!_vocbase.isDangling());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief create the guard, using a database name
|
/// @brief create the guard, using a database name
|
||||||
DatabaseGuard::DatabaseGuard(std::string const& name) : _vocbase(nullptr) {
|
DatabaseGuard::DatabaseGuard(std::string const& name): _vocbase(vocbase(name)) {
|
||||||
DatabaseFeature* databaseFeature = DatabaseFeature::DATABASE;
|
TRI_ASSERT(!_vocbase.isDangling());
|
||||||
_vocbase = databaseFeature->useDatabase(name);
|
|
||||||
|
|
||||||
if (_vocbase == nullptr) {
|
|
||||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
TRI_ASSERT(!_vocbase->isDangling());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DatabaseGuard::DatabaseGuard(DatabaseGuard&& other) : _vocbase(other._vocbase) {
|
} // arangodb
|
||||||
other._vocbase = nullptr;
|
|
||||||
}
|
|
||||||
|
|
|
@ -32,17 +32,22 @@ namespace arangodb {
|
||||||
/// dropped while still using it.
|
/// dropped while still using it.
|
||||||
class DatabaseGuard {
|
class DatabaseGuard {
|
||||||
public:
|
public:
|
||||||
|
DatabaseGuard(DatabaseGuard&&) = delete;
|
||||||
DatabaseGuard(DatabaseGuard const&) = delete;
|
DatabaseGuard(DatabaseGuard const&) = delete;
|
||||||
DatabaseGuard& operator=(DatabaseGuard const&) = delete;
|
DatabaseGuard& operator=(DatabaseGuard const&) = delete;
|
||||||
|
|
||||||
/// @brief create guard on existing db
|
/// @brief create guard on existing db
|
||||||
explicit DatabaseGuard(TRI_vocbase_t* vocbase) : _vocbase(vocbase) {
|
explicit DatabaseGuard(TRI_vocbase_t& vocbase): _vocbase(vocbase) {
|
||||||
TRI_ASSERT(vocbase != nullptr);
|
if (!_vocbase.use()) {
|
||||||
if (!_vocbase->use()) {
|
|
||||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief create guard on existing db pointer (not nullptr)
|
||||||
|
/// @deprecated DO NOT USE for new code
|
||||||
|
/// FIXME TODO remove once V8Task and arangodb::pregel::GraphStore are fixed
|
||||||
|
explicit DatabaseGuard(TRI_vocbase_t* vocbase);
|
||||||
|
|
||||||
/// @brief create the guard, using a database id
|
/// @brief create the guard, using a database id
|
||||||
explicit DatabaseGuard(TRI_voc_tick_t id);
|
explicit DatabaseGuard(TRI_voc_tick_t id);
|
||||||
|
|
||||||
|
@ -51,22 +56,18 @@ class DatabaseGuard {
|
||||||
|
|
||||||
/// @brief destroy the guard
|
/// @brief destroy the guard
|
||||||
~DatabaseGuard() {
|
~DatabaseGuard() {
|
||||||
if (_vocbase != nullptr) {
|
TRI_ASSERT(!_vocbase.isDangling());
|
||||||
TRI_ASSERT(!_vocbase->isDangling());
|
_vocbase.release();
|
||||||
_vocbase->release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DatabaseGuard(DatabaseGuard&&);
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// @brief return the database pointer
|
/// @brief return the database pointer
|
||||||
inline TRI_vocbase_t* database() const { return _vocbase; }
|
inline TRI_vocbase_t& database() const { return _vocbase; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// @brief pointer to database
|
/// @brief pointer to database
|
||||||
TRI_vocbase_t* _vocbase;
|
TRI_vocbase_t& _vocbase;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -1913,6 +1913,8 @@ static void JS_PregelStart(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_vocbase_t* vocbase = GetContextVocBase(isolate);
|
TRI_vocbase_t* vocbase = GetContextVocBase(isolate);
|
||||||
|
TRI_ASSERT(vocbase != nullptr); // for clarity assert duplicated from v8-util.cpp GetContextVocBase(...)
|
||||||
|
|
||||||
for (std::string const& name : paramVertices) {
|
for (std::string const& name : paramVertices) {
|
||||||
if (ss->isCoordinator()) {
|
if (ss->isCoordinator()) {
|
||||||
try {
|
try {
|
||||||
|
@ -1982,8 +1984,9 @@ static void JS_PregelStart(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t en = pregel::PregelFeature::instance()->createExecutionNumber();
|
uint64_t en = pregel::PregelFeature::instance()->createExecutionNumber();
|
||||||
auto c = std::make_unique<pregel::Conductor>(en, vocbase, paramVertices, edgeColls,
|
auto c = std::make_unique<pregel::Conductor>(
|
||||||
algorithm, paramBuilder.slice());
|
en, *vocbase, paramVertices, edgeColls, algorithm, paramBuilder.slice()
|
||||||
|
);
|
||||||
pregel::PregelFeature::instance()->addConductor(std::move(c), en);
|
pregel::PregelFeature::instance()->addConductor(std::move(c), en);
|
||||||
TRI_ASSERT(pregel::PregelFeature::instance()->conductor(en));
|
TRI_ASSERT(pregel::PregelFeature::instance()->conductor(en));
|
||||||
pregel::PregelFeature::instance()->conductor(en)->start();
|
pregel::PregelFeature::instance()->conductor(en)->start();
|
||||||
|
|
|
@ -232,7 +232,7 @@ void V8Task::removeTasksForDatabase(std::string const& name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool V8Task::databaseMatches(std::string const& name) const {
|
bool V8Task::databaseMatches(std::string const& name) const {
|
||||||
return (_dbGuard->database()->name() == name);
|
return (_dbGuard->database().name() == name);
|
||||||
}
|
}
|
||||||
|
|
||||||
V8Task::V8Task(std::string const& id, std::string const& name,
|
V8Task::V8Task(std::string const& id, std::string const& name,
|
||||||
|
@ -299,14 +299,16 @@ V8Task::callbackFunction() {
|
||||||
|
|
||||||
// get the permissions to be used by this task
|
// get the permissions to be used by this task
|
||||||
bool allowContinue = true;
|
bool allowContinue = true;
|
||||||
|
|
||||||
std::unique_ptr<ExecContext> execContext;
|
std::unique_ptr<ExecContext> execContext;
|
||||||
|
|
||||||
if (!_user.empty()) { // not superuser
|
if (!_user.empty()) { // not superuser
|
||||||
std::string const& dbname = _dbGuard->database()->name();
|
auto& dbname = _dbGuard->database().name();
|
||||||
|
|
||||||
execContext.reset(ExecContext::create(_user, dbname));
|
execContext.reset(ExecContext::create(_user, dbname));
|
||||||
allowContinue = execContext->canUseDatabase(dbname, auth::Level::RW);
|
allowContinue = execContext->canUseDatabase(dbname, auth::Level::RW);
|
||||||
allowContinue = allowContinue && ServerState::writeOpsEnabled();
|
allowContinue = allowContinue && ServerState::writeOpsEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecContextScope scope(_user.empty() ?
|
ExecContextScope scope(_user.empty() ?
|
||||||
ExecContext::superuser() : execContext.get());
|
ExecContext::superuser() : execContext.get());
|
||||||
|
|
||||||
|
@ -412,12 +414,13 @@ void V8Task::toVelocyPack(VPackBuilder& builder) const {
|
||||||
builder.add("offset", VPackValue(_offset.count() / 1000000.0));
|
builder.add("offset", VPackValue(_offset.count() / 1000000.0));
|
||||||
|
|
||||||
builder.add("command", VPackValue(_command));
|
builder.add("command", VPackValue(_command));
|
||||||
builder.add("database", VPackValue(_dbGuard->database()->name()));
|
builder.add("database", VPackValue(_dbGuard->database().name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void V8Task::work(ExecContext const* exec) {
|
void V8Task::work(ExecContext const* exec) {
|
||||||
auto context = V8DealerFeature::DEALER->enterContext(_dbGuard->database(),
|
auto context = V8DealerFeature::DEALER->enterContext(
|
||||||
_allowUseDatabase);
|
&(_dbGuard->database()), _allowUseDatabase
|
||||||
|
);
|
||||||
|
|
||||||
// note: the context might be 0 in case of shut-down
|
// note: the context might be 0 in case of shut-down
|
||||||
if (context == nullptr) {
|
if (context == nullptr) {
|
||||||
|
|
|
@ -191,7 +191,6 @@ static void SynchronizeReplication(
|
||||||
|
|
||||||
// treat the argument as an object from now on
|
// treat the argument as an object from now on
|
||||||
v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(args[0]);
|
v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(args[0]);
|
||||||
|
|
||||||
VPackBuilder builder;
|
VPackBuilder builder;
|
||||||
int res = TRI_V8ToVPack(isolate, builder, args[0], false);
|
int res = TRI_V8ToVPack(isolate, builder, args[0], false);
|
||||||
|
|
||||||
|
@ -222,10 +221,9 @@ static void SynchronizeReplication(
|
||||||
v8::Handle<v8::Object> result = v8::Object::New(isolate);
|
v8::Handle<v8::Object> result = v8::Object::New(isolate);
|
||||||
std::unique_ptr<InitialSyncer> syncer;
|
std::unique_ptr<InitialSyncer> syncer;
|
||||||
|
|
||||||
|
|
||||||
if (applierType == APPLIER_DATABASE) {
|
if (applierType == APPLIER_DATABASE) {
|
||||||
// database-specific synchronization
|
// database-specific synchronization
|
||||||
syncer.reset(new DatabaseInitialSyncer(vocbase, configuration));
|
syncer.reset(new DatabaseInitialSyncer(*vocbase, configuration));
|
||||||
|
|
||||||
if (object->Has(TRI_V8_ASCII_STRING(isolate, "leaderId"))) {
|
if (object->Has(TRI_V8_ASCII_STRING(isolate, "leaderId"))) {
|
||||||
syncer->setLeaderId(TRI_ObjectToString(object->Get(TRI_V8_ASCII_STRING(isolate, "leaderId"))));
|
syncer->setLeaderId(TRI_ObjectToString(object->Get(TRI_V8_ASCII_STRING(isolate, "leaderId"))));
|
||||||
|
|
|
@ -1773,7 +1773,7 @@ TRI_vocbase_t::TRI_vocbase_t(TRI_vocbase_type_e type, TRI_voc_tick_t id,
|
||||||
_deadlockDetector(false),
|
_deadlockDetector(false),
|
||||||
_userStructures(nullptr) {
|
_userStructures(nullptr) {
|
||||||
_queries.reset(new arangodb::aql::QueryList(this));
|
_queries.reset(new arangodb::aql::QueryList(this));
|
||||||
_cursorRepository.reset(new arangodb::CursorRepository(this));
|
_cursorRepository.reset(new arangodb::CursorRepository(*this));
|
||||||
_collectionKeys.reset(new arangodb::CollectionKeysRepository());
|
_collectionKeys.reset(new arangodb::CollectionKeysRepository());
|
||||||
|
|
||||||
// init collections
|
// init collections
|
||||||
|
@ -1856,7 +1856,8 @@ bool TRI_vocbase_t::IsAllowedName(
|
||||||
}
|
}
|
||||||
|
|
||||||
void TRI_vocbase_t::addReplicationApplier() {
|
void TRI_vocbase_t::addReplicationApplier() {
|
||||||
DatabaseReplicationApplier* applier = DatabaseReplicationApplier::create(this);
|
auto* applier = DatabaseReplicationApplier::create(*this);
|
||||||
|
|
||||||
_replicationApplier.reset(applier);
|
_replicationApplier.reset(applier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1866,6 +1867,7 @@ void TRI_vocbase_t::updateReplicationClient(TRI_server_id_t serverId, double ttl
|
||||||
if (ttl <= 0.0) {
|
if (ttl <= 0.0) {
|
||||||
ttl = InitialSyncer::defaultBatchTimeout;
|
ttl = InitialSyncer::defaultBatchTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
double const expires = TRI_microtime() + ttl;
|
double const expires = TRI_microtime() + ttl;
|
||||||
|
|
||||||
WRITE_LOCKER(writeLocker, _replicationClientsLock);
|
WRITE_LOCKER(writeLocker, _replicationClientsLock);
|
||||||
|
|
Loading…
Reference in New Issue