mirror of https://gitee.com/bigwinds/arangodb
296 lines
8.7 KiB
JavaScript
296 lines
8.7 KiB
JavaScript
'use strict';
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Replication management
|
|
///
|
|
/// @file
|
|
///
|
|
/// DISCLAIMER
|
|
///
|
|
/// Copyright 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 2013, triAGENS GmbH, Cologne, Germany
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
var internal = require("internal");
|
|
var arangosh = require("@arangodb/arangosh");
|
|
|
|
var logger = {};
|
|
var applier = {};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief return the replication logger state
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
logger.state = function() {
|
|
var db = internal.db;
|
|
|
|
var requestResult = db._connection.GET("/_api/replication/logger-state");
|
|
arangosh.checkRequestResult(requestResult);
|
|
|
|
return requestResult;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief return the tick ranges that can be provided by the replication logger
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
logger.tickRanges = function() {
|
|
var db = internal.db;
|
|
|
|
var requestResult = db._connection.GET("/_api/replication/logger-tick-ranges");
|
|
arangosh.checkRequestResult(requestResult);
|
|
|
|
return requestResult;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief return the first tick that can be provided by the replication logger
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
logger.firstTick = function() {
|
|
var db = internal.db;
|
|
|
|
var requestResult = db._connection.GET("/_api/replication/logger-first-tick");
|
|
arangosh.checkRequestResult(requestResult);
|
|
|
|
return requestResult.firstTick;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief starts the replication applier
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
applier.start = function(initialTick) {
|
|
var db = internal.db;
|
|
var append = "";
|
|
|
|
if (initialTick !== undefined) {
|
|
append = "?from=" + encodeURIComponent(initialTick);
|
|
}
|
|
|
|
var requestResult = db._connection.PUT("/_api/replication/applier-start" + append, "");
|
|
arangosh.checkRequestResult(requestResult);
|
|
|
|
return requestResult;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief stops the replication applier
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
applier.stop = applier.shutdown = function() {
|
|
var db = internal.db;
|
|
|
|
var requestResult = db._connection.PUT("/_api/replication/applier-stop", "");
|
|
arangosh.checkRequestResult(requestResult);
|
|
|
|
return requestResult;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief return the replication applier state
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
applier.state = function() {
|
|
var db = internal.db;
|
|
|
|
var requestResult = db._connection.GET("/_api/replication/applier-state");
|
|
arangosh.checkRequestResult(requestResult);
|
|
|
|
return requestResult;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief stop the replication applier state and "forget" all state
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
applier.forget = function() {
|
|
var db = internal.db;
|
|
|
|
var requestResult = db._connection.DELETE("/_api/replication/applier-state");
|
|
arangosh.checkRequestResult(requestResult);
|
|
|
|
return requestResult;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief configures the replication applier
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
applier.properties = function(config) {
|
|
var db = internal.db;
|
|
|
|
var requestResult;
|
|
if (config === undefined) {
|
|
requestResult = db._connection.GET("/_api/replication/applier-config");
|
|
} else {
|
|
requestResult = db._connection.PUT("/_api/replication/applier-config",
|
|
JSON.stringify(config));
|
|
}
|
|
|
|
arangosh.checkRequestResult(requestResult);
|
|
|
|
return requestResult;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief performs a one-time synchronization with a remote endpoint
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
var sync = function(config) {
|
|
const db = internal.db;
|
|
|
|
const body = JSON.stringify(config || {});
|
|
const headers = {
|
|
"X-Arango-Async": "store"
|
|
};
|
|
|
|
const requestResult = db._connection.PUT_RAW("/_api/replication/sync", body, headers);
|
|
arangosh.checkRequestResult(requestResult);
|
|
|
|
|
|
if (config.async) {
|
|
return requestResult.headers["x-arango-async-id"];
|
|
}
|
|
|
|
let count = 0;
|
|
|
|
while (true) {
|
|
const jobResult = db._connection.PUT(
|
|
"/_api/job/" + requestResult.headers["x-arango-async-id"], "");
|
|
arangosh.checkRequestResult(jobResult);
|
|
|
|
if (jobResult.code !== 204) {
|
|
return jobResult;
|
|
}
|
|
|
|
if (++count % 6 === 0) {
|
|
internal.print("still synchronizing, please wait...");
|
|
}
|
|
|
|
internal.sleep(5);
|
|
}
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief performs a one-time synchronization with a remote endpoint, for
|
|
/// a single collection
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
var syncCollection = function(collection, config) {
|
|
var db = internal.db;
|
|
|
|
config = config || {};
|
|
config.restrictType = "include";
|
|
config.restrictCollections = [collection];
|
|
config.includeSystem = true;
|
|
|
|
return sync(config);
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief sets up the replication (all-in-one function for initial
|
|
/// synchronization and continuous replication)
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
var setupReplication = function(config) {
|
|
config = config || { };
|
|
if (! config.hasOwnProperty('autoStart')) {
|
|
config.autoStart = true;
|
|
}
|
|
if (! config.hasOwnProperty('includeSystem')) {
|
|
config.includeSystem = true;
|
|
}
|
|
if (! config.hasOwnProperty('verbose')) {
|
|
config.verbose = false;
|
|
}
|
|
|
|
const db = internal.db;
|
|
|
|
const body = JSON.stringify(config);
|
|
const headers = {
|
|
"X-Arango-Async": "store"
|
|
};
|
|
|
|
const requestResult = db._connection.PUT_RAW("/_api/replication/make-slave", body, headers);
|
|
arangosh.checkRequestResult(requestResult);
|
|
|
|
|
|
if (config.async) {
|
|
return requestResult.headers["x-arango-async-id"];
|
|
}
|
|
|
|
let count = 0;
|
|
|
|
while (true) {
|
|
const jobResult = db._connection.PUT(
|
|
"/_api/job/" + requestResult.headers["x-arango-async-id"], "");
|
|
arangosh.checkRequestResult(jobResult);
|
|
|
|
if (jobResult.code !== 204) {
|
|
return jobResult;
|
|
}
|
|
|
|
if (++count % 6 === 0) {
|
|
internal.print("still synchronizing, please wait...");
|
|
}
|
|
|
|
internal.sleep(5);
|
|
}
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief queries the sync result status
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
var getSyncResult = function(id) {
|
|
var db = internal.db;
|
|
|
|
var requestResult = db._connection.PUT_RAW("/_api/job/" + encodeURIComponent(id), "");
|
|
arangosh.checkRequestResult(requestResult);
|
|
|
|
if (requestResult.headers.hasOwnProperty("x-arango-async-id")) {
|
|
return JSON.parse(requestResult.body);
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief fetches a server's id
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
var serverId = function() {
|
|
var db = internal.db;
|
|
|
|
var requestResult = db._connection.GET("/_api/replication/server-id");
|
|
|
|
arangosh.checkRequestResult(requestResult);
|
|
|
|
return requestResult.serverId;
|
|
};
|
|
|
|
exports.logger = logger;
|
|
exports.applier = applier;
|
|
exports.sync = sync;
|
|
exports.syncCollection = syncCollection;
|
|
exports.setupReplication = setupReplication;
|
|
exports.getSyncResult = getSyncResult;
|
|
exports.serverId = serverId;
|