Skip to content

Commit 0ebf680

Browse files
Merge pull request #41 from LuccaSA/Simplify-quorum-creation
Queues quorum helper implementation + tests update
2 parents b57d02c + f2c6755 commit 0ebf680

35 files changed

+183
-180
lines changed

.github/workflows/dotnetcore.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ jobs:
1818
- name: Setup .NET
1919
uses: actions/setup-dotnet@v1
2020
with:
21-
dotnet-version: '6.0.x'
21+
dotnet-version: '8.0.x'
2222

2323
- name: Install GitVersion
2424
uses: gittools/actions/gitversion/setup@v0.9.7
2525
with:
26-
versionSpec: '5.10.1'
26+
versionSpec: '5.10.1'
2727

2828
- name: Use GitVersion
2929
id: gitversion # step id used as reference for output values

MerQure.sln

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1616
build_local.ps1 = build_local.ps1
1717
Directory.Build.props = Directory.Build.props
1818
.github\workflows\dotnetcore.yml = .github\workflows\dotnetcore.yml
19+
CHANGELOG.md = CHANGELOG.md
20+
GitVersion.yml = GitVersion.yml
21+
global.json = global.json
1922
EndProjectSection
2023
EndProject
2124
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MerQure.Tools", "src\MerQure.Tools\MerQure.Tools.csproj", "{46469C09-4E46-4C96-8588-49D121B4E4C0}"

global.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"sdk" : {
3-
"version": "6.0.100",
2+
"sdk": {
3+
"version": "8.0.203",
44
"rollForward": "latestFeature"
55
}
6-
}
6+
}

samples/MerQure.Samples/DeadLetterExample.cs

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using MerQure.RbMQ;
2-
using MerQure.RbMQ.Content;
1+
using MerQure.RbMQ.Content;
32
using System;
43
using System.Collections.Generic;
54

@@ -18,12 +17,12 @@ public void Run()
1817
{
1918
// RabbitMQ init
2019
_messagingService.DeclareExchange("deadletter.exchange", Constants.ExchangeTypeFanout);
21-
_messagingService.DeclareQueue("deadletter.queue");
20+
_messagingService.DeclareQueue("deadletter.queue", isQuorum: true);
2221
_messagingService.DeclareBinding("deadletter.exchange", "deadletter.queue", "#");
2322

2423
_messagingService.DeclareExchange("delay.exchange", Constants.ExchangeTypeHeaders);
25-
_messagingService.DeclareQueueWithDeadLetterPolicy("deadletter.queue.5", "deadletter.exchange", 5000, null);
26-
_messagingService.DeclareQueueWithDeadLetterPolicy("deadletter.queue.30", "deadletter.exchange", 30000, null);
24+
_messagingService.DeclareQueueWithDeadLetterPolicy("deadletter.queue.5", "deadletter.exchange", 5000, null, isQuorum: true);
25+
_messagingService.DeclareQueueWithDeadLetterPolicy("deadletter.queue.30", "deadletter.exchange", 30000, null, isQuorum: true);
2726

2827
_messagingService.DeclareBinding("delay.exchange", "deadletter.queue.5", "#", new Dictionary<string, object> { { "delay", 5 } });
2928
_messagingService.DeclareBinding("delay.exchange", "deadletter.queue.30", "#", new Dictionary<string, object> { { "delay", 30 } });

samples/MerQure.Samples/MerQure.Samples.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net6.0</TargetFramework>
5+
<TargetFramework>net8.0</TargetFramework>
66
</PropertyGroup>
77

88
<ItemGroup>

samples/MerQure.Samples/SimpleExample.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public void Run()
1616
{
1717
// RabbitMQ init
1818
_messagingService.DeclareExchange("simple.exchange");
19-
_messagingService.DeclareQueue("simple.queue");
19+
_messagingService.DeclareQueue("simple.queue", isQuorum: true);
2020
_messagingService.DeclareBinding("simple.exchange", "simple.queue", "simple.message.*");
2121

2222
// Get the publisher and declare Exhange where publish messages

samples/MerQure.Samples/StopExample.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using MerQure.RbMQ;
2-
using MerQure.RbMQ.Content;
1+
using MerQure.RbMQ.Content;
32
using System;
43

54
namespace MerQure.Samples
@@ -17,7 +16,7 @@ public void Run()
1716
{
1817
// RabbitMQ init
1918
_messagingService.DeclareExchange("stop.exchange");
20-
_messagingService.DeclareQueue("stop.queue");
19+
_messagingService.DeclareQueue("stop.queue", isQuorum: true);
2120
_messagingService.DeclareBinding("stop.exchange", "stop.queue", "stop.message.* ");
2221

2322
// Get the publisher and declare Exhange where publish messages

samples/MerQure.Tools.Samples/MerQure.Tools.Samples.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net6.0</TargetFramework>
5+
<TargetFramework>net8.0</TargetFramework>
66
</PropertyGroup>
77

88
<ItemGroup>

samples/MerQure.Tools.Samples/RetryBusExample/Domain/Sample.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11

22
using MerQure.Messages;
3-
using MerQure.Tools.Messages;
43

54
namespace MerQure.Tools.Samples.RetryBusExample.Domain
65
{

samples/MerQure.Tools.Samples/RetryBusExample/Domain/SampleException.cs

-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
62

73
namespace MerQure.Tools.Samples.RetryBusExample.Domain
84
{

samples/MerQure.Tools.Samples/RetryBusExample/Infra/SampleService.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public SampleService(IRetryBusService retryBusService)
3333
DeliveryDelayInMilliseconds = 1000
3434
};
3535

36-
SampleBus = _retryBusService.CreateNewBus<Sample>(sampleConfiguration);
36+
SampleBus = _retryBusService.CreateNewBus<Sample>(sampleConfiguration, isQuorum: true);
3737
}
3838

3939
public void Send(Sample sample)

src/MerQure.RbMQ/Clients/Publisher.cs

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using MerQure.RbMQ.Helpers;
44
using MerQure.RbMQ.Content;
55
using System.Collections.Generic;
6-
using System.Threading;
76

87
namespace MerQure.RbMQ.Clients
98
{

src/MerQure.RbMQ/Constants.cs

+3
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,8 @@ public static class Constants
5959
/// Routing Dead-Lettered Messages
6060
/// </summary>
6161
public const string QueueDeadLetterRoutingKey = "x-dead-letter-routing-key";
62+
63+
public const string HeaderQueueType = "x-queue-type";
64+
public const string HeaderQueueTypeQuorumValue = "quorum";
6265
}
6366
}

src/MerQure.RbMQ/MessagingService.cs

+36-15
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,19 @@ public class MessagingService : IMessagingService
1818
protected IConnection CurrentConnection => _sharedConnection.CurrentConnection;
1919

2020
private readonly SharedConnection _sharedConnection;
21-
private readonly IOptions<MerQureConfiguration> _merQureConfiguration;
2221

2322
public MessagingService(IOptions<MerQureConfiguration> merQureConfiguration, SharedConnection sharedConnection)
2423
{
25-
_merQureConfiguration = merQureConfiguration;
2624
_sharedConnection = sharedConnection;
2725

28-
if (_merQureConfiguration == null)
26+
if (merQureConfiguration == null)
2927
{
3028
return;
3129
}
32-
Durable = _merQureConfiguration.Value.Durable;
33-
AutoDeleteQueue = _merQureConfiguration.Value.AutoDeleteQueue;
34-
DefaultPrefetchCount = _merQureConfiguration.Value.DefaultPrefetchCount;
35-
PublisherAcknowledgementsTimeoutInMilliseconds = _merQureConfiguration.Value.PublisherAcknowledgementsTimeoutInMilliseconds;
30+
Durable = merQureConfiguration.Value.Durable;
31+
AutoDeleteQueue = merQureConfiguration.Value.AutoDeleteQueue;
32+
DefaultPrefetchCount = merQureConfiguration.Value.DefaultPrefetchCount;
33+
PublisherAcknowledgementsTimeoutInMilliseconds = merQureConfiguration.Value.PublisherAcknowledgementsTimeoutInMilliseconds;
3634
}
3735

3836
public void DeclareExchange(string exchangeName)
@@ -50,20 +48,20 @@ public void DeclareExchange(string exchangeName, string exchangeType)
5048
}
5149
}
5250

53-
public void DeclareQueue(string queueName, byte maxPriority)
51+
public string DeclareQueue(string queueName, byte maxPriority, bool isQuorum)
5452
{
5553
var queueArgs = new Dictionary<string, object> {
5654
{ Constants.QueueMaxPriority, maxPriority }
5755
};
58-
DeclareQueue(queueName, queueArgs);
56+
return DeclareQueue(queueName, queueArgs, isQuorum);
5957
}
6058

61-
public void DeclareQueue(string queueName)
59+
public string DeclareQueue(string queueName, bool isQuorum)
6260
{
63-
DeclareQueue(queueName, new Dictionary<string, object>());
61+
return DeclareQueue(queueName, new Dictionary<string, object>(), isQuorum);
6462
}
6563

66-
public void DeclareQueueWithDeadLetterPolicy(string queueName, string deadLetterExchange, int messageTimeToLive, string deadLetterRoutingKey)
64+
public string DeclareQueueWithDeadLetterPolicy(string queueName, string deadLetterExchange, int messageTimeToLive, string deadLetterRoutingKey, bool isQuorum)
6765
{
6866
if (string.IsNullOrWhiteSpace(deadLetterExchange)) throw new ArgumentNullException(nameof(deadLetterExchange));
6967
if (messageTimeToLive <= 0) throw new ArgumentOutOfRangeException(nameof(messageTimeToLive));
@@ -76,18 +74,41 @@ public void DeclareQueueWithDeadLetterPolicy(string queueName, string deadLetter
7674
{
7775
queueArgs.Add(Constants.QueueDeadLetterRoutingKey, deadLetterRoutingKey);
7876
}
79-
DeclareQueue(queueName, queueArgs);
77+
return DeclareQueue(queueName, queueArgs, isQuorum);
8078
}
79+
private const string QuorumQueueNameSuffix ="-q";
8180

82-
public void DeclareQueue(string queueName, Dictionary<string, object> queueArgs)
81+
public string DeclareQueue(string queueName, Dictionary<string, object> queueArgs, bool isQuorum)
8382
{
8483
if (string.IsNullOrWhiteSpace(queueName)) throw new ArgumentNullException(nameof(queueName));
8584
if (queueArgs == null) throw new ArgumentNullException(nameof(queueArgs));
8685

86+
Dictionary<string, object> effectiveQueueArgs;
87+
string effectiveQueueName;
88+
if(isQuorum)
89+
{
90+
if(!Durable || AutoDeleteQueue)
91+
{
92+
throw new ArgumentException("Quorum queues must be durable and non-auto-delete");
93+
}
94+
effectiveQueueArgs = new Dictionary<string, object>(queueArgs)
95+
{
96+
{ Constants.HeaderQueueType, Constants.HeaderQueueTypeQuorumValue }
97+
};
98+
effectiveQueueName = $"{queueName}{QuorumQueueNameSuffix}";
99+
}
100+
else
101+
{
102+
effectiveQueueArgs = queueArgs;
103+
effectiveQueueName = queueName;
104+
}
105+
87106
using (var channel = CurrentConnection.CreateModel())
88107
{
89-
channel.QueueDeclare(queueName.ToLowerInvariant(), this.Durable, false, this.AutoDeleteQueue, queueArgs);
108+
channel.QueueDeclare(effectiveQueueName.ToLowerInvariant(), this.Durable, false, this.AutoDeleteQueue, effectiveQueueArgs);
90109
}
110+
111+
return effectiveQueueName;
91112
}
92113

93114
public void DeclareBinding(string exchangeName, string queueName, string routingKey)

src/MerQure.Tools/Buses/Bus.cs

-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
using MerQure.Messages;
22
using MerQure.Tools.Configurations;
3-
using MerQure.Tools.Messages;
43
using System;
54
using System.Collections.Generic;
6-
using System.Text;
75

86
namespace MerQure.Tools.Buses
97
{

src/MerQure.Tools/Buses/Consumer.cs

-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
using Newtonsoft.Json;
55
using System;
66
using System.Collections.Generic;
7-
using System.Linq;
8-
using System.Text;
9-
using System.Threading.Tasks;
107

118
namespace MerQure.Tools.Buses
129
{

src/MerQure.Tools/Buses/ConsumerProvider.cs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
using MerQure.Tools.Configurations;
2-
using System;
32
using System.Collections.Generic;
43

54
namespace MerQure.Tools.Buses
65
{
76
public class ConsumerProvider
87
{
9-
private static object _syncRoot = new Object();
8+
private static readonly object _syncRoot = new();
109

1110
private readonly Dictionary<string, IConsumer> _consumers = new Dictionary<string, IConsumer>();
1211
private readonly IMessagingService _messagingService;
@@ -21,9 +20,9 @@ public IConsumer Get(Channel channel)
2120
IConsumer consumer;
2221
lock (_syncRoot)
2322
{
24-
if (_consumers.ContainsKey(channel.Value))
23+
if (_consumers.TryGetValue(channel.Value, out var foundConsumer))
2524
{
26-
consumer = _consumers[channel.Value];
25+
consumer = foundConsumer;
2726
}
2827
else
2928
{

src/MerQure.Tools/Buses/Publisher.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public void PublishOnRetryExchange(Channel channel, T message, RetryInformations
6767
}
6868
else
6969
{
70-
delay = delays.Last();
70+
delay = delays[delays.Count-1];
7171
}
7272
retryInformations.NumberOfRetry++;
7373
RetryMessage<T> retryMessage = new RetryMessage<T>
@@ -97,7 +97,7 @@ internal void PublishOnErrorExchange(Channel channel, T message, RetryInformatio
9797
}
9898
}
9999

100-
internal void TryPublishWithBrokerAcknowledgement(IPublisher publisher, string channelName, string message)
100+
private static void TryPublishWithBrokerAcknowledgement(IPublisher publisher, string channelName, string message)
101101
{
102102
bool published = publisher.PublishWithAcknowledgement(channelName, message);
103103
if (!published)
@@ -106,7 +106,7 @@ internal void TryPublishWithBrokerAcknowledgement(IPublisher publisher, string c
106106
}
107107
}
108108

109-
internal void PublishWithTransaction(IPublisher publisher, string channelName, IEnumerable<string> messages)
109+
private static void PublishWithTransaction(IPublisher publisher, string channelName, List<string> messages)
110110
{
111111
try
112112
{
@@ -118,7 +118,7 @@ internal void PublishWithTransaction(IPublisher publisher, string channelName, I
118118
}
119119
}
120120

121-
private RetryMessage<T> CreateRetryMessage(T message)
121+
private static RetryMessage<T> CreateRetryMessage(T message)
122122
{
123123
return new RetryMessage<T>
124124
{

src/MerQure.Tools/Buses/RetryConsumer.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ internal void SendToErrorExchange(Channel channel, T deliveredMessage)
3535

3636
public MessageInformations ForceRetryStrategy(Channel channel, T message, int attemptNumber)
3737
{
38-
var retryInformations = new RetryInformations()
38+
var retryInformations = new RetryInformations
3939
{
4040
NumberOfRetry = attemptNumber > 0 ? attemptNumber - 1 : 0
4141
};

src/MerQure.Tools/Configurations/Channel.cs

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
6-
7-
namespace MerQure.Tools.Configurations
1+
namespace MerQure.Tools.Configurations
82
{
93
public class Channel
104
{

src/MerQure.Tools/Configurations/RetryStrategyConfiguration.cs

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
using MerQure;
2-
using System;
3-
using System.Collections.Generic;
4-
using System.Linq;
5-
using System.Text;
6-
using System.Threading.Tasks;
1+
using System.Collections.Generic;
72

83
namespace MerQure.Tools.Configurations
94
{

src/MerQure.Tools/IRetryBusService.cs

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
using MerQure.Messages;
22
using MerQure.Tools.Buses;
33
using MerQure.Tools.Configurations;
4-
using System;
5-
using System.Collections.Generic;
6-
using System.Linq;
7-
using System.Text;
8-
using System.Threading.Tasks;
94

105
namespace MerQure.Tools
116
{
127
public interface IRetryBusService
138
{
14-
IBus<T> CreateNewBus<T>(RetryStrategyConfiguration configuration) where T : IDelivered;
9+
IBus<T> CreateNewBus<T>(RetryStrategyConfiguration configuration, bool isQuorum) where T : IDelivered;
1510
}
1611
}

src/MerQure.Tools/MerQure.Tools.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
</PropertyGroup>
66

77
<ItemGroup>
8-
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
8+
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
99
</ItemGroup>
1010

1111
<ItemGroup>

src/MerQure.Tools/Messages/RetryInformations.cs

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
6-
7-
namespace MerQure.Tools.Messages
1+
namespace MerQure.Tools.Messages
82
{
93
public class RetryInformations
104
{

0 commit comments

Comments
 (0)