|
7 | 7 | using System.Threading.Tasks; |
8 | 8 | using Amazon.SQS; |
9 | 9 | using Amazon.SQS.Model; |
| 10 | +using AWS.Messaging.Configuration; |
10 | 11 | using AWS.Messaging.IntegrationTests.Handlers; |
11 | 12 | using AWS.Messaging.IntegrationTests.Models; |
12 | 13 | using AWS.Messaging.Tests.Common.Services; |
@@ -146,6 +147,88 @@ await publisher.PublishAsync(new ChatMessage |
146 | 147 | } |
147 | 148 | } |
148 | 149 |
|
| 150 | + [Fact] |
| 151 | + public async Task ReceiveMultipleMessagesOnlyWhenPollingControlTokenStarted() |
| 152 | + { |
| 153 | + var pollingControlToken = new PollingControlToken(); |
| 154 | + _serviceCollection.AddSingleton<TempStorage<ChatMessage>>(); |
| 155 | + _serviceCollection.AddAWSMessageBus(builder => |
| 156 | + { |
| 157 | + builder.ConfigurePollingControlToken(pollingControlToken); |
| 158 | + builder.AddSQSPublisher<ChatMessage>(_sqsQueueUrl); |
| 159 | + builder.AddSQSPoller(_sqsQueueUrl, options => |
| 160 | + { |
| 161 | + options.VisibilityTimeoutExtensionThreshold = 3; // and a message is eligible for extension after it's been processing at least 3 seconds |
| 162 | + options.MaxNumberOfConcurrentMessages = 10; |
| 163 | + options.WaitTimeSeconds = 2; |
| 164 | + }); |
| 165 | + builder.AddMessageHandler<ChatMessageHandler, ChatMessage>(); |
| 166 | + builder.AddMessageSource("/aws/messaging"); |
| 167 | + builder.ConfigureBackoffPolicy(policyBuilder => |
| 168 | + { |
| 169 | + policyBuilder.UseNoBackoff(); |
| 170 | + }); |
| 171 | + }); |
| 172 | + var serviceProvider = _serviceCollection.BuildServiceProvider(); |
| 173 | + |
| 174 | + var publishStartTime = DateTime.UtcNow; |
| 175 | + var publisher = serviceProvider.GetRequiredService<IMessagePublisher>(); |
| 176 | + for (int i = 0; i < 5; i++) |
| 177 | + { |
| 178 | + await publisher.PublishAsync(new ChatMessage |
| 179 | + { |
| 180 | + MessageDescription = $"Test{i + 1}" |
| 181 | + }); |
| 182 | + } |
| 183 | + var publishEndTime = DateTime.UtcNow; |
| 184 | + |
| 185 | + var pump = serviceProvider.GetRequiredService<IHostedService>() as MessagePumpService; |
| 186 | + Assert.NotNull(pump); |
| 187 | + var source = new CancellationTokenSource(); |
| 188 | + |
| 189 | + await pump.StartAsync(source.Token); |
| 190 | + |
| 191 | + // Wait for the pump to shut down after processing the expected number of messages, |
| 192 | + // with some padding to ensure messages aren't being processed more than once |
| 193 | + source.CancelAfter(30_000); |
| 194 | + |
| 195 | + var tempStorage = serviceProvider.GetRequiredService<TempStorage<ChatMessage>>(); |
| 196 | + while (tempStorage.Messages.Count < 5 && !source.IsCancellationRequested) |
| 197 | + { |
| 198 | + await Task.Delay(200, source.Token); |
| 199 | + } |
| 200 | + |
| 201 | + // Stop polling and wait for the polling cycle to complete with a buffer |
| 202 | + pollingControlToken.StopPolling(); |
| 203 | + |
| 204 | + await Task.Delay(5_000); |
| 205 | + |
| 206 | + // Publish the next 5 messages that should not be received due to stopping polling |
| 207 | + for (int i = 5; i < 10; i++) |
| 208 | + { |
| 209 | + await publisher.PublishAsync(new ChatMessage |
| 210 | + { |
| 211 | + MessageDescription = $"Test{i + 1}" |
| 212 | + }); |
| 213 | + } |
| 214 | + |
| 215 | + SpinWait.SpinUntil(() => source.IsCancellationRequested); |
| 216 | + |
| 217 | + var inMemoryLogger = serviceProvider.GetRequiredService<InMemoryLogger>(); |
| 218 | + |
| 219 | + Assert.Empty(inMemoryLogger.Logs.Where(x => x.Exception is AmazonSQSException ex && ex.ErrorCode.Equals("AWS.SimpleQueueService.TooManyEntriesInBatchRequest"))); |
| 220 | + Assert.Equal(5, tempStorage.Messages.Count); |
| 221 | + for (int i = 0; i < 5; i++) |
| 222 | + { |
| 223 | + var message = tempStorage.Messages.FirstOrDefault(x => x.Message.MessageDescription.Equals($"Test{i + 1}")); |
| 224 | + Assert.NotNull(message); |
| 225 | + Assert.False(string.IsNullOrEmpty(message.Id)); |
| 226 | + Assert.Equal("/aws/messaging", message.Source.ToString()); |
| 227 | + Assert.True(message.TimeStamp > publishStartTime); |
| 228 | + Assert.True(message.TimeStamp < publishEndTime); |
| 229 | + } |
| 230 | + } |
| 231 | + |
149 | 232 | [Theory] |
150 | 233 | [InlineData(20)] |
151 | 234 | public async Task SendMixOfMessageTypesToSameQueue(int numberOfMessages) |
|
0 commit comments