caliper icon indicating copy to clipboard operation
caliper copied to clipboard

Allow workload modules to signal the end of a round when deemed necessary

Open aklenik opened this issue 4 years ago • 0 comments

Please share the technical limitation of Caliper that you encountered.

Caliper workers call workload modules either for a specific number of transactions or a fixed duration. However, benchmarks containing randomness might not be covered by either driving mode. For example, if an initialization phase must insert a random (fix, but a priory unknown) number of entries, then neither a transaction number nor duration can be specified beforehand (as part of the benchmark configuration file).

Please detail your feature idea that could alleviate the limitation.

The limitation can be lifted by introducing a third, "conditional" driving mode that delegates the "round ended" decision to the workload modules. Thus a workload module can signal the encapsulating worker service when it deems the round finished, and the worker ends the round.

Please share some details about your use case if possible, and how the new feature would make Caliper a better performance benchmarking framework.

The use case is a benchmark whose initialization phase requires the insertion of a random number of entries. A conditional driving mode (implemented by workload modules or any other plugin) would allow for a priory unknown round "durations".

Please share any suggestions about the new feature's code/configuration API (using formatted YAML segments or pseudo-code).

Workload modules (or other plugins) can signal the worker process through a CancellationToken object (commonly utilized by async libraries):

class CancellationToken {
    cancel(reason) {}
    isCanceled() {}
    getReason() {}
}

Caliper workers can pass these tokens to the workload modules, and end the round based on the cancel signal:

let error = undefined;
let cancellationToken = new CancellationToken();
while (!cancellationToken.isCanceled() && !error) {
    await rateController.applyRateControl(cancellationToken );
    await this.setImmediatePromise(() => {
        workloadModule.submitTransaction(cancellationToken )
            .catch(err => { error = err; });
    });
}

Workload modules can cancel a round (after the current transaction) if, for example, no more entries need to be inserted into the SUT:

if (!entryGenerator.hasNext()) {
    cancellationToken.cancel('No more entries to generate.');
}

aklenik avatar Jan 07 '22 15:01 aklenik