Exemple #1
0
        public async Task TryProcess_IncrementsExecutedMetric()
        {
            // Arrange
            var metricsRegistry = new Mock <IMetricsRegistry> {
                DefaultValue = DefaultValue.Mock
            };
            var limit = new FixedLimit(5, metricsRegistry.Object);

            var operationsExecuted = new Mock <ICounter>();

            metricsRegistry.Setup(r => r.CreateCounter(
                                      SimpleLimiter.Metrics.Executed.Name,
                                      It.IsAny <string>(),
                                      It.IsAny <string[]>())
                                  .WithLabels(It.IsAny <string[]>())).Returns(operationsExecuted.Object);

            var limiter = new SimpleLimiter(limit, metricsRegistry.Object);

            // Act
            await limiter.TryProcess(() => Task.FromResult(0));

            await limiter.TryProcess(() => Task.FromResult(0));

            await limiter.TryProcess(() => Task.FromResult(0));

            await limiter.TryProcess(() => Task.FromResult(0));

            // Assert
            operationsExecuted.Verify(c => c.Increment(), Times.Exactly(4));
        }
Exemple #2
0
        public void TryProcess_IncrementsLimitedMetric()
        {
            // Arrange
            var metricsRegistry = new Mock <IMetricsRegistry> {
                DefaultValue = DefaultValue.Mock
            };
            var limit = new FixedLimit(2, metricsRegistry.Object);

            var operationsLimited = new Mock <ICounter>();

            metricsRegistry.Setup(r => r.CreateCounter(
                                      SimpleLimiter.Metrics.Limited.Name,
                                      It.IsAny <string>(),
                                      It.IsAny <string[]>())
                                  .WithLabels(It.IsAny <string[]>())).Returns(operationsLimited.Object);

            var limiter = new SimpleLimiter(limit, metricsRegistry.Object);

            var requestBlocker          = new ManualResetEvent(false);
            var taskExecutedWaitHandles = new List <WaitHandle>
            {
                this.ProcessBlockingTask(limiter, requestBlocker),
                this.ProcessBlockingTask(limiter, requestBlocker)
            };

            WaitHandle.WaitAll(taskExecutedWaitHandles.ToArray());

            // Act
            // Temporarily ignore the warning about not awaiting Tasks since we actually
            // want the tasks to block so that we can build up the current operation count
            #pragma warning disable CS4014

            // Limit reached - the following requests will be limited
            limiter.TryProcess(() => Task.FromResult(0));
            limiter.TryProcess(() => Task.FromResult(0));
            #pragma warning restore CS4014

            // Assert
            operationsLimited.Verify(c => c.Increment(), Times.Exactly(2));

            requestBlocker.Set();
        }
Exemple #3
0
        /// <summary>
        /// Calls <see cref="SimpleLimiter.TryProcess(System.Func{Task})" /> with an
        /// operation that blocks until <paramref ref="blockUntil" /> is signalled.
        /// </summary>
        /// <param name="limiter">The limiter.</param>
        /// <param name="blockUntil">
        /// A <see cref="WaitHandle" /> handle that signals when the operation can complete.
        /// </param>
        /// <returns>
        /// A <see cref="WaitHandle" /> that can be waited on to ensure that the
        /// operation has begun executing before continuing.
        /// </returns>
        private WaitHandle ProcessBlockingTask(SimpleLimiter limiter, WaitHandle blockUntil)
        {
            var executedHandle = new ManualResetEvent(false);

            Task.Run(() => limiter.TryProcess(() =>
            {
                executedHandle.Set();
                blockUntil.WaitOne();

                return(Task.FromResult(0));
            }));

            return(executedHandle);
        }