start and stop services

This commit is contained in:
Patrick Nagurny 2015-08-20 17:50:14 -04:00
parent a65a097e8a
commit a61e1d9b8f
7 changed files with 156 additions and 68 deletions

View File

@ -141,3 +141,33 @@ node.chain.on('addblock', function(block) {
}, 10000); }, 10000);
} }
}); });
process.stdin.resume();//so the program will not close instantly
function exitHandler(options, err) {
if (err) {
log.error('uncaught exception:', err);
if(err.stack) {
console.log(err.stack);
}
process.exit(-1);
}
if (options.sigint) {
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);
});
}
}
//catches ctrl+c event
process.on('SIGINT', exitHandler.bind(null, {sigint:true}));
//catches uncaught exceptions
process.on('uncaughtException', exitHandler.bind(null, {exit:true}));

View File

@ -50,6 +50,15 @@ function Chain(options) {
util.inherits(Chain, BaseChain); util.inherits(Chain, BaseChain);
Chain.prototype.start = function(callback) {
this.on('initialized', callback);
this.initialize();
};
Chain.prototype.stop = function(callback) {
setImmediate(callback);
};
Chain.prototype._writeBlock = function(block, callback) { Chain.prototype._writeBlock = function(block, callback) {
// Update hashes // Update hashes
this.cache.hashes[block.hash] = block.prevHash; this.cache.hashes[block.hash] = block.prevHash;

View File

@ -35,7 +35,7 @@ function Daemon(options) {
this.on('newListener', function(name) { this.on('newListener', function(name) {
if (name === 'open') { if (name === 'open') {
self.start(); //self.start();
} }
}); });
} }
@ -67,22 +67,9 @@ Daemon.prototype.__defineGetter__('global', function() {
return Daemon.global; return Daemon.global;
}); });
Daemon.prototype.start = function(options, callback) { Daemon.prototype.start = function(callback) {
var self = this; var self = this;
if (!callback) {
callback = options;
options = null;
}
if (!options) {
options = {};
}
if (!callback) {
callback = function() {};
}
if (this.instances[this.datadir]) { if (this.instances[this.datadir]) {
return; return;
} }
@ -97,12 +84,12 @@ Daemon.prototype.start = function(options, callback) {
var errorCaught = none; var errorCaught = none;
Object.keys(this.options).forEach(function(key) { Object.keys(this.options).forEach(function(key) {
if (options[key] == null) { if (self.options[key] == null) {
options[key] = self.options[key]; self.options[key] = self.options[key];
} }
}); });
bitcoind.start(options, function(err, status) { bitcoind.start(this.options, function(err, status) {
self._started = true; self._started = true;
// Poll for queued packet // Poll for queued packet
@ -179,23 +166,12 @@ Daemon.prototype.start = function(options, callback) {
}); });
setTimeout(function callee() { setTimeout(function callee() {
// Wait until wallet is loaded:
if (callback) {
callback(err ? err : null);
}
if (err) { if (err) {
self.emit('error', err); self.emit('error', err);
callback(err);
} else { } else {
if (callback) {
self.emit('open', status); self.emit('open', status);
} else { callback();
self.emit('status', status);
}
}
if (callback) {
callback = null;
} }
}, 100); }, 100);
}); });

View File

@ -40,7 +40,7 @@ function DB(options) {
util.inherits(DB, BaseDB); util.inherits(DB, BaseDB);
DB.prototype.initialize = function() { DB.prototype.start = function(callback) {
// Add all db option modules // Add all db option modules
if(this._modules && this._modules.length) { if(this._modules && this._modules.length) {
for(var i = 0; i < this._modules.length; i++) { for(var i = 0; i < this._modules.length; i++) {
@ -49,7 +49,12 @@ DB.prototype.initialize = function() {
} }
this.bitcoind.on('tx', this.transactionHandler.bind(this)); this.bitcoind.on('tx', this.transactionHandler.bind(this));
this.emit('ready'); this.emit('ready');
} callback();
};
DB.prototype.stop = function(callback) {
this.store.close(callback);
};
DB.prototype.getBlock = function(hash, callback) { DB.prototype.getBlock = function(hash, callback) {
var self = this; var self = this;

View File

@ -45,4 +45,12 @@ Module.prototype.getAPIMethods = function() {
// //
// }; // };
Module.prototype.start = function() {
};
Module.prototype.stop = function() {
};
module.exports = Module; module.exports = Module;

View File

@ -25,6 +25,12 @@ function Node(config) {
util.inherits(Node, BaseNode); util.inherits(Node, BaseNode);
var defaultServices = {
'bitcoind': [],
'db': ['bitcoind'],
'chain': ['db'],
};
Node.prototype.openBus = function() { Node.prototype.openBus = function() {
return new Bus({db: this.db}); return new Bus({db: this.db});
}; };
@ -372,15 +378,23 @@ Node.prototype._loadConsensus = function(config) {
this.chain = new Chain(config.consensus); this.chain = new Chain(config.consensus);
}; };
Node.prototype._initializeBitcoind = function() { Node.prototype._initialize = function() {
var self = this; var self = this;
// DB References
this.db.chain = this.chain;
this.db.Block = this.Block;
this.db.bitcoind = this.bitcoind;
// Chain References
this.chain.db = this.db;
// Bitcoind
this.bitcoind.on('ready', function(status) { this.bitcoind.on('ready', function(status) {
log.info('Bitcoin Daemon Ready'); log.info('Bitcoin Daemon Ready');
// Set the current chain height // Set the current chain height
var info = self.bitcoind.getInfo(); var info = self.bitcoind.getInfo();
self.bitcoindHeight = info.blocks; self.bitcoindHeight = info.blocks;
self.db.initialize();
}); });
this.bitcoind.on('open', function(status) { this.bitcoind.on('open', function(status) {
@ -400,27 +414,6 @@ Node.prototype._initializeBitcoind = function() {
self.emit('error', err); self.emit('error', err);
}); });
};
Node.prototype._initializeDatabase = function() {
var self = this;
// Database
this.db.on('ready', function() {
log.info('Bitcoin Database Ready');
self.chain.initialize();
});
this.db.on('error', function(err) {
Error.captureStackTrace(err);
self.emit('error', err);
});
};
Node.prototype._initializeChain = function() {
var self = this;
// Chain // Chain
this.chain.on('ready', function() { this.chain.on('ready', function() {
log.info('Bitcoin Chain Ready'); log.info('Bitcoin Chain Ready');
@ -432,23 +425,74 @@ Node.prototype._initializeChain = function() {
Error.captureStackTrace(err); Error.captureStackTrace(err);
self.emit('error', err); self.emit('error', err);
}); });
// Database
this.db.on('ready', function() {
log.info('Bitcoin Database Ready');
});
this.db.on('error', function(err) {
Error.captureStackTrace(err);
self.emit('error', err);
});
this.start(function(err) {
if(err) {
log.error('Failed starting services: ' + err);
}
});
}; };
Node.prototype._initialize = function() { Node.prototype.getServiceOrder = function(services, keys, stack) {
if(!services) {
services = defaultServices;
}
// DB References if(!keys) {
this.db.chain = this.chain; keys = Object.keys(services);
this.db.Block = this.Block; }
this.db.bitcoind = this.bitcoind;
// Chain References if(!stack) {
this.chain.db = this.db; stack = [];
}
// Setup Chain of Events for(var i = 0; i < keys.length; i++) {
this._initializeBitcoind(); this.getServiceOrder(services, services[keys[i]], stack);
this._initializeDatabase(); if(stack.indexOf(keys[i]) === -1) {
this._initializeChain(); stack.push(keys[i]);
}
}
return stack;
}; };
Node.prototype.start = function(callback) {
var self = this;
var services = this.getServiceOrder();
async.eachSeries(
services,
function(service, next) {
log.info('Starting ' + service);
self[service].start(next);
},
callback
);
};
Node.prototype.stop = function(callback) {
var self = this;
var services = this.getServiceOrder().reverse();
async.eachSeries(
services,
function(service, next) {
log.info('Stopping ' + service);
self[service].stop(next);
},
callback
);
};
module.exports = Node; module.exports = Node;

View File

@ -533,4 +533,20 @@ describe('Bitcoind Node', function() {
}); });
}); });
describe('#getServiceOrder', function() {
var services = {
'chain': ['db'],
'db': ['daemon', 'p2p'],
'daemon': [],
'p2p': []
};
it('should return the services in the correct order', function() {
var node = new Node({});
var order = node.getServiceOrder(services);
order.should.deep.equal(['daemon', 'p2p', 'db', 'chain']);
});
});
}); });