From c0e559a7d9bdc1fdc4d29a5a0c90d5012a7c88a4 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Mon, 4 Jun 2018 18:15:27 -0400 Subject: [PATCH] assign roles so ipc connections don't conflict; fallback if can't connect to ipc --- lib/core/engine.js | 2 +- lib/core/ipc.js | 28 +++++++++++++++++++++++++++- lib/modules/solidity/solcW.js | 27 +++++++++++++++++++-------- lib/tests/test.js | 2 +- 4 files changed, 48 insertions(+), 11 deletions(-) diff --git a/lib/core/engine.js b/lib/core/engine.js index f31d770d6..13f1c0705 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -183,7 +183,7 @@ class Engine { compiler.compile_contracts(contractFiles, cb); }); - this.ipc = new IPC({logger: this.logger}); + this.ipc = new IPC({logger: this.logger, ipcRole: options.ipcRole}); this.registerModule('solidity', {useIpc: options.useIpc, ipc: this.ipc}); this.registerModule('vyper'); this.registerModule('profiler'); diff --git a/lib/core/ipc.js b/lib/core/ipc.js index 00930f43a..9bae112e2 100644 --- a/lib/core/ipc.js +++ b/lib/core/ipc.js @@ -6,13 +6,31 @@ class IPC { constructor(options) { this.logger = options.logger; this.socketPath = options.socketPath || fs.dappPath(".embark/embark.ipc"); + this.ipcRole = options.ipcRole || "server"; ipc.config.silent = true; + this.connected = false; } connect(done) { + const self = this; function connecting(socket) { + let connectedBefore = false, alreadyDisconnected = false;; ipc.of['embark'].on('connect',function() { - done(); + connectedBefore = true; + if (!alreadyDisconnected) { + self.connected = true; + done(); + } + }); + ipc.of['embark'].on('disconnect',function() { + self.connected = false; + ipc.disconnect('embark'); + + // we only want to trigger the error callback the first time + if (!connectedBefore && !alreadyDisconnected) { + alreadyDisconnected = true; + done(new Error("no connection found")); + } }); } @@ -59,6 +77,14 @@ class IPC { ipc.of['embark'].emit('message', {action: action, message: data}); } + isClient() { + return this.ipcRole === 'client'; + } + + isServer() { + return this.ipcRole === 'server'; + } + } module.exports = IPC; diff --git a/lib/modules/solidity/solcW.js b/lib/modules/solidity/solcW.js index 3f40d62a8..93139f8a1 100644 --- a/lib/modules/solidity/solcW.js +++ b/lib/modules/solidity/solcW.js @@ -10,7 +10,6 @@ class SolcW { constructor(options) { this.logger = options.logger; this.events = options.events; - this.useIpc = options.useIpc; this.ipc = options.ipc; this.compilerLoaded = false; this.solcProcess = null; @@ -18,11 +17,21 @@ class SolcW { load_compiler(done) { const self = this; - if (self.useIpc) { - self.compilerLoaded = true; - - return self.ipc.connect(done); + if (self.ipc.isClient()) { + return self.ipc.connect((err) => { + if (err) { + return self.load_compiler_internally(done); + } + self.compilerLoaded = true; + done(); + }); } + + self.load_compiler_internally(done); + } + + load_compiler_internally(done) { + const self = this; if (this.compilerLoaded) { return done(); } @@ -38,8 +47,10 @@ class SolcW { done(); }); - this.ipc.serve(); - this.ipc.on('compile', self.compile.bind(this)); + if (this.ipc.isServer()) { + this.ipc.serve(); + this.ipc.on('compile', self.compile.bind(this)); + } this.events.request("version:get:solc", function(solcVersion) { if (solcVersion === currentSolcVersion) { @@ -64,7 +75,7 @@ class SolcW { const id = uuid(); let a = new Date(); - if (this.useIpc) { + if (this.ipc.isClient() && this.ipc.connected) { return this.ipc.request('compile', jsonObj, done); } diff --git a/lib/tests/test.js b/lib/tests/test.js index d75cddce5..eabb68128 100644 --- a/lib/tests/test.js +++ b/lib/tests/test.js @@ -65,7 +65,7 @@ class Test { }); this.engine.startService("deployment", { trackContracts: false, - useIpc: true + ipcRole: 'client' }); this.engine.startService("codeGenerator"); }