1
0
Fork 0

First set of changes, not yet activated.

This commit is contained in:
Max Neunhoeffer 2017-01-10 16:54:51 +01:00
parent f47329f3c0
commit e9630b7aca
1 changed files with 271 additions and 158 deletions

View File

@ -1,7 +1,7 @@
/* global ArangoServerState, ArangoClusterInfo */
'use strict';
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief JavaScript cluster functionality
// /
// / @file
@ -26,7 +26,7 @@
// /
// / @author Jan Steemann
// / @author Copyright 2012, triAGENS GmbH, Cologne, Germany
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
var console = require('console');
var arangodb = require('@arangodb');
@ -133,9 +133,9 @@ function cancelReadLockOnLeader (endpoint, database, lockJobId) {
return true;
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief cancel barrier from sync
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function cancelBarrier (endpoint, database, barrierId) {
if (barrierId <= 0) {
@ -152,9 +152,9 @@ function cancelBarrier (endpoint, database, barrierId) {
return true;
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief tell leader that we are in sync
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function addShardFollower (endpoint, database, shard) {
console.debug('addShardFollower: tell the leader to put us into the follower list...');
@ -169,9 +169,9 @@ function addShardFollower (endpoint, database, shard) {
return true;
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief tell leader that we are stop following
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function removeShardFollower (endpoint, database, shard) {
console.debug('removeShardFollower: tell the leader to take us off the follower list...');
@ -186,9 +186,9 @@ function removeShardFollower (endpoint, database, shard) {
return true;
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief lookup for 4-dimensional nested dictionary data
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function lookup4d (data, a, b, c) {
if (!data.hasOwnProperty(a)) {
@ -203,9 +203,9 @@ function lookup4d (data, a, b, c) {
return data[a][b][c];
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief return a shardId => server map
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function getShardMap (plannedCollections) {
var shardMap = { };
@ -235,9 +235,9 @@ function getShardMap (plannedCollections) {
return shardMap;
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief return the indexes of a collection as a map
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function getIndexMap (shard) {
var indexes = { }, i;
@ -254,24 +254,28 @@ function getIndexMap (shard) {
return indexes;
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief return a hash with the local databases
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function getLocalDatabases () {
var result = { };
var db = require('internal').db;
db._databases().forEach(function (database) {
result[database] = { name: database };
});
let result = { };
let db = require('internal').db;
let curDb = db._name();
try {
db._databases().forEach(function (database) {
db._useDatabase(database);
result[database] = { name: database, id: db._id() };
});
} finally {
db._useDatabase(curDb);
}
return result;
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief return a hash with the local collections
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function getLocalCollections () {
var result = { };
@ -305,9 +309,9 @@ function getLocalCollections () {
return result;
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief create databases if they exist in the plan but not locally
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function createLocalDatabases (plannedDatabases, currentDatabases) {
var ourselves = global.ArangoServerState.id();
@ -360,9 +364,9 @@ function createLocalDatabases (plannedDatabases, currentDatabases) {
}
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief drop databases if they do exist locally but not in the plan
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function dropLocalDatabases (plannedDatabases) {
var ourselves = global.ArangoServerState.id();
@ -415,9 +419,9 @@ function dropLocalDatabases (plannedDatabases) {
}
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief clean up what's in Current/Databases for ourselves
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function cleanupCurrentDatabases (currentDatabases) {
var ourselves = global.ArangoServerState.id();
@ -455,9 +459,9 @@ function cleanupCurrentDatabases (currentDatabases) {
}
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief handle database changes
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function handleDatabaseChanges (plan, current) {
var plannedDatabases = plan.Databases;
@ -468,9 +472,9 @@ function handleDatabaseChanges (plan, current) {
cleanupCurrentDatabases(currentDatabases);
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief create collections if they exist in the plan but not locally
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function createLocalCollections (plannedCollections, planVersion,
currentCollections, takeOverResponsibility) {
@ -785,9 +789,9 @@ function leaderResign (database, collId, shardName, ourselves) {
}
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief drop collections if they exist locally but not in the plan
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function dropLocalCollections (plannedCollections, currentCollections) {
var ourselves = global.ArangoServerState.id();
@ -898,9 +902,9 @@ function dropLocalCollections (plannedCollections, currentCollections) {
}
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief clean up what's in Current/Collections for ourselves
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function cleanupCurrentCollections (plannedCollections, currentCollections) {
var dropCollectionAgency = function (database, collection, shardID) {
@ -955,9 +959,9 @@ function cleanupCurrentCollections (plannedCollections, currentCollections) {
}
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief lock key space
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function lockSyncKeyspace () {
while (!global.KEY_SET_CAS('shardSynchronization', 'lock', 1, null)) {
@ -965,17 +969,17 @@ function lockSyncKeyspace () {
}
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief unlock key space
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function unlockSyncKeyspace () {
global.KEY_SET('shardSynchronization', 'lock', null);
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief launch a scheduled job if needed
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function tryLaunchJob () {
const registerTask = require('internal').registerTask;
@ -1033,9 +1037,9 @@ function tryLaunchJob () {
}
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief synchronize one shard, this is run as a V8 task
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function synchronizeOneShard (database, shard, planId, leader) {
// synchronize this shard from the leader
@ -1183,9 +1187,9 @@ function synchronizeOneShard (database, shard, planId, leader) {
database, shard, database, planId);
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief schedule a shard synchronization
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function scheduleOneShardSynchronization (database, shard, planId, leader) {
console.debug('scheduleOneShardSynchronization:', database, shard, planId,
@ -1222,10 +1226,10 @@ function scheduleOneShardSynchronization (database, shard, planId, leader) {
return true;
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief synchronize collections for which we are followers (synchronously
// / replicated shards)
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function synchronizeLocalFollowerCollections (plannedCollections,
currentCollections) {
@ -1299,9 +1303,9 @@ function synchronizeLocalFollowerCollections (plannedCollections,
return true;
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief handle collection changes
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function handleCollectionChanges (plan, current, takeOverResponsibility) {
var plannedCollections = plan.Collections;
@ -1335,7 +1339,7 @@ function handleCollectionChanges (plan, current, takeOverResponsibility) {
function migratePrimary(plan, current) {
// will analyze local state and then issue db._create(),
// db._drop() etc. to sync plan and local state for shards
let localErrors = executePlanForDatabases(plan);
let localErrors = executePlanForCollections(plan);
// will do a diff between plan and current to find out
// the shards for which this db server is a planned
@ -1350,9 +1354,139 @@ function migratePrimary(plan, current) {
// diff current and local and prepare agency transactions or whatever
// to update current. Will report the errors created locally to the agency
updateCurrentForDatabases(localErrors, current);
updateCurrentForCollections(localErrors, current);
}
// /////////////////////////////////////////////////////////////////////////////
// / @brief executePlanForDatabases
// /////////////////////////////////////////////////////////////////////////////
function executePlanForDatabases(plan) {
let plannedDatabases = plan.Databases;
let localErrors = {};
let db = require('internal').db;
db._useDatabase('_system');
let localDatabases = getLocalDatabases();
let name;
// check which databases need to be created locally:
for (name in plannedDatabases) {
if (plannedDatabases.hasOwnProperty(name)) {
if (!localDatabases.hasOwnProperty(name)) {
// must create database
// TODO: handle options and user information
console.debug("creating local database '%s'", name);
try {
db._createDatabase(name);
} catch (err) {
localErrors[name] = { error: true, errorNum: err.errorNum,
errorMessage: err.errorMessage, name: name };
}
}
}
}
// check which databases need to be deleted locally
localDatabases = getLocalDatabases();
for (name in localDatabases) {
if (localDatabases.hasOwnProperty(name)) {
if (!plannedDatabases.hasOwnProperty(name) && name.substr(0, 1) !== '_') {
// must drop database
console.info("dropping local database '%s'", name);
// Do we have to stop a replication applier first?
if (ArangoServerState.role() === 'SECONDARY') {
try {
db._useDatabase(name);
var rep = require('@arangodb/replication');
var state = rep.applier.state();
if (state.state.running === true) {
console.info('stopping replication applier first');
rep.applier.stop();
}
}
finally {
db._useDatabase('_system');
}
}
db._dropDatabase(name);
}
}
}
return localErrors;
}
// /////////////////////////////////////////////////////////////////////////////
// / @brief updateCurrentForDatabases
// /////////////////////////////////////////////////////////////////////////////
function updateCurrentForDatabases(localErrors, current) {
let ourselves = global.ArangoServerState.id();
function makeAddDatabaseAgencyOperation(payload, trx) {
trx[0][curDatabases + payload.name + '/' + ourselves] =
{op: 'set', new: payload};
};
function makeDropDatabaseAgencyOperation(name, trx) {
trx[0][curDatabases + name + '/' + ourselves] = {'op':'delete'};
};
let db = require('internal').db;
db._useDatabase('_system');
let localDatabases = getLocalDatabases();
let currentDatabases = current.Databases;
let name;
let trx = [{}]; // Here we collect all write operations
// Add entries that we have but that are not in Current:
for (name in localDatabases) {
if (localDatabases.hasOwnProperty(name) && name.substr(0, 1) !== '_') {
if (!currentDatabases.hasOwnProperty(name) ||
!currentDatabases[name].hasOwnProperty(ourselves)) {
console.debug("adding entry in Current for database '%s'", name);
makeAddDatabaseAgencyOperation({error: false, errorNum: 0, name: name,
id: localDatabases[name].id,
errorMessage: ""}, trx);
}
}
}
// Remove entries from current that no longer exist locally:
for (name in currentDatabases) {
if (currentDatabases.hasOwnProperty(name) && name.substr(0, 1) !== '_') {
if (!localDatabases.hasOwnProperty(name)) {
// we found a database we don't have locally
if (currentDatabases[name].hasOwnProperty(ourselves)) {
// we are entered for a database that we don't have locally
console.debug("cleaning up entry for unknown database '%s'", name);
makeDropDatabaseAgencyOperation(name, trx);
}
}
}
}
// Finally, report any errors that might have been produced earlier when
// we were trying to execute the Plan:
for (name in localErrors) {
if (localErrors.hasOwnProperty(name)) {
console.debug("reporting error to Current about database '%s'", name);
makeAddDatabaseAgencyOperation(localErrors[name], trx);
}
}
return trx;
}
// /////////////////////////////////////////////////////////////////////////////
// / @brief take care of databases on any type of server according to Plan
// /////////////////////////////////////////////////////////////////////////////
@ -1360,10 +1494,22 @@ function migratePrimary(plan, current) {
function migrateAnyServer(plan, current) {
// will analyze local state and then issue db._createDatabase(),
// db._dropDatabase() etc. to sync plan and local state for databases
let localErrors = executePlanForCollections(plan);
let localErrors = executePlanForDatabases(plan);
// diff current and local and prepare agency transactions or whatever
// to update current. will report the errors created locally to the agency
updateCurrentForCollections(localErrors, current);
let trx = updateCurrentForDatabases(localErrors, current);
if (Object.keys().length !== 0) {
trx[0][curVersion] = {op: 'increment'};
// TODO: reduce timeout when we can:
try {
let res = global.ArangoAgency.write([trx]);
if (typeof res !== 'object' || res.length !== 1 || res[0] === 0) {
console.error('migrateAnyServer: could not send transaction for Current to agency, result:', res);
}
} catch (err) {
console.error('migrateAnyServer: caught exception when sending transaction for Current to agency:', err);
}
}
}
// /////////////////////////////////////////////////////////////////////////////
@ -1408,9 +1554,9 @@ function setupReplication () {
return ok;
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief role change from secondary to primary
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function secondaryToPrimary () {
console.info('Switching role from secondary to primary...');
@ -1440,49 +1586,49 @@ function secondaryToPrimary () {
}
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief role change from primary to secondary
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function primaryToSecondary () {
console.info('Switching role from primary to secondary...');
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief change handling trampoline function
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function handleChanges (plan, current) {
// Note: This is never called with role === 'COORDINATOR' or on a single
// server.
var changed = false;
var role = ArangoServerState.role();
if (role === 'PRIMARY' || role === 'SECONDARY') {
// Need to check role change for automatic failover:
var myId = ArangoServerState.id();
if (role === 'PRIMARY') {
if (!plan.DBServers[myId]) {
// Ooops! We do not seem to be a primary any more!
changed = ArangoServerState.redetermineRole();
// Need to check role change for automatic failover:
var myId = ArangoServerState.id();
if (role === 'PRIMARY') {
if (!plan.DBServers[myId]) {
// Ooops! We do not seem to be a primary any more!
changed = ArangoServerState.redetermineRole();
}
} else { // role === "SECONDARY"
if (plan.DBServers[myId]) {
changed = ArangoServerState.redetermineRole();
if (!changed) {
// mop: oops...changing role has failed. retry next time.
return false;
}
} else { // role === "SECONDARY"
if (plan.DBServers[myId]) {
} else {
var found = null;
var p;
for (p in plan) {
if (plan.hasOwnProperty(p) && plan[p] === myId) {
found = p;
break;
}
}
if (found !== ArangoServerState.idOfPrimary()) {
// Note this includes the case that we are not found at all!
changed = ArangoServerState.redetermineRole();
if (!changed) {
// mop: oops...changing role has failed. retry next time.
return false;
}
} else {
var found = null;
var p;
for (p in plan) {
if (plan.hasOwnProperty(p) && plan[p] === myId) {
found = p;
break;
}
}
if (found !== ArangoServerState.idOfPrimary()) {
// Note this includes the case that we are not found at all!
changed = ArangoServerState.redetermineRole();
}
}
}
}
@ -1501,7 +1647,7 @@ function handleChanges (plan, current) {
// migrateAnyServer(plan, current)
// if (role === 'PRIMARY') {
// migratePrimary(plan, current);
// } else if (role == 'SECONDARY') {
// } else { // if (role == 'SECONDARY') {
// setupReplication();
// }
@ -1519,9 +1665,9 @@ function handleChanges (plan, current) {
return success;
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief throw an ArangoError
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
var raiseError = function (code, msg) {
var err = new ArangoError();
@ -1531,9 +1677,9 @@ var raiseError = function (code, msg) {
throw err;
};
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief retrieve a list of shards for a collection
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
var shardList = function (dbName, collectionName) {
let ci = global.ArangoClusterInfo.getCollectionInfo(dbName, collectionName);
@ -1561,9 +1707,9 @@ var shardList = function (dbName, collectionName) {
return shards;
};
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief wait for a distributed response
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
var waitForDistributedResponse = function (data, numberOfRequests) {
var received = [];
@ -1612,9 +1758,9 @@ var waitForDistributedResponse = function (data, numberOfRequests) {
return received;
};
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief whether or not clustering is enabled
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
var isCluster = function () {
var role = global.ArangoServerState.role();
@ -1622,17 +1768,17 @@ var isCluster = function () {
return (role !== undefined && role !== 'SINGLE' && role !== 'AGENT');
};
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief whether or not we are a coordinator
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
var isCoordinator = function () {
return global.ArangoServerState.isCoordinator();
};
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief role
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
var role = function () {
var role = global.ArangoServerState.role();
@ -1643,9 +1789,9 @@ var role = function () {
return undefined;
};
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief status
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
var status = function () {
if (!isCluster() || !global.ArangoServerState.initialized()) {
@ -1655,9 +1801,9 @@ var status = function () {
return global.ArangoServerState.status();
};
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief isCoordinatorRequest
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
var isCoordinatorRequest = function (req) {
if (!req || !req.hasOwnProperty('headers')) {
@ -1667,11 +1813,13 @@ var isCoordinatorRequest = function (req) {
return req.headers.hasOwnProperty('x-arango-coordinator');
};
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief handlePlanChange
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
var handlePlanChange = function (plan, current) {
// This is never called on a coordinator, we still make sure that it
// is not executed on a single server or coordinator, just to be sure:
if (!isCluster() || isCoordinator() || !global.ArangoServerState.initialized()) {
return true;
}
@ -1681,43 +1829,8 @@ var handlePlanChange = function (plan, current) {
current: current.Version
};
// ////////////////////////////////////////////////////////////////////////////
// / @brief execute an action under a write-lock
// ////////////////////////////////////////////////////////////////////////////
function writeLocked (lockInfo, cb, args) {
var timeout = lockInfo.timeout;
if (timeout === undefined) {
timeout = 60;
}
var ttl = lockInfo.ttl;
if (ttl === undefined) {
ttl = 120;
}
if (require('internal').coverage || require('internal').valgrind) {
ttl *= 10;
timeout *= 10;
}
global.ArangoAgency.lockWrite(lockInfo.part, ttl, timeout);
try {
cb.apply(null, args);
global.ArangoAgency.increaseVersion(lockInfo.part + '/Version');
let version = global.ArangoAgency.get(lockInfo.part + '/Version');
versions[lockInfo.part.toLowerCase()] = version.arango[lockInfo.part].Version;
global.ArangoAgency.unlockWrite(lockInfo.part, timeout);
} catch (err) {
global.ArangoAgency.unlockWrite(lockInfo.part, timeout);
throw err;
}
}
try {
versions.success = handleChanges(plan, current, writeLocked);
versions.success = handleChanges(plan, current);
console.debug('plan change handling successful');
} catch (err) {
@ -1729,9 +1842,9 @@ var handlePlanChange = function (plan, current) {
return versions;
};
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief coordinatorId
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
var coordinatorId = function () {
if (!isCoordinator()) {
@ -1740,9 +1853,9 @@ var coordinatorId = function () {
return global.ArangoServerState.id();
};
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief bootstrap db servers
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
var bootstrapDbServers = function (isRelaunch) {
global.ArangoClusterInfo.reloadDBServers();
@ -1790,9 +1903,9 @@ var bootstrapDbServers = function (isRelaunch) {
return result;
};
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief shard distribution
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function format (x) {
var r = {};
@ -1830,9 +1943,9 @@ function shardDistribution () {
};
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief move shard
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function moveShard (info) {
var isLeader;
@ -1874,9 +1987,9 @@ function moveShard (info) {
return {error: false, id: id};
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief rebalance shards
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function rebalanceShards () {
var dbServers = global.ArangoClusterInfo.getDBServers();
@ -1982,9 +2095,9 @@ function rebalanceShards () {
return true;
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief supervision state
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function supervisionState () {
try {
@ -2000,9 +2113,9 @@ function supervisionState () {
}
}
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
// / @brief wait for synchronous replication to settle
// //////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
function waitForSyncReplOneCollection (dbName, collName) {
console.debug('waitForSyncRepl:', dbName, collName);