1
0
Fork 0

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

This commit is contained in:
Simon Grätzer 2017-04-25 20:55:26 +02:00
commit 020c3db093
16 changed files with 274 additions and 43 deletions

View File

@ -35,6 +35,7 @@
#include <rocksdb/comparator.h>
#include <rocksdb/convenience.h>
#include <rocksdb/utilities/transaction_db.h>
#include <velocypack/Iterator.h>
#include "Logger/Logger.h"
namespace arangodb {
@ -127,6 +128,30 @@ void uint64ToPersistent(std::string& p, uint64_t value) {
} while (++len < sizeof(uint64_t));
}
void stripObjectIds(VPackBuilder& builder, VPackSlice const& slice) {
if (slice.isObject()) {
builder.openObject();
for (auto it = arangodb::velocypack::ObjectIterator(slice); it.valid();
it++) {
if (it.key().copyString() == "objectId") {
continue;
}
builder.add(it.key());
stripObjectIds(builder, it.value());
}
builder.close();
} else if (slice.isArray()) {
builder.openArray();
for (auto it = arangodb::velocypack::ArrayIterator(slice); it.valid();
it++) {
stripObjectIds(builder, it.value());
}
builder.close();
} else {
builder.add(slice);
}
}
RocksDBTransactionState* toRocksTransactionState(transaction::Methods* trx) {
TRI_ASSERT(trx != nullptr);
TransactionState* state = trx->state();

View File

@ -88,6 +88,9 @@ arangodb::Result convertStatus(rocksdb::Status const&,
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&);
RocksDBTransactionState* toRocksTransactionState(transaction::Methods* trx);
rocksdb::TransactionDB* globalRocksDB();
RocksDBEngine* globalRocksEngine();

View File

@ -48,6 +48,7 @@ double const RocksDBReplicationContext::DefaultTTL = 30 * 60.0;
RocksDBReplicationContext::RocksDBReplicationContext()
: _id(TRI_NewTickServer()),
_lastTick(0),
_currentTick(0),
_trx(),
_collection(nullptr),
_iter(),
@ -77,21 +78,26 @@ uint64_t RocksDBReplicationContext::count() const {
// creates new transaction/snapshot
void RocksDBReplicationContext::bind(TRI_vocbase_t* vocbase) {
releaseDumpingResources();
_trx = createTransaction(vocbase);
if ((_trx.get() == nullptr) || (_trx->vocbase() != vocbase)) {
releaseDumpingResources();
_trx = createTransaction(vocbase);
}
}
int RocksDBReplicationContext::bindCollection(
std::string const& collectionName) {
if ((_collection == nullptr) || _collection->name() != collectionName) {
if ((_collection == nullptr) ||
((_collection->name() != collectionName) &&
std::to_string(_collection->cid()) != collectionName)) {
_collection = _trx->vocbase()->lookupCollection(collectionName);
if (_collection == nullptr) {
return TRI_ERROR_BAD_PARAMETER;
}
_trx->addCollectionAtRuntime(collectionName);
_iter = _collection->getAllIterator(_trx.get(), &_mdr,
false); //_mdr is not used nor updated
_currentTick = 1;
_hasMore = true;
}
return TRI_ERROR_NO_ERROR;
@ -174,13 +180,19 @@ RocksDBReplicationResult RocksDBReplicationContext::dump(
try {
_hasMore = _iter->next(cb, 10); // TODO: adjust limit?
} catch (std::exception const& ex) {
_hasMore = false;
return RocksDBReplicationResult(TRI_ERROR_INTERNAL, _lastTick);
} catch (RocksDBReplicationResult const& ex) {
_hasMore = false;
return ex;
}
}
return RocksDBReplicationResult(TRI_ERROR_NO_ERROR, _lastTick);
if (_hasMore) {
_currentTick++;
}
return RocksDBReplicationResult(TRI_ERROR_NO_ERROR, _currentTick);
}
arangodb::Result RocksDBReplicationContext::dumpKeyChunks(VPackBuilder& b,

View File

@ -106,6 +106,7 @@ class RocksDBReplicationContext {
private:
TRI_voc_tick_t _id;
uint64_t _lastTick;
uint64_t _currentTick;
std::unique_ptr<transaction::Methods> _trx;
LogicalCollection* _collection;
std::unique_ptr<IndexIterator> _iter;

View File

@ -826,7 +826,9 @@ void RocksDBRestReplicationHandler::handleCommandRestoreCollection() {
"invalid JSON");
return;
}
VPackSlice const slice = parsedRequest->slice();
VPackBuilder builder;
stripObjectIds(builder, parsedRequest->slice());
VPackSlice const slice = builder.slice();
bool overwrite = false;

View File

@ -74,8 +74,9 @@ macro (install_readme input output)
if (MSVC)
set(CRLFSTYLE "CRLF")
endif ()
configure_file(${PROJECT_SOURCE_DIR}/${input} "${PROJECT_BINARY_DIR}/${output}" NEWLINE_STYLE ${CRLFSTYLE})
install(
CODE "configure_file(${PROJECT_SOURCE_DIR}/${input} \"${PROJECT_BINARY_DIR}/${output}\" NEWLINE_STYLE ${CRLFSTYLE})"
FILES "${PROJECT_BINARY_DIR}/${output}"
DESTINATION "${where}"
)

View File

@ -68,6 +68,8 @@ function collectionRepresentation(collection, showProperties, showCount, showFig
result.distributeShardsLike = properties.distributeShardsLike;
result.numberOfShards = properties.numberOfShards;
result.replicationFactor = properties.replicationFactor;
result.avoidServers = properties.avoidServers;
result.distributeShardsLike = properties.distributeShardsLike;
result.shardKeys = properties.shardKeys;
}
}

View File

@ -39,6 +39,7 @@
'nodes': 'nodes',
'shards': 'shards',
'node/:name': 'node',
'nodeInfo/:id': 'nodeInfo',
'logs': 'logger',
'helpus': 'helpUs',
'graph/:name': 'graph',
@ -327,16 +328,40 @@
return;
}
if (!this.nodeView) {
this.nodeView = new window.NodeView({
coordname: name,
coordinators: this.coordinatorCollection,
dbServers: this.dbServers
});
if (this.nodeView) {
this.nodeView.remove();
}
this.nodeView = new window.NodeView({
coordname: name,
coordinators: this.coordinatorCollection,
dbServers: this.dbServers
});
this.nodeView.render();
},
nodeInfo: function (id, initialized) {
this.checkUser();
if (!initialized || this.isCluster === undefined) {
this.waitForInit(this.nodeInfo.bind(this), id);
return;
}
if (this.isCluster === false) {
this.routes[''] = 'dashboard';
this.navigate('#dashboard', {trigger: true});
return;
}
if (this.nodeInfoView) {
this.nodeInfoView.remove();
}
this.nodeInfoView = new window.NodeInfoView({
nodeId: id,
coordinators: this.coordinatorCollection,
dbServers: this.dbServers[0]
});
this.nodeInfoView.render();
},
shards: function (initialized) {
this.checkUser();
if (!initialized || this.isCluster === undefined) {
@ -367,10 +392,11 @@
this.navigate('#dashboard', {trigger: true});
return;
}
if (!this.nodesView) {
this.nodesView = new window.NodesView({
});
if (this.nodesView) {
this.nodesView.remove();
}
this.nodesView = new window.NodesView({
});
this.nodesView.render();
},

View File

@ -0,0 +1,27 @@
<script id="nodeInfoView.ejs" type="text/template">
<div class="nodeInfoView">
<div class="modal-body">
<table id="serverInfoTable" class="arango-table">
<tbody>
<% _.each(entries, function (entry, name) { %>
<tr>
<th class="collectionInfoTh2"><%=name%></th>
<th class="collectionInfoTh">
<div id="server-<%=name%>" class="modal-text"><%=entry%></div>
</th>
<th>
<% if (entry.description) { %>
<th class="tooltipInfoTh">
<span class="tippy" title="<%=entry.description%>"></span>
</th>
<% } %>
</th>
</tr>
<% }); %>
</tbody>
</table>
</div>
</div>
</script>

View File

@ -47,10 +47,10 @@
<div class="pure-g cluster-nodes-title pure-table pure-table-header pure-title" style="clear: both">
<div class="pure-table-row">
<div class="pure-u-9-24 left">Name</div>
<div class="pure-u-8-24 left">Endpoint</div>
<div class="pure-u-3-24 mid hide-small">Heartbeat</div>
<div class="pure-u-3-24 mid">Status</div>
<div class="pure-u-1-24 mid"></div>
<div class="pure-u-9-24 left">Endpoint</div>
<div class="pure-u-2-24 mid hide-small">Since</div>
<div class="pure-u-2-24 mid">Info</div>
<div class="pure-u-2-24 mid">Status</div>
</div>
</div>
@ -67,16 +67,17 @@
<i class="fa fa-trash-o"></i>
<% } %>
</div>
<div class="pure-u-8-24 left"><%= node.Endpoint %></div>
<div class="pure-u-9-24 left"><%= node.Endpoint %></div>
<% var formatted = (node.LastHeartbeatAcked).substr(11, 18).slice(0, -1); %>
<div class="pure-u-3-24 hide-small mid"><%= formatted %></div>
<div class="pure-u-3-24 mid"><%= node.LastHeartbeatStatus %></div>
<div class="pure-u-2-24 hide-small mid"><%= formatted %></div>
<div class="pure-u-2-24 mid"><i class="fa fa-info-circle"></i></div>
<% if(node.Status === 'GOOD') { %>
<div class="pure-u-1-24 mid state"><i class="fa fa-check-circle"></i></div>
<div class="pure-u-2-24 mid state"><i class="fa fa-check-circle tippy" title="<%= node.LastHeartbeatStatus %>"></i></div>
<% } else { %>
<div class="pure-u-1-24 mid state"><i class="fa fa-exclamation-circle"></i></div>
<div class="pure-u-2-24 mid state"><i class="fa fa-exclamation-circle"></i></div>
<% } %>
</div>
@ -128,10 +129,10 @@
<div class="pure-g cluster-nodes-title pure-table pure-table-header pure-title">
<div class="pure-table-row">
<div class="pure-u-9-24 left">Name</div>
<div class="pure-u-8-24 left">Endpoint</div>
<div class="pure-u-3-24 mid hide-small">Heartbeat</div>
<div class="pure-u-3-24 mid">Status</div>
<div class="pure-u-1-24 mid"></div>
<div class="pure-u-9-24 left">Endpoint</div>
<div class="pure-u-2-24 mid hide-small">Since</div>
<div class="pure-u-2-24 mid">Info</div>
<div class="pure-u-2-24 mid">Status</div>
</div>
</div>
<% } %>
@ -143,16 +144,17 @@
<div class="pure-table-row <%= disabled %>" id="<%= id %>">
<div class="pure-u-9-24 left"><%= node.ShortName %></div>
<div class="pure-u-8-24 left"><%= node.Endpoint %></div>
<div class="pure-u-9-24 left"><%= node.Endpoint %></div>
<% var formatted = (node.LastHeartbeatAcked).substr(11, 18).slice(0, -1); %>
<div class="pure-u-3-24 mid hide-small"><%= formatted %></div>
<div class="pure-u-3-24 mid"><%= node.LastHeartbeatStatus %></div>
<div class="pure-u-2-24 mid hide-small"><%= formatted %></div>
<div class="pure-u-2-24 mid"><i class="fa fa-info-circle"></i></div>
<% if(node.Status === 'GOOD') { %>
<div class="pure-u-1-24 mid state"><i class="fa fa-check-circle"></i></div>
<div class="pure-u-2-24 mid state"><i class="fa fa-check-circle tippy" title="<%= node.LastHeartbeatStatus %>"></i></div>
<% } else { %>
<div class="pure-u-1-24 mid state"><i class="fa fa-exclamation-circle"></i></div>
<div class="pure-u-2-24 mid state"><i class="fa fa-exclamation-circle"></i></div>
<% } %>
</div>

View File

@ -0,0 +1,108 @@
/* jshint browser: true */
/* jshint unused: false */
/* global arangoHelper, $, Backbone, templateEngine, window */
(function () {
'use strict';
window.NodeInfoView = Backbone.View.extend({
el: '#content',
template: templateEngine.createTemplate('nodeInfoView.ejs'),
initialize: function (options) {
if (window.App.isCluster) {
this.nodeId = options.nodeId;
this.dbServers = options.dbServers;
this.coordinators = options.coordinators;
}
},
remove: function () {
this.$el.empty().off(); /* off to unbind the events */
this.stopListening();
this.unbind();
delete this.el;
return this;
},
render: function () {
this.$el.html(this.template.render({entries: []}));
var callback = function () {
this.continueRender();
this.breadcrumb(arangoHelper.getCoordinatorShortName(this.nodeId));
$(window).trigger('resize');
}.bind(this);
if (!this.initCoordDone) {
this.waitForCoordinators();
}
if (!this.initDBDone) {
this.waitForDBServers(callback);
} else {
this.nodeId = window.location.hash.split('/')[1];
this.coordinator = this.coordinators.findWhere({name: this.coordname});
callback();
}
},
continueRender: function () {
var model;
if (this.coordinator) {
model = this.coordinator.toJSON();
} else {
model = this.dbServer.toJSON();
}
var renderObj = {};
renderObj.Name = model.name;
renderObj.Address = model.address;
renderObj.Status = model.status;
renderObj.Protocol = model.protocol;
renderObj.Role = model.role;
this.$el.html(this.template.render({entries: renderObj}));
},
breadcrumb: function (name) {
$('#subNavigationBar .breadcrumb').html('Node: ' + name);
},
waitForCoordinators: function (callback) {
var self = this;
window.setTimeout(function () {
if (self.coordinators.length === 0) {
self.waitForCoordinators(callback);
} else {
self.coordinator = self.coordinators.findWhere({name: self.nodeId});
self.initCoordDone = true;
if (callback) {
callback();
}
}
}, 200);
},
waitForDBServers: function (callback) {
var self = this;
window.setTimeout(function () {
if (self.dbServers.length === 0) {
self.waitForDBServers(callback);
} else {
self.initDBDone = true;
self.dbServers.each(function (model) {
if (model.get('id') === self.nodeId) {
self.dbServer = model;
}
});
callback();
}
}, 200);
}
});
}());

View File

@ -30,6 +30,14 @@
}
},
remove: function () {
this.$el.empty().off(); /* off to unbind the events */
this.stopListening();
this.unbind();
delete this.el;
return this;
},
breadcrumb: function (name) {
$('#subNavigationBar .breadcrumb').html('Node: ' + name);
},

View File

@ -22,6 +22,14 @@
'keyup #plannedDBs': 'checkKey'
},
remove: function () {
this.$el.empty().off(); /* off to unbind the events */
this.stopListening();
this.unbind();
delete this.el;
return this;
},
checkKey: function (e) {
if (e.keyCode === 13) {
var self = this;
@ -121,11 +129,16 @@
},
navigateToNode: function (elem) {
var name = $(elem.currentTarget).attr('node').slice(0, -5);
if ($(elem.target).hasClass('fa-info-circle')) {
window.App.navigate('#nodeInfo/' + encodeURIComponent(name), {trigger: true});
return;
}
if ($(elem.currentTarget).hasClass('noHover')) {
return;
}
var name = $(elem.currentTarget).attr('node').slice(0, -5);
window.App.navigate('#node/' + encodeURIComponent(name), {trigger: true});
},

View File

@ -33,8 +33,9 @@
.pure-table-body {
.fa-check-circle,
.fa-info-circle,
.fa-exclamation-circle {
font-size: 15pt;
font-size: 13pt;
}
}

View File

@ -347,8 +347,8 @@ function printTraversalDetails (traversals) {
maxEdgeCollectionNameStrLen = node.edgeCollectionNameStrLen;
}
}
if (node.hasOwnProperty('traversalFlags')) {
var opts = optify(node.traversalFlags);
if (node.hasOwnProperty('options')) {
var opts = optify(node.options);
if (opts.length > maxOptionsLen) {
maxOptionsLen = opts.length;
}
@ -384,8 +384,8 @@ function printTraversalDetails (traversals) {
line += pad(1 + maxEdgeCollectionNameStrLen) + ' ';
}
if (traversals[i].hasOwnProperty('traversalFlags')) {
line += optify(traversals[i].traversalFlags, true) + pad(1 + maxOptionsLen - optify(traversals[i].traversalFlags, false).length) + ' ';
if (traversals[i].hasOwnProperty('options')) {
line += optify(traversals[i].options, true) + pad(1 + maxOptionsLen - optify(traversals[i].options, false).length) + ' ';
} else {
line += pad(1 + maxOptionsLen) + ' ';
}
@ -856,7 +856,7 @@ function processQuery (query, explain) {
return keyword('FOR') + ' ' + variableName(node.outVariable) + ' ' + keyword('IN') + ' ' + collection(node.collection) + ' ' + annotation('/* ' + (node.reverse ? 'reverse ' : '') + node.index.type + ' index scan */');
case 'TraversalNode':
node.minMaxDepth = node.traversalFlags.minDepth + '..' + node.traversalFlags.maxDepth;
node.minMaxDepth = node.options.minDepth + '..' + node.options.maxDepth;
node.minMaxDepthLen = node.minMaxDepth.length;
rc = keyword('FOR ');

View File

@ -185,7 +185,7 @@ function dumpTestSuite () {
assertFalse(p.waitForSync);
assertFalse(p.isVolatile);
assertEqual(9, c.getIndexes().length);
assertEqual(7, c.getIndexes().length);
assertEqual("primary", c.getIndexes()[0].type);
assertEqual("hash", c.getIndexes()[1].type);
@ -241,7 +241,7 @@ function dumpTestSuite () {
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());