Skip to content

Commit

Permalink
Fix CompositeRateController class bug (#1181) (#1184)
Browse files Browse the repository at this point in the history
* Rename old "roundConfig" references to the new "testMessage"
* Extend TestMessage class with some functions to allow modification by CompositeRateController
* Fix passed arguments to the new RateControl constructor when creating subcontrollers
* Add a composite rate controller to one of the Fabric CI phases

Signed-off-by: Attila Klenik <a.klenik@gmail.com>
  • Loading branch information
aklenik committed Dec 9, 2021
1 parent 595942a commit aa0b3db
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 14 deletions.
33 changes: 33 additions & 0 deletions packages/caliper-core/lib/common/messages/testMessage.js
Expand Up @@ -66,6 +66,14 @@ class TestMessage extends Message {
return this.content.rateControl;
}

/**
* Sets the rate control specification for the round.
* @param {object} rateControlSpec The rate control specification.
*/
setRateControlSpec(rateControlSpec) {
this.content.rateControl = rateControlSpec;
}

/**
* Gets the trim length for the round.
* @return {number} The trim length.
Expand Down Expand Up @@ -106,13 +114,38 @@ class TestMessage extends Message {
return this.content.numb;
}

/**
* Sets the number of TXs to perform in the round.
* @param {number} numberOfTxs The number of TXs.
*/
setNumberOfTxs(numberOfTxs) {
this.content.numb = numberOfTxs;
}

/**
* Gets the target duration for the round in seconds.
* @return {number} The duration of the round in seconds.
*/
getRoundDuration() {
return this.content.txDuration;
}

/**
* Sets the target duration for the round in seconds.
* @param {number} txDuration The duration of the round in seconds.
*/
setRoundDuration(txDuration) {
this.content.txDuration = txDuration;
}

/**
* Deep-clones the test message.
* @returns {TestMessage} The clone test message.
*/
clone() {
const contentClone = JSON.parse(JSON.stringify(this.content));
return new TestMessage(this.sender, Array.from(this.recipients), contentClone, this.date, this.error);
}
}

module.exports = TestMessage;
26 changes: 13 additions & 13 deletions packages/caliper-core/lib/worker/rate-control/compositeRate.js
Expand Up @@ -116,8 +116,10 @@ class CompositeRateController extends RateInterface{
}
weights = weights.map(w => w / weightSum);

const numberOfTxs = this.testMessage.getNumberOfTxs();

// pre-set switch logic to avoid an other condition check during rate control
this.controllerSwitch = this.roundConfig.txNumber ? this._controllerSwitchForTxNumber : this._controllerSwitchForDuration;
this.controllerSwitch = numberOfTxs ? this._controllerSwitchForTxNumber : this._controllerSwitchForDuration;

let currentWeightSum = 0;
// create controller instances, skip zero-weight cases
Expand All @@ -132,35 +134,36 @@ class CompositeRateController extends RateInterface{
currentWeightSum += currentWeight;

// create a modified copy of the round configuration according to the weights
let controllerRoundConfig = Object.assign({}, this.roundConfig);
let controllerRoundConfig = this.testMessage.clone();

// lie to the sub-controller that it's the only one
controllerRoundConfig.rateControl = currentControllerOptions;
controllerRoundConfig.setRateControlSpec(currentControllerOptions);

// create the sub-collector to be activated later, and add it to the current stats collector (which could be another sub-collector)
let statSubCollector = new TransactionStatisticsCollector(this.workerIndex, this.roundIndex, this.roundLabel);
this.stats.addSubCollector(statSubCollector);

// scale down number of TXs or the duration
if (this.roundConfig.txNumber) {
controllerRoundConfig.txNumber = Math.floor(this.roundConfig.txNumber * currentWeight);
if (numberOfTxs) {
controllerRoundConfig.setNumberOfTxs(Math.floor(numberOfTxs * currentWeight));

// the sub-controller is initialized with the TX stat sub-collector, which is inactive at this point (i.e., the round hasn't started for it)
let subcontroller = new RateControl(rateControllers[i], statSubCollector, this.workerIndex, this.roundIndex, this.numberOfWorkers, controllerRoundConfig);
let subcontroller = new RateControl(controllerRoundConfig, statSubCollector, this.workerIndex);
let controllerData = new ControllerData(subcontroller, statSubCollector);

// the sub-controller should be switched after this TX index
controllerData.lastTxIndex = Math.floor(this.roundConfig.txNumber * currentWeightSum);
controllerData.lastTxIndex = Math.floor(numberOfTxs * currentWeightSum);
this.controllers.push(controllerData);
} else {
controllerRoundConfig.txDuration = Math.floor(this.roundConfig.txDuration * currentWeight);
const txDuration = this.testMessage.getRoundDuration();
controllerRoundConfig.setRoundDuration(Math.floor(txDuration * currentWeight));

// the sub-controller is initialized with the TX stat sub-collector, which is inactive at this point (i.e., the round hasn't started for it)
let subcontroller = new RateControl(rateControllers[i], statSubCollector, this.workerIndex, this.roundIndex, this.numberOfWorkers, controllerRoundConfig);
let subcontroller = new RateControl(controllerRoundConfig, statSubCollector, this.workerIndex);
let controllerData = new ControllerData(subcontroller, statSubCollector);

// the sub-controller should be switched "around" this time
controllerData.relFinishTime = Math.floor(this.roundConfig.txDuration * 1000 * currentWeightSum);
controllerData.relFinishTime = Math.floor(txDuration * 1000 * currentWeightSum);
this.controllers.push(controllerData);
}
}
Expand Down Expand Up @@ -254,9 +257,6 @@ class CompositeRateController extends RateInterface{
* @param {TestMessage} testMessage start test message
* @param {TransactionStatisticsCollector} stats The TX stats collector instance.
* @param {number} workerIndex The 0-based index of the worker node.
* @param {number} roundIndex The 0-based index of the current round.
* @param {number} numberOfWorkers The total number of worker nodes.
* @param {object} roundConfig The round configuration object.
*
* @return {RateInterface} The new rate controller instance.
*/
Expand Down
Expand Up @@ -20,7 +20,17 @@ test:
rounds:
- label: query1
txNumber: 50
rateControl: { type: 'fixed-rate', opts: { tps: 3 } }
rateControl:
type: composite-rate
opts:
weights: [2,1]
rateControllers:
- type: fixed-rate
opts:
tps: 2
- type: fixed-rate
opts:
tps: 4
workload:
module: ./../query.js
- label: query2
Expand Down

0 comments on commit aa0b3db

Please sign in to comment.