From c5b11ae6c79a9a7d06f1e5f8f21c7cb694586054 Mon Sep 17 00:00:00 2001 From: emizzle Date: Thu, 21 Mar 2019 18:00:10 +1100 Subject: [PATCH] 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 --- .../src/lib/modules/codeRunner/index.ts | 3 +- packages/embark/src/lib/modules/ipfs/index.js | 57 +++++++++---------- .../embark/src/lib/modules/storage/index.js | 4 +- .../embark/src/lib/modules/swarm/index.js | 56 +++++++++--------- packages/embarkjs/src/storage.js | 2 +- 5 files changed, 60 insertions(+), 62 deletions(-) diff --git a/packages/embark/src/lib/modules/codeRunner/index.ts b/packages/embark/src/lib/modules/codeRunner/index.ts index 0dec78bbf..87069fd6e 100644 --- a/packages/embark/src/lib/modules/codeRunner/index.ts +++ b/packages/embark/src/lib/modules/codeRunner/index.ts @@ -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); diff --git a/packages/embark/src/lib/modules/ipfs/index.js b/packages/embark/src/lib/modules/ipfs/index.js index 6476ff597..b371a7434 100644 --- a/packages/embark/src/lib/modules/ipfs/index.js +++ b/packages/embark/src/lib/modules/ipfs/index.js @@ -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() { diff --git a/packages/embark/src/lib/modules/storage/index.js b/packages/embark/src/lib/modules/storage/index.js index b7de558ab..190e6b7aa 100644 --- a/packages/embark/src/lib/modules/storage/index.js +++ b/packages/embark/src/lib/modules/storage/index.js @@ -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(); + }); }); } diff --git a/packages/embark/src/lib/modules/swarm/index.js b/packages/embark/src/lib/modules/swarm/index.js index 23ff6a840..0ca9dd537 100644 --- a/packages/embark/src/lib/modules/swarm/index.js +++ b/packages/embark/src/lib/modules/swarm/index.js @@ -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() { diff --git a/packages/embarkjs/src/storage.js b/packages/embarkjs/src/storage.js index f2aaeb296..f8dcd1922 100644 --- a/packages/embarkjs/src/storage.js +++ b/packages/embarkjs/src/storage.js @@ -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(); };