From 3dcc339e4dbbe0f66818db4360857bc97c4cc521 Mon Sep 17 00:00:00 2001 From: emizzle Date: Fri, 3 May 2019 17:43:21 +1000 Subject: [PATCH] feat(@embark/storage): Add command `service swarm on/off` Add support for ability to start and stop Swarm via command `service swarm on/off`. Fix issue with swarm not starting due to missing web3 object. `service swarm on` - starts a swarm node if not already started. Shows an error if the node is already starting or started. `service swarm off` - kills the running swarm node as long as Embark has started the swarm process. If the swarm process was started externally, an error is shown. --- .../embark/src/lib/modules/storage/index.js | 2 +- .../embark/src/lib/modules/swarm/index.js | 69 +++++++++++++++---- .../embark/src/lib/modules/swarm/process.js | 1 + packages/embarkjs-swarm/src/index.js | 9 ++- packages/embarkjs/src/storage.js | 3 +- 5 files changed, 65 insertions(+), 19 deletions(-) diff --git a/packages/embark/src/lib/modules/storage/index.js b/packages/embark/src/lib/modules/storage/index.js index 190e6b7aa..36b1dc624 100644 --- a/packages/embark/src/lib/modules/storage/index.js +++ b/packages/embark/src/lib/modules/storage/index.js @@ -41,7 +41,7 @@ class Storage { } addSetProviders(cb) { - let code = `\nEmbarkJS.Storage.setProviders(${JSON.stringify(this.storageConfig.dappConnection || [])});`; + let code = `\nEmbarkJS.Storage.setProviders(${JSON.stringify(this.storageConfig.dappConnection || [])}, {web3});`; let shouldInit = (storageConfig) => { return storageConfig.enabled; diff --git a/packages/embark/src/lib/modules/swarm/index.js b/packages/embark/src/lib/modules/swarm/index.js index 50d9cb268..4e72a7f04 100644 --- a/packages/embark/src/lib/modules/swarm/index.js +++ b/packages/embark/src/lib/modules/swarm/index.js @@ -17,6 +17,11 @@ class Swarm { this.port = this.storageConfig.port; this.embark = embark; this.fs = embark.fs; + this.isServiceRegistered = false; + this.addedToEmbarkJs = false; + this.addedToConsole = false; + this.storageProcessesLauncher = null; + this.usingRunningNode = false; this.webServerConfig = embark.config.webServerConfig; this.blockchainConfig = embark.config.blockchainConfig; @@ -49,18 +54,44 @@ class Swarm { this.registerUploadCommand(); this.listenToCommands(); this.registerConsoleCommands(); - this.startProcess((err, newProcessStarted) => { - this.addProviderToEmbarkJS(); - this.addObjectToConsole(); - this.events.emit("swarm:process:started", err, newProcessStarted); + this.events.request("processes:register", "swarm", { + launchFn: (cb) => { + if(this.usingRunningNode) { + return cb(__("Swarm process is running in a separate process and cannot be started by Embark.")); + } + this.startProcess((err, newProcessStarted) => { + this.addProviderToEmbarkJS(); + this.addObjectToConsole(); + this.events.emit("swarm:process:started", err, newProcessStarted); + cb(); + }); + }, + stopFn: (cb) => { + if(this.usingRunningNode) { + return cb(__("Swarm process is running in a separate process and cannot be stopped by Embark.")); + } + this.stopProcess(cb); + } + }); + this.events.request("processes:launch", "swarm", (err, msg) => { + if (err) { + return this.logger.error(err); + } + if (msg) { + this.logger.info(msg); + } }); } addObjectToConsole() { + if (this.addedToConsole) return; + this.addedToConsole = true; this.events.emit("runcode:register", "swarm", this.swarm); } setServiceCheck() { + if (this.isServiceRegistered) return; + this.isServiceRegistered = true; let self = this; this.events.on('check:backOnline:Swarm', function () { @@ -89,6 +120,8 @@ class Swarm { } addProviderToEmbarkJS() { + if(this.addedToEmbarkJs) return; + this.addedToEmbarkJs = true; let code = ""; code += "\nconst __embarkSwarm = require('embarkjs-swarm')"; code += "\nEmbarkJS.Storage.registerProvider('swarm', __embarkSwarm.default || __embarkSwarm);"; @@ -99,27 +132,35 @@ class Swarm { startProcess(callback) { this.swarm.isAvailable((err, isAvailable) => { if (!err || isAvailable) { + this.usingRunningNode = true; 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 - }); + if(this.storageProcessesLauncher === null) { + this.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) => { + return this.storageProcessesLauncher.launchProcess('swarm', (err) => { callback(err, true); }); }); } + stopProcess(cb) { + if(!this.storageProcessesLauncher) return cb(); + this.storageProcessesLauncher.stopProcess("swarm", cb); + } + registerUploadCommand() { const self = this; this.embark.registerUploadCommand('swarm', (cb) => { diff --git a/packages/embark/src/lib/modules/swarm/process.js b/packages/embark/src/lib/modules/swarm/process.js index 0df6e705e..8a3ed535f 100644 --- a/packages/embark/src/lib/modules/swarm/process.js +++ b/packages/embark/src/lib/modules/swarm/process.js @@ -78,6 +78,7 @@ class SwarmProcess extends ProcessWrapper { kill() { if (this.child) { this.child.kill(); + swarmProcess.send({result: constants.storage.exit}); } } } diff --git a/packages/embarkjs-swarm/src/index.js b/packages/embarkjs-swarm/src/index.js index 61bdd2a30..146667bf6 100644 --- a/packages/embarkjs-swarm/src/index.js +++ b/packages/embarkjs-swarm/src/index.js @@ -1,4 +1,3 @@ -/*global web3 */ let __embarkSwarm = {_swarmConnection: undefined}; let SwarmAPI = require('swarm-api'); if (SwarmAPI.default) { @@ -14,11 +13,15 @@ __embarkSwarm.setProvider = function (options) { this._connectError = new Error(`Cannot connect to Swarm node on ${this._connectUrl}`); return new Promise((resolve, reject) => { + if(!options.web3) { + reject(__("A web3 object must be passed in to __embarkSwarm.setProvider")); + } + const {web3, useOnlyGivenProvider} = options; try { - if (!web3.bzz.currentProvider && !options.useOnlyGivenProvider) { + if (!web3.bzz.currentProvider && !useOnlyGivenProvider) { this._swarmConnection = new SwarmAPI({gateway: this._connectUrl}); } - else if (options.useOnlyGivenProvider && web3.bzz.givenProvider !== null) { + else if (useOnlyGivenProvider && web3.bzz.givenProvider !== null) { this._swarmConnection = new SwarmAPI({gateway: web3.bzz.givenProvider}); } resolve(this); diff --git a/packages/embarkjs/src/storage.js b/packages/embarkjs/src/storage.js index f8dcd1922..8f436f0b1 100644 --- a/packages/embarkjs/src/storage.js +++ b/packages/embarkjs/src/storage.js @@ -72,11 +72,12 @@ Storage.isAvailable = function () { }; // TODO: most of this logic should move to the provider implementations themselves -Storage.setProviders = function (dappConnOptions) { +Storage.setProviders = function (dappConnOptions, addlOpts) { const self = this; detectSeries(dappConnOptions, (dappConn, callback) => { let options = dappConn; if (dappConn === '$BZZ') options = {"useOnlyGivenProvider": true}; + options = {...options, ...addlOpts}; try { self.setProvider(dappConn === '$BZZ' ? dappConn : dappConn.provider, options).then(() => { self.isAvailable().then((isAvailable) => {