-
Notifications
You must be signed in to change notification settings - Fork 10
2.13 Benchmarking
In computing, a benchmark is the act of running a computer program, a set of programs, or other operations, in order to assess the relative performance of an object, normally by running a number of standard tests and trials against it.
Signals offers an implementation for the Benchmarking aspect out of the box:
- Signals.Aspects.Benchmarking.Database
When we implement any type of process a benchmarking provider is automatically injected in the process context.
public class MyProcess : BusinessProcess<VoidResult>
{
/// <summary>
/// Authenticate process
/// </summary>
/// <returns></returns>
public override VoidResult Auth()
{
return Ok();
}
/// <summary>
/// Validate process
/// </summary>
/// <returns></returns>
public override VoidResult Validate()
{
return Ok();
}
/// <summary>
/// Handle process
/// </summary>
/// <returns></returns>
public override VoidResult Handle()
{
// Starting a benchmarking epic
Context.Benchmarker.StartEpic("my_epic");
// starting checkpoint
Context.Benchmarker.Bench("my_start_checkpoint", "my_description_1", new { MyPayload1 = 1 });
// some task that needs to be benchmarked
LongRunningTask1();
// checkpoint for measuring @LongRunningTask1();
Context.Benchmarker.Bench("my_long_running_checkpoint_1", "my_description_2", new { MyPayload2 = 2 });
// some task that needs to be benchmarked
LongRunningTask2();
// checkpoint for measuring @LongRunningTask2();
Context.Benchmarker.Bench("my_end_checkpoint", "my_description_3", new { MyPayload3 = 3 });
// Ending and saving a benchmarking epic
Context.Benchmarker.FlushEpic();
return Ok();
}
}
Other more manual way of using the benchmarker is through the IBenchmarker instance.
public void BenchmarkAction(Action myAction)
{
Guid epicId = Guid.NewGuid();
var benchmarkProvider = SystemBootstrapper.GetInstance<IBenchmarker>();
// Starting a benchmarking epic
benchmarkProvider.StartEpic(epicId, "my_epic");
// starting checkpoint
benchmarkProvider.Bench("my_start_checkpoint", epicId, "myAction", "my_description_1", new { MyPayload1 = 1 });
// some task that needs to be benchmarked
myAction.Invoke();
// checkpoint for measuring @LongRunningTask2();
benchmarkProvider.Bench("my_end_checkpoint", epicId, "myAction", "my_description_3", new { MyPayload2 = 2 });
// Ending and saving a benchmarking epic
Context.Benchmarker.FlushEpic(epicId);
}
We configure the benchmarking aspect by using an instance of Signals.Aspects.Benchmarking.Configurations.IBenchmarkingConfiguration
which we pass in the ApplicationBootstrapConfiguration
instance (web or background) at startup.
-
ConnectionString
: Database connection string -
TableName
: Benchmark checkpoints table name. Default BenchmarkingEntry -
IsEnabled
: Is the aspect enabled. Default true
Using Signals.Aspects.Benchmarking.Database
services
.AddSignals(config =>
{
config.BenchmarkingConfiguration = new DatabaseBenchmarkingConfiguration
{
ConnectionString = myConnectionString,
TableName = "BenchmarkingEntry",
IsEnabled = true
}
});
- Install package Signals.Aspects.Benchmarking
- Create class with implementation of
Signals.Aspects.Benchmarking.Configurations.IBenchmarkingConfiguration
/// <summary>
/// Benchmarking configuration contract
/// </summary>
public class MyBenchmarkingConfiguration : IBenchmarkingConfiguration
{
/// <summary>
/// Custom property
/// </summary>
public string MyProperty { get; set; }
}
- Create class with implementation of
Signals.Aspects.Benchmarking.IBenchmarker
/// <summary>
/// Storage contract
/// </summary>
public class MyStorageProvider : IStorageProvider
{
private MyBenchmarkingConfiguration _configuraiton;
/// <summary>
/// Hit benchmarking checkpoint
/// </summary>
/// <param name="checkpointName"></param>
/// <param name="epicId"></param>
/// <param name="processName"></param>
/// <param name="callerProcessName"></param>
/// <param name="description"></param>
/// <param name="payload"></param>
void Bench(
string checkpointName,
Guid epicId,
string processName,
string callerProcessName = null,
string description = null,
object payload = null);
/// <summary>
/// Persist epic data
/// </summary>
/// <param name="epicId"></param>
void FlushEpic(Guid epicId);
/// <summary>
/// Get epic report data
/// </summary>
/// <param name="epicName"></param>
/// <param name="afterDate"></param>
/// <returns></returns>
EpicsReport GetEpicReport(string epicName, DateTime afterDate);
/// <summary>
/// Mark epic as started
/// </summary>
/// <param name="epicId"></param>
/// <param name="epicName"></param>
void StartEpic(Guid epicId, string epicName);
}
- Use our implementation of
IBenchmarkingConfiguration
when configuring our application
public static IServiceProvider AddSignals(this IServiceCollection services)
{
services
.AddSignals(config =>
{
config.BenchmarkingConfiguration = new MyBenchmarkingConfiguration
{
MyProperty = "my_value"
};
});
}