Skip to content

Commit

Permalink
Merge pull request #899 from maxime-poulain/fix-benchmarks
Browse files Browse the repository at this point in the history
Fix broken Benchmarks
  • Loading branch information
jbogard authored May 17, 2023
2 parents b6a30a1 + 5417eb4 commit f33439d
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 66 deletions.
11 changes: 5 additions & 6 deletions test/MediatR.Benchmarks/Benchmarks.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.IO;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using MediatR.Pipeline;
using Microsoft.Extensions.DependencyInjection;

namespace MediatR.Benchmarks
Expand All @@ -20,11 +19,11 @@ public void GlobalSetup()

services.AddSingleton(TextWriter.Null);

services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining(typeof(Ping)));

services.AddScoped(typeof(IPipelineBehavior<,>), typeof(GenericPipelineBehavior<,>));
services.AddScoped(typeof(IRequestPreProcessor<>), typeof(GenericRequestPreProcessor<>));
services.AddScoped(typeof(IRequestPostProcessor<,>), typeof(GenericRequestPostProcessor<,>));
services.AddMediatR(cfg =>
{
cfg.RegisterServicesFromAssemblyContaining(typeof(Ping));
cfg.AddOpenBehavior(typeof(GenericPipelineBehavior<,>));
});

var provider = services.BuildServiceProvider();

Expand Down
132 changes: 78 additions & 54 deletions test/MediatR.Benchmarks/DotTraceDiagnoser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ public DotTraceDiagnoserAttribute()

internal sealed class DotTraceDiagnoser : IDiagnoser
{
private Process _process;
private string _saveLocation;
private const string DotTraceExecutableNotFoundErrorMessage = "dotTrace executable was not found. " +
"Make sure it is part of the PATH or install JetBrains.dotTrace.GlobalTools";

private readonly string _saveLocation;

public DotTraceDiagnoser()
{
_saveLocation = $"C:\\temp\\MyProject\\{DateTimeOffset.Now.UtcDateTime:yyyyMMddTHHmmss}.bench.dtp";
_saveLocation = $"C:\\temp\\MediatR\\{DateTimeOffset.Now.UtcDateTime:yyyy-MM-dd-HH_mm_ss}.bench.dtp";
}

/// <inheritdoc />
Expand All @@ -43,60 +45,58 @@ public DotTraceDiagnoser()
/// <inheritdoc />
public void Handle(HostSignal signal, DiagnoserActionParameters parameters)
{
switch (signal)
if (signal != HostSignal.BeforeActualRun)
{
return;
}

try
{
if (!CanRunDotTrace())
{
Console.WriteLine(DotTraceExecutableNotFoundErrorMessage);
return;
}

// The directory must exist or an error is thrown by dotTrace.
Directory.CreateDirectory(_saveLocation);
RunDotTrace(parameters);
}
catch (Exception e)
{
case HostSignal.BeforeActualRun:
try
{
var dotTracePath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
@"JetBrains\Installations\dotTrace192\ConsoleProfiler.exe");
var startInfo = new ProcessStartInfo(
dotTracePath,
$"attach {parameters.Process.Id} --save-to={_saveLocation} --profiling-type=Sampling")
{
RedirectStandardError
= true,
RedirectStandardOutput = true,
WindowStyle = ProcessWindowStyle.Normal,
UseShellExecute = false,
};
Console.WriteLine(startInfo.FileName);
Console.WriteLine(startInfo.Arguments);
_process = new Process
{
StartInfo = startInfo
};
_process.ErrorDataReceived += (sender, eventArgs) => Console.Error.WriteLine(eventArgs.Data);
_process.OutputDataReceived += (sender, eventArgs) => Console.WriteLine(eventArgs.Data);
_process.Start();
_process.BeginErrorReadLine();
_process.BeginOutputReadLine();
_process.Exited += (sender, args) => { _process.Dispose(); };
}
catch (Exception e)
{
Console.Error.WriteLine(e.StackTrace);
throw;
}
break;
case HostSignal.AfterActualRun:
break;
case HostSignal.BeforeAnythingElse:
break;
case HostSignal.AfterAll:
break;
case HostSignal.SeparateLogic:
break;
case HostSignal.BeforeProcessStart:
break;
case HostSignal.AfterProcessExit:
break;
default:
throw new ArgumentOutOfRangeException(nameof(signal), signal, null);
Console.Error.WriteLine(e.ToString());
throw;
}
}

private void RunDotTrace(DiagnoserActionParameters parameters)
{
var dotTrace = new Process
{
StartInfo = PrepareProcessStartInfo(parameters)
};
dotTrace.ErrorDataReceived += (sender, eventArgs) => Console.Error.WriteLine(eventArgs.Data);
dotTrace.OutputDataReceived += (sender, eventArgs) => Console.WriteLine(eventArgs.Data);
dotTrace.Start();
dotTrace.BeginErrorReadLine();
dotTrace.BeginOutputReadLine();
dotTrace.Exited += (sender, args) => dotTrace.Dispose();
}

private ProcessStartInfo PrepareProcessStartInfo(DiagnoserActionParameters parameters)
{
return new ProcessStartInfo(
"dottrace",
$"attach {parameters.Process.Id} --save-to={_saveLocation}")
{
RedirectStandardError = true,
RedirectStandardOutput = true,
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
CreateNoWindow = true,
};
}

/// <inheritdoc />
public IEnumerable<Metric> ProcessResults(DiagnoserResults results) => Enumerable.Empty<Metric>();

Expand All @@ -114,5 +114,29 @@ public IEnumerable<ValidationError> Validate(ValidationParameters validationPara
public IEnumerable<IExporter> Exporters => Enumerable.Empty<IExporter>();

public IEnumerable<IAnalyser> Analysers { get; } = Enumerable.Empty<IAnalyser>();

private static bool CanRunDotTrace()
{
try
{
var startInfo = new ProcessStartInfo("dottrace")
{
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
};

using var process = new Process { StartInfo = startInfo };
process.Start();
process.WaitForExit();

return true;
}
catch (Exception)
{
return false;
}
}
}
}
}
2 changes: 1 addition & 1 deletion test/MediatR.Benchmarks/GenericPipelineBehavior.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace MediatR.Benchmarks
{
public class GenericPipelineBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
where TRequest : IRequest<TResponse>
where TRequest : notnull
{
private readonly TextWriter _writer;

Expand Down
2 changes: 1 addition & 1 deletion test/MediatR.Benchmarks/GenericRequestPostProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace MediatR.Benchmarks
{
public class GenericRequestPostProcessor<TRequest, TResponse> : IRequestPostProcessor<TRequest, TResponse>
where TRequest : IRequest<TResponse>
where TRequest : notnull
{
private readonly TextWriter _writer;

Expand Down
1 change: 1 addition & 0 deletions test/MediatR.Benchmarks/GenericRequestPreProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
namespace MediatR.Benchmarks
{
public class GenericRequestPreProcessor<TRequest> : IRequestPreProcessor<TRequest>
where TRequest : notnull
{
private readonly TextWriter _writer;

Expand Down
6 changes: 2 additions & 4 deletions test/MediatR.Benchmarks/MediatR.Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<OutputType>Exe</OutputType>
<!-- BenchmarkDotNet 0.12.1 has an issue and doesn't support latest value. To remove for the next version. -->
<LangVersion>7.3</LangVersion>
</PropertyGroup>
<PropertyGroup>
<PlatformTarget>AnyCPU</PlatformTarget>
Expand All @@ -14,8 +12,8 @@
<Configuration>Release</Configuration>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.13.1" />
<PackageReference Include="BenchmarkDotNet" Version="0.13.5" />
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.13.5" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
Expand Down
8 changes: 8 additions & 0 deletions test/MediatR.Benchmarks/Ping.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
using System.Threading;
using System.Threading.Tasks;

namespace MediatR.Benchmarks
{
public class Ping : IRequest
{
public string Message { get; set; }
}

public class PingHandler : IRequestHandler<Ping>
{
public Task Handle(Ping request, CancellationToken cancellationToken) => Task.CompletedTask;
}
}
10 changes: 10 additions & 0 deletions test/MediatR.Benchmarks/Pinged.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
using System.Threading;
using System.Threading.Tasks;

namespace MediatR.Benchmarks
{
public class Pinged : INotification
{
}

public class PingedHandler : INotificationHandler<Pinged>
{
public Task Handle(Pinged notification, CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
}

0 comments on commit f33439d

Please sign in to comment.