Merge pull request #481 from embark-framework/ipc

add socket support
This commit is contained in:
Iuri Matias 2018-06-05 16:42:44 -04:00 committed by GitHub
commit f44ed981b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 140 additions and 7 deletions

View File

@ -1,6 +1,7 @@
const async = require('async'); const async = require('async');
const utils = require('../utils/utils'); const utils = require('../utils/utils');
const IPC = require('./ipc');
class Engine { class Engine {
constructor(options) { constructor(options) {
@ -182,7 +183,8 @@ class Engine {
compiler.compile_contracts(contractFiles, cb); compiler.compile_contracts(contractFiles, cb);
}); });
this.registerModule('solidity'); this.ipc = new IPC({logger: this.logger, ipcRole: options.ipcRole});
this.registerModule('solidity', {ipc: this.ipc});
this.registerModule('vyper'); this.registerModule('vyper');
this.registerModule('profiler'); this.registerModule('profiler');
this.registerModule('deploytracker'); this.registerModule('deploytracker');

90
lib/core/ipc.js Normal file
View File

@ -0,0 +1,90 @@
let fs = require('./fs.js');
let ipc = require('node-ipc');
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() {
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"));
}
});
}
ipc.connectTo('embark', this.socketPath, connecting);
}
serve() {
ipc.serve(this.socketPath, () => {});
ipc.server.start();
this.logger.info(`pid ${process.pid} listening on ${this.socketPath}`);
}
on(action, done) {
const self = this;
ipc.server.on('message', function(data, socket) {
if (data.action !== action) {
return;
}
let reply = function(replyData) {
self.reply(socket, 'compile', replyData);
};
done(data.message, reply, socket);
});
}
reply(client, action, data) {
ipc.server.emit(client, 'message', {action: action, message: data});
}
once(action, cb) {
ipc.of['embark'].once('message', function(msg) {
if (msg.action !== action) {
return;
}
cb(msg.message);
});
}
request(action, data, cb) {
if (cb) {
this.once(action, cb);
}
ipc.of['embark'].emit('message', {action: action, message: data});
}
isClient() {
return this.ipcRole === 'client';
}
isServer() {
return this.ipcRole === 'server';
}
}
module.exports = IPC;

View File

@ -3,9 +3,10 @@ let SolcW = require('./solcW.js');
class Solidity { class Solidity {
constructor(embark, _options) { constructor(embark, options) {
this.logger = embark.logger; this.logger = embark.logger;
this.events = embark.events; this.events = embark.events;
this.ipc = options.ipc;
this.contractDirectories = embark.config.contractDirectories; this.contractDirectories = embark.config.contractDirectories;
this.solcAlreadyLoaded = false; this.solcAlreadyLoaded = false;
this.solcW = null; this.solcW = null;
@ -48,7 +49,7 @@ class Solidity {
if (self.solcAlreadyLoaded) { if (self.solcAlreadyLoaded) {
return callback(); return callback();
} }
self.solcW = new SolcW({logger: self.logger, events: self.events}); self.solcW = new SolcW({logger: self.logger, events: self.events, ipc: self.ipc});
self.logger.info(__("loading solc compiler") + ".."); self.logger.info(__("loading solc compiler") + "..");
self.solcW.load_compiler(function (err) { self.solcW.load_compiler(function (err) {

View File

@ -9,11 +9,27 @@ class SolcW {
constructor(options) { constructor(options) {
this.logger = options.logger; this.logger = options.logger;
this.events = options.events; this.events = options.events;
this.ipc = options.ipc;
this.compilerLoaded = false; this.compilerLoaded = false;
this.solcProcess = null; this.solcProcess = null;
} }
load_compiler(done) { load_compiler(done) {
const self = this;
if (!self.ipc.isClient()) {
return self.load_compiler_internally(done);
}
self.ipc.connect((err) => {
if (err) {
return self.load_compiler_internally(done);
}
self.compilerLoaded = true;
done();
});
}
load_compiler_internally(done) {
const self = this; const self = this;
if (this.compilerLoaded) { if (this.compilerLoaded) {
return done(); return done();
@ -30,6 +46,11 @@ class SolcW {
done(); done();
}); });
if (this.ipc.isServer()) {
this.ipc.serve();
this.ipc.on('compile', self.compile.bind(this));
}
this.events.request("version:get:solc", function(solcVersion) { this.events.request("version:get:solc", function(solcVersion) {
if (solcVersion === currentSolcVersion) { if (solcVersion === currentSolcVersion) {
self.solcProcess.send({action: 'loadCompiler', requirePath: 'solc'}); self.solcProcess.send({action: 'loadCompiler', requirePath: 'solc'});
@ -51,6 +72,11 @@ class SolcW {
compile(jsonObj, done) { compile(jsonObj, done) {
const id = uuid(); const id = uuid();
if (this.ipc.isClient() && this.ipc.connected) {
return this.ipc.request('compile', jsonObj, done);
}
this.solcProcess.once('result', 'compilation-' + id, (msg) => { this.solcProcess.once('result', 'compilation-' + id, (msg) => {
done(JSON.parse(msg.output)); done(JSON.parse(msg.output));
}); });

View File

@ -64,7 +64,8 @@ class Test {
web3: this.web3 web3: this.web3
}); });
this.engine.startService("deployment", { this.engine.startService("deployment", {
trackContracts: false trackContracts: false,
ipcRole: 'client'
}); });
this.engine.startService("codeGenerator"); this.engine.startService("codeGenerator");
} }

View File

@ -54,6 +54,7 @@
"ipfs-api": "17.2.4", "ipfs-api": "17.2.4",
"live-plugin-manager": "https://github.com/iurimatias/live-plugin-manager.git", "live-plugin-manager": "https://github.com/iurimatias/live-plugin-manager.git",
"merge": "^1.2.0", "merge": "^1.2.0",
"node-ipc": "^9.1.1",
"os-locale": "^2.1.0", "os-locale": "^2.1.0",
"p-iteration": "^1.1.7", "p-iteration": "^1.1.7",
"parse-json": "^4.0.0", "parse-json": "^4.0.0",

View File

@ -2,6 +2,7 @@
let SolidityCompiler = require('../lib/modules/solidity'); let SolidityCompiler = require('../lib/modules/solidity');
let TestLogger = require('../lib/tests/test_logger.js'); let TestLogger = require('../lib/tests/test_logger.js');
let File = require('../lib/core/file.js'); let File = require('../lib/core/file.js');
let Ipc = require('../lib/core/ipc.js');
let assert = require('assert'); let assert = require('assert');
let readFile = function(file) { let readFile = function(file) {
@ -16,6 +17,10 @@ var TestEvents = {
} }
}; };
let ipcObject = new Ipc({
ipcRole: 'none'
});
var apiObject = { var apiObject = {
registerCompiler: function() {}, registerCompiler: function() {},
logger: new TestLogger({}), logger: new TestLogger({}),
@ -27,7 +32,7 @@ var apiObject = {
describe('embark.Compiler', function() { describe('embark.Compiler', function() {
//let compiler = new Compiler({logger: new TestLogger({})}); //let compiler = new Compiler({logger: new TestLogger({})});
let compiler = new SolidityCompiler(apiObject); let compiler = new SolidityCompiler(apiObject, {ipc: ipcObject});
describe('#compile_solidity', function() { describe('#compile_solidity', function() {
this.timeout(0); this.timeout(0);

View File

@ -5,6 +5,7 @@ let Logger = require('../lib/core/logger.js');
let File = require('../lib/core/file.js'); let File = require('../lib/core/file.js');
let TestLogger = require('../lib/tests/test_logger.js'); let TestLogger = require('../lib/tests/test_logger.js');
let Events = require('../lib/core/events'); let Events = require('../lib/core/events');
let Ipc = require('../lib/core/ipc.js');
let assert = require('assert'); let assert = require('assert');
//let SolidityCompiler = require('../lib/modules/solidity'); //let SolidityCompiler = require('../lib/modules/solidity');
@ -31,7 +32,10 @@ describe('embark.Contracts', function() {
contractDirectories: ['app/contracts/'] contractDirectories: ['app/contracts/']
} }
}); });
plugins.loadInternalPlugin('solidity'); let ipcObject = new Ipc({
ipcRole: 'none'
});
plugins.loadInternalPlugin('solidity', {ipc: ipcObject});
let compiler = new Compiler({plugins: plugins, logger: plugins.logger}); let compiler = new Compiler({plugins: plugins, logger: plugins.logger});
let events = new Events(); let events = new Events();
@ -123,7 +127,10 @@ describe('embark.Contracts', function() {
contractDirectories: ['app/contracts/'] contractDirectories: ['app/contracts/']
} }
}); });
plugins.loadInternalPlugin('solidity'); let ipcObject = new Ipc({
ipcRole: 'none'
});
plugins.loadInternalPlugin('solidity', {ipc: ipcObject});
let compiler = new Compiler({plugins: plugins, logger: plugins.logger}); let compiler = new Compiler({plugins: plugins, logger: plugins.logger});
let events = new Events(); let events = new Events();