1
0
Fork 0

Merge branch 'devel' of https://github.com/arangodb/arangodb into devel

# Conflicts:
#	arangod/Replication/InitialSyncer.cpp
This commit is contained in:
Simon Grätzer 2017-04-26 11:06:09 +02:00
commit d228a94462
55 changed files with 1270 additions and 630 deletions

View File

@ -182,9 +182,12 @@ class ObjectIterator {
ObjectIterator() = delete;
explicit ObjectIterator(Slice const& slice, bool allowRandomIteration = false)
// The useSequentialIteration flag indicates whether or not the iteration
// simply jumps from key/value pair to key/value pair without using the
// index. The default `false` is to use the index if it is there.
explicit ObjectIterator(Slice const& slice, bool useSequentialIteration = false)
: _slice(slice), _size(_slice.length()), _position(0), _current(nullptr),
_allowRandomIteration(allowRandomIteration) {
_useSequentialIteration(useSequentialIteration) {
if (!slice.isObject()) {
throw Exception(Exception::InvalidValueType, "Expecting Object slice");
}
@ -193,7 +196,7 @@ class ObjectIterator {
auto h = slice.head();
if (h == 0x14) {
_current = slice.keyAt(0, false).start();
} else if (allowRandomIteration) {
} else if (useSequentialIteration) {
_current = slice.begin() + slice.findDataOffset(h);
}
}
@ -204,7 +207,7 @@ class ObjectIterator {
_size(other._size),
_position(other._position),
_current(other._current),
_allowRandomIteration(other._allowRandomIteration) {}
_useSequentialIteration(other._useSequentialIteration) {}
ObjectIterator& operator=(ObjectIterator const& other) = delete;
@ -306,7 +309,7 @@ class ObjectIterator {
ValueLength const _size;
ValueLength _position;
uint8_t const* _current;
bool const _allowRandomIteration;
bool const _useSequentialIteration;
};
} // namespace arangodb::velocypack

View File

@ -113,7 +113,7 @@ devel
when unused.
Waiting for an unused V8 context will now also abort if no V8 context can be
acquired/created after 120 seconds.
acquired/created after 60 seconds.
* improved diagnostic messages written to logfiles by supervisor process

View File

@ -254,6 +254,7 @@ while [ $# -gt 0 ]; do
MAKE="cmake --build . --config ${BUILD_CONFIG}"
PACKAGE_MAKE="cmake --build . --config ${BUILD_CONFIG} --target"
CONFIGURE_OPTIONS="${CONFIGURE_OPTIONS} -DV8_TARGET_ARCHS=Release"
export _IsNativeEnvironment=true
;;
--symsrv)

View File

@ -1223,7 +1223,7 @@ bool AgencyComm::lock(std::string const& key, double ttl, double timeout,
return true;
}
usleep(sleepTime);
usleep((TRI_usleep_t) sleepTime);
if (sleepTime < MAX_SLEEP_TIME) {
sleepTime += INITIAL_SLEEP_TIME;
@ -1264,7 +1264,7 @@ bool AgencyComm::unlock(std::string const& key, VPackSlice const& slice,
return true;
}
usleep(sleepTime);
usleep((TRI_usleep_t)sleepTime);
if (sleepTime < MAX_SLEEP_TIME) {
sleepTime += INITIAL_SLEEP_TIME;

View File

@ -208,6 +208,13 @@ void AgencyFeature::start() {
return;
}
// Find the agency prefix:
auto feature = ApplicationServer::getFeature<ClusterFeature>("Cluster");
arangodb::consensus::Supervision::setAgencyPrefix(
std::string("/") + feature->agencyPrefix());
arangodb::consensus::Job::agencyPrefix
= std::string("/") + feature->agencyPrefix();
// TODO: Port this to new options handling
std::string endpoint;

View File

@ -27,10 +27,14 @@
#include "Aql/ExecutionPlan.h"
#include "Aql/Query.h"
#include "Cluster/ClusterComm.h"
#include "Graph/AttributeWeightShortestPathFinder.h"
#include "Graph/ConstantWeightShortestPathFinder.h"
#include "Graph/ShortestPathFinder.h"
#include "Graph/ShortestPathResult.h"
#include "Graph/AttributeWeightShortestPathFinder.h"
#include "Graph/ConstantWeightShortestPathFinder.h"
#include "Transaction/Methods.h"
#include "Utils/OperationCursor.h"
#include "VocBase/EdgeCollectionInfo.h"
#include "VocBase/LogicalCollection.h"
#include "VocBase/ManagedDocumentResult.h"
#include "VocBase/ticks.h"
@ -48,7 +52,7 @@ ShortestPathBlock::ShortestPathBlock(ExecutionEngine* engine,
_vertexReg(ExecutionNode::MaxRegisterId),
_edgeVar(nullptr),
_edgeReg(ExecutionNode::MaxRegisterId),
_opts(nullptr),
_opts(static_cast<ShortestPathOptions*>(ep->options())),
_posInPath(0),
_pathLength(0),
_path(nullptr),
@ -58,8 +62,7 @@ ShortestPathBlock::ShortestPathBlock(ExecutionEngine* engine,
_useTargetRegister(false),
_usedConstant(false),
_engines(nullptr) {
_opts = static_cast<ShortestPathOptions*>(ep->options());
_mmdr.reset(new ManagedDocumentResult);
TRI_ASSERT(_opts != nullptr);
if (!ep->usesStartInVariable()) {
_startVertexId = ep->getStartVertex();
@ -257,9 +260,7 @@ bool ShortestPathBlock::nextPath(AqlItemBlock const* items) {
VPackSlice start = _opts->getStart();
VPackSlice end = _opts->getEnd();
TRI_ASSERT(_finder != nullptr);
// We do not need this data anymore. Result has been processed.
// Save some memory.
_coordinatorCache.clear();
bool hasPath =
_finder->shortestPath(start, end, *_path, [this]() { throwIfKilled(); });

View File

@ -32,25 +32,15 @@ namespace arangodb {
class ManagedDocumentResult;
namespace graph {
class ConstantWeightShortestPathFinder;
class ShortestPathFinder;
class ShortestPathResult;
}
namespace traverser {
class EdgeCollectionInfo;
}
namespace aql {
class ShortestPathNode;
class ShortestPathBlock : public ExecutionBlock {
friend struct EdgeWeightExpanderLocal;
friend struct EdgeWeightExpanderCluster;
// TODO ONLY TEMPORARY
friend class graph::ConstantWeightShortestPathFinder;
public:
ShortestPathBlock(ExecutionEngine* engine, ShortestPathNode const* ep);
@ -100,8 +90,6 @@ class ShortestPathBlock : public ExecutionBlock {
/// @brief Register for the edge output
RegisterId _edgeReg;
std::unique_ptr<ManagedDocumentResult> _mmdr;
/// @brief options to compute the shortest path
graph::ShortestPathOptions* _opts;
@ -146,9 +134,6 @@ class ShortestPathBlock : public ExecutionBlock {
/// We use it to check if we are done with enumerating.
bool _usedConstant;
/// @brief Cache for edges send over the network
std::vector<std::shared_ptr<VPackBuffer<uint8_t>>> _coordinatorCache;
/// @brief Traverser Engines
std::unordered_map<ServerID, traverser::TraverserEngineID> const* _engines;

View File

@ -577,7 +577,7 @@ bool ClusterComm::match(ClientTransactionID const& clientTransactionID,
/// from deleting `result` and `answer`.
////////////////////////////////////////////////////////////////////////////////
ClusterCommResult const ClusterComm::enquire(Ticket const ticketId) {
ClusterCommResult const ClusterComm::enquire(communicator::Ticket const ticketId) {
ResponseIterator i;
AsyncResponse response;
@ -614,7 +614,7 @@ ClusterCommResult const ClusterComm::enquire(Ticket const ticketId) {
ClusterCommResult const ClusterComm::wait(
ClientTransactionID const& clientTransactionID,
CoordTransactionID const coordTransactionID, Ticket const ticketId,
CoordTransactionID const coordTransactionID, communicator::Ticket const ticketId,
ShardID const& shardID, ClusterCommTimeout timeout) {
ResponseIterator i;
@ -1123,6 +1123,19 @@ void ClusterComm::addAuthorization(std::unordered_map<std::string, std::string>*
}
}
std::vector<communicator::Ticket> ClusterComm::activeServerTickets(std::vector<std::string> const& servers) {
std::vector<communicator::Ticket> tickets;
CONDITION_LOCKER(locker, somethingReceived);
for (auto const& it: responses) {
for (auto const& server: servers) {
if (it.second.result && it.second.result->serverID == server) {
tickets.push_back(it.first);
}
}
}
return tickets;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief ClusterComm main loop
////////////////////////////////////////////////////////////////////////////////
@ -1130,18 +1143,10 @@ void ClusterComm::addAuthorization(std::unordered_map<std::string, std::string>*
void ClusterCommThread::abortRequestsToFailedServers() {
ClusterInfo* ci = ClusterInfo::instance();
auto failedServers = ci->getFailedServers();
std::vector<std::string> failedServerEndpoints;
failedServerEndpoints.reserve(failedServers.size());
for (auto const& failedServer: failedServers) {
failedServerEndpoints.push_back(_cc->createCommunicatorDestination(ci->getServerEndpoint(failedServer), "/").url());
}
for (auto const& request: _cc->communicator()->requestsInProgress()) {
for (auto const& failedServerEndpoint: failedServerEndpoints) {
if (request->_destination.url().substr(0, failedServerEndpoint.length()) == failedServerEndpoint) {
_cc->communicator()->abortRequest(request->_ticketId);
}
if (failedServers.size() > 0) {
auto ticketIds = _cc->activeServerTickets(failedServers);
for (auto const& ticketId: ticketIds) {
_cc->communicator()->abortRequest(ticketId);
}
}
}

View File

@ -616,6 +616,12 @@ class ClusterComm {
void cleanupAllQueues();
//////////////////////////////////////////////////////////////////////////////
/// @brief activeServerTickets for a list of servers
//////////////////////////////////////////////////////////////////////////////
std::vector<communicator::Ticket> activeServerTickets(std::vector<std::string> const& servers);
//////////////////////////////////////////////////////////////////////////////
/// @brief our background communications thread
//////////////////////////////////////////////////////////////////////////////

View File

@ -133,6 +133,10 @@ void ClusterFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
options->addOption("--cluster.system-replication-factor",
"replication factor for system collections",
new UInt32Parameter(&_systemReplicationFactor));
options->addOption("--cluster.create-waits-for-sync-replication",
"active coordinator will wait for all replicas to create collection",
new BooleanParameter(&_createWaitsForSyncReplication));
}
void ClusterFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {

View File

@ -45,6 +45,10 @@ class ClusterFeature : public application_features::ApplicationFeature {
void start() override final;
void unprepare() override final;
std::string agencyPrefix() {
return _agencyPrefix;
}
private:
std::vector<std::string> _agencyEndpoints;
std::string _agencyPrefix;
@ -58,6 +62,7 @@ class ClusterFeature : public application_features::ApplicationFeature {
std::string _dbserverConfig;
std::string _coordinatorConfig;
uint32_t _systemReplicationFactor = 2;
bool _createWaitsForSyncReplication = false;
private:
void reportRole(ServerState::RoleEnum);
@ -72,6 +77,7 @@ class ClusterFeature : public application_features::ApplicationFeature {
};
void setUnregisterOnShutdown(bool);
bool createWaitsForSyncReplication() { return _createWaitsForSyncReplication; };
void stop() override final;

View File

@ -1042,6 +1042,7 @@ int ClusterInfo::createCollectionCoordinator(std::string const& databaseName,
std::string const& collectionID,
uint64_t numberOfShards,
uint64_t replicationFactor,
bool waitForReplication,
VPackSlice const& json,
std::string& errorMsg,
double timeout) {
@ -1100,19 +1101,10 @@ int ClusterInfo::createCollectionCoordinator(std::string const& databaseName,
[=](VPackSlice const& result) {
if (result.isObject() && result.length() == (size_t)numberOfShards) {
std::string tmpMsg = "";
bool tmpHaveError = false;
for (auto const& p : VPackObjectIterator(result)) {
if (replicationFactor == 0) {
VPackSlice servers = p.value.get("servers");
if (!servers.isArray() || servers.length() < dbServers.size()) {
return true;
}
}
if (arangodb::basics::VelocyPackHelper::getBooleanValue(
p.value, "error", false)) {
tmpHaveError = true;
tmpMsg += " shardID:" + p.key.copyString() + ":";
tmpMsg += arangodb::basics::VelocyPackHelper::getStringValue(
p.value, "errorMessage", "");
@ -1125,13 +1117,24 @@ int ClusterInfo::createCollectionCoordinator(std::string const& databaseName,
tmpMsg += ")";
}
}
*errMsg = "Error in creation of collection:" + tmpMsg + " "
+ __FILE__ + std::to_string(__LINE__);
*dbServerResult = TRI_ERROR_CLUSTER_COULD_NOT_CREATE_COLLECTION;
return true;
}
// wait that all followers have created our new collection
if (waitForReplication) {
uint64_t mutableReplicationFactor = replicationFactor;
if (mutableReplicationFactor == 0) {
mutableReplicationFactor = dbServers.size();
}
VPackSlice servers = p.value.get("servers");
if (!servers.isArray() || servers.length() < mutableReplicationFactor) {
return true;
}
}
}
if (tmpHaveError) {
*errMsg = "Error in creation of collection:" + tmpMsg + " "
+ __FILE__ + std::to_string(__LINE__);
*dbServerResult = TRI_ERROR_CLUSTER_COULD_NOT_CREATE_COLLECTION;
return true;
}
*dbServerResult = setErrormsg(TRI_ERROR_NO_ERROR, *errMsg);
}

View File

@ -349,6 +349,7 @@ class ClusterInfo {
std::string const& collectionID,
uint64_t numberOfShards,
uint64_t replicationFactor,
bool waitForReplication,
arangodb::velocypack::Slice const& json,
std::string& errorMsg, double timeout);

View File

@ -2264,12 +2264,13 @@ std::unique_ptr<LogicalCollection>
ClusterMethods::createCollectionOnCoordinator(TRI_col_type_e collectionType,
TRI_vocbase_t* vocbase,
VPackSlice parameters,
bool ignoreDistributeShardsLikeErrors) {
bool ignoreDistributeShardsLikeErrors,
bool waitForSyncReplication) {
auto col = std::make_unique<LogicalCollection>(vocbase, parameters);
// Collection is a temporary collection object that undergoes sanity checks etc.
// It is not used anywhere and will be cleaned up after this call.
// Persist collection will return the real object.
return persistCollectionInAgency(col.get(), ignoreDistributeShardsLikeErrors);
return persistCollectionInAgency(col.get(), ignoreDistributeShardsLikeErrors, waitForSyncReplication);
}
#endif
@ -2279,7 +2280,7 @@ ClusterMethods::createCollectionOnCoordinator(TRI_col_type_e collectionType,
std::unique_ptr<LogicalCollection>
ClusterMethods::persistCollectionInAgency(
LogicalCollection* col, bool ignoreDistributeShardsLikeErrors) {
LogicalCollection* col, bool ignoreDistributeShardsLikeErrors, bool waitForSyncReplication) {
std::string distributeShardsLike = col->distributeShardsLike();
std::vector<std::string> dbServers;
std::vector<std::string> avoid = col->avoidServers();
@ -2364,7 +2365,7 @@ ClusterMethods::persistCollectionInAgency(
std::string errorMsg;
int myerrno = ci->createCollectionCoordinator(
col->dbName(), col->cid_as_string(),
col->numberOfShards(), col->replicationFactor(), velocy.slice(), errorMsg, 240.0);
col->numberOfShards(), col->replicationFactor(), waitForSyncReplication, velocy.slice(), errorMsg, 240.0);
if (myerrno != TRI_ERROR_NO_ERROR) {
if (errorMsg.empty()) {

View File

@ -258,7 +258,8 @@ class ClusterMethods {
static std::unique_ptr<LogicalCollection> createCollectionOnCoordinator(
TRI_col_type_e collectionType, TRI_vocbase_t* vocbase,
arangodb::velocypack::Slice parameters,
bool ignoreDistributeShardsLikeErrors = false);
bool ignoreDistributeShardsLikeErrors,
bool waitForSyncReplication);
private:
@ -267,7 +268,7 @@ class ClusterMethods {
////////////////////////////////////////////////////////////////////////////////
static std::unique_ptr<LogicalCollection> persistCollectionInAgency(
LogicalCollection* col, bool ignoreDistributeShardsLikeErrors = false);
LogicalCollection* col, bool ignoreDistributeShardsLikeErrors, bool waitForSyncReplication);
};
} // namespace arangodb

View File

@ -1134,7 +1134,7 @@ int MMFilesDatafile::truncateAndSeal(TRI_voc_size_t position) {
}
char zero = 0;
int res = TRI_WRITE(fd, &zero, 1);
long res = TRI_WRITE(fd, &zero, 1);
if (res < 0) {
TRI_SYSTEM_ERROR();
@ -1155,7 +1155,7 @@ int MMFilesDatafile::truncateAndSeal(TRI_voc_size_t position) {
if (res != TRI_ERROR_NO_ERROR) {
TRI_SYSTEM_ERROR();
TRI_set_errno(res);
TRI_set_errno((int)res);
TRI_TRACKED_CLOSE_FILE(fd);
// remove empty file

View File

@ -152,7 +152,7 @@ MMFilesEngine::MMFilesEngine(application_features::ApplicationServer* server)
MMFilesEngine::~MMFilesEngine() {}
// perform a physical deletion of the database
Result MMFilesEngine::dropDatabase(Database* database) {
Result MMFilesEngine::dropDatabase(TRI_vocbase_t* database) {
// delete persistent indexes for this database
MMFilesPersistentIndexFeature::dropDatabase(database->id());

View File

@ -138,14 +138,14 @@ class MMFilesEngine final : public StorageEngine {
void waitForSync(TRI_voc_tick_t tick) override;
virtual TRI_vocbase_t* openDatabase(arangodb::velocypack::Slice const& parameters, bool isUpgrade, int&) override;
Database* createDatabase(TRI_voc_tick_t id, arangodb::velocypack::Slice const& args, int& status) override {
TRI_vocbase_t* createDatabase(TRI_voc_tick_t id, arangodb::velocypack::Slice const& args, int& status) override {
status = TRI_ERROR_NO_ERROR;
return createDatabaseMMFiles(id, args);
}
int writeCreateDatabaseMarker(TRI_voc_tick_t id, VPackSlice const& slice) override;
void prepareDropDatabase(TRI_vocbase_t* vocbase, bool useWriteMarker, int& status) override;
Result dropDatabase(Database* database) override;
Result dropDatabase(TRI_vocbase_t* database) override;
void waitUntilDeletion(TRI_voc_tick_t id, bool force, int& status) override;
// wal in recovery

View File

@ -29,6 +29,7 @@
#include "Basics/conversions.h"
#include "Basics/files.h"
#include "Cluster/ClusterComm.h"
#include "Cluster/ClusterFeature.h"
#include "Cluster/ClusterMethods.h"
#include "Cluster/FollowerInfo.h"
#include "GeneralServer/GeneralServer.h"
@ -1592,14 +1593,15 @@ int MMFilesRestReplicationHandler::processRestoreCollectionCoordinator(
if (dropExisting) {
int res = ci->dropCollectionCoordinator(dbName, col->cid_as_string(),
errorMsg, 0.0);
if (res == TRI_ERROR_FORBIDDEN) {
if (res == TRI_ERROR_FORBIDDEN ||
res == TRI_ERROR_CLUSTER_MUST_NOT_DROP_COLL_OTHER_DISTRIBUTESHARDSLIKE) {
// some collections must not be dropped
res = truncateCollectionOnCoordinator(dbName, name);
if (res != TRI_ERROR_NO_ERROR) {
errorMsg =
"unable to truncate collection (dropping is forbidden): " + name;
return res;
}
return res;
}
if (res != TRI_ERROR_NO_ERROR) {
@ -1679,8 +1681,9 @@ int MMFilesRestReplicationHandler::processRestoreCollectionCoordinator(
VPackSlice const merged = mergedBuilder.slice();
try {
bool createWaitsForSyncReplication = application_features::ApplicationServer::getFeature<ClusterFeature>("Cluster")->createWaitsForSyncReplication();
auto col = ClusterMethods::createCollectionOnCoordinator(
collectionType, _vocbase, merged, ignoreDistributeShardsLikeErrors);
collectionType, _vocbase, merged, ignoreDistributeShardsLikeErrors, createWaitsForSyncReplication);
TRI_ASSERT(col != nullptr);
} catch (basics::Exception const& e) {
// Error, report it.

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@
/// @author Jan Christoph Uhde
////////////////////////////////////////////////////////////////////////////////
#include "Basics/StringRef.h"
#include "RocksDBEngine/RocksDBCommon.h"
#include "RocksDBEngine/RocksDBComparator.h"
#include "RocksDBEngine/RocksDBEngine.h"
@ -128,28 +129,66 @@ void uint64ToPersistent(std::string& p, uint64_t value) {
} while (++len < sizeof(uint64_t));
}
void stripObjectIds(VPackBuilder& builder, VPackSlice const& slice) {
if (slice.isObject()) {
bool hasObjectIds(VPackSlice const& inputSlice) {
bool rv = false;
if (inputSlice.isObject()) {
for (auto const& objectPair :
arangodb::velocypack::ObjectIterator(inputSlice)) {
if (arangodb::StringRef(objectPair.key) == "objectId") {
return true;
}
rv = hasObjectIds(objectPair.value);
if (rv) {
return rv;
}
}
} else if (inputSlice.isArray()) {
for (auto const& slice : arangodb::velocypack::ArrayIterator(inputSlice)) {
if (rv) {
return rv;
}
rv = hasObjectIds(slice);
}
}
return rv;
}
VPackBuilder& stripObjectIdsImpl(VPackBuilder& builder, VPackSlice const& inputSlice) {
if (inputSlice.isObject()) {
builder.openObject();
for (auto it = arangodb::velocypack::ObjectIterator(slice); it.valid();
it++) {
if (it.key().copyString() == "objectId") {
for (auto const& objectPair :
arangodb::velocypack::ObjectIterator(inputSlice)) {
if (arangodb::StringRef(objectPair.key) == "objectId") {
continue;
}
builder.add(it.key());
stripObjectIds(builder, it.value());
builder.add(objectPair.key);
stripObjectIdsImpl(builder, objectPair.value);
}
builder.close();
} else if (slice.isArray()) {
} else if (inputSlice.isArray()) {
builder.openArray();
for (auto it = arangodb::velocypack::ArrayIterator(slice); it.valid();
it++) {
stripObjectIds(builder, it.value());
for (auto const& slice : arangodb::velocypack::ArrayIterator(inputSlice)) {
stripObjectIdsImpl(builder, slice);
}
builder.close();
} else {
builder.add(slice);
builder.add(inputSlice);
}
return builder;
}
std::pair<VPackSlice, std::unique_ptr<VPackBuffer<uint8_t>>> stripObjectIds(
VPackSlice const& inputSlice, bool checkBeforeCopy) {
std::unique_ptr<VPackBuffer<uint8_t>> buffer = nullptr;
if (checkBeforeCopy) {
if (!hasObjectIds(inputSlice)) {
return {inputSlice, std::move(buffer)};
}
}
buffer.reset(new VPackBuffer<uint8_t>);
VPackBuilder builder(*buffer);
stripObjectIdsImpl(builder, inputSlice);
return {VPackSlice(buffer->data()), std::move(buffer)};
}
RocksDBTransactionState* toRocksTransactionState(transaction::Methods* trx) {

View File

@ -89,7 +89,8 @@ uint64_t uint64FromPersistent(char const* p);
void uint64ToPersistent(char* p, uint64_t value);
void uint64ToPersistent(std::string& out, uint64_t value);
void stripObjectIds(VPackBuilder&, VPackSlice const&);
std::pair<VPackSlice, std::unique_ptr<VPackBuffer<uint8_t>>> stripObjectIds(
VPackSlice const& inputSlice, bool checkBeforeCopy = true);
RocksDBTransactionState* toRocksTransactionState(transaction::Methods* trx);
rocksdb::TransactionDB* globalRocksDB();

View File

@ -230,7 +230,12 @@ void RocksDBEngine::start() {
}
}
void RocksDBEngine::stop() {}
void RocksDBEngine::stop() {
if (!isEnabled()) {
return;
}
replicationManager()->dropAll();
}
void RocksDBEngine::unprepare() {
if (!isEnabled()) {
@ -486,7 +491,7 @@ TRI_vocbase_t* RocksDBEngine::openDatabase(
return openExistingDatabase(id, name, true, isUpgrade);
}
RocksDBEngine::Database* RocksDBEngine::createDatabase(
TRI_vocbase_t* RocksDBEngine::createDatabase(
TRI_voc_tick_t id, arangodb::velocypack::Slice const& args, int& status) {
status = TRI_ERROR_NO_ERROR;
auto vocbase = std::make_unique<TRI_vocbase_t>(TRI_VOCBASE_TYPE_NORMAL, id,
@ -519,10 +524,6 @@ int RocksDBEngine::writeCreateCollectionMarker(TRI_voc_tick_t databaseId,
void RocksDBEngine::prepareDropDatabase(TRI_vocbase_t* vocbase,
bool useWriteMarker, int& status) {
// probably not required
// THROW_ARANGO_NOT_YET_IMPLEMENTED();
// status = saveDatabaseParameters(vocbase->id(), vocbase->name(), true);
VPackBuilder builder;
builder.openObject();
builder.add("id", VPackValue(std::to_string(vocbase->id())));
@ -533,7 +534,8 @@ void RocksDBEngine::prepareDropDatabase(TRI_vocbase_t* vocbase,
status = writeCreateDatabaseMarker(vocbase->id(), builder.slice());
}
Result RocksDBEngine::dropDatabase(Database* database) {
Result RocksDBEngine::dropDatabase(TRI_vocbase_t* database) {
replicationManager()->drop(database);
return dropDatabase(database->id());
}

View File

@ -123,14 +123,14 @@ class RocksDBEngine final : public StorageEngine {
virtual TRI_vocbase_t* openDatabase(
arangodb::velocypack::Slice const& parameters, bool isUpgrade,
int&) override;
Database* createDatabase(TRI_voc_tick_t id,
TRI_vocbase_t* createDatabase(TRI_voc_tick_t id,
arangodb::velocypack::Slice const& args,
int& status) override;
int writeCreateDatabaseMarker(TRI_voc_tick_t id,
VPackSlice const& slice) override;
void prepareDropDatabase(TRI_vocbase_t* vocbase, bool useWriteMarker,
int& status) override;
Result dropDatabase(Database* database) override;
Result dropDatabase(TRI_vocbase_t* database) override;
void waitUntilDeletion(TRI_voc_tick_t id, bool force, int& status) override;
// wal in recovery

View File

@ -74,7 +74,7 @@ class RocksDBLogValue {
//////////////////////////////////////////////////////////////////////////////
/// @brief Returns a reference to the underlying string buffer.
//////////////////////////////////////////////////////////////////////////////
std::string const& string() { return _buffer; } // to be used with put
std::string const& string() const { return _buffer; } // to be used with put
/*VPackSlice slice() const { return VPackSlice(
reinterpret_cast<uint8_t const*>(_buffer.data())
); }*/ // return a slice
@ -82,6 +82,7 @@ class RocksDBLogValue {
RocksDBLogType type() const {
return static_cast<RocksDBLogType>(*(_buffer.data()));
}
rocksdb::Slice slice() const { return rocksdb::Slice(_buffer); }
private:
RocksDBLogValue(RocksDBLogType type, uint64_t);

View File

@ -33,6 +33,7 @@
#include "Transaction/Helpers.h"
#include "Transaction/StandaloneContext.h"
#include "Transaction/UserTransaction.h"
#include "Utils/DatabaseGuard.h"
#include "VocBase/replication-common.h"
#include "VocBase/ticks.h"
@ -55,6 +56,7 @@ RocksDBReplicationContext::RocksDBReplicationContext()
_mdr(),
_customTypeHandler(),
_vpackOptions(Options::Defaults),
_lastChunkOffset(0),
_expires(TRI_microtime() + DefaultTTL),
_isDeleted(false),
_isUsed(true),
@ -390,10 +392,13 @@ void RocksDBReplicationContext::releaseDumpingResources() {
_iter.reset();
}
_collection = nullptr;
_guard.reset();
}
std::unique_ptr<transaction::Methods>
RocksDBReplicationContext::createTransaction(TRI_vocbase_t* vocbase) {
_guard.reset(new DatabaseGuard(vocbase));
double lockTimeout = transaction::Methods::DefaultLockTimeout;
std::shared_ptr<transaction::StandaloneContext> ctx =
transaction::StandaloneContext::Create(vocbase);
@ -401,6 +406,7 @@ RocksDBReplicationContext::createTransaction(TRI_vocbase_t* vocbase) {
ctx, {}, {}, {}, lockTimeout, false, true));
Result res = trx->begin();
if (!res.ok()) {
_guard.reset();
THROW_ARANGO_EXCEPTION(res);
}
_customTypeHandler = ctx->orderCustomTypeHandler();

View File

@ -36,6 +36,7 @@
#include <velocypack/Slice.h>
namespace arangodb {
class DatabaseGuard;
class RocksDBReplicationContext {
public:
@ -53,6 +54,13 @@ class RocksDBReplicationContext {
TRI_voc_tick_t id() const;
uint64_t lastTick() const;
uint64_t count() const;
TRI_vocbase_t* vocbase() const {
if (_trx == nullptr) {
return nullptr;
}
return _trx->vocbase();
}
// creates new transaction/snapshot
void bind(TRI_vocbase_t*);
@ -113,7 +121,8 @@ class RocksDBReplicationContext {
ManagedDocumentResult _mdr;
std::shared_ptr<arangodb::velocypack::CustomTypeHandler> _customTypeHandler;
arangodb::velocypack::Options _vpackOptions;
uint64_t _lastChunkOffset = 0;
uint64_t _lastChunkOffset;
std::unique_ptr<DatabaseGuard> _guard;
double _expires;
bool _isDeleted;

View File

@ -238,6 +238,40 @@ bool RocksDBReplicationManager::containsUsedContext() {
return false;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief drop contexts by database (at least mark them as deleted)
////////////////////////////////////////////////////////////////////////////////
void RocksDBReplicationManager::drop(TRI_vocbase_t* vocbase) {
{
MUTEX_LOCKER(mutexLocker, _lock);
for (auto& context : _contexts) {
if (context.second->vocbase() == vocbase) {
context.second->deleted();
}
}
}
garbageCollect(true);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief drop all contexts (at least mark them as deleted)
////////////////////////////////////////////////////////////////////////////////
void RocksDBReplicationManager::dropAll() {
{
MUTEX_LOCKER(mutexLocker, _lock);
for (auto& context : _contexts) {
context.second->deleted();
}
}
garbageCollect(true);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief run a garbage collection on the contexts
////////////////////////////////////////////////////////////////////////////////

View File

@ -92,6 +92,18 @@ class RocksDBReplicationManager {
bool containsUsedContext();
//////////////////////////////////////////////////////////////////////////////
/// @brief drop contexts by database (at least mark them as deleted)
//////////////////////////////////////////////////////////////////////////////
void drop(TRI_vocbase_t*);
//////////////////////////////////////////////////////////////////////////////
/// @brief drop all contexts (at least mark them as deleted)
//////////////////////////////////////////////////////////////////////////////
void dropAll();
//////////////////////////////////////////////////////////////////////////////
/// @brief run a garbage collection on the contexts
//////////////////////////////////////////////////////////////////////////////

View File

@ -43,7 +43,7 @@ class WBReader : public rocksdb::WriteBatch::Handler {
explicit WBReader(TRI_vocbase_t* vocbase, uint64_t from, size_t& limit,
bool includeSystem, VPackBuilder& builder)
: _vocbase(vocbase),
_from(from),
/* _from(from), */
_limit(limit),
_includeSystem(includeSystem),
_builder(builder) {}
@ -170,7 +170,7 @@ class WBReader : public rocksdb::WriteBatch::Handler {
private:
TRI_vocbase_t* _vocbase;
uint64_t _from;
/* uint64_t _from; */
size_t& _limit;
bool _includeSystem;
VPackBuilder& _builder;

View File

@ -30,6 +30,7 @@
#include "Basics/conversions.h"
#include "Basics/files.h"
#include "Cluster/ClusterComm.h"
#include "Cluster/ClusterFeature.h"
#include "Cluster/ClusterMethods.h"
#include "Cluster/FollowerInfo.h"
#include "GeneralServer/GeneralServer.h"
@ -826,9 +827,8 @@ void RocksDBRestReplicationHandler::handleCommandRestoreCollection() {
"invalid JSON");
return;
}
VPackBuilder builder;
stripObjectIds(builder, parsedRequest->slice());
VPackSlice const slice = builder.slice();
auto pair = stripObjectIds(parsedRequest->slice());
VPackSlice const slice = pair.first;
bool overwrite = false;
@ -1732,14 +1732,15 @@ int RocksDBRestReplicationHandler::processRestoreCollectionCoordinator(
if (dropExisting) {
int res = ci->dropCollectionCoordinator(dbName, col->cid_as_string(),
errorMsg, 0.0);
if (res == TRI_ERROR_FORBIDDEN) {
if (res == TRI_ERROR_FORBIDDEN ||
res == TRI_ERROR_CLUSTER_MUST_NOT_DROP_COLL_OTHER_DISTRIBUTESHARDSLIKE) {
// some collections must not be dropped
res = truncateCollectionOnCoordinator(dbName, name);
if (res != TRI_ERROR_NO_ERROR) {
errorMsg =
"unable to truncate collection (dropping is forbidden): " + name;
return res;
}
return res;
}
if (res != TRI_ERROR_NO_ERROR) {
@ -1819,8 +1820,9 @@ int RocksDBRestReplicationHandler::processRestoreCollectionCoordinator(
VPackSlice const merged = mergedBuilder.slice();
try {
bool createWaitsForSyncReplication = application_features::ApplicationServer::getFeature<ClusterFeature>("Cluster")->createWaitsForSyncReplication();
auto col = ClusterMethods::createCollectionOnCoordinator(collectionType,
_vocbase, merged);
_vocbase, merged, true, createWaitsForSyncReplication);
TRI_ASSERT(col != nullptr);
} catch (basics::Exception const& e) {
// Error, report it.

View File

@ -33,6 +33,7 @@
#include "RocksDBEngine/RocksDBCommon.h"
#include "RocksDBEngine/RocksDBCounterManager.h"
#include "RocksDBEngine/RocksDBEngine.h"
#include "RocksDBEngine/RocksDBLogValue.h"
#include "RocksDBEngine/RocksDBTransactionCollection.h"
#include "StorageEngine/EngineSelectorFeature.h"
#include "StorageEngine/StorageEngine.h"
@ -156,6 +157,11 @@ Result RocksDBTransactionState::beginTransaction(transaction::Hints hints) {
_rocksWriteOptions, rocksdb::TransactionOptions()));
_rocksTransaction->SetSnapshot();
_rocksReadOptions.snapshot = _rocksTransaction->GetSnapshot();
RocksDBLogValue header = RocksDBLogValue::BeginTransaction(_vocbase->id(),
_id);
_rocksTransaction->PutLogData(header.slice());
} else {
TRI_ASSERT(_status == transaction::Status::RUNNING);
}

View File

@ -146,7 +146,7 @@ class Socket {
virtual void shutdownReceive() = 0;
virtual void shutdownReceive(boost::system::error_code& ec) = 0;
virtual void shutdownSend(boost::system::error_code& ec) = 0;
virtual int available(boost::system::error_code& ec) = 0;
virtual size_t available(boost::system::error_code& ec) = 0;
virtual void asyncRead(boost::asio::mutable_buffers_1 const& buffer,
AsyncHandler const& handler) = 0;

View File

@ -44,7 +44,7 @@ void SocketUnixDomain::shutdownReceive(boost::system::error_code& ec) {
void SocketUnixDomain::shutdownSend(boost::system::error_code& ec) {
_socket.shutdown(boost::asio::local::stream_protocol::socket::shutdown_send, ec);
}
int SocketUnixDomain::available(boost::system::error_code& ec) {
size_t SocketUnixDomain::available(boost::system::error_code& ec) {
return _socket.available(ec);
}
void SocketUnixDomain::asyncRead(boost::asio::mutable_buffers_1 const& buffer, AsyncHandler const& handler) {

View File

@ -65,8 +65,8 @@ class SocketUnixDomain final : public Socket {
void shutdownSend(boost::system::error_code& ec) override;
int available(boost::system::error_code& ec) override;
size_t available(boost::system::error_code& ec) override;
void asyncRead(boost::asio::mutable_buffers_1 const& buffer, AsyncHandler const& handler) override;
public:

View File

@ -65,7 +65,7 @@ class ConnectionStatistics {
_error = false;
}
static size_t const QUEUE_SIZE = 5000;
static size_t const QUEUE_SIZE = 64 * 1024 - 2; // current (1.62) boost maximum
static Mutex _dataLock;

View File

@ -152,7 +152,7 @@ class RequestStatistics {
void trace_log();
private:
static size_t const QUEUE_SIZE = 1000;
static size_t const QUEUE_SIZE = 64 * 1024 - 2; // current (1.62) boost maximum
static arangodb::Mutex _dataLock;

View File

@ -146,7 +146,6 @@ class StorageEngine : public application_features::ApplicationFeature {
// TODO add pre / post conditions for functions
using Database = TRI_vocbase_t;
using CollectionView = LogicalCollection;
virtual void waitForSync(TRI_voc_tick_t tick) = 0;
@ -154,10 +153,10 @@ class StorageEngine : public application_features::ApplicationFeature {
//// operations on databasea
/// @brief opens a database
virtual Database* openDatabase(arangodb::velocypack::Slice const& args, bool isUpgrade, int& status) = 0;
Database* openDatabase(arangodb::velocypack::Slice const& args, bool isUpgrade){
virtual TRI_vocbase_t* openDatabase(arangodb::velocypack::Slice const& args, bool isUpgrade, int& status) = 0;
TRI_vocbase_t* openDatabase(arangodb::velocypack::Slice const& args, bool isUpgrade){
int status;
Database* rv = openDatabase(args, isUpgrade, status);
TRI_vocbase_t* rv = openDatabase(args, isUpgrade, status);
TRI_ASSERT(status == TRI_ERROR_NO_ERROR);
TRI_ASSERT(rv != nullptr);
return rv;
@ -172,16 +171,16 @@ class StorageEngine : public application_features::ApplicationFeature {
// the WAL entry for the database creation will be written *after* the call
// to "createDatabase" returns
// no way to acquire id within this function?!
virtual Database* createDatabase(TRI_voc_tick_t id, arangodb::velocypack::Slice const& args, int& status) = 0;
Database* createDatabase(TRI_voc_tick_t id, arangodb::velocypack::Slice const& args ){
virtual TRI_vocbase_t* createDatabase(TRI_voc_tick_t id, arangodb::velocypack::Slice const& args, int& status) = 0;
TRI_vocbase_t* createDatabase(TRI_voc_tick_t id, arangodb::velocypack::Slice const& args ){
int status;
Database* rv = createDatabase(id, args, status);
TRI_vocbase_t* rv = createDatabase(id, args, status);
TRI_ASSERT(status == TRI_ERROR_NO_ERROR);
TRI_ASSERT(rv != nullptr);
return rv;
}
// @brief wirte create marker for database
// @brief write create marker for database
virtual int writeCreateDatabaseMarker(TRI_voc_tick_t id, VPackSlice const& slice) = 0;
// asks the storage engine to drop the specified database and persist the
@ -194,14 +193,14 @@ class StorageEngine : public application_features::ApplicationFeature {
//
// is done under a lock in database feature
virtual void prepareDropDatabase(TRI_vocbase_t* vocbase, bool useWriteMarker, int& status) = 0;
void prepareDropDatabase(Database* db, bool useWriteMarker){
void prepareDropDatabase(TRI_vocbase_t* db, bool useWriteMarker){
int status = 0;
prepareDropDatabase(db, useWriteMarker, status);
TRI_ASSERT(status == TRI_ERROR_NO_ERROR);
};
// perform a physical deletion of the database
virtual Result dropDatabase(Database*) = 0;
virtual Result dropDatabase(TRI_vocbase_t*) = 0;
/// @brief wait until a database directory disappears - not under lock in databaseFreature
virtual void waitUntilDeletion(TRI_voc_tick_t id, bool force, int& status) = 0;

View File

@ -40,7 +40,9 @@ class DatabaseGuard {
explicit DatabaseGuard(TRI_vocbase_t* vocbase)
: _vocbase(vocbase) {
TRI_ASSERT(vocbase != nullptr);
_vocbase->use();
if (!_vocbase->use()) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
}
}
/// @brief create the guard, using a database id

View File

@ -566,7 +566,7 @@ V8Context* V8DealerFeature::enterContext(TRI_vocbase_t* vocbase,
TimedAction exitWhenNoContext([](double waitTime) {
LOG_TOPIC(WARN, arangodb::Logger::V8) << "giving up waiting for unused V8 context after " << Logger::FIXED(waitTime) << " s";
}, 120);
}, 60);
V8Context* context = nullptr;

View File

@ -27,6 +27,7 @@
#include "Basics/VelocyPackHelper.h"
#include "Basics/conversions.h"
#include "Basics/tri-strings.h"
#include "Cluster/ClusterFeature.h"
#include "Cluster/ClusterInfo.h"
#include "Cluster/ClusterMethods.h"
#include "Indexes/Index.h"
@ -669,12 +670,8 @@ static void CreateVocBase(v8::FunctionCallbackInfo<v8::Value> const& args,
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
}
// ...........................................................................
// We require exactly 1 or exactly 2 arguments -- anything else is an error
// ...........................................................................
if (args.Length() < 1 || args.Length() > 3) {
TRI_V8_THROW_EXCEPTION_USAGE("_create(<name>, <properties>, <type>)");
if (args.Length() < 1 || args.Length() > 4) {
TRI_V8_THROW_EXCEPTION_USAGE("_create(<name>, <properties>, <type>, <options>)");
}
if (TRI_GetOperationModeServer() == TRI_VOCBASE_MODE_NO_CREATE) {
@ -682,7 +679,7 @@ static void CreateVocBase(v8::FunctionCallbackInfo<v8::Value> const& args,
}
// optional, third parameter can override collection type
if (args.Length() == 3 && args[2]->IsString()) {
if (args.Length() >= 3 && args[2]->IsString()) {
std::string typeString = TRI_ObjectToString(args[2]);
if (typeString == "edge") {
collectionType = TRI_COL_TYPE_EDGE;
@ -691,6 +688,7 @@ static void CreateVocBase(v8::FunctionCallbackInfo<v8::Value> const& args,
}
}
PREVENT_EMBEDDED_TRANSACTION();
// extract the name
@ -725,9 +723,19 @@ static void CreateVocBase(v8::FunctionCallbackInfo<v8::Value> const& args,
infoSlice = builder.slice();
if (ServerState::instance()->isCoordinator()) {
bool createWaitsForSyncReplication = application_features::ApplicationServer::getFeature<ClusterFeature>("Cluster")->createWaitsForSyncReplication();
if (args.Length() >= 3 && args[args.Length()-1]->IsObject()) {
v8::Handle<v8::Object> obj = args[args.Length()-1]->ToObject();
auto v8WaitForSyncReplication = obj->Get(TRI_V8_ASCII_STRING("waitForSyncReplication"));
if (!v8WaitForSyncReplication->IsUndefined()) {
createWaitsForSyncReplication = TRI_ObjectToBoolean(v8WaitForSyncReplication);
}
}
std::unique_ptr<LogicalCollection> col =
ClusterMethods::createCollectionOnCoordinator(collectionType, vocbase,
infoSlice);
infoSlice, true, createWaitsForSyncReplication);
TRI_V8_RETURN(WrapCollection(isolate, col.release()));
}

View File

@ -76,7 +76,8 @@ macro (install_readme input output)
endif ()
install(
CODE "configure_file(${PROJECT_SOURCE_DIR}/${input} \"${PROJECT_BINARY_DIR}/${output}\" NEWLINE_STYLE ${CRLFSTYLE})"
CODE "configure_file(${PROJECT_SOURCE_DIR}/${input} \"${PROJECT_BINARY_DIR}/${output}\" NEWLINE_STYLE ${CRLFSTYLE})")
install(
FILES "${PROJECT_BINARY_DIR}/${output}"
DESTINATION "${where}"
)

View File

@ -65,7 +65,6 @@ function collectionRepresentation(collection, showProperties, showCount, showFig
if (cluster.isCoordinator()) {
result.avoidServers = properties.avoidServers;
result.distributeShardsLike = properties.distributeShardsLike;
result.numberOfShards = properties.numberOfShards;
result.replicationFactor = properties.replicationFactor;
result.avoidServers = properties.avoidServers;
@ -206,6 +205,15 @@ function post_api_collection (req, res) {
}
try {
var options = {};
if (req.parameters.hasOwnProperty('waitForSyncReplication')) {
var value = req.parameters.waitForSyncReplication.toLowerCase();
if (value === 'true' || value === 'yes' || value === 'on' || value === 'y' || value === '1') {
options.waitForSyncReplication = true;
} else {
options.waitForSyncReplication = false;
}
}
var collection;
if (typeof (r.type) === 'string') {
if (r.type.toLowerCase() === 'edge' || r.type === '3') {
@ -213,9 +221,9 @@ function post_api_collection (req, res) {
}
}
if (r.type === arangodb.ArangoCollection.TYPE_EDGE) {
collection = arangodb.db._createEdgeCollection(r.name, r.parameters);
collection = arangodb.db._createEdgeCollection(r.name, r.parameters, options);
} else {
collection = arangodb.db._createDocumentCollection(r.name, r.parameters);
collection = arangodb.db._createDocumentCollection(r.name, r.parameters, options);
}
var result = {};

View File

@ -970,12 +970,25 @@ actions.defineHttp({
"body must be an object with a string attribute 'server'");
return;
}
// First translate the server name from short name to long name:
var server = body.server;
var servers = global.ArangoClusterInfo.getDBServers();
for (let i = 0; i < servers.length; i++) {
if (servers[i].serverId !== server) {
if (servers[i].serverName === server) {
server = servers[i].serverId;
break;
}
}
}
var ok = true;
var id;
try {
id = ArangoClusterInfo.uniqid();
var todo = { 'type': 'cleanOutServer',
'server': body.server,
'server': server,
'jobId': id,
'timeCreated': (new Date()).toISOString(),
'creator': ArangoServerState.id() };

View File

@ -345,7 +345,7 @@ ArangoCollection.prototype.properties = function (properties) {
requestResult = this._database._connection.GET(this._baseurl('properties'));
arangosh.checkRequestResult(requestResult);
}else {
} else {
var body = {};
for (a in attributes) {

View File

@ -339,7 +339,7 @@ ArangoDatabase.prototype._collection = function (id) {
// / @brief creates a new collection
// //////////////////////////////////////////////////////////////////////////////
ArangoDatabase.prototype._create = function (name, properties, type) {
ArangoDatabase.prototype._create = function (name, properties, type, options) {
var body = {
'name': name,
'type': ArangoCollection.TYPE_DOCUMENT
@ -355,12 +355,23 @@ ArangoDatabase.prototype._create = function (name, properties, type) {
}
});
}
let urlAddon = '';
if (typeof options === "object" && options !== null) {
if (options.hasOwnProperty('waitForSyncReplication')) {
if (options.waitForSyncReplication) {
urlAddon = '?waitForSyncReplication=1';
} else {
urlAddon = '?waitForSyncReplication=0';
}
}
}
if (type !== undefined) {
body.type = type;
}
var requestResult = this._connection.POST(this._collectionurl(),
var requestResult = this._connection.POST(this._collectionurl() + urlAddon,
JSON.stringify(body));
arangosh.checkRequestResult(requestResult);

View File

@ -805,6 +805,58 @@ describe('Cluster sync', function() {
db._useDatabase('test');
expect(db._collection('s100001').isLeader()).to.equal(true);
});
it('should kill any unplanned server from current', function() {
let collection = db._create('s100001');
collection.assumeLeadership();
collection.addFollower('test');
collection.addFollower('test2');
let plan = {
test: {
"100001": {
"deleted": false,
"doCompact": true,
"id": "100001",
"indexBuckets": 8,
"indexes": [
{
"fields": [
"_key"
],
"id": "0",
"sparse": false,
"type": "primary",
"unique": true
}
],
"isSystem": false,
"isVolatile": false,
"journalSize": 1048576,
"keyOptions": {
"allowUserKeys": true,
"type": "traditional"
},
"name": "testi",
"numberOfShards": 1,
"replicationFactor": 2,
"shardKeys": [
"_key"
],
"shards": {
"s100001": [
"repltest",
"test2",
]
},
"status": 2,
"type": 2,
"waitForSync": false
}
}
};
cluster.executePlanForCollections(plan);
db._useDatabase('test');
expect(collection.getFollowers()).to.deep.equal(['test2']);
});
});
describe('Update current database', function() {
beforeEach(function() {
@ -972,7 +1024,7 @@ describe('Cluster sync', function() {
let collection = db._create('testi', props);
let current = {
};
let result = cluster.updateCurrentForCollections({}, current);
let result = cluster.updateCurrentForCollections({}, {}, current);
expect(Object.keys(result)).to.have.lengthOf(0);
});
it('should not delete any collections for which we are not a leader locally', function() {
@ -983,7 +1035,7 @@ describe('Cluster sync', function() {
},
}
};
let result = cluster.updateCurrentForCollections({}, current);
let result = cluster.updateCurrentForCollections({}, {}, current);
expect(Object.keys(result)).to.have.lengthOf(0);
});
it('should resign leadership for which we are no more leader locally', function() {
@ -996,7 +1048,7 @@ describe('Cluster sync', function() {
},
}
};
let result = cluster.updateCurrentForCollections({}, current);
let result = cluster.updateCurrentForCollections({}, {}, current);
expect(result).to.be.an('object');
expect(Object.keys(result)).to.have.lengthOf(1);
expect(result).to.have.property('/arango/Current/Collections/testung/888111/testi/servers')
@ -1016,7 +1068,7 @@ describe('Cluster sync', function() {
},
}
};
let result = cluster.updateCurrentForCollections({}, current);
let result = cluster.updateCurrentForCollections({}, {}, current);
expect(result).to.be.an('object');
expect(Object.keys(result)).to.have.lengthOf(1);
expect(result).to.have.property('/arango/Current/Collections/testung/888111/testi')
@ -1033,7 +1085,7 @@ describe('Cluster sync', function() {
},
}
};
let result = cluster.updateCurrentForCollections({}, current);
let result = cluster.updateCurrentForCollections({}, {}, current);
expect(result).to.be.an('object');
expect(Object.keys(result)).to.have.lengthOf(1);
expect(result).to.have.property('/arango/Current/Collections/testung/888111/testi')
@ -1051,7 +1103,7 @@ describe('Cluster sync', function() {
},
}
};
let result = cluster.updateCurrentForCollections({}, current);
let result = cluster.updateCurrentForCollections({}, {}, current);
expect(result).to.be.an('object');
expect(Object.keys(result)).to.have.lengthOf(1);
expect(result).to.have.property('/arango/Current/Collections/testung/888111/testi')

View File

@ -58,7 +58,7 @@ function dumpTestSuite () {
////////////////////////////////////////////////////////////////////////////////
/// @brief test the empty collection
////////////////////////////////////////////////////////////////////////////////
testEmpty : function () {
var c = db._collection("UnitTestsDumpEmpty");
var p = c.properties();
@ -76,7 +76,7 @@ function dumpTestSuite () {
////////////////////////////////////////////////////////////////////////////////
/// @brief test the collection with many documents
////////////////////////////////////////////////////////////////////////////////
testMany : function () {
var c = db._collection("UnitTestsDumpMany");
var p = c.properties();
@ -101,7 +101,7 @@ function dumpTestSuite () {
////////////////////////////////////////////////////////////////////////////////
/// @brief test the edges collection
////////////////////////////////////////////////////////////////////////////////
testEdges : function () {
var c = db._collection("UnitTestsDumpEdges");
var p = c.properties();
@ -128,7 +128,7 @@ function dumpTestSuite () {
////////////////////////////////////////////////////////////////////////////////
/// @brief test the order of documents
////////////////////////////////////////////////////////////////////////////////
testOrder : function () {
var c = db._collection("UnitTestsDumpOrder");
var p = c.properties();
@ -146,7 +146,7 @@ function dumpTestSuite () {
////////////////////////////////////////////////////////////////////////////////
/// @brief test document removal & update
////////////////////////////////////////////////////////////////////////////////
testRemoved : function () {
var c = db._collection("UnitTestsDumpRemoved");
var p = c.properties();
@ -178,7 +178,7 @@ function dumpTestSuite () {
////////////////////////////////////////////////////////////////////////////////
/// @brief test indexes
////////////////////////////////////////////////////////////////////////////////
testIndexes : function () {
var c = db._collection("UnitTestsDumpIndexes");
var p = c.properties();
@ -200,32 +200,32 @@ function dumpTestSuite () {
assertFalse(c.getIndexes()[2].unique);
assertFalse(c.getIndexes()[2].sparse);
assertEqual([ "a_s1", "a_s2" ], c.getIndexes()[2].fields);
assertEqual("hash", c.getIndexes()[3].type);
assertFalse(c.getIndexes()[3].unique);
assertFalse(c.getIndexes()[3].sparse);
assertEqual([ "a_h1", "a_h2" ], c.getIndexes()[3].fields);
assertEqual("skiplist", c.getIndexes()[4].type);
assertTrue(c.getIndexes()[4].unique);
assertFalse(c.getIndexes()[4].sparse);
assertEqual([ "a_su" ], c.getIndexes()[4].fields);
assertEqual("hash", c.getIndexes()[5].type);
assertFalse(c.getIndexes()[5].unique);
assertTrue(c.getIndexes()[5].sparse);
assertEqual([ "a_hs1", "a_hs2" ], c.getIndexes()[5].fields);
assertEqual("skiplist", c.getIndexes()[6].type);
assertFalse(c.getIndexes()[6].unique);
assertTrue(c.getIndexes()[6].sparse);
assertEqual([ "a_ss1", "a_ss2" ], c.getIndexes()[6].fields);
if (db._engine().name !== "rocksdb") {
assertFalse(c.getIndexes()[7].unique);
assertEqual("fulltext", c.getIndexes()[7].type);
assertEqual([ "a_f" ], c.getIndexes()[7].fields);
assertEqual("geo2", c.getIndexes()[8].type);
assertEqual([ "a_la", "a_lo" ], c.getIndexes()[8].fields);
assertFalse(c.getIndexes()[8].unique);
@ -237,7 +237,7 @@ function dumpTestSuite () {
////////////////////////////////////////////////////////////////////////////////
/// @brief test truncate
////////////////////////////////////////////////////////////////////////////////
testTruncated : function () {
var c = db._collection("UnitTestsDumpTruncated");
var p = c.properties();
@ -254,7 +254,7 @@ function dumpTestSuite () {
////////////////////////////////////////////////////////////////////////////////
/// @brief test keygen
////////////////////////////////////////////////////////////////////////////////
testKeygen : function () {
var c = db._collection("UnitTestsDumpKeygen");
var p = c.properties();
@ -270,7 +270,7 @@ function dumpTestSuite () {
assertEqual(1, c.getIndexes().length); // just primary index
assertEqual("primary", c.getIndexes()[0].type);
assertEqual(1000, c.count());
for (var i = 0; i < 1000; ++i) {
var doc = c.document(String(7 + (i * 42)));
@ -283,7 +283,7 @@ function dumpTestSuite () {
////////////////////////////////////////////////////////////////////////////////
/// @brief test strings
////////////////////////////////////////////////////////////////////////////////
testStrings : function () {
var c = db._collection("UnitTestsDumpStrings");
var p = c.properties();
@ -298,18 +298,18 @@ function dumpTestSuite () {
var texts = [
"big. Really big. He moment. Magrathea! - insisted Arthur, - I do you can sense no further because it doesn't fit properly. In my the denies faith, and the atmosphere beneath You are not cheap He was was his satchel. He throughout Magrathea. - He pushed a tore the ecstatic crowd. Trillian sat down the time, the existence is it? And he said, - What they don't want this airtight hatchway. - it's we you shooting people would represent their Poet Master Grunthos is in his mind.",
"Ultimo cadere chi sedete uso chiuso voluto ora. Scotendosi portartela meraviglia ore eguagliare incessante allegrezza per. Pensava maestro pungeva un le tornano ah perduta. Fianco bearmi storia soffio prende udi poteva una. Cammino fascino elisire orecchi pollici mio cui sai sul. Chi egli sino sei dita ben. Audace agonie groppa afa vai ultima dentro scossa sii. Alcuni mia blocco cerchi eterno andare pagine poi. Ed migliore di sommesso oh ai angoscia vorresti.",
"Ultimo cadere chi sedete uso chiuso voluto ora. Scotendosi portartela meraviglia ore eguagliare incessante allegrezza per. Pensava maestro pungeva un le tornano ah perduta. Fianco bearmi storia soffio prende udi poteva una. Cammino fascino elisire orecchi pollici mio cui sai sul. Chi egli sino sei dita ben. Audace agonie groppa afa vai ultima dentro scossa sii. Alcuni mia blocco cerchi eterno andare pagine poi. Ed migliore di sommesso oh ai angoscia vorresti.",
"Νέο βάθος όλα δομές της χάσει. Μέτωπο εγώ συνάμα τρόπος και ότι όσο εφόδιο κόσμου. Προτίμηση όλη διάφορους του όλο εύθραυστη συγγραφής. Στα άρα ένα μία οποία άλλων νόημα. Ένα αποβαίνει ρεαλισμού μελετητές θεόσταλτο την. Ποντιακών και rites κοριτσάκι παπούτσια παραμύθια πει κυρ.",
"Mody laty mnie ludu pole rury Białopiotrowiczowi. Domy puer szczypię jemy pragnął zacność czytając ojca lasy Nowa wewnątrz klasztoru. Chce nóg mego wami. Zamku stał nogą imion ludzi ustaw Białopiotrowiczem. Kwiat Niesiołowskiemu nierostrzygniony Staje brał Nauka dachu dumę Zamku Kościuszkowskie zagon. Jakowaś zapytać dwie mój sama polu uszakach obyczaje Mój. Niesiołowski książkowéj zimny mały dotychczasowa Stryj przestraszone Stolnikównie wdał śmiertelnego. Stanisława charty kapeluszach mięty bratem każda brząknął rydwan.",
"Мелких против летают хижину тмится. Чудесам возьмет звездна Взжигай. . Податель сельские мучитель сверкает очищаясь пламенем. Увы имя меч Мое сия. Устранюсь воздушных Им от До мысленные потушатся Ко Ея терпеньем.",
"Мелких против летают хижину тмится. Чудесам возьмет звездна Взжигай. . Податель сельские мучитель сверкает очищаясь пламенем. Увы имя меч Мое сия. Устранюсь воздушных Им от До мысленные потушатся Ко Ея терпеньем.",
"dotyku. Výdech spalin bude položen záplavový detekční kabely 1x UPS Newave Conceptpower DPA 5x 40kVA bude ukončen v samostatné strojovně. Samotné servery mají pouze lokalita Ústí nad zdvojenou podlahou budou zakončené GateWayí HiroLink - Monitoring rozvaděče RTN na jednotlivých záplavových zón na soustrojí resp. technologie jsou označeny SA-MKx.y. Jejich výstupem je zajištěn přestupem dat z jejich provoz. Na dveřích vylepené výstražné tabulky. Kabeláž z okruhů zálohovaných obvodů v R.MON-I. Monitoring EZS, EPS, ... možno zajistit funkčností FireWallů na strukturovanou kabeláží vedenou v měrných jímkách zapuštěných v každém racku budou zakončeny v R.MON-NrNN. Monitoring motorgenerátorů: řídící systém bude zakončena v modulu",
"ramien mu zrejme vôbec niekto je už presne čo mám tendenciu prispôsobiť dych jej páčil, čo chce. Hmm... Včera sa mi pozdava, len dočkali, ale keďže som na uz boli u jej nezavrela. Hlava jej to ve městě nepotká, hodně mi to tí vedci pri hre, keď je tu pre Designiu. Pokiaľ viete o odbornejšie texty. Prvým z tmavých uličiek, každý to niekedy, zrovnávať krok s obrovským batohom na okraj vane a temné úmysly, tak rozmýšľam, aký som si hromady mailov, čo chcem a neraz sa pokúšal o filmovém klubu v budúcnosti rozhodne uniesť mladú maliarku (Linda Rybová), ktorú so",
" 復讐者」. 復讐者」. 伯母さん 復讐者」. 復讐者」. 復讐者」. 復讐者」. 第九章 第五章 第六章 第七章 第八章. 復讐者」 伯母さん. 復讐者」 伯母さん. 第十一章 第十九章 第十四章 第十八章 第十三章 第十五章. 復讐者」 . 第十四章 第十一章 第十二章 第十五章 第十七章 手配書. 第十四章 手配書 第十八章 第十七章 第十六章 第十三章. 第十一章 第十三章 第十八章 第十四章 手配書. 復讐者」."
];
texts.forEach(function (t, i) {
texts.forEach(function (t, i) {
var doc = c.document("text" + i);
assertEqual(t, doc.value);
});
@ -318,12 +318,12 @@ function dumpTestSuite () {
////////////////////////////////////////////////////////////////////////////////
/// @brief test committed trx
////////////////////////////////////////////////////////////////////////////////
testTransactionCommit : function () {
var c = db._collection("UnitTestsDumpTransactionCommit");
assertEqual(1000, c.count());
for (var i = 0; i < 1000; ++i) {
var doc = c.document("test" + i);
@ -336,12 +336,12 @@ function dumpTestSuite () {
////////////////////////////////////////////////////////////////////////////////
/// @brief test committed trx
////////////////////////////////////////////////////////////////////////////////
testTransactionUpdate : function () {
var c = db._collection("UnitTestsDumpTransactionUpdate");
assertEqual(1000, c.count());
for (var i = 0; i < 1000; ++i) {
var doc = c.document("test" + i);
@ -359,37 +359,37 @@ function dumpTestSuite () {
////////////////////////////////////////////////////////////////////////////////
/// @brief test aborted trx
////////////////////////////////////////////////////////////////////////////////
testTransactionAbort : function () {
var c = db._collection("UnitTestsDumpTransactionAbort");
assertEqual(1, c.count());
assertTrue(c.exists("foo"));
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test persistent
////////////////////////////////////////////////////////////////////////////////
testPersistent : function () {
var c = db._collection("UnitTestsDumpPersistent");
var p = c.properties();
assertEqual(2, c.getIndexes().length);
assertEqual(2, c.getIndexes().length);
assertEqual("primary", c.getIndexes()[0].type);
assertEqual("persistent", c.getIndexes()[1].type);
assertEqual(10000, c.count());
var res = db._query("FOR doc IN " + c.name() + " FILTER doc.value >= 0 RETURN doc").toArray();
assertEqual(10000, res.length);
res = db._query("FOR doc IN " + c.name() + " FILTER doc.value >= 5000 RETURN doc").toArray();
assertEqual(5000, res.length);
res = db._query("FOR doc IN " + c.name() + " FILTER doc.value >= 9000 RETURN doc").toArray();
assertEqual(1000, res.length);
res = db._query("FOR doc IN " + c.name() + " FILTER doc.value >= 10000 RETURN doc").toArray();
assertEqual(0, res.length);
}
@ -404,4 +404,3 @@ function dumpTestSuite () {
jsunity.run(dumpTestSuite);
return jsunity.done();

View File

@ -0,0 +1,308 @@
/*jshint globalstrict:false, strict:false, maxlen : 4000 */
/*global assertEqual, assertTrue, assertFalse */
////////////////////////////////////////////////////////////////////////////////
/// @brief tests for dump/reload
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
var internal = require("internal");
var jsunity = require("jsunity");
////////////////////////////////////////////////////////////////////////////////
/// @brief test suite
////////////////////////////////////////////////////////////////////////////////
function dumpTestSuite () {
'use strict';
var db = internal.db;
return {
////////////////////////////////////////////////////////////////////////////////
/// @brief set up
////////////////////////////////////////////////////////////////////////////////
setUp : function () {
},
////////////////////////////////////////////////////////////////////////////////
/// @brief tear down
////////////////////////////////////////////////////////////////////////////////
tearDown : function () {
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test the empty collection
////////////////////////////////////////////////////////////////////////////////
testEmpty : function () {
var c = db._collection("UnitTestsDumpEmpty");
var p = c.properties();
assertEqual(2, c.type()); // document
assertTrue(p.waitForSync);
assertEqual(1, c.getIndexes().length); // just primary index
assertEqual("primary", c.getIndexes()[0].type);
assertEqual(0, c.count());
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test the collection with many documents
////////////////////////////////////////////////////////////////////////////////
testMany : function () {
var c = db._collection("UnitTestsDumpMany");
var p = c.properties();
assertEqual(2, c.type()); // document
assertFalse(p.waitForSync);
assertEqual(1, c.getIndexes().length); // just primary index
assertEqual("primary", c.getIndexes()[0].type);
assertEqual(100000, c.count());
// test all documents
var r = db._query(`FOR d IN ${c.name()} RETURN d`).toArray();
var rr = new Map();
for (let i = 0; i < r.length; ++i) {
rr.set(r[i]._key, r[i]);
}
for (let i = 0; i < 100000; ++i) {
var doc = rr.get("test" + i);
assertEqual(i, doc.value1);
assertEqual("this is a test", doc.value2);
assertEqual("test" + i, doc.value3);
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test the edges collection
////////////////////////////////////////////////////////////////////////////////
testEdges : function () {
var c = db._collection("UnitTestsDumpEdges");
var p = c.properties();
assertEqual(3, c.type()); // edges
assertFalse(p.waitForSync);
assertEqual(2, c.getIndexes().length); // primary index + edges index
assertEqual("primary", c.getIndexes()[0].type);
assertEqual("edge", c.getIndexes()[1].type);
assertEqual(10, c.count());
// test all documents
for (var i = 0; i < 10; ++i) {
var doc = c.document("test" + i);
assertEqual("test" + i, doc._key);
assertEqual("UnitTestsDumpMany/test" + i, doc._from);
assertEqual("UnitTestsDumpMany/test" + (i + 1), doc._to);
assertEqual(i + "->" + (i + 1), doc.what);
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test the order of documents
////////////////////////////////////////////////////////////////////////////////
testOrder : function () {
var c = db._collection("UnitTestsDumpOrder");
var p = c.properties();
assertEqual(2, c.type()); // document
assertFalse(p.waitForSync);
assertEqual(1, c.getIndexes().length); // just primary index
assertEqual("primary", c.getIndexes()[0].type);
assertEqual(3, c.count());
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test document removal & update
////////////////////////////////////////////////////////////////////////////////
testRemoved : function () {
var c = db._collection("UnitTestsDumpRemoved");
var p = c.properties();
assertEqual(2, c.type()); // document
assertFalse(p.waitForSync);
assertEqual(1, c.getIndexes().length); // just primary index
assertEqual("primary", c.getIndexes()[0].type);
assertEqual(9000, c.count());
var i;
for (i = 0; i < 10000; ++i) {
if (i % 10 === 0) {
assertFalse(c.exists("test" + i));
}
else {
var doc = c.document("test" + i);
assertEqual(i, doc.value1);
if (i < 1000) {
assertEqual(i + 1, doc.value2);
}
}
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test indexes
////////////////////////////////////////////////////////////////////////////////
testIndexes : function () {
var c = db._collection("UnitTestsDumpIndexes");
var p = c.properties();
assertEqual(2, c.type()); // document
assertFalse(p.waitForSync);
assertEqual(7, c.getIndexes().length);
assertEqual("primary", c.getIndexes()[0].type);
assertEqual("hash", c.getIndexes()[1].type);
assertTrue(c.getIndexes()[1].unique);
assertFalse(c.getIndexes()[1].sparse);
assertEqual([ "a_uc" ], c.getIndexes()[1].fields);
assertEqual("skiplist", c.getIndexes()[2].type);
assertFalse(c.getIndexes()[2].unique);
assertFalse(c.getIndexes()[2].sparse);
assertEqual([ "a_s1", "a_s2" ], c.getIndexes()[2].fields);
assertEqual("hash", c.getIndexes()[3].type);
assertFalse(c.getIndexes()[3].unique);
assertFalse(c.getIndexes()[3].sparse);
assertEqual([ "a_h1", "a_h2" ], c.getIndexes()[3].fields);
assertEqual("skiplist", c.getIndexes()[4].type);
assertTrue(c.getIndexes()[4].unique);
assertFalse(c.getIndexes()[4].sparse);
assertEqual([ "a_su" ], c.getIndexes()[4].fields);
assertEqual("hash", c.getIndexes()[5].type);
assertFalse(c.getIndexes()[5].unique);
assertTrue(c.getIndexes()[5].sparse);
assertEqual([ "a_hs1", "a_hs2" ], c.getIndexes()[5].fields);
assertEqual("skiplist", c.getIndexes()[6].type);
assertFalse(c.getIndexes()[6].unique);
assertTrue(c.getIndexes()[6].sparse);
assertEqual([ "a_ss1", "a_ss2" ], c.getIndexes()[6].fields);
assertEqual(0, c.count());
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test truncate
////////////////////////////////////////////////////////////////////////////////
testTruncated : function () {
var c = db._collection("UnitTestsDumpTruncated");
var p = c.properties();
assertEqual(2, c.type()); // document
assertFalse(p.waitForSync);
assertEqual(1, c.getIndexes().length); // just primary index
assertEqual("primary", c.getIndexes()[0].type);
assertEqual(0, c.count());
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test shards
////////////////////////////////////////////////////////////////////////////////
testShards : function () {
var c = db._collection("UnitTestsDumpShards");
var p = c.properties();
assertEqual(2, c.type()); // document
assertFalse(p.waitForSync);
assertEqual(9, p.numberOfShards);
assertEqual(1, c.getIndexes().length); // just primary index
assertEqual("primary", c.getIndexes()[0].type);
assertEqual(1000, c.count());
for (var i = 0; i < 1000; ++i) {
var doc = c.document(String(7 + (i * 42)));
assertEqual(String(7 + (i * 42)), doc._key);
assertEqual(i, doc.value);
assertEqual({ value: [ i, i ] }, doc.more);
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test strings
////////////////////////////////////////////////////////////////////////////////
testStrings : function () {
var c = db._collection("UnitTestsDumpStrings");
var p = c.properties();
assertEqual(2, c.type()); // document
assertFalse(p.waitForSync);
assertEqual(1, c.getIndexes().length); // just primary index
assertEqual("primary", c.getIndexes()[0].type);
assertEqual(8, c.count());
var texts = [
"big. Really big. He moment. Magrathea! - insisted Arthur, - I do you can sense no further because it doesn't fit properly. In my the denies faith, and the atmosphere beneath You are not cheap He was was his satchel. He throughout Magrathea. - He pushed a tore the ecstatic crowd. Trillian sat down the time, the existence is it? And he said, - What they don't want this airtight hatchway. - it's we you shooting people would represent their Poet Master Grunthos is in his mind.",
"Ultimo cadere chi sedete uso chiuso voluto ora. Scotendosi portartela meraviglia ore eguagliare incessante allegrezza per. Pensava maestro pungeva un le tornano ah perduta. Fianco bearmi storia soffio prende udi poteva una. Cammino fascino elisire orecchi pollici mio cui sai sul. Chi egli sino sei dita ben. Audace agonie groppa afa vai ultima dentro scossa sii. Alcuni mia blocco cerchi eterno andare pagine poi. Ed migliore di sommesso oh ai angoscia vorresti.",
"Νέο βάθος όλα δομές της χάσει. Μέτωπο εγώ συνάμα τρόπος και ότι όσο εφόδιο κόσμου. Προτίμηση όλη διάφορους του όλο εύθραυστη συγγραφής. Στα άρα ένα μία οποία άλλων νόημα. Ένα αποβαίνει ρεαλισμού μελετητές θεόσταλτο την. Ποντιακών και rites κοριτσάκι παπούτσια παραμύθια πει κυρ.",
"Mody laty mnie ludu pole rury Białopiotrowiczowi. Domy puer szczypię jemy pragnął zacność czytając ojca lasy Nowa wewnątrz klasztoru. Chce nóg mego wami. Zamku stał nogą imion ludzi ustaw Białopiotrowiczem. Kwiat Niesiołowskiemu nierostrzygniony Staje brał Nauka dachu dumę Zamku Kościuszkowskie zagon. Jakowaś zapytać dwie mój sama polu uszakach obyczaje Mój. Niesiołowski książkowéj zimny mały dotychczasowa Stryj przestraszone Stolnikównie wdał śmiertelnego. Stanisława charty kapeluszach mięty bratem każda brząknął rydwan.",
"Мелких против летают хижину тмится. Чудесам возьмет звездна Взжигай. . Податель сельские мучитель сверкает очищаясь пламенем. Увы имя меч Мое сия. Устранюсь воздушных Им от До мысленные потушатся Ко Ея терпеньем.",
"dotyku. Výdech spalin bude položen záplavový detekční kabely 1x UPS Newave Conceptpower DPA 5x 40kVA bude ukončen v samostatné strojovně. Samotné servery mají pouze lokalita Ústí nad zdvojenou podlahou budou zakončené GateWayí HiroLink - Monitoring rozvaděče RTN na jednotlivých záplavových zón na soustrojí resp. technologie jsou označeny SA-MKx.y. Jejich výstupem je zajištěn přestupem dat z jejich provoz. Na dveřích vylepené výstražné tabulky. Kabeláž z okruhů zálohovaných obvodů v R.MON-I. Monitoring EZS, EPS, ... možno zajistit funkčností FireWallů na strukturovanou kabeláží vedenou v měrných jímkách zapuštěných v každém racku budou zakončeny v R.MON-NrNN. Monitoring motorgenerátorů: řídící systém bude zakončena v modulu",
"ramien mu zrejme vôbec niekto je už presne čo mám tendenciu prispôsobiť dych jej páčil, čo chce. Hmm... Včera sa mi pozdava, len dočkali, ale keďže som na uz boli u jej nezavrela. Hlava jej to ve městě nepotká, hodně mi to tí vedci pri hre, keď je tu pre Designiu. Pokiaľ viete o odbornejšie texty. Prvým z tmavých uličiek, každý to niekedy, zrovnávať krok s obrovským batohom na okraj vane a temné úmysly, tak rozmýšľam, aký som si hromady mailov, čo chcem a neraz sa pokúšal o filmovém klubu v budúcnosti rozhodne uniesť mladú maliarku (Linda Rybová), ktorú so",
" 復讐者」. 復讐者」. 伯母さん 復讐者」. 復讐者」. 復讐者」. 復讐者」. 第九章 第五章 第六章 第七章 第八章. 復讐者」 伯母さん. 復讐者」 伯母さん. 第十一章 第十九章 第十四章 第十八章 第十三章 第十五章. 復讐者」 . 第十四章 第十一章 第十二章 第十五章 第十七章 手配書. 第十四章 手配書 第十八章 第十七章 第十六章 第十三章. 第十一章 第十三章 第十八章 第十四章 手配書. 復讐者」."
];
texts.forEach(function (t, i) {
var doc = c.document("text" + i);
assertEqual(t, doc.value);
});
}
};
}
////////////////////////////////////////////////////////////////////////////////
/// @brief executes the test suite
////////////////////////////////////////////////////////////////////////////////
jsunity.run(dumpTestSuite);
return jsunity.done();

View File

@ -0,0 +1,95 @@
/*jshint globalstrict:false, strict:false */
/*global fail, assertEqual */
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2017 ArangoDB GmbH, Cologne, Germany
/// Copyright 2010-2017 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Max Neunhoeffer
////////////////////////////////////////////////////////////////////////////////
var jsunity = require("jsunity");
var arangodb = require("@arangodb");
var errors = require("internal").errors;
var db = arangodb.db;
function DistributeShardsLikeSuite() {
'use strict';
var cn1 = "UnitTestsDistributeShardsLike1";
var cn2 = "UnitTestsDistributeShardsLike2";
var cn3 = "UnitTestsDistributeShardsLike3";
return {
setUp: function() {
db._drop(cn2);
db._drop(cn3);
db._drop(cn1);
},
tearDown: function() {
db._drop(cn2);
db._drop(cn3);
db._drop(cn1);
},
testPointToEmpty: function() {
try {
db._create(cn1, {numberOfShards: 2, distributeShardsLike: cn2});
fail();
}
catch (err) {
require("internal").print("FUXX:", JSON.stringify(err));
assertEqual(errors.ERROR_CLUSTER_UNKNOWN_DISTRIBUTESHARDSLIKE.code,
err.errorNum);
}
},
testAvoidChain: function() {
db._create(cn1, {numberOfShards: 2});
db._create(cn2, {numberOfShards: 2, distributeShardsLike: cn1});
try {
db._create(cn3, {numberOfShards: 2, distributeShardsLike: cn2});
fail();
}
catch (err) {
assertEqual(errors.ERROR_CLUSTER_CHAIN_OF_DISTRIBUTESHARDSLIKE.code,
err.errorNum);
}
},
testPreventDrop: function() {
db._create(cn1, {numberOfShards: 2});
db._create(cn2, {numberOfShards: 2, distributeShardsLike: cn1});
db._create(cn3, {numberOfShards: 2, distributeShardsLike: cn1});
try {
db._drop(cn1);
fail();
}
catch (err) {
assertEqual(errors.ERROR_CLUSTER_MUST_NOT_DROP_COLL_OTHER_DISTRIBUTESHARDSLIKE.code,
err.errorNum);
}
}
};
}
jsunity.run(DistributeShardsLikeSuite);
return jsunity.done();

View File

@ -92,11 +92,11 @@ static inline TRI_socket_t TRI_accept(TRI_socket_t s, struct sockaddr* address,
////////////////////////////////////////////////////////////////////////////////
static inline int TRI_bind(TRI_socket_t s, const struct sockaddr* address,
int addr_len) {
size_t addr_len) {
#ifdef _WIN32
return bind(s.fileHandle, address, addr_len);
#else
return bind(s.fileDescriptor, address, addr_len);
return bind(s.fileDescriptor, address, (socklen_t)addr_len);
#endif
}

View File

@ -190,7 +190,7 @@ TRI_socket_t EndpointIp::connectSocket(const struct addrinfo* aip,
#endif
// server needs to bind to socket
int result = TRI_bind(listenSocket, aip->ai_addr, (int)aip->ai_addrlen);
int result = TRI_bind(listenSocket, aip->ai_addr, aip->ai_addrlen);
if (result != 0) {
pErr = STR_ERROR();

View File

@ -69,7 +69,7 @@ TRI_socket_t EndpointUnixDomain::connect(double connectTimeout,
if (_type == EndpointType::SERVER) {
int result =
TRI_bind(listenSocket, (struct sockaddr*)&address, SUN_LEN(&address));
TRI_bind(listenSocket, (struct sockaddr*)&address, (int) SUN_LEN(&address));
if (result != 0) {
// bind error
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "bind() failed with " << errno << " (" << strerror(errno)

View File

@ -543,7 +543,6 @@ bool SslClientConnection::writeClientConnection(void const* buffer,
return false;
}
int errorDetail;
int written = SSL_write(_ssl, buffer, (int)length);
int err = SSL_get_error(_ssl, written);
switch (err) {
@ -569,16 +568,16 @@ bool SslClientConnection::writeClientConnection(void const* buffer,
break;
}
case SSL_ERROR_SSL:
case SSL_ERROR_SSL:{
/* A failure in the SSL library occurred, usually a protocol error.
The OpenSSL error queue contains more information on the error. */
errorDetail = ERR_get_error();
unsigned long errorDetail = ERR_get_error();
char errorBuffer[256];
ERR_error_string_n(errorDetail, errorBuffer, sizeof(errorBuffer));
_errorDetails = std::string("SSL: while writing: ") + errorBuffer;
break;
}
default:
/* a true error */
_errorDetails =