public void ReturnsZeroTimeSpan_WhenMoreThanOneMessage()
        {
            var sut = new SqsReceiveDelayCalculator(new SqsPollingQueueReaderOptions
            {
                InitialDelay = TimeSpan.FromSeconds(2)
            });

            var result = sut.CalculateSecondsToDelay(new Message[] { new Message() });

            result.TotalSeconds.Should().Be(0);
        }
        public void ReturnsMaxValue_WhenSet()
        {
            var sut = new SqsReceiveDelayCalculator(new SqsPollingQueueReaderOptions
            {
                InitialDelay = TimeSpan.FromSeconds(10),
                MaxDelay     = TimeSpan.FromSeconds(5)
            });

            sut.CalculateSecondsToDelay(Array.Empty <Message>());

            var result = sut.CalculateSecondsToDelay(Array.Empty <Message>());

            result.TotalSeconds.Should().Be(5);
        }
        public void ReturnsInitialDelayForAllCalls_WhenNotUsingExponentialBackOff()
        {
            var sut = new SqsReceiveDelayCalculator(new SqsPollingQueueReaderOptions
            {
                InitialDelay          = TimeSpan.FromSeconds(10),
                UseExponentialBackoff = false
            });

            sut.CalculateSecondsToDelay(Array.Empty <Message>());
            sut.CalculateSecondsToDelay(Array.Empty <Message>());

            var result = sut.CalculateSecondsToDelay(Array.Empty <Message>());

            result.TotalSeconds.Should().Be(10);
        }
        public void ReturnsExpectedDelay_WhenUsingExponentialBackOff(int numberOfEmptyPolls, int expected)
        {
            var sut = new SqsReceiveDelayCalculator(new SqsPollingQueueReaderOptions
            {
                InitialDelay = TimeSpan.FromSeconds(2)
            });

            TimeSpan result = TimeSpan.FromSeconds(-1);

            for (int i = 0; i < numberOfEmptyPolls; i++)
            {
                result = sut.CalculateSecondsToDelay(Array.Empty <Message>());
            }

            result.TotalSeconds.Should().Be(expected);
        }
        public ISqsPollingQueueReader GetOrCreateReader(string name)
        {
            _ = name ?? throw new ArgumentNullException(nameof(name));

            var channel = GetOrCreateChannel(name);

            var options = _optionsMonitor.Get(name);

            var sqs             = _services.GetRequiredService <IAmazonSQS>();
            var delayCalculator = new SqsReceiveDelayCalculator(options.Options);

            var exceptionHandler =
                options.ExceptionHandlerType is object type?_services.GetService((Type)type) as IExceptionHandler : null;

            exceptionHandler ??= _exceptionHandler ?? DefaultExceptionHandler.Instance;

            var queueReader = new Lazy <SqsPollingQueueReader>(() => new SqsPollingQueueReader(options.Options, sqs, delayCalculator, exceptionHandler, channel), LazyThreadSafetyMode.ExecutionAndPublication).Value;

            return(queueReader);
        }