diff --git a/Documentation/Books/AQL/book.json b/Documentation/Books/AQL/book.json index 9da08cac29..b6583d29b7 100644 --- a/Documentation/Books/AQL/book.json +++ b/Documentation/Books/AQL/book.json @@ -4,7 +4,7 @@ "author": "ArangoDB GmbH", "description": "Official AQL manual for ArangoDB - the multi-model NoSQL database", "language": "en", - "plugins":["-search", "-lunr", "-sharing", "toggle-chapters", "addcssjs", "anchorjs", "piwik", "sitemap-general", "ga"], + "plugins":["-search", "-lunr", "-sharing", "toggle-chapters", "addcssjs", "anchorjs", "sitemap-general", "ga"], "pdf": { "fontSize": 12, "toc": true, @@ -23,10 +23,6 @@ "js": ["styles/header.js"], "css": ["styles/header.css"] }, - "piwik": { - "URL": "www.arangodb.com/piwik/", - "siteId": 12 - }, "sitemap-general": { "prefix": "https://docs.arangodb.com/devel/AQL/" }, diff --git a/Documentation/Books/HTTP/book.json b/Documentation/Books/HTTP/book.json index 18d64e25fe..22baabc11c 100644 --- a/Documentation/Books/HTTP/book.json +++ b/Documentation/Books/HTTP/book.json @@ -4,7 +4,7 @@ "author": "ArangoDB GmbH", "description": "Official HTTP API manual for ArangoDB - the multi-model NoSQL database", "language": "en", - "plugins":["-search", "-lunr", "-sharing", "toggle-chapters", "addcssjs", "anchorjs", "piwik", "sitemap-general", "ga"], + "plugins":["-search", "-lunr", "-sharing", "toggle-chapters", "addcssjs", "anchorjs", "sitemap-general", "ga"], "pdf": { "fontSize": 12, "toc": true, @@ -23,10 +23,6 @@ "js": ["styles/header.js"], "css": ["styles/header.css"] }, - "piwik": { - "URL": "www.arangodb.com/piwik/", - "siteId": 12 - }, "sitemap-general": { "prefix": "https://docs.arangodb.com/devel/HTTP/" }, diff --git a/Documentation/Books/Manual/book.json b/Documentation/Books/Manual/book.json index 00f8bdd1a4..3f23d64373 100644 --- a/Documentation/Books/Manual/book.json +++ b/Documentation/Books/Manual/book.json @@ -4,7 +4,7 @@ "author": "ArangoDB GmbH", "description": "Official manual for ArangoDB - the multi-model NoSQL database", "language": "en", - "plugins":["-search", "-lunr", "-sharing", "toggle-chapters", "addcssjs", "anchorjs", "piwik", "sitemap-general", "ga", "callouts@git+https://github.com/Simran-B/gitbook-plugin-callouts.git"], + "plugins":["-search", "-lunr", "-sharing", "toggle-chapters", "addcssjs", "anchorjs", "sitemap-general", "ga", "callouts@git+https://github.com/Simran-B/gitbook-plugin-callouts.git"], "pdf": { "fontSize": 12, "toc": true, @@ -23,10 +23,6 @@ "js": ["styles/header.js"], "css": ["styles/header.css"] }, - "piwik": { - "URL": "www.arangodb.com/piwik/", - "siteId": 12 - }, "sitemap-general": { "prefix": "https://docs.arangodb.com/devel/Manual/" }, diff --git a/arangod/Aql/ClusterBlocks.cpp b/arangod/Aql/ClusterBlocks.cpp index 397071a0f5..4f5caf6762 100644 --- a/arangod/Aql/ClusterBlocks.cpp +++ b/arangod/Aql/ClusterBlocks.cpp @@ -103,14 +103,19 @@ int GatherBlock::shutdown(int errorCode) { DEBUG_BEGIN_BLOCK(); // don't call default shutdown method since it does the wrong thing to // _gatherBlockBuffer + int ret = TRI_ERROR_NO_ERROR; for (auto it = _dependencies.begin(); it != _dependencies.end(); ++it) { int res = (*it)->shutdown(errorCode); if (res != TRI_ERROR_NO_ERROR) { - return res; + ret = res; } } + if (ret != TRI_ERROR_NO_ERROR) { + return ret; + } + if (!_isSimple) { for (std::deque& x : _gatherBlockBuffer) { for (AqlItemBlock* y : x) { @@ -506,7 +511,7 @@ bool GatherBlock::OurLessThan::operator()(std::pair const& a, BlockWithClients::BlockWithClients(ExecutionEngine* engine, ExecutionNode const* ep, std::vector const& shardIds) - : ExecutionBlock(engine, ep), _nrClients(shardIds.size()) { + : ExecutionBlock(engine, ep), _nrClients(shardIds.size()), _wasShutdown(false) { _shardIdMap.reserve(_nrClients); for (size_t i = 0; i < _nrClients; i++) { _shardIdMap.emplace(std::make_pair(shardIds[i], i)); @@ -542,7 +547,12 @@ int BlockWithClients::shutdown(int errorCode) { _doneForClient.clear(); - return ExecutionBlock::shutdown(errorCode); + if (_wasShutdown) { + return TRI_ERROR_NO_ERROR; + } + int res = ExecutionBlock::shutdown(errorCode); + _wasShutdown = true; + return res; // cppcheck-suppress style DEBUG_END_BLOCK(); @@ -1371,19 +1381,21 @@ int RemoteBlock::initializeCursor(AqlItemBlock* items, size_t pos) { int RemoteBlock::shutdown(int errorCode) { DEBUG_BEGIN_BLOCK(); - if (!_isResponsibleForInitializeCursor) { - // do nothing... - return TRI_ERROR_NO_ERROR; - } - // For every call we simply forward via HTTP std::unique_ptr res = sendRequest(rest::RequestType::PUT, "/_api/aql/shutdown/", std::string("{\"code\":" + std::to_string(errorCode) + "}")); - if (throwExceptionAfterBadSyncRequest(res.get(), true)) { - // artificially ignore error in case query was not found during shutdown - return TRI_ERROR_NO_ERROR; + try { + if (throwExceptionAfterBadSyncRequest(res.get(), true)) { + // artificially ignore error in case query was not found during shutdown + return TRI_ERROR_NO_ERROR; + } + } catch (arangodb::basics::Exception &ex) { + if (ex.code() == TRI_ERROR_CLUSTER_BACKEND_UNAVAILABLE) { + return TRI_ERROR_CLUSTER_BACKEND_UNAVAILABLE; + } + throw; } StringBuffer const& responseBodyBuf(res->result->getBody()); diff --git a/arangod/Aql/ClusterBlocks.h b/arangod/Aql/ClusterBlocks.h index 3821cc925e..c65d8aa96d 100644 --- a/arangod/Aql/ClusterBlocks.h +++ b/arangod/Aql/ClusterBlocks.h @@ -194,6 +194,9 @@ class BlockWithClients : public ExecutionBlock { /// @brief _doneForClient: the analogue of _done: _doneForClient.at(i) = true /// if we are done for the shard with clientId = i std::vector _doneForClient; + + private: + bool _wasShutdown; }; class ScatterBlock : public BlockWithClients { diff --git a/arangod/Aql/ExecutionEngine.cpp b/arangod/Aql/ExecutionEngine.cpp index 2566159f46..04cb65239b 100644 --- a/arangod/Aql/ExecutionEngine.cpp +++ b/arangod/Aql/ExecutionEngine.cpp @@ -1187,25 +1187,26 @@ struct CoordinatorInstanciator : public WalkerWorker { /// @brief shutdown, will be called exactly once for the whole query int ExecutionEngine::shutdown(int errorCode) { + int res = TRI_ERROR_NO_ERROR; if (_root != nullptr && !_wasShutdown) { // Take care of locking prevention measures in the cluster: if (_lockedShards != nullptr) { if (CollectionLockState::_noLockHeaders == _lockedShards) { CollectionLockState::_noLockHeaders = _previouslyLockedShards; } + delete _lockedShards; _lockedShards = nullptr; _previouslyLockedShards = nullptr; } + res = _root->shutdown(errorCode); + // prevent a duplicate shutdown - int res = _root->shutdown(errorCode); _wasShutdown = true; - - return res; } - return TRI_ERROR_NO_ERROR; + return res; } /// @brief create an execution engine from a plan diff --git a/arangod/Aql/Query.cpp b/arangod/Aql/Query.cpp index 22db2366c0..a87efcf375 100644 --- a/arangod/Aql/Query.cpp +++ b/arangod/Aql/Query.cpp @@ -884,6 +884,9 @@ QueryResultV8 Query::executeV8(v8::Isolate* isolate, QueryRegistry* registry) { } } } catch (...) { + LOG_TOPIC(DEBUG, Logger::QUERIES) << TRI_microtime() - _startTime << " " + << "got an exception executing " + << " this: " << (uintptr_t) this; delete value; throw; } diff --git a/js/apps/system/_admin/aardvark/APP/frontend/js/routers/router.js b/js/apps/system/_admin/aardvark/APP/frontend/js/routers/router.js index e2f535a24b..a48b241117 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/js/routers/router.js +++ b/js/apps/system/_admin/aardvark/APP/frontend/js/routers/router.js @@ -562,11 +562,12 @@ return; } var self = this; - if (!this.collectionsView) { - this.collectionsView = new window.CollectionsView({ - collection: this.arangoCollectionsStore - }); + if (this.collectionsView) { + this.collectionsView.remove(); } + this.collectionsView = new window.CollectionsView({ + collection: this.arangoCollectionsStore + }); this.arangoCollectionsStore.fetch({ cache: false, success: function () { diff --git a/js/apps/system/_admin/aardvark/APP/frontend/js/templates/collectionsView.ejs b/js/apps/system/_admin/aardvark/APP/frontend/js/templates/collectionsView.ejs index 6ea71d1f3d..9aab04b6c2 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/js/templates/collectionsView.ejs +++ b/js/apps/system/_admin/aardvark/APP/frontend/js/templates/collectionsView.ejs @@ -106,7 +106,7 @@
diff --git a/js/apps/system/_admin/aardvark/APP/frontend/js/templates/userManagementView.ejs b/js/apps/system/_admin/aardvark/APP/frontend/js/templates/userManagementView.ejs index 3eadde512c..a4bf8206a2 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/js/templates/userManagementView.ejs +++ b/js/apps/system/_admin/aardvark/APP/frontend/js/templates/userManagementView.ejs @@ -54,7 +54,7 @@
- + Add User diff --git a/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsView.js b/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsView.js index 83efc91ea2..ff8b7268ed 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsView.js +++ b/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsView.js @@ -13,6 +13,14 @@ template: templateEngine.createTemplate('collectionsView.ejs'), + remove: function () { + this.$el.empty().off(); /* off to unbind the events */ + this.stopListening(); + this.unbind(); + delete this.el; + return this; + }, + refetchCollections: function () { var self = this; this.collection.fetch({ diff --git a/js/server/modules/@arangodb/cluster.js b/js/server/modules/@arangodb/cluster.js index d80608e6a5..433a6b97ef 100644 --- a/js/server/modules/@arangodb/cluster.js +++ b/js/server/modules/@arangodb/cluster.js @@ -992,6 +992,9 @@ function updateCurrentForCollections(localErrors, currentCollections) { Object.assign(agencyIndex, index); // Fix up the IDs of the indexes: let pos = index.id.indexOf("/"); + if (agencyIndex.hasOwnProperty("selectivityEstimate")) { + delete agencyIndex.selectivityEstimate; + } if (pos >= 0) { agencyIndex.id = index.id.slice(pos+1); } else { diff --git a/lib/V8/v8-utils.cpp b/lib/V8/v8-utils.cpp index ea9242928a..567a9e893b 100644 --- a/lib/V8/v8-utils.cpp +++ b/lib/V8/v8-utils.cpp @@ -525,7 +525,10 @@ static std::string GetEndpointFromUrl(std::string const& url) { size_t slashes = 0; while (p < e) { - if (*p == '/') { + if (*p == '?') { + // http(s)://example.com?foo=bar + return url.substr(0, p - url.c_str()); + } else if (*p == '/') { if (++slashes == 3) { return url.substr(0, p - url.c_str()); } @@ -777,33 +780,25 @@ void JS_Download(v8::FunctionCallbackInfo const& args) { std::string relative; if (url.substr(0, 7) == "http://") { - size_t found = url.find('/', 7); + endpoint = GetEndpointFromUrl(url).substr(7); + relative = url.substr(7 + endpoint.length()); - relative = "/"; - if (found != std::string::npos) { - relative.append(url.substr(found + 1)); - endpoint = url.substr(7, found - 7); - } else { - endpoint = url.substr(7); + if (relative.empty() || relative[0] != '/') { + relative = "/" + relative; } - found = endpoint.find(":"); - if (found == std::string::npos) { - endpoint = endpoint + ":80"; + if (endpoint.find(':') == std::string::npos) { + endpoint.append(":80"); } endpoint = "tcp://" + endpoint; } else if (url.substr(0, 8) == "https://") { - size_t found = url.find('/', 8); + endpoint = GetEndpointFromUrl(url).substr(8); + relative = url.substr(8 + endpoint.length()); - relative = "/"; - if (found != std::string::npos) { - relative.append(url.substr(found + 1)); - endpoint = url.substr(8, found - 8); - } else { - endpoint = url.substr(8); + if (relative.empty() || relative[0] != '/') { + relative = "/" + relative; } - found = endpoint.find(":"); - if (found == std::string::npos) { - endpoint = endpoint + ":443"; + if (endpoint.find(':') == std::string::npos) { + endpoint.append(":443"); } endpoint = "ssl://" + endpoint; } else if (url.substr(0, 6) == "srv://") {