wip
This commit is contained in:
parent
e1b8c583d8
commit
eb39e5bf19
@ -26,6 +26,10 @@ var BlockService = function(options) {
|
|||||||
this._subscriptions.block = [];
|
this._subscriptions.block = [];
|
||||||
this._subscriptions.reorg = [];
|
this._subscriptions.reorg = [];
|
||||||
|
|
||||||
|
//memory
|
||||||
|
this._maxMem = options.maxMemory || 1500; // in MB
|
||||||
|
this._deferTimeout = null;
|
||||||
|
|
||||||
// meta is [{ chainwork: chainwork, hash: hash }]
|
// meta is [{ chainwork: chainwork, hash: hash }]
|
||||||
this._meta = [];
|
this._meta = [];
|
||||||
|
|
||||||
@ -198,6 +202,9 @@ BlockService.prototype.start = function(callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
BlockService.prototype.stop = function(callback) {
|
BlockService.prototype.stop = function(callback) {
|
||||||
|
if (this._deferTimeout) {
|
||||||
|
this._deferTimeout.unref();
|
||||||
|
}
|
||||||
callback();
|
callback();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -663,23 +670,44 @@ BlockService.prototype._sendDelta = function() {
|
|||||||
if (++this._blockCount >= BlockService.MAX_BLOCKS) {
|
if (++this._blockCount >= BlockService.MAX_BLOCKS) {
|
||||||
this._latestBlockHash = this._tip.hash;
|
this._latestBlockHash = this._tip.hash;
|
||||||
this._blockCount = 0;
|
this._blockCount = 0;
|
||||||
// this is where we ask the p2p network for more block
|
this._continueSync();
|
||||||
var self = this;
|
|
||||||
|
|
||||||
// we need a pause here before asking for more blocks so that the db work write queue,
|
|
||||||
// does not get too large and cause a memory issue
|
|
||||||
// the larger the difference between network speeds and disk i/o speeds should result in
|
|
||||||
// larger waits, e.g. gigabit internet speeds and a usb 2.0 5400 rpm hard disk might 10-20
|
|
||||||
// between each 500 block chunk
|
|
||||||
setTimeout(function() {
|
|
||||||
|
|
||||||
self._sync();
|
|
||||||
|
|
||||||
}, 10000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BlockService.prototype._continueSync = function() {
|
||||||
|
/*
|
||||||
|
Essentially, we have three distinct tasks taking place during a sync operation
|
||||||
|
|
||||||
|
1. receiving network data
|
||||||
|
2. light processing of that data (data manipulation)
|
||||||
|
3. writing that data to disk
|
||||||
|
|
||||||
|
Our goal: Sync as quickly as our least performant task will allow using a modest amount of memory.
|
||||||
|
If our network is very fast and our disk is very slow and we have very little memory to work with,
|
||||||
|
this is the worst case scenario. We want to defer asking the p2p service for more blocks until the
|
||||||
|
disk has time to process all the queued everts.
|
||||||
|
|
||||||
|
Our way of dealing with this is to review the resident set size and defer the next call to sync if
|
||||||
|
we are in danger of a 'JS Object Allocation Failed - Out of Memory' fault.
|
||||||
|
|
||||||
|
You can use the "maxMemory" config setting for this service to limit the amount of memory considered.
|
||||||
|
The default is 1.5GB of memory, max.
|
||||||
|
|
||||||
|
If we are over 95% of max memory usage, we will defer the sync until we are 95% or less.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
var totalRss = process.memoryUsage().rss;
|
||||||
|
if ((totalRss / 1E6) / self._maxMem > 0.95) {
|
||||||
|
self._deferTimeout = setTimeout(function() {
|
||||||
|
self._continueSync();
|
||||||
|
}, 1000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self._sync();
|
||||||
|
};
|
||||||
|
|
||||||
BlockService.prototype._setListeners = function() {
|
BlockService.prototype._setListeners = function() {
|
||||||
|
|
||||||
this._p2p.once('bestHeight', this._onBestHeight.bind(this));
|
this._p2p.once('bestHeight', this._onBestHeight.bind(this));
|
||||||
|
|||||||
@ -37,6 +37,7 @@ function DB(options) {
|
|||||||
|
|
||||||
this.subscriptions = {};
|
this.subscriptions = {};
|
||||||
|
|
||||||
|
this._operationsCount = 0;
|
||||||
this.GENESIS_HASH = constants.BITCOIN_GENESIS_HASH[this.node.getNetworkName()];
|
this.GENESIS_HASH = constants.BITCOIN_GENESIS_HASH[this.node.getNetworkName()];
|
||||||
this.node.on('stopping', function() {
|
this.node.on('stopping', function() {
|
||||||
log.warn('Node is stopping, gently closing the database.');
|
log.warn('Node is stopping, gently closing the database.');
|
||||||
@ -158,8 +159,10 @@ DB.prototype.put = function(key, value, options) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self._operationsCount++;
|
||||||
self._store.put(key, value, options, function(err) {
|
self._store.put(key, value, options, function(err) {
|
||||||
|
|
||||||
|
self._operationsCount--;
|
||||||
if (err) {
|
if (err) {
|
||||||
self.emit('error', err);
|
self.emit('error', err);
|
||||||
return;
|
return;
|
||||||
@ -176,8 +179,11 @@ DB.prototype.batch = function(ops, options) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self._operationsCount += ops.length;
|
||||||
self._store.batch(ops, options, function(err) {
|
self._store.batch(ops, options, function(err) {
|
||||||
|
|
||||||
|
self._operationsCount -= ops.length;
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
self.emit('error', err);
|
self.emit('error', err);
|
||||||
return;
|
return;
|
||||||
@ -212,6 +218,7 @@ DB.prototype.createKeyStream = function(op) {
|
|||||||
DB.prototype.stop = function(callback) {
|
DB.prototype.stop = function(callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
self._stopping = true;
|
self._stopping = true;
|
||||||
|
|
||||||
self.close(callback);
|
self.close(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user