fix(@embark/storage): Fix hang when IPFS/Swarm started externally

Fix hang when the storage provider (IPFS or Swarm) was started externally before running Embark.

If IPFS/Swarm was already running before `embark run` was run, then the relevant `registerProvider` and `setProvider` code was not being run through the console, and thus the module init event was never fired, preventing the DApp from being built.

This PR refactors the way the IPFS/Swarm process is launched so that the `registerProvider` and `setProvider` code snippets are run through the console in the case of:
* IPFS/Swarm running externally from Embark
* IPFS/Swarm started in a child process by Embark
* Storage is disabled in the DApp config
This commit is contained in:
emizzle 2019-03-21 18:00:10 +11:00 committed by Iuri Matias
parent d0d89fc5ae
commit c5b11ae6c7
5 changed files with 60 additions and 62 deletions

View File

@ -40,9 +40,8 @@ class CodeRunner {
private generateListener(provider: string, eventType: ProviderEventType) {
const providerStateName = `${provider}:${eventType}`;
const eventName = `runcode:${providerStateName}`;
this.providerStates[`${provider}:${eventType}`] = false;
this.events.setCommandHandler(eventName, (cb) => {
if (this.providerStates[providerStateName]) {
if (this.providerStates[providerStateName] === true) {
return cb();
}
this.events.once(eventName, cb);

View File

@ -21,29 +21,17 @@ class IPFS {
this.blockchainConfig = embark.config.blockchainConfig;
if (!this.isIpfsStorageEnabledInTheConfig()) {
return this.events.emit("ipfs:process:started", false);
return this.events.emit("ipfs:process:started", null, false);
}
this.setServiceCheck();
this.registerUploadCommand();
this.events.request("processes:register", "ipfs", (cb) => {
this.startProcess(() => {
this.addStorageProviderToEmbarkJS();
this.addObjectToConsole();
this.events.emit("ipfs:process:started");
cb();
});
});
this._checkService((err) => {
if (!err) {
return;
}
this.logger.info("IPFS node not found, attempting to start own node");
this.listenToCommands();
this.registerConsoleCommands();
this.events.request('processes:launch', 'ipfs');
this.listenToCommands();
this.registerConsoleCommands();
this.startProcess((err, newProcessStarted) => {
this.addStorageProviderToEmbarkJS();
this.addObjectToConsole();
this.events.emit("ipfs:process:started", err, newProcessStarted);
});
}
@ -142,18 +130,27 @@ class IPFS {
}
startProcess(callback) {
let self = this;
const storageProcessesLauncher = new StorageProcessesLauncher({
logger: self.logger,
events: self.events,
storageConfig: self.storageConfig,
webServerConfig: self.webServerConfig,
blockchainConfig: self.blockchainConfig,
corsParts: self.embark.config.corsParts,
embark: self.embark
this._checkService((err) => {
if (!err) {
this.logger.info("IPFS node found, using currently running node");
return callback(null, false);
}
this.logger.info("IPFS node not found, attempting to start own node");
let self = this;
const storageProcessesLauncher = new StorageProcessesLauncher({
logger: self.logger,
events: self.events,
storageConfig: self.storageConfig,
webServerConfig: self.webServerConfig,
blockchainConfig: self.blockchainConfig,
corsParts: self.embark.config.corsParts,
embark: self.embark
});
self.logger.trace(`Storage module: Launching ipfs process...`);
return storageProcessesLauncher.launchProcess('ipfs', (err) => {
callback(err, true);
});
});
self.logger.trace(`Storage module: Launching ipfs process...`);
return storageProcessesLauncher.launchProcess('ipfs', callback);
}
registerUploadCommand() {

View File

@ -50,7 +50,9 @@ class Storage {
this.embark.addProviderInit('storage', code, shouldInit);
this.embark.events.request("runcode:storage:providerRegistered", () => {
this.embark.addConsoleProviderInit('storage', code, shouldInit);
cb();
this.embark.events.request("runcode:storage:providerSet", () => {
cb();
});
});
}

View File

@ -26,7 +26,7 @@ class Swarm {
if (this.isSwarmEnabledInTheConfig() && cantDetermineUrl) {
console.warn('\n===== Swarm module will not be loaded =====');
console.warn(`Swarm is enabled in the config, however the config is not setup to provide a URL for swarm and therefore the Swarm module will not be loaded. Please either change the ${'config/storage > upload'.bold} setting to Swarm or add the Swarm config to the ${'config/storage > dappConnection'.bold} array. Please see ${'https://embark.status.im/docs/storage_configuration.html'.underline} for more information.\n`);
return this.events.emit("swarm:process:started", false);
return this.events.emit("swarm:process:started", null, false);
}
if (!this.isSwarmEnabledInTheConfig()) {
this.embark.registerConsoleCommand({
@ -36,7 +36,7 @@ class Swarm {
cb();
}
});
return this.events.emit("swarm:process:started", false);
return this.events.emit("swarm:process:started", null, false);
}
this.providerUrl = utils.buildUrl(this.storageConfig.upload.protocol, this.storageConfig.upload.host, this.storageConfig.upload.port);
@ -47,21 +47,12 @@ class Swarm {
this.setServiceCheck();
this.registerUploadCommand();
// swarm needs geth to be running first
this.swarm.isAvailable((err, isAvailable) => {
if (!err || isAvailable) {
this.logger.info("Swarm node found, using currently running node");
return;
}
this.logger.info("SWARM: Swarm node not found, attempting to start own node");
this.listenToCommands();
this.registerConsoleCommands();
return this.startProcess(() => {
this.addProviderToEmbarkJS();
this.addObjectToConsole();
this.events.emit("swarm:process:started");
});
this.listenToCommands();
this.registerConsoleCommands();
this.startProcess((err, newProcessStarted) => {
this.addProviderToEmbarkJS();
this.addObjectToConsole();
this.events.emit("swarm:process:started", err, newProcessStarted);
});
}
@ -106,18 +97,27 @@ class Swarm {
}
startProcess(callback) {
let self = this;
const storageProcessesLauncher = new StorageProcessesLauncher({
logger: self.logger,
events: self.events,
storageConfig: self.storageConfig,
webServerConfig: self.webServerConfig,
corsParts: self.embark.config.corsParts,
blockchainConfig: self.blockchainConfig,
embark: self.embark
this.swarm.isAvailable((err, isAvailable) => {
if (!err || isAvailable) {
this.logger.info("Swarm node found, using currently running node");
return callback(null, false);
}
this.logger.info("Swarm node not found, attempting to start own node");
let self = this;
const storageProcessesLauncher = new StorageProcessesLauncher({
logger: self.logger,
events: self.events,
storageConfig: self.storageConfig,
webServerConfig: self.webServerConfig,
corsParts: self.embark.config.corsParts,
blockchainConfig: self.blockchainConfig,
embark: self.embark
});
self.logger.trace(`Storage module: Launching swarm process...`);
return storageProcessesLauncher.launchProcess('swarm', (err) => {
callback(err, true);
});
});
self.logger.trace(`Storage module: Launching swarm process...`);
return storageProcessesLauncher.launchProcess('swarm', callback);
}
registerUploadCommand() {

View File

@ -66,7 +66,7 @@ Storage.setProvider = function (providerName, options) {
Storage.isAvailable = function () {
if (!this.currentStorage) {
return false;
return Promise.resolve(false);
}
return this.currentStorage.isAvailable();
};