Merge pull request #566 from embark-framework/features/para-deploy

Async contract deploy (parallel deploy prequel)
This commit is contained in:
Iuri Matias 2018-06-20 16:57:24 -04:00 committed by GitHub
commit 109e5171c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 10 deletions

View File

@ -152,16 +152,16 @@ class ContractDeployer {
accounts = _accounts; accounts = _accounts;
// applying deployer account configuration, if any // applying deployer account configuration, if any
if (typeof contract.fromIndex == 'number') { if (typeof contract.fromIndex === 'number') {
deploymentAccount = accounts[contract.fromIndex]; deploymentAccount = accounts[contract.fromIndex];
if (deploymentAccount === undefined) { if (deploymentAccount === undefined) {
return next(__("error deploying") + " " + contract.className + ": " + __("no account found at index") + " " + contract.fromIndex + __(" check the config")); return next(__("error deploying") + " " + contract.className + ": " + __("no account found at index") + " " + contract.fromIndex + __(" check the config"));
} }
} }
if (typeof contract.from == 'string' && typeof contract.fromIndex != 'undefined') { if (typeof contract.from === 'string' && typeof contract.fromIndex !== 'undefined') {
self.logger.warn(__('Both "from" and "fromIndex" are defined for contract') + ' "' + contract.className + '". ' + __('Using "from" as deployer account.')); self.logger.warn(__('Both "from" and "fromIndex" are defined for contract') + ' "' + contract.className + '". ' + __('Using "from" as deployer account.'));
} }
if (typeof contract.from == 'string') { if (typeof contract.from === 'string') {
deploymentAccount = contract.from; deploymentAccount = contract.from;
} }

View File

@ -261,8 +261,45 @@ class ContractsManager {
}); });
} }
callback(); callback();
},
function setDependencyCount(callback) {
let className;
function getDependencyCount(contractName, cycleDetector) {
if (!self.contracts[contractName]) {
return 0;
} }
], function (err, _result) { if (self.contracts[contractName].dependencyCount || self.contracts[contractName].dependencyCount === 0) {
// Already have that count
return self.contracts[contractName].dependencyCount;
}
if (!self.contractDependencies[contractName] || !self.contractDependencies[contractName].length) {
self.contracts[contractName].dependencyCount = 0;
return 0;
}
let total = self.contractDependencies[contractName].length;
self.contractDependencies[contractName].some(dependencyName => {
if (cycleDetector.indexOf(dependencyName) > -1) {
// We are in a cycle because of the dependency, set both to Infinity
self.contracts[dependencyName].dependencyCount = Infinity;
total = Infinity;
return true;
}
cycleDetector.push(dependencyName);
total += getDependencyCount(dependencyName, cycleDetector);
});
self.contracts[contractName].dependencyCount = total;
return total;
}
let cycleDetector;
for (className in self.contracts) {
cycleDetector = [];
getDependencyCount(className, cycleDetector);
}
callback();
}
], function (err) {
if (err) { if (err) {
self.compileError = true; self.compileError = true;
self.events.emit("status", __("Compile/Build error")); self.events.emit("status", __("Compile/Build error"));

View File

@ -1,4 +1,5 @@
let async = require('async'); let async = require('async');
const _ = require('underscore');
class DeployManager { class DeployManager {
constructor(options) { constructor(options) {
@ -31,12 +32,15 @@ class DeployManager {
self.logger.info(__("deploying contracts")); self.logger.info(__("deploying contracts"));
self.events.emit("deploy:beforeAll"); self.events.emit("deploy:beforeAll");
async.eachOfSeries(contracts, const contractsPerDependencyCount = _.groupBy(contracts, 'dependencyCount');
function (contract, key, callback) { async.eachSeries(contractsPerDependencyCount,
function (parallelGroups, callback) {
async.each(parallelGroups, (contract, eachCb) => {
contract._gasLimit = self.gasLimit; contract._gasLimit = self.gasLimit;
self.events.request('deploy:contract', contract, (err) => { self.events.request('deploy:contract', contract, (err) => {
callback(err); eachCb(err);
}); });
}, callback);
}, },
function (err, _results) { function (err, _results) {
if (err) { if (err) {

View File

@ -123,6 +123,10 @@ class Test {
this.engine.contractsManager.build(() => { this.engine.contractsManager.build(() => {
self.builtContracts = cloneDeep(self.engine.contractsManager.contracts); self.builtContracts = cloneDeep(self.engine.contractsManager.contracts);
let className;
for (className in self.builtContracts) {
self.builtContracts[className].dependencyCount = null;
}
self.compiledContracts = cloneDeep(self.engine.contractsManager.compiledContracts); self.compiledContracts = cloneDeep(self.engine.contractsManager.compiledContracts);
callback(); callback();
}); });
@ -211,6 +215,7 @@ class Test {
function resetContracts(next) { function resetContracts(next) {
self.engine.contractsManager.contracts = cloneDeep(self.builtContracts); self.engine.contractsManager.contracts = cloneDeep(self.builtContracts);
self.engine.contractsManager.compiledContracts = cloneDeep(self.compiledContracts); self.engine.contractsManager.compiledContracts = cloneDeep(self.compiledContracts);
self.engine.contractsManager.contractDependencies = {};
next(); next();
}, },
function deploy(next) { function deploy(next) {