-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Request Response Benchmark (#110)
- Loading branch information
Showing
15 changed files
with
431 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
using System.Diagnostics; | ||
using ActiveMQ.Artemis.Core.Client; | ||
|
||
namespace PingPong_ArtemisNetCoreClient | ||
{ | ||
public class Ping : IAsyncDisposable | ||
{ | ||
private readonly IConnection _connection; | ||
private readonly ISession _session; | ||
private readonly IProducer _producer; | ||
private readonly IConsumer _consumer; | ||
private readonly Stopwatch _stopwatch; | ||
private int _numberOfMessages; | ||
private int _skipMessages; | ||
private int _counter; | ||
private TaskCompletionSource<Stats> _tsc; | ||
private readonly Task _consumerLoopTask; | ||
private readonly CancellationTokenSource _cts; | ||
|
||
private Ping(IConnection connection, ISession session, IProducer producer, IConsumer consumer) | ||
{ | ||
_connection = connection; | ||
_session = session; | ||
_producer = producer; | ||
_consumer = consumer; | ||
_stopwatch = new Stopwatch(); | ||
|
||
_cts = new CancellationTokenSource(); | ||
|
||
_consumerLoopTask = ConsumerLoop(); | ||
} | ||
|
||
public static async Task<Ping> CreateAsync(Endpoint endpoint) | ||
{ | ||
var connectionFactory = new ConnectionFactory(); | ||
var connection = await connectionFactory.CreateAsync(endpoint); | ||
var session = await connection.CreateSessionAsync(); | ||
|
||
var producer = await session.CreateProducerAsync(new ProducerConfiguration { Address = "ping" }); | ||
var consumer = await session.CreateConsumerAsync(new ConsumerConfiguration { QueueName = "pong" }); | ||
return new Ping(connection, session, producer, consumer); | ||
} | ||
|
||
public Task<Stats> Start(int numberOfMessages, int skipMessages) | ||
{ | ||
_numberOfMessages = numberOfMessages; | ||
_skipMessages = skipMessages; | ||
_stopwatch.Start(); | ||
_tsc = new TaskCompletionSource<Stats>(); | ||
var pingMessage = new Message { Body = "Ping"u8.ToArray() }; | ||
_producer.SendMessageAsync(pingMessage); | ||
return _tsc.Task; | ||
} | ||
|
||
private Task ConsumerLoop() | ||
{ | ||
return Task.Run(async () => | ||
{ | ||
try | ||
{ | ||
while (!_cts.IsCancellationRequested) | ||
{ | ||
var msg = await _consumer.ReceiveMessageAsync(_cts.Token); | ||
if (_skipMessages > 0) | ||
_skipMessages--; | ||
else | ||
_counter++; | ||
if (_counter == _numberOfMessages) | ||
{ | ||
_stopwatch.Stop(); | ||
_tsc.TrySetResult(new Stats { MessagesCount = _counter, Elapsed = _stopwatch.Elapsed }); | ||
} | ||
else | ||
{ | ||
var pingMessage = new Message { Body = "Ping"u8.ToArray() }; | ||
await _producer.SendMessageAsync(pingMessage, _cts.Token); | ||
} | ||
await _consumer.AcknowledgeAsync(msg.MessageDelivery, _cts.Token); | ||
} | ||
} | ||
catch (OperationCanceledException) | ||
{ | ||
} | ||
}); | ||
} | ||
|
||
public async ValueTask DisposeAsync() | ||
{ | ||
await _cts.CancelAsync(); | ||
_cts.Dispose(); | ||
await _consumerLoopTask; | ||
await _consumer.DisposeAsync(); | ||
await _producer.DisposeAsync(); | ||
await _session.DisposeAsync(); | ||
await _connection.DisposeAsync(); | ||
} | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
benchmark/PingPong_ArtemisNetCoreClient/PingPong_ArtemisNetCoreClient.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<RootNamespace>PingPong_ArtemisNetCoreClient</RootNamespace> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\src\ArtemisNetCoreClient\ArtemisNetCoreClient.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
using ActiveMQ.Artemis.Core.Client; | ||
|
||
namespace PingPong_ArtemisNetCoreClient | ||
{ | ||
public class Pong : IAsyncDisposable | ||
{ | ||
private readonly IConnection _connection; | ||
private readonly ISession _session; | ||
private readonly IProducer _producer; | ||
private readonly IConsumer _consumer; | ||
private readonly Task _consumerLoopTask; | ||
private readonly CancellationTokenSource _cts; | ||
|
||
private Pong(IConnection connection, ISession session, IProducer producer, IConsumer consumer) | ||
{ | ||
_connection = connection; | ||
_session = session; | ||
_producer = producer; | ||
_consumer = consumer; | ||
_cts = new CancellationTokenSource(); | ||
|
||
_consumerLoopTask = ConsumerLoop(); | ||
} | ||
|
||
public static async Task<Pong> CreateAsync(Endpoint endpoint) | ||
{ | ||
var connectionFactory = new ConnectionFactory(); | ||
var connection = await connectionFactory.CreateAsync(endpoint); | ||
var session = await connection.CreateSessionAsync(); | ||
var producer = await session.CreateProducerAsync(new ProducerConfiguration { Address = "pong" }); | ||
var consumer = await session.CreateConsumerAsync(new ConsumerConfiguration { QueueName = "ping" }); | ||
return new Pong(connection, session, producer, consumer); | ||
} | ||
|
||
private Task ConsumerLoop() | ||
{ | ||
return Task.Run(async () => | ||
{ | ||
try | ||
{ | ||
while (!_cts.IsCancellationRequested) | ||
{ | ||
var pingMsg = await _consumer.ReceiveMessageAsync(_cts.Token); | ||
var pongMessage = new Message { Body = "Pong"u8.ToArray() }; | ||
await _producer.SendMessageAsync(pongMessage, _cts.Token); | ||
await _consumer.AcknowledgeAsync(pingMsg.MessageDelivery, _cts.Token); | ||
} | ||
} | ||
catch (OperationCanceledException) | ||
{ | ||
} | ||
}); | ||
} | ||
|
||
public async ValueTask DisposeAsync() | ||
{ | ||
await _cts.CancelAsync(); | ||
_cts.Dispose(); | ||
await _consumerLoopTask; | ||
await _consumer.DisposeAsync(); | ||
await _producer.DisposeAsync(); | ||
await _session.DisposeAsync(); | ||
await _connection.DisposeAsync(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
using ActiveMQ.Artemis.Core.Client; | ||
|
||
namespace PingPong_ArtemisNetCoreClient; | ||
|
||
class Program | ||
{ | ||
static async Task Main() | ||
{ | ||
var endpoint = new Endpoint | ||
{ | ||
Host = "localhost", | ||
Port = 61616, | ||
User = "artemis", | ||
Password = "artemis" | ||
}; | ||
|
||
for (int i = 0; i < 10; i++) | ||
{ | ||
await using var ping = await Ping.CreateAsync(endpoint); | ||
await using var pong = await Pong.CreateAsync(endpoint); | ||
var start = await ping.Start(skipMessages: 100, numberOfMessages: 10000); | ||
Console.WriteLine(start); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
namespace PingPong_ArtemisNetCoreClient; | ||
|
||
public class Stats | ||
{ | ||
public int MessagesCount { get; init; } | ||
public TimeSpan Elapsed { get; init; } | ||
|
||
public override string ToString() | ||
{ | ||
return $"Sent {MessagesCount} msgs in {Elapsed.TotalMilliseconds:F2}ms -- {MessagesCount / Elapsed.TotalSeconds:F2} msg/s"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
using System.Diagnostics; | ||
using Apache.NMS; | ||
|
||
namespace PingPong_NMS.AMQP | ||
{ | ||
public class Ping: IDisposable | ||
{ | ||
private readonly IConnection _connection; | ||
private readonly ISession _session; | ||
private readonly IMessageProducer _messageProducer; | ||
private readonly IMessageConsumer _messageConsumer; | ||
private readonly Stopwatch _stopwatch; | ||
private TaskCompletionSource<Stats>? _tsc; | ||
private int _numberOfMessages; | ||
private int _skipMessages; | ||
private int _counter; | ||
|
||
public Ping(IConnectionFactory connectionFactory) | ||
{ | ||
_connection = connectionFactory.CreateConnection(); | ||
_session = _connection.CreateSession(); | ||
_messageProducer = _session.CreateProducer(_session.GetQueue("ping")); | ||
_messageConsumer = _session.CreateConsumer(_session.GetQueue("pong")); | ||
_messageConsumer.Listener += OnMessage; | ||
_stopwatch = new Stopwatch(); | ||
_connection.Start(); | ||
} | ||
|
||
private void OnMessage(IMessage message) | ||
{ | ||
if (_skipMessages > 0) | ||
_skipMessages--; | ||
else | ||
_counter++; | ||
|
||
if (_counter == _numberOfMessages) | ||
{ | ||
_stopwatch.Stop(); | ||
_tsc.SetResult(new Stats { MessagesCount = _counter, Elapsed = _stopwatch.Elapsed }); | ||
} | ||
else | ||
{ | ||
var pingMessage = _messageProducer.CreateBytesMessage("Ping"u8.ToArray()); | ||
_messageProducer.Send(pingMessage); | ||
} | ||
} | ||
|
||
public Task<Stats> Start(int numberOfMessages, int skipMessages) | ||
{ | ||
_numberOfMessages = numberOfMessages; | ||
_skipMessages = skipMessages; | ||
_tsc = new TaskCompletionSource<Stats>(TaskCreationOptions.RunContinuationsAsynchronously); | ||
_stopwatch.Start(); | ||
var pingMessage = _messageProducer.CreateBytesMessage("Ping"u8.ToArray()); | ||
_messageProducer.Send(pingMessage); | ||
return _tsc.Task; | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
_messageConsumer.Dispose(); | ||
_messageProducer.Dispose(); | ||
_session.Dispose(); | ||
_connection.Dispose(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Apache.NMS.AMQP" Version="2.2.0" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Oops, something went wrong.