mirror of https://github.com/embarklabs/embark.git
Merge pull request #573 from embark-framework/bug_fix/blockchain-kill-causes-error
Handle geth process exit via crash/kill and also via killing `embark blockchain`
This commit is contained in:
commit
3bea80a820
|
@ -14,6 +14,7 @@ var Blockchain = function(options) {
|
||||||
this.client = options.client;
|
this.client = options.client;
|
||||||
this.isDev = options.isDev;
|
this.isDev = options.isDev;
|
||||||
this.onReadyCallback = options.onReadyCallback;
|
this.onReadyCallback = options.onReadyCallback;
|
||||||
|
this.onExitCallback = options.onExitCallback;
|
||||||
|
|
||||||
if ((this.blockchainConfig === {} || JSON.stringify(this.blockchainConfig) === '{"enabled":true}') && this.env !== 'development') {
|
if ((this.blockchainConfig === {} || JSON.stringify(this.blockchainConfig) === '{"enabled":true}') && this.env !== 'development') {
|
||||||
console.log("===> " + __("warning: running default config on a non-development environment"));
|
console.log("===> " + __("warning: running default config on a non-development environment"));
|
||||||
|
@ -167,8 +168,24 @@ Blockchain.prototype.run = function() {
|
||||||
console.log('Geth: ' + data);
|
console.log('Geth: ' + data);
|
||||||
});
|
});
|
||||||
self.child.on('exit', (code) => {
|
self.child.on('exit', (code) => {
|
||||||
|
let strCode;
|
||||||
if (code) {
|
if (code) {
|
||||||
console.error('Geth exited with error code ' + code);
|
strCode = ' with error code ' + code;
|
||||||
|
} else {
|
||||||
|
strCode = ' with no error code (manually killed?)';
|
||||||
|
}
|
||||||
|
console.error('Geth exited' + strCode);
|
||||||
|
|
||||||
|
if(self.onExitCallback){
|
||||||
|
self.onExitCallback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
self.child.on('uncaughtException', (err) => {
|
||||||
|
console.error('Uncaught geth exception', err);
|
||||||
|
|
||||||
|
if(self.onExitCallback){
|
||||||
|
self.onExitCallback();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -252,10 +269,10 @@ Blockchain.prototype.initChainAndGetAddress = function(callback) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var BlockchainClient = function(blockchainConfig, client, env, isDev, onReadyCallback) {
|
var BlockchainClient = function(blockchainConfig, client, env, isDev, onReadyCallback, onExitCallback) {
|
||||||
// TODO add other clients at some point
|
// TODO add other clients at some point
|
||||||
if (client === 'geth') {
|
if (client === 'geth') {
|
||||||
return new Blockchain({blockchainConfig, client: GethCommands, env, isDev, onReadyCallback});
|
return new Blockchain({blockchainConfig, client: GethCommands, env, isDev, onReadyCallback, onExitCallback});
|
||||||
} else {
|
} else {
|
||||||
throw new Error('unknown client');
|
throw new Error('unknown client');
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,8 @@ class BlockchainProcess extends ProcessWrapper {
|
||||||
this.client,
|
this.client,
|
||||||
this.env,
|
this.env,
|
||||||
this.isDev,
|
this.isDev,
|
||||||
this.blockchainReady.bind(this)
|
this.blockchainReady.bind(this),
|
||||||
|
this.blockchainExit.bind(this)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.blockchain.run();
|
this.blockchain.run();
|
||||||
|
@ -31,6 +32,11 @@ class BlockchainProcess extends ProcessWrapper {
|
||||||
blockchainProcess.send({result: constants.blockchain.blockchainReady});
|
blockchainProcess.send({result: constants.blockchain.blockchainReady});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blockchainExit() {
|
||||||
|
// tell our parent process that geth has exited
|
||||||
|
blockchainProcess.send({result: constants.blockchain.blockchainExit});
|
||||||
|
}
|
||||||
|
|
||||||
kill() {
|
kill() {
|
||||||
this.blockchain.kill();
|
this.blockchain.kill();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
},
|
},
|
||||||
"blockchain": {
|
"blockchain": {
|
||||||
"blockchainReady": "blockchainReady",
|
"blockchainReady": "blockchainReady",
|
||||||
|
"blockchainExit": "blockchainExit",
|
||||||
"init": "init",
|
"init": "init",
|
||||||
"initiated": "initiated",
|
"initiated": "initiated",
|
||||||
"servicePortOnProxy": 10
|
"servicePortOnProxy": 10
|
||||||
|
|
|
@ -48,7 +48,7 @@ class Blockchain {
|
||||||
}
|
}
|
||||||
|
|
||||||
const protocol = (this.contractsConfig.deployment.type === "rpc") ? this.contractsConfig.deployment.protocol : 'ws';
|
const protocol = (this.contractsConfig.deployment.type === "rpc") ? this.contractsConfig.deployment.protocol : 'ws';
|
||||||
let provider;
|
|
||||||
this.web3Endpoint = utils.buildUrl(protocol, this.contractsConfig.deployment.host, this.contractsConfig.deployment.port);//`${protocol}://${this.contractsConfig.deployment.host}:${this.contractsConfig.deployment.port}`;
|
this.web3Endpoint = utils.buildUrl(protocol, this.contractsConfig.deployment.host, this.contractsConfig.deployment.port);//`${protocol}://${this.contractsConfig.deployment.host}:${this.contractsConfig.deployment.port}`;
|
||||||
|
|
||||||
const providerOptions = {
|
const providerOptions = {
|
||||||
|
@ -60,7 +60,7 @@ class Blockchain {
|
||||||
type: this.contractsConfig.deployment.type,
|
type: this.contractsConfig.deployment.type,
|
||||||
web3Endpoint: self.web3Endpoint
|
web3Endpoint: self.web3Endpoint
|
||||||
};
|
};
|
||||||
provider = new Provider(providerOptions);
|
this.provider = new Provider(providerOptions);
|
||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function checkNode(next) {
|
function checkNode(next) {
|
||||||
|
@ -73,21 +73,35 @@ class Blockchain {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
self.isWeb3Ready = true;
|
self.isWeb3Ready = true;
|
||||||
self.events.emit(WEB3_READY);
|
self.events.emit(WEB3_READY);
|
||||||
|
// if the ethereum node goes offline, we need a check to ensure
|
||||||
|
// the provider is also stopped
|
||||||
|
self.events.on('check:wentOffline:Ethereum', () => {
|
||||||
|
self.logger.trace('Ethereum went offline: stopping web3 provider...');
|
||||||
|
self.provider.stop();
|
||||||
|
|
||||||
|
// once the node goes back online, we can restart the provider
|
||||||
|
self.events.once('check:backOnline:Ethereum', () => {
|
||||||
|
self.logger.trace('Ethereum back online: starting web3 provider...');
|
||||||
|
self.provider.startWeb3Provider(() => {
|
||||||
|
self.logger.trace('web3 provider restarted after ethereum node came back online');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
self.web3StartedInProcess = true;
|
self.web3StartedInProcess = true;
|
||||||
self.startBlockchainNode(() => {
|
self.startBlockchainNode(() => {
|
||||||
// Need to re-initialize web3 to connect to the new blockchain node
|
// Need to re-initialize web3 to connect to the new blockchain node
|
||||||
provider.stop();
|
self.provider.stop();
|
||||||
self.initWeb3(cb);
|
self.initWeb3(cb);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function startProvider(next) {
|
function startProvider(next) {
|
||||||
provider.startWeb3Provider(next);
|
self.provider.startWeb3Provider(next);
|
||||||
},
|
},
|
||||||
function fundAccountsIfNeeded(next) {
|
function fundAccountsIfNeeded(next) {
|
||||||
provider.fundAccounts(next);
|
self.provider.fundAccounts(next);
|
||||||
}
|
}
|
||||||
], (err) => {
|
], (err) => {
|
||||||
self.registerWeb3Object();
|
self.registerWeb3Object();
|
||||||
|
@ -120,6 +134,10 @@ class Blockchain {
|
||||||
self.events.once(constants.blockchain.blockchainReady, () => {
|
self.events.once(constants.blockchain.blockchainReady, () => {
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
|
self.events.once(constants.blockchain.blockchainExit, () => {
|
||||||
|
self.provider.stop();
|
||||||
|
callback();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
registerServiceCheck() {
|
registerServiceCheck() {
|
||||||
|
|
|
@ -39,12 +39,16 @@ class Provider {
|
||||||
|
|
||||||
// network connectivity error
|
// network connectivity error
|
||||||
self.engine.on('error', (err) => {
|
self.engine.on('error', (err) => {
|
||||||
// report connectivity errors
|
// report connectivity errors as trace due to polling
|
||||||
self.logger.error(err.stack);
|
self.logger.trace('web3 provider error: ', err);
|
||||||
|
self.logger.trace('stopping web3 provider due to error');
|
||||||
|
|
||||||
|
// prevent continuous polling errors
|
||||||
|
self.engine.stop();
|
||||||
});
|
});
|
||||||
|
|
||||||
self.engine.start();
|
self.engine.start();
|
||||||
self.web3.setProvider(self);
|
self.web3.setProvider(self);
|
||||||
|
|
||||||
self.accounts = AccountParser.parseAccountsConfig(self.accountsConfig, self.web3, self.logger);
|
self.accounts = AccountParser.parseAccountsConfig(self.accountsConfig, self.web3, self.logger);
|
||||||
self.addresses = [];
|
self.addresses = [];
|
||||||
|
|
|
@ -44,6 +44,14 @@ class BlockchainProcessLauncher {
|
||||||
this.events.emit(constants.blockchain.blockchainReady);
|
this.events.emit(constants.blockchain.blockchainReady);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.blockchainProcess.once('result', constants.blockchain.blockchainExit, () => {
|
||||||
|
// telle everyone that our blockchain process (ie geth) died
|
||||||
|
this.events.emit(constants.blockchain.blockchainExit);
|
||||||
|
|
||||||
|
// then kill off the blockchain process
|
||||||
|
this.blockchainProcess.kill();
|
||||||
|
});
|
||||||
|
|
||||||
this.events.on('exit', () => {
|
this.events.on('exit', () => {
|
||||||
this.blockchainProcess.send('exit');
|
this.blockchainProcess.send('exit');
|
||||||
});
|
});
|
||||||
|
|
|
@ -79,7 +79,7 @@
|
||||||
"uuid": "^3.2.1",
|
"uuid": "^3.2.1",
|
||||||
"viz.js": "^1.8.1",
|
"viz.js": "^1.8.1",
|
||||||
"web3": "1.0.0-beta.34",
|
"web3": "1.0.0-beta.34",
|
||||||
"embark-web3-provider-engine": "14.0.6",
|
"embark-web3-provider-engine": "14.0.7",
|
||||||
"webpack": "^3.10.0",
|
"webpack": "^3.10.0",
|
||||||
"window-size": "^1.1.0"
|
"window-size": "^1.1.0"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue