cleanup daemon
This commit is contained in:
parent
a61e1d9b8f
commit
164a2cad75
17
bin/start.js
17
bin/start.js
|
@ -142,6 +142,10 @@ node.chain.on('addblock', function(block) {
|
|||
}
|
||||
});
|
||||
|
||||
node.on('stopping', function() {
|
||||
clearInterval(interval);
|
||||
});
|
||||
|
||||
process.stdin.resume();//so the program will not close instantly
|
||||
|
||||
function exitHandler(options, err) {
|
||||
|
@ -169,5 +173,18 @@ function exitHandler(options, err) {
|
|||
//catches ctrl+c event
|
||||
process.on('SIGINT', exitHandler.bind(null, {sigint:true}));
|
||||
|
||||
/*setTimeout(function() {
|
||||
log.info('Stopping Services');
|
||||
node.stop(function(err) {
|
||||
if(err) {
|
||||
log.error('Failed to stop services: ' + err);
|
||||
return process.exit(1);
|
||||
}
|
||||
|
||||
log.info('Halted');
|
||||
process.exit(0);
|
||||
});
|
||||
}, 10000);*/
|
||||
|
||||
//catches uncaught exceptions
|
||||
process.on('uncaughtException', exitHandler.bind(null, {exit:true}));
|
||||
|
|
167
lib/daemon.js
167
lib/daemon.js
|
@ -33,29 +33,10 @@ function Daemon(options) {
|
|||
self[key] = exports[key];
|
||||
});
|
||||
|
||||
this.on('newListener', function(name) {
|
||||
if (name === 'open') {
|
||||
//self.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
util.inherits(Daemon, EventEmitter);
|
||||
|
||||
// Make sure signal handlers are not overwritten
|
||||
Daemon._signalQueue = [];
|
||||
Daemon._processOn = process.on;
|
||||
process.addListener =
|
||||
process.on = function(name, listener) {
|
||||
if (~['SIGINT', 'SIGHUP', 'SIGQUIT'].indexOf(name.toUpperCase())) {
|
||||
if (!Daemon.global || !Daemon.global._started) {
|
||||
Daemon._signalQueue.push([name, listener]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return Daemon._processOn.apply(this, arguments);
|
||||
};
|
||||
|
||||
Daemon.instances = {};
|
||||
Daemon.prototype.instances = Daemon.instances;
|
||||
|
||||
|
@ -71,77 +52,17 @@ Daemon.prototype.start = function(callback) {
|
|||
var self = this;
|
||||
|
||||
if (this.instances[this.datadir]) {
|
||||
return;
|
||||
return callback(new Error('Daemon already started'));
|
||||
}
|
||||
this.instances[this.datadir] = true;
|
||||
|
||||
var none = {};
|
||||
var isSignal = {};
|
||||
var sigint = { name: 'SIGINT', signal: isSignal };
|
||||
var sighup = { name: 'SIGHUP', signal: isSignal };
|
||||
var sigquit = { name: 'SIGQUIT', signal: isSignal };
|
||||
var exitCaught = none;
|
||||
var errorCaught = none;
|
||||
|
||||
Object.keys(this.options).forEach(function(key) {
|
||||
if (self.options[key] == null) {
|
||||
self.options[key] = self.options[key];
|
||||
bitcoind.start(this.options, function(err) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
});
|
||||
|
||||
bitcoind.start(this.options, function(err, status) {
|
||||
self._started = true;
|
||||
|
||||
// Poll for queued packet
|
||||
[sigint, sighup, sigquit].forEach(function(signal) {
|
||||
process.on(signal.name, signal.listener = function() {
|
||||
if (process.listeners(signal.name).length > 1) {
|
||||
return;
|
||||
}
|
||||
if (!self._shutdown) {
|
||||
process.exit(0);
|
||||
} else {
|
||||
self.stop();
|
||||
exitCaught = signal;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Finally set signal handlers
|
||||
process.on = process.addListener = Daemon._processOn;
|
||||
Daemon._signalQueue.forEach(function(event) {
|
||||
process.on(event[0], event[1]);
|
||||
});
|
||||
|
||||
var exit = process.exit;
|
||||
self._exit = function() {
|
||||
return exit.apply(process, arguments);
|
||||
};
|
||||
|
||||
process.exit = function(code) {
|
||||
exitCaught = code || 0;
|
||||
if (!self._shutdown) {
|
||||
return self._exit(code);
|
||||
}
|
||||
self.stop();
|
||||
};
|
||||
|
||||
process.on('uncaughtException', function(err) {
|
||||
if (process.listeners('uncaughtException').length > 1) {
|
||||
return;
|
||||
}
|
||||
errorCaught = err;
|
||||
log.error('Uncaught error: shutting down safely before throwing...');
|
||||
if (!self._shutdown) {
|
||||
if (err && err.stack) {
|
||||
log.error(err.stack);
|
||||
}
|
||||
self._exit(1);
|
||||
return;
|
||||
}
|
||||
self.stop();
|
||||
});
|
||||
|
||||
bitcoind.onBlocksReady(function(err, result) {
|
||||
|
||||
function onTipUpdateListener(result) {
|
||||
|
@ -155,58 +76,18 @@ Daemon.prototype.start = function(callback) {
|
|||
|
||||
bitcoind.onTipUpdate(onTipUpdateListener);
|
||||
|
||||
self.emit('ready', result);
|
||||
|
||||
bitcoind.startTxMon(function(txs) {
|
||||
for(var i = 0; i < txs.length; i++) {
|
||||
self.emit('tx', txs[i]);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
setTimeout(function callee() {
|
||||
if (err) {
|
||||
self.emit('error', err);
|
||||
callback(err);
|
||||
} else {
|
||||
self.emit('open', status);
|
||||
setImmediate(function() {
|
||||
self.emit('ready', result);
|
||||
callback();
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// bitcoind's boost threads aren't in the thread pool
|
||||
// or on node's event loop, so we need to keep node open.
|
||||
this._shutdown = setInterval(function() {
|
||||
if (!self._stoppingSaid && bitcoind.stopping()) {
|
||||
self._stoppingSaid = true;
|
||||
}
|
||||
|
||||
if (bitcoind.stopped()) {
|
||||
|
||||
clearInterval(self._shutdown);
|
||||
delete self._shutdown;
|
||||
|
||||
if (exitCaught !== none) {
|
||||
if (exitCaught.signal === isSignal) {
|
||||
process.removeListener(exitCaught.name, exitCaught.listener);
|
||||
setImmediate(function() {
|
||||
process.kill(process.pid, exitCaught.name);
|
||||
});
|
||||
return;
|
||||
}
|
||||
return self._exit(exitCaught);
|
||||
}
|
||||
|
||||
if (errorCaught !== none) {
|
||||
if (errorCaught && errorCaught.stack) {
|
||||
log.error(errorCaught.stack);
|
||||
}
|
||||
return self._exit(0);
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
Daemon.prototype.isSynced = function() {
|
||||
|
@ -258,33 +139,17 @@ Daemon.prototype.getInfo = function() {
|
|||
};
|
||||
|
||||
Daemon.prototype.stop = function(callback) {
|
||||
if (Daemon.stopping) return [];
|
||||
var self = this;
|
||||
return bitcoind.stop(function(err, status) {
|
||||
if (err) {
|
||||
self.error(err.message);
|
||||
} else {
|
||||
log.info(status);
|
||||
}
|
||||
if (!callback) return;
|
||||
return callback(err, status);
|
||||
setImmediate(function() {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
} else {
|
||||
log.info(status);
|
||||
return callback();
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Daemon.prototype.__defineGetter__('stopping', function() {
|
||||
return bitcoind.stopping() || bitcoind.stopped();
|
||||
});
|
||||
|
||||
Daemon.prototype.__defineGetter__('stopped', function() {
|
||||
return bitcoind.stopped();
|
||||
});
|
||||
|
||||
Daemon.__defineGetter__('stopping', function() {
|
||||
return bitcoind.stopping() || bitcoind.stopped();
|
||||
});
|
||||
|
||||
Daemon.__defineGetter__('stopped', function() {
|
||||
return bitcoind.stopped();
|
||||
});
|
||||
|
||||
module.exports = Daemon;
|
||||
|
|
15
lib/node.js
15
lib/node.js
|
@ -236,12 +236,13 @@ Node.prototype._syncBitcoind = function() {
|
|||
|
||||
async.whilst(function() {
|
||||
height = self.chain.tip.__height;
|
||||
return height < self.bitcoindHeight;
|
||||
return height < self.bitcoindHeight && !self.stopping;
|
||||
}, function(done) {
|
||||
self.bitcoind.getBlock(height + 1, function(err, blockBuffer) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
var block = self.Block.fromBuffer(blockBuffer);
|
||||
if (block.prevHash === self.chain.tip.hash) {
|
||||
|
||||
|
@ -259,17 +260,17 @@ Node.prototype._syncBitcoind = function() {
|
|||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
delete self.chain.tip.__transactions;
|
||||
self.chain.tip = block;
|
||||
log.debug('Saving metadata');
|
||||
self.chain.saveMetadata();
|
||||
log.debug('Chain added block to main chain');
|
||||
self.chain.emit('addblock', block);
|
||||
done();
|
||||
setImmediate(done);
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
// This block doesn't progress the current tip, so we'll attempt
|
||||
// to rewind the chain to the common ancestor of the block and
|
||||
// then we can resume syncing.
|
||||
|
@ -397,10 +398,6 @@ Node.prototype._initialize = function() {
|
|||
self.bitcoindHeight = info.blocks;
|
||||
});
|
||||
|
||||
this.bitcoind.on('open', function(status) {
|
||||
log.info('Bitcoin Core Daemon Status:', status);
|
||||
});
|
||||
|
||||
// Notify that there is a new tip
|
||||
this.bitcoind.on('tip', function(height) {
|
||||
var percentage = self.bitcoind.syncPercentage();
|
||||
|
@ -481,9 +478,13 @@ Node.prototype.start = function(callback) {
|
|||
};
|
||||
|
||||
Node.prototype.stop = function(callback) {
|
||||
log.info('Stopping Bitcore Node');
|
||||
var self = this;
|
||||
var services = this.getServiceOrder().reverse();
|
||||
|
||||
this.stopping = true;
|
||||
this.emit('stopping');
|
||||
|
||||
async.eachSeries(
|
||||
services,
|
||||
function(service, next) {
|
||||
|
|
|
@ -885,30 +885,6 @@ async_stop_node_after(uv_work_t *req) {
|
|||
delete req;
|
||||
}
|
||||
|
||||
/**
|
||||
* IsStopping()
|
||||
* bitcoind.stopping()
|
||||
* Check whether bitcoind is in the process of shutting down. This is polled
|
||||
* from javascript.
|
||||
*/
|
||||
|
||||
NAN_METHOD(IsStopping) {
|
||||
NanScope();
|
||||
NanReturnValue(NanNew<Boolean>(ShutdownRequested()));
|
||||
}
|
||||
|
||||
/**
|
||||
* IsStopped()
|
||||
* bitcoind.stopped()
|
||||
* Check whether bitcoind has shutdown completely. This will be polled by
|
||||
* javascript to check whether the libuv event loop is safe to stop.
|
||||
*/
|
||||
|
||||
NAN_METHOD(IsStopped) {
|
||||
NanScope();
|
||||
NanReturnValue(NanNew<Boolean>(shutdown_complete));
|
||||
}
|
||||
|
||||
/**
|
||||
* GetBlock()
|
||||
* bitcoind.getBlock([blockhash,blockheight], callback)
|
||||
|
@ -1650,8 +1626,6 @@ init(Handle<Object> target) {
|
|||
NODE_SET_METHOD(target, "onBlocksReady", OnBlocksReady);
|
||||
NODE_SET_METHOD(target, "onTipUpdate", OnTipUpdate);
|
||||
NODE_SET_METHOD(target, "stop", StopBitcoind);
|
||||
NODE_SET_METHOD(target, "stopping", IsStopping);
|
||||
NODE_SET_METHOD(target, "stopped", IsStopped);
|
||||
NODE_SET_METHOD(target, "getBlock", GetBlock);
|
||||
NODE_SET_METHOD(target, "getTransaction", GetTransaction);
|
||||
NODE_SET_METHOD(target, "getTransactionWithBlockInfo", GetTransactionWithBlockInfo);
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
NAN_METHOD(StartBitcoind);
|
||||
NAN_METHOD(OnBlocksReady);
|
||||
NAN_METHOD(OnTipUpdate);
|
||||
NAN_METHOD(IsStopping);
|
||||
NAN_METHOD(IsStopped);
|
||||
NAN_METHOD(StopBitcoind);
|
||||
NAN_METHOD(GetBlock);
|
||||
NAN_METHOD(GetTransaction);
|
||||
|
|
Loading…
Reference in New Issue