Skip to content
Snippets Groups Projects
Commit 63a7f4b7 authored by Vincent Rousseau's avatar Vincent Rousseau
Browse files

Add and remove workers during eco mode

parent 53fdad34
No related branches found
No related tags found
1 merge request!1214Reduce cpu
...@@ -48,6 +48,14 @@ export class WorkerFarm { ...@@ -48,6 +48,14 @@ export class WorkerFarm {
return this.theEngine.getNbWorkers() return this.theEngine.getNbWorkers()
} }
reduceNbCores() {
return this.theEngine.reduceNbCores()
}
boostCPU(){
return this.theEngine.boostCPU()
}
changeCPU(cpu:any) { changeCPU(cpu:any) {
return this.theEngine.setConf({ cpu }) return this.theEngine.setConf({ cpu })
} }
...@@ -194,13 +202,12 @@ export class BlockProver { ...@@ -194,13 +202,12 @@ export class BlockProver {
}); });
if (!result) { if (!result) {
this.logger.info('GIVEN proof-of-work for block#%s with %s leading zeros followed by [0-' + highMark + ']! stop PoW for %s', block.number, nbZeros, this.pair && this.pair.pub.slice(0,6)); this.logger.info('GIVEN proof-of-work for block#%s with %s leading zeros followed by [0-' + highMark + ']! stop PoW for %s', block.number, nbZeros, this.pair && this.pair.pub.slice(0,6));
let selfNbBlockInFrame = await this.server.getBcContext().getIssuerNbBlockInFrame(this.server.PeeringService.selfPubkey)
if(this.conf.ecoMode === true) { if(this.conf.ecoMode === true) {
let selfNbBlockInFrame = await this.server.getBcContext().getIssuerNbBlockInFrame(this.server.PeeringService.selfPubkey) let selfNbBlockInFrame = await this.server.getBcContext().getIssuerNbBlockInFrame(this.server.PeeringService.selfPubkey)
if(selfNbBlockInFrame < 2) { if(selfNbBlockInFrame < 2) {
this.changeCPU(1) this.boostCPU()
this.conf.nbCores = this.server.conf.nbCores this.conf.nbCores = powFarm.nbWorkers
this.logger.info("Boost number of CPU cores "+this.conf.nbCores+" with only "+selfNbBlockInFrame+" block member in frame") this.logger.info("Boost number of CPU cores "+powFarm.nbWorkers+" with only "+selfNbBlockInFrame+" block member in frame")
} }
} }
throw 'Proof-of-work computation canceled because block received'; throw 'Proof-of-work computation canceled because block received';
...@@ -214,14 +221,15 @@ export class BlockProver { ...@@ -214,14 +221,15 @@ export class BlockProver {
if(this.conf.ecoMode === true) { if(this.conf.ecoMode === true) {
let selfNbBlockInFrame = await this.server.getBcContext().getIssuerNbBlockInFrame(this.server.PeeringService.selfPubkey) let selfNbBlockInFrame = await this.server.getBcContext().getIssuerNbBlockInFrame(this.server.PeeringService.selfPubkey)
if(selfNbBlockInFrame < 2) { if(selfNbBlockInFrame < 2) {
this.changeCPU(1) this.boostCPU()
this.conf.nbCores = this.server.conf.nbCores this.conf.nbCores = powFarm.nbWorkers
this.logger.info("Boost number of CPU cores "+this.conf.nbCores+" with only "+selfNbBlockInFrame+" block member in frame") this.logger.info("Boost number of CPU cores "+powFarm.nbWorkers+" with only "+selfNbBlockInFrame+" block member in frame")
} }
else if(this.conf.nbCores*testsPerSecond > ProverConstants.ECO_MODE_MINIMAL_TESTS_PER_SECONDS) { else if(testsPerSecond > ProverConstants.ECO_MODE_MINIMAL_TESTS_PER_SECONDS) {
if(this.conf.nbCores > 1) { if(powFarm.nbWorkers > 1) {
this.logger.info("Reducing number of CPU cores "+this.conf.nbCores) this.logger.info("Reducing number of CPU cores "+powFarm.nbWorkers)
this.conf.nbCores = this.conf.nbCores -1 this.reduceNbCores()
this.conf.nbCores = powFarm.nbWorkers
} }
else if(this.conf.cpu > ProverConstants.ECO_MODE_MINIMAL_CPU){ else if(this.conf.cpu > ProverConstants.ECO_MODE_MINIMAL_CPU){
let cpu:number = this.conf.cpu - 0.1 let cpu:number = this.conf.cpu - 0.1
...@@ -235,6 +243,17 @@ export class BlockProver { ...@@ -235,6 +243,17 @@ export class BlockProver {
})() })()
}; };
async reduceNbCores() {
const farm = await this.getWorker()
return farm.reduceNbCores()
}
async boostCPU() {
this.conf.cpu = 1.0
const farm = await this.getWorker()
return farm.boostCPU()
}
async changeCPU(cpu:number) { async changeCPU(cpu:number) {
this.conf.cpu = Math.max(0.01, Math.min(1.0, cpu)); this.conf.cpu = Math.max(0.01, Math.min(1.0, cpu));
const farm = await this.getWorker() const farm = await this.getWorker()
......
...@@ -12,15 +12,12 @@ if(debug) { ...@@ -12,15 +12,12 @@ if(debug) {
export class PowEngine { export class PowEngine {
private nbWorkers:number
private cluster:PowCluster private cluster:PowCluster
readonly id:number readonly id:number
constructor(private conf:ConfDTO, logger:any) { constructor(private conf:ConfDTO, logger:any) {
// We use as much cores as available, but not more than CORES_MAXIMUM_USE_IN_PARALLEL // We use as much cores as available, but not more than CORES_MAXIMUM_USE_IN_PARALLEL
this.nbWorkers = conf.nbCores this.cluster = new PowCluster(conf.nbCores, logger)
this.cluster = new PowCluster(this.nbWorkers, logger)
this.id = this.cluster.clusterId this.id = this.cluster.clusterId
} }
...@@ -41,6 +38,14 @@ export class PowEngine { ...@@ -41,6 +38,14 @@ export class PowEngine {
return this.cluster.cancelWork() return this.cluster.cancelWork()
} }
reduceNbCores() {
return this.cluster.removeSlave()
}
boostCPU() {
return this.cluster.boostCPU()
}
setConf(value:any) { setConf(value:any) {
return this.cluster.changeConf(value) return this.cluster.changeConf(value)
} }
......
...@@ -35,6 +35,7 @@ export class Master { ...@@ -35,6 +35,7 @@ export class Master {
logger:any logger:any
onInfoCallback:any onInfoCallback:any
workersOnline:Promise<any>[] workersOnline:Promise<any>[]
maxNbCores:number = Math.min(ProverConstants.CORES_MAXIMUM_USE_IN_PARALLEL, require('os').cpus().length)
constructor(private nbCores:number, logger:any) { constructor(private nbCores:number, logger:any) {
this.clusterId = clusterId++ this.clusterId = clusterId++
...@@ -65,18 +66,7 @@ export class Master { ...@@ -65,18 +66,7 @@ export class Master {
// this.logger.debug(`ENGINE c#${this.clusterId}#${this.slavesMap[worker.id].index}:`, message) // this.logger.debug(`ENGINE c#${this.clusterId}#${this.slavesMap[worker.id].index}:`, message)
} }
/***************** createSlave(index:number) {
* CLUSTER METHODS
****************/
initCluster() {
// Setup master
cluster.setupMaster({
exec: __filename,
execArgv: [] // Do not try to debug forks
})
this.slaves = Array.from({ length: this.nbCores }).map((value, index) => {
const nodejsWorker = cluster.fork() const nodejsWorker = cluster.fork()
const worker = new PowWorker(nodejsWorker, message => { const worker = new PowWorker(nodejsWorker, message => {
this.onWorkerMessage(index, message) this.onWorkerMessage(index, message)
...@@ -107,6 +97,38 @@ export class Master { ...@@ -107,6 +97,38 @@ export class Master {
} }
this.slavesMap[nodejsWorker.id] = slave this.slavesMap[nodejsWorker.id] = slave
return slave return slave
}
boostCPU() {
if(this.nbWorkers < this.maxNbCores) {
while(this.nbWorkers < this.maxNbCores) {
this.slaves.push(this.createSlave(this.nbWorkers))
}
}
let conf:any = {cpu: 1}
this.changeConf(conf)
}
async removeSlave() {
let nb_workers = this.nbWorkers
await this.slaves[nb_workers-1].worker.kill()
this.slaves.pop()
this.logger.info('Remove slave number '+ (nb_workers-1))
}
/*****************
* CLUSTER METHODS
****************/
initCluster() {
// Setup master
cluster.setupMaster({
exec: __filename,
execArgv: [] // Do not try to debug forks
})
this.slaves = Array.from({ length: this.nbCores }).map((value, index) => {
return this.createSlave(index)
}) })
this.workersOnline = this.slaves.map((s) => s.online) this.workersOnline = this.slaves.map((s) => s.online)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment