diff --git a/arangod/Cluster/ClusterComm.cpp b/arangod/Cluster/ClusterComm.cpp index f527f7068c..8bee5cea7d 100644 --- a/arangod/Cluster/ClusterComm.cpp +++ b/arangod/Cluster/ClusterComm.cpp @@ -1131,7 +1131,11 @@ size_t ClusterComm::performRequests(std::vector& requests, continue; } auto it = opIDtoIndex.find(res.operationID); - TRI_ASSERT(it != opIDtoIndex.end()); // we should really know this! + if (it == opIDtoIndex.end()) { + // Ooops, we got a response to which we did not send the request + LOG(ERR) << "Received ClusterComm response for a request we did not send!"; + continue; + } size_t index = it->second; if (res.status == CL_COMM_RECEIVED) { requests[index].result = res; diff --git a/arangod/Cluster/v8-cluster.cpp b/arangod/Cluster/v8-cluster.cpp index 1b41f0c6ec..9165f612a2 100644 --- a/arangod/Cluster/v8-cluster.cpp +++ b/arangod/Cluster/v8-cluster.cpp @@ -1852,7 +1852,7 @@ static void JS_Drop(v8::FunctionCallbackInfo const& args) { TRI_V8_CURRENT_GLOBALS_AND_SCOPE; if (args.Length() != 1) { - TRI_V8_THROW_EXCEPTION_USAGE("wait(obj)"); + TRI_V8_THROW_EXCEPTION_USAGE("drop(obj)"); } // Possible options: // - clientTransactionID (string) @@ -1860,14 +1860,6 @@ static void JS_Drop(v8::FunctionCallbackInfo const& args) { // - operationID (number) // - shardID (string) - // Disabled to allow communication originating in a DBserver: - // 31.7.2014 Max - - // if (ServerState::instance()->getRole() != ServerState::ROLE_COORDINATOR) { - // TRI_V8_THROW_EXCEPTION_INTERNAL(scope,"request works only in coordinator - // role"); - // } - ClusterComm* cc = ClusterComm::instance(); if (cc == nullptr) { @@ -1911,6 +1903,25 @@ static void JS_Drop(v8::FunctionCallbackInfo const& args) { TRI_V8_TRY_CATCH_END } +//////////////////////////////////////////////////////////////////////////////// +/// @brief get an ID for use with coordTransactionId +//////////////////////////////////////////////////////////////////////////////// + +static void JS_GetId(v8::FunctionCallbackInfo const& args) { + TRI_V8_TRY_CATCH_BEGIN(isolate); + + if (args.Length() != 0) { + TRI_V8_THROW_EXCEPTION_USAGE("getId()"); + } + + auto id = TRI_NewTickServer(); + std::string st = StringUtils::itoa(id); + v8::Handle s = TRI_V8_ASCII_STRING(st.c_str()); + + TRI_V8_RETURN(s); + TRI_V8_TRY_CATCH_END +} + //////////////////////////////////////////////////////////////////////////////// /// @brief creates a global cluster context //////////////////////////////////////////////////////////////////////////////// @@ -2106,6 +2117,7 @@ void TRI_InitV8Cluster(v8::Isolate* isolate, v8::Handle context) { TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("enquire"), JS_Enquire); TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("wait"), JS_Wait); TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("drop"), JS_Drop); + TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("getId"), JS_GetId); v8g->ClusterCommTempl.Reset(isolate, rt); TRI_AddGlobalFunctionVocbase(isolate, context, diff --git a/js/actions/api-cluster.js b/js/actions/api-cluster.js index 58005060c4..d41eb4a572 100644 --- a/js/actions/api-cluster.js +++ b/js/actions/api-cluster.js @@ -194,8 +194,7 @@ actions.defineHttp({ return; } var DBserver = req.parameters.DBserver; - var coord = { coordTransactionID: ArangoClusterInfo.uniqid() }; - var options = { coordTransactionID: coord.coordTransactionID, timeout:10 }; + var options = { timeout:10 }; var op = ArangoClusterComm.asyncRequest("GET","server:"+DBserver,"_system", "/_admin/statistics","",{},options); var r = ArangoClusterComm.wait(op); @@ -343,8 +342,7 @@ actions.defineHttp({ } else { // query a remote statistics collection - var coord = { coordTransactionID: ArangoClusterInfo.uniqid() }; - var options = { coordTransactionID: coord.coordTransactionID, timeout:10 }; + var options = { timeout:10 }; var op = ArangoClusterComm.asyncRequest("POST","server:"+DBserver,"_system", "/_api/cursor",JSON.stringify({query: myQueryVal, bindVars: bind}),{},options); var r = ArangoClusterComm.wait(op); diff --git a/js/apps/system/_admin/aardvark/APP/statistics.js b/js/apps/system/_admin/aardvark/APP/statistics.js index 1c694f8db7..5954a92171 100644 --- a/js/apps/system/_admin/aardvark/APP/statistics.js +++ b/js/apps/system/_admin/aardvark/APP/statistics.js @@ -443,8 +443,7 @@ router.get("/cluster", function (req, res) { const DBserver = req.queryParams.DBserver; let type = req.queryParams.type; - const coord = { coordTransactionID: ArangoClusterInfo.uniqid() }; - const options = { coordTransactionID: coord.coordTransactionID, timeout: 10 }; + const options = { timeout: 10 }; if (type !== "short" && type !== "long") { type = "short"; diff --git a/js/server/modules/@arangodb/arango-collection.js b/js/server/modules/@arangodb/arango-collection.js index 0fa392c751..94e0ef791e 100644 --- a/js/server/modules/@arangodb/arango-collection.js +++ b/js/server/modules/@arangodb/arango-collection.js @@ -1,5 +1,5 @@ /*jshint strict: false */ -/*global ArangoClusterComm, ArangoClusterInfo, require, exports, module */ +/*global ArangoClusterComm, require, exports, module */ //////////////////////////////////////////////////////////////////////////////// /// @brief ArangoCollection @@ -135,7 +135,7 @@ ArangoCollection.prototype.truncate = function () { } var dbName = require("internal").db._name(); var shards = cluster.shardList(dbName, this.name()); - var coord = { coordTransactionID: ArangoClusterInfo.uniqid() }; + var coord = { coordTransactionID: ArangoClusterComm.getId() }; var options = { coordTransactionID: coord.coordTransactionID, timeout: 360 }; shards.forEach(function (shard) { @@ -259,7 +259,7 @@ ArangoCollection.prototype.any = function () { if (cluster.isCoordinator()) { var dbName = require("internal").db._name(); var shards = cluster.shardList(dbName, this.name()); - var coord = { coordTransactionID: ArangoClusterInfo.uniqid() }; + var coord = { coordTransactionID: ArangoClusterComm.getId() }; var options = { coordTransactionID: coord.coordTransactionID, timeout: 360 }; shards.forEach(function (shard) { @@ -356,7 +356,7 @@ ArangoCollection.prototype.removeByExample = function (example, if (cluster.isCoordinator()) { var dbName = require("internal").db._name(); var shards = cluster.shardList(dbName, this.name()); - var coord = { coordTransactionID: ArangoClusterInfo.uniqid() }; + var coord = { coordTransactionID: ArangoClusterComm.getId() }; var options = { coordTransactionID: coord.coordTransactionID, timeout: 360 }; if (limit > 0 && shards.length > 1) { @@ -443,7 +443,7 @@ ArangoCollection.prototype.replaceByExample = function (example, if (cluster.isCoordinator()) { var dbName = require("internal").db._name(); var shards = cluster.shardList(dbName, this.name()); - var coord = { coordTransactionID: ArangoClusterInfo.uniqid() }; + var coord = { coordTransactionID: ArangoClusterComm.getId() }; var options = { coordTransactionID: coord.coordTransactionID, timeout: 360 }; if (limit > 0 && shards.length > 1) { @@ -542,7 +542,7 @@ ArangoCollection.prototype.updateByExample = function (example, if (cluster.isCoordinator()) { var dbName = require("internal").db._name(); var shards = cluster.shardList(dbName, this.name()); - var coord = { coordTransactionID: ArangoClusterInfo.uniqid() }; + var coord = { coordTransactionID: ArangoClusterComm.getId() }; var options = { coordTransactionID: coord.coordTransactionID, timeout: 360 }; if (limit > 0 && shards.length > 1) { diff --git a/js/server/modules/@arangodb/cluster.js b/js/server/modules/@arangodb/cluster.js index 34c68b01e6..e0871b3840 100644 --- a/js/server/modules/@arangodb/cluster.js +++ b/js/server/modules/@arangodb/cluster.js @@ -1355,51 +1355,54 @@ var shardList = function (dbName, collectionName) { var waitForDistributedResponse = function (data, shards) { var received = [ ]; + try { - while (received.length < shards.length) { - var result = global.ArangoClusterComm.wait(data); - var status = result.status; + while (received.length < shards.length) { + var result = global.ArangoClusterComm.wait(data); + var status = result.status; - if (status === "ERROR") { - raiseError(arangodb.errors.ERROR_INTERNAL.code, - "received an error from a DB server: " + JSON.stringify(result)); - } - else if (status === "TIMEOUT") { - raiseError(arangodb.errors.ERROR_CLUSTER_TIMEOUT.code, - arangodb.errors.ERROR_CLUSTER_TIMEOUT.message); - } - else if (status === "DROPPED") { - raiseError(arangodb.errors.ERROR_INTERNAL.code, - "the operation was dropped"); - } - else if (status === "RECEIVED") { - received.push(result); + if (status === "ERROR") { + raiseError(arangodb.errors.ERROR_INTERNAL.code, + "received an error from a DB server: " + JSON.stringify(result)); + } + else if (status === "TIMEOUT") { + raiseError(arangodb.errors.ERROR_CLUSTER_TIMEOUT.code, + arangodb.errors.ERROR_CLUSTER_TIMEOUT.message); + } + else if (status === "DROPPED") { + raiseError(arangodb.errors.ERROR_INTERNAL.code, + "the operation was dropped"); + } + else if (status === "RECEIVED") { + received.push(result); - if (result.headers && result.headers.hasOwnProperty('x-arango-response-code')) { - var code = parseInt(result.headers['x-arango-response-code'].substr(0, 3), 10); + if (result.headers && result.headers.hasOwnProperty('x-arango-response-code')) { + var code = parseInt(result.headers['x-arango-response-code'].substr(0, 3), 10); - if (code >= 400) { - var body; + if (code >= 400) { + var body; - try { - body = JSON.parse(result.body); + try { + body = JSON.parse(result.body); + } + catch (err) { + raiseError(arangodb.errors.ERROR_INTERNAL.code, + "error parsing JSON received from a DB server: " + err.message); + } + + raiseError(body.errorNum, + body.errorMessage); } - catch (err) { - raiseError(arangodb.errors.ERROR_INTERNAL.code, - "error parsing JSON received from a DB server: " + err.message); - } - - raiseError(body.errorNum, - body.errorMessage); } } + else { + // something else... wait without GC + require("internal").wait(0.1, false); + } } - else { - // something else... wait without GC - require("internal").wait(0.1, false); - } + } finally { + global.ArangoClusterComm.drop(data); } - return received; }; @@ -1543,7 +1546,7 @@ var bootstrapDbServers = function (isRelaunch) { var i; var options = { - coordTransactionID: global.ArangoClusterInfo.uniqid(), + coordTransactionID: global.ArangoClusterComm.getId(), timeout: 90 }; diff --git a/js/server/modules/@arangodb/foxx/manager.js b/js/server/modules/@arangodb/foxx/manager.js index f48380196a..e531906c6b 100644 --- a/js/server/modules/@arangodb/foxx/manager.js +++ b/js/server/modules/@arangodb/foxx/manager.js @@ -616,7 +616,7 @@ function createService(mount, options, activateDevelopment) { function uploadToPeerCoordinators(serviceInfo, coordinators) { let coordOptions = { - coordTransactionID: ArangoClusterInfo.uniqid() + coordTransactionID: ArangoClusterComm.getId() }; let req = fs.readBuffer(joinPath(fs.getTempPath(), serviceInfo)); let httpOptions = {}; @@ -1159,7 +1159,7 @@ function install(serviceInfo, mount, options) { let intOpts = JSON.parse(JSON.stringify(options)); intOpts.__clusterDistribution = true; let coordOptions = { - coordTransactionID: ArangoClusterInfo.uniqid() + coordTransactionID: ArangoClusterComm.getId() }; let httpOptions = {}; for (let i = 0; i < res.length; ++i) { @@ -1177,7 +1177,7 @@ function install(serviceInfo, mount, options) { /*jshint -W075:false */ let httpOptions = {}; let coordOptions = { - coordTransactionID: ArangoClusterInfo.uniqid() + coordTransactionID: ArangoClusterComm.getId() }; req.options.__clusterDistribution = true; req = JSON.stringify(req); @@ -1187,6 +1187,7 @@ function install(serviceInfo, mount, options) { '/_admin/foxx/install', req, httpOptions, coordOptions); } } + cluster.wait(coordOptions, coordinators); } } reloadRouting(); @@ -1283,7 +1284,7 @@ function uninstall(mount, options) { /*jshint -W075:false */ let httpOptions = {}; let coordOptions = { - coordTransactionID: ArangoClusterInfo.uniqid() + coordTransactionID: ArangoClusterComm.getId() }; req.options.__clusterDistribution = true; req.options.force = true; @@ -1294,6 +1295,7 @@ function uninstall(mount, options) { '/_admin/foxx/uninstall', req, httpOptions, coordOptions); } } + cluster.wait(coordOptions, coordinators); } reloadRouting(); return service.simpleJSON(); @@ -1327,7 +1329,7 @@ function replace(serviceInfo, mount, options) { let intOpts = JSON.parse(JSON.stringify(options)); intOpts.__clusterDistribution = true; let coordOptions = { - coordTransactionID: ArangoClusterInfo.uniqid() + coordTransactionID: ArangoClusterComm.getId() }; let httpOptions = {}; for (let i = 0; i < res.length; ++i) { @@ -1346,7 +1348,7 @@ function replace(serviceInfo, mount, options) { /*jshint -W075:false */ let httpOptions = {}; let coordOptions = { - coordTransactionID: ArangoClusterInfo.uniqid() + coordTransactionID: ArangoClusterComm.getId() }; req.options.__clusterDistribution = true; req.options.force = true; @@ -1355,6 +1357,7 @@ function replace(serviceInfo, mount, options) { ArangoClusterComm.asyncRequest('POST', 'server:' + coordinators[i], db._name(), '/_admin/foxx/replace', req, httpOptions, coordOptions); } + cluster.wait(coordOptions, coordinators); } } _uninstall(mount, {teardown: true, @@ -1394,7 +1397,7 @@ function upgrade(serviceInfo, mount, options) { let intOpts = JSON.parse(JSON.stringify(options)); intOpts.__clusterDistribution = true; let coordOptions = { - coordTransactionID: ArangoClusterInfo.uniqid() + coordTransactionID: ArangoClusterComm.getId() }; let httpOptions = {}; for (let i = 0; i < res.length; ++i) { @@ -1413,7 +1416,7 @@ function upgrade(serviceInfo, mount, options) { /*jshint -W075:false */ let httpOptions = {}; let coordOptions = { - coordTransactionID: ArangoClusterInfo.uniqid() + coordTransactionID: ArangoClusterComm.getId() }; req.options.__clusterDistribution = true; req.options.force = true; @@ -1422,6 +1425,7 @@ function upgrade(serviceInfo, mount, options) { ArangoClusterComm.asyncRequest('POST', 'server:' + coordinators[i], db._name(), '/_admin/foxx/update', req, httpOptions, coordOptions); } + cluster.wait(coordOptions, coordinators); } } var oldService = lookupService(mount); diff --git a/js/server/modules/@arangodb/simple-query.js b/js/server/modules/@arangodb/simple-query.js index 94ab9f8f02..6d1c2318a3 100644 --- a/js/server/modules/@arangodb/simple-query.js +++ b/js/server/modules/@arangodb/simple-query.js @@ -1,5 +1,5 @@ /*jshint strict: false */ -/*global ArangoClusterComm, ArangoClusterInfo */ +/*global ArangoClusterComm */ //////////////////////////////////////////////////////////////////////////////// /// @brief Arango Simple Query Language @@ -219,7 +219,7 @@ SimpleQueryNear.prototype.execute = function () { var dbName = require("internal").db._name(); var shards = cluster.shardList(dbName, this._collection.name()); - var coord = { coordTransactionID: ArangoClusterInfo.uniqid() }; + var coord = { coordTransactionID: ArangoClusterComm.getId() }; var options = { coordTransactionID: coord.coordTransactionID, timeout: 360 }; var _limit = 0; @@ -343,7 +343,7 @@ SimpleQueryWithin.prototype.execute = function () { var dbName = require("internal").db._name(); var shards = cluster.shardList(dbName, this._collection.name()); - var coord = { coordTransactionID: ArangoClusterInfo.uniqid() }; + var coord = { coordTransactionID: ArangoClusterComm.getId() }; var options = { coordTransactionID: coord.coordTransactionID, timeout: 360 }; var _limit = 0; @@ -460,7 +460,7 @@ SimpleQueryFulltext.prototype.execute = function () { if (cluster.isCoordinator()) { var dbName = require("internal").db._name(); var shards = cluster.shardList(dbName, this._collection.name()); - var coord = { coordTransactionID: ArangoClusterInfo.uniqid() }; + var coord = { coordTransactionID: ArangoClusterComm.getId() }; var options = { coordTransactionID: coord.coordTransactionID, timeout: 360 }; var _limit = 0; if (this._limit > 0) { @@ -547,7 +547,7 @@ SimpleQueryWithinRectangle.prototype.execute = function () { if (cluster.isCoordinator()) { var dbName = require("internal").db._name(); var shards = cluster.shardList(dbName, this._collection.name()); - var coord = { coordTransactionID: ArangoClusterInfo.uniqid() }; + var coord = { coordTransactionID: ArangoClusterComm.getId() }; var options = { coordTransactionID: coord.coordTransactionID, timeout: 360 }; var _limit = 0; if (this._limit > 0) {