fsync all chain writes.
This commit is contained in:
parent
0f4d2ca281
commit
cbed3bbc4f
@ -1242,6 +1242,15 @@ BlockData.prototype.truncateAsync = function truncateAsync(size, callback) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BlockData.prototype._ioError = function _ioError(name, size, offset) {
|
||||||
|
return new Error(name
|
||||||
|
+ '() failed at offset '
|
||||||
|
+ offset
|
||||||
|
+ ' with '
|
||||||
|
+ size
|
||||||
|
+ ' bytes left.');
|
||||||
|
};
|
||||||
|
|
||||||
BlockData.prototype._readSync = function _readSync(size, offset) {
|
BlockData.prototype._readSync = function _readSync(size, offset) {
|
||||||
var index = 0;
|
var index = 0;
|
||||||
var data, bytes;
|
var data, bytes;
|
||||||
@ -1271,7 +1280,7 @@ BlockData.prototype._readSync = function _readSync(size, offset) {
|
|||||||
|
|
||||||
this._free(data);
|
this._free(data);
|
||||||
|
|
||||||
throw new Error('_readSync() failed.');
|
throw this._ioError('_readSync', size, offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockData.prototype._readAsync = function _readAsync(size, offset, callback) {
|
BlockData.prototype._readAsync = function _readAsync(size, offset, callback) {
|
||||||
@ -1297,7 +1306,7 @@ BlockData.prototype._readAsync = function _readAsync(size, offset, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!bytes)
|
if (!bytes)
|
||||||
return callback(new Error('_readAsync() failed at offset ' + offset + ' ' + size + ' to go'));
|
return callback(self._ioError('_readAsync', size, offset));
|
||||||
|
|
||||||
index += bytes;
|
index += bytes;
|
||||||
size -= bytes;
|
size -= bytes;
|
||||||
@ -1342,7 +1351,9 @@ BlockData.prototype._writeSync = function _writeSync(data, offset) {
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error('_writeSync() failed.');
|
fs.fsyncSync(this.fd);
|
||||||
|
|
||||||
|
throw this._ioError('_writeSync', size, offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockData.prototype._writeAsync = function _writeAsync(data, offset, callback) {
|
BlockData.prototype._writeAsync = function _writeAsync(data, offset, callback) {
|
||||||
@ -1372,7 +1383,7 @@ BlockData.prototype._writeAsync = function _writeAsync(data, offset, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!bytes)
|
if (!bytes)
|
||||||
return callback(new Error('_writeAsync() failed.'));
|
return callback(self._ioError('_writeAsync', size, offset));
|
||||||
|
|
||||||
index += bytes;
|
index += bytes;
|
||||||
size -= bytes;
|
size -= bytes;
|
||||||
|
|||||||
@ -47,6 +47,8 @@ function Chain(options) {
|
|||||||
this.pendingLimit = options.pendingLimit || 10 * 1024 * 1024;
|
this.pendingLimit = options.pendingLimit || 10 * 1024 * 1024;
|
||||||
this.invalid = {};
|
this.invalid = {};
|
||||||
this.bestHeight = -1;
|
this.bestHeight = -1;
|
||||||
|
this.lastUpdate = utils.now();
|
||||||
|
this.blockDelta = 0;
|
||||||
|
|
||||||
this.orphan = {
|
this.orphan = {
|
||||||
map: {},
|
map: {},
|
||||||
@ -716,7 +718,7 @@ Chain.prototype._fillBlock = function _fillBlock(block, callback) {
|
|||||||
|
|
||||||
Chain.prototype._addEntry = function _addEntry(entry, block, callback) {
|
Chain.prototype._addEntry = function _addEntry(entry, block, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var existing;
|
var existing, now;
|
||||||
|
|
||||||
callback = utils.asyncify(callback);
|
callback = utils.asyncify(callback);
|
||||||
|
|
||||||
@ -731,6 +733,10 @@ Chain.prototype._addEntry = function _addEntry(entry, block, callback) {
|
|||||||
if (existing && existing.hash === entry.hash)
|
if (existing && existing.hash === entry.hash)
|
||||||
return callback(null, false);
|
return callback(null, false);
|
||||||
|
|
||||||
|
now = utils.now();
|
||||||
|
this.blockDelta = now - this.lastUpdate;
|
||||||
|
this.lastUpdate = now;
|
||||||
|
|
||||||
this._saveBlock(block, function(err) {
|
this._saveBlock(block, function(err) {
|
||||||
if (err)
|
if (err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
@ -1539,6 +1545,14 @@ Chain.prototype.isFull = function isFull() {
|
|||||||
return delta < 40 * 60;
|
return delta < 40 * 60;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Chain.prototype.isInitial = function isInitial() {
|
||||||
|
if (!this.tip)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Should mimic the original IsInitialBlockDownload() function
|
||||||
|
return this.blockDelta < 10 && this.tip.ts < utils.now() - 24 * 60 * 60;
|
||||||
|
};
|
||||||
|
|
||||||
Chain.prototype.getProgress = function getProgress() {
|
Chain.prototype.getProgress = function getProgress() {
|
||||||
if (!this.tip)
|
if (!this.tip)
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -47,6 +47,7 @@ function ChainDB(chain, options) {
|
|||||||
this.size = 0;
|
this.size = 0;
|
||||||
this.fd = null;
|
this.fd = null;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
this.loaded = false;
|
||||||
|
|
||||||
// Need to cache up to the retarget interval
|
// Need to cache up to the retarget interval
|
||||||
// if we're going to be checking the damn
|
// if we're going to be checking the damn
|
||||||
@ -122,6 +123,7 @@ ChainDB.prototype.load = function load(start, callback) {
|
|||||||
|
|
||||||
function finish(err) {
|
function finish(err) {
|
||||||
self.loading = false;
|
self.loading = false;
|
||||||
|
self.loaded = true;
|
||||||
self.emit('load');
|
self.emit('load');
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
@ -617,6 +619,15 @@ ChainDB.prototype.has = function has(height) {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ChainDB.prototype._ioError = function _ioError(name, size, offset) {
|
||||||
|
return new Error(name
|
||||||
|
+ '() failed at offset '
|
||||||
|
+ offset
|
||||||
|
+ ' with '
|
||||||
|
+ size
|
||||||
|
+ ' bytes left.');
|
||||||
|
};
|
||||||
|
|
||||||
ChainDB.prototype._readSync = function _readSync(size, offset) {
|
ChainDB.prototype._readSync = function _readSync(size, offset) {
|
||||||
var index = 0;
|
var index = 0;
|
||||||
var data, bytes;
|
var data, bytes;
|
||||||
@ -646,7 +657,7 @@ ChainDB.prototype._readSync = function _readSync(size, offset) {
|
|||||||
|
|
||||||
this._free(data);
|
this._free(data);
|
||||||
|
|
||||||
throw new Error('_readSync() failed.');
|
throw this._ioError('_readSync', size, offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
ChainDB.prototype._readAsync = function _readAsync(size, offset, callback) {
|
ChainDB.prototype._readAsync = function _readAsync(size, offset, callback) {
|
||||||
@ -672,7 +683,7 @@ ChainDB.prototype._readAsync = function _readAsync(size, offset, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!bytes)
|
if (!bytes)
|
||||||
return callback(new Error('_readAsync() failed.'));
|
return callback(self._ioError('_readAsync', size, offset));
|
||||||
|
|
||||||
index += bytes;
|
index += bytes;
|
||||||
size -= bytes;
|
size -= bytes;
|
||||||
@ -717,7 +728,9 @@ ChainDB.prototype._writeSync = function _writeSync(data, offset) {
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error('_writeSync() failed.');
|
fs.fsyncSync(this.fd);
|
||||||
|
|
||||||
|
throw this._ioError('_writeSync', size, offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
ChainDB.prototype._writeAsync = function _writeAsync(data, offset, callback) {
|
ChainDB.prototype._writeAsync = function _writeAsync(data, offset, callback) {
|
||||||
@ -747,14 +760,23 @@ ChainDB.prototype._writeAsync = function _writeAsync(data, offset, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!bytes)
|
if (!bytes)
|
||||||
return callback(new Error('_writeAsync() failed.'));
|
return callback(self._ioError('_writeAsync', size, offset));
|
||||||
|
|
||||||
index += bytes;
|
index += bytes;
|
||||||
size -= bytes;
|
size -= bytes;
|
||||||
offset += bytes;
|
offset += bytes;
|
||||||
|
|
||||||
if (index === data.length)
|
if (index === data.length) {
|
||||||
return callback(null, true);
|
// Don't fsync when we're
|
||||||
|
// potentially preloading headers.
|
||||||
|
if (!self.chain.loaded)
|
||||||
|
return callback(null, true);
|
||||||
|
return fs.fsync(self.fd, function(err) {
|
||||||
|
if (err)
|
||||||
|
return callback(err);
|
||||||
|
return callback(null, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user