Пример #1
0
 protected BaseLookupFacade(LookupDispatcher lookupDispatcher, LookupRateLimiter lookupRateLimiter, ExceptionFactory exceptionFactory, TimeSpan timeout)
 {
     _lookupRateLimiter = lookupRateLimiter;
     _lookupDispatcher  = lookupDispatcher;
     _exceptionFactory  = exceptionFactory;
     _timeout           = timeout;
 }
Пример #2
0
 public MarketSummaryFacade(
     MarketSummaryRequestFormatter marketSummaryRequestFormatter,
     LookupDispatcher lookupDispatcher,
     LookupRateLimiter lookupRateLimiter,
     ExceptionFactory exceptionFactory,
     TimeSpan timeout) : base(lookupDispatcher, lookupRateLimiter, exceptionFactory, timeout)
 {
     _marketSummaryRequestFormatter = marketSummaryRequestFormatter;
 }
Пример #3
0
 public ChainsFacade(
     ChainsRequestFormatter chainsRequestFormatter,
     ChainsMessageHandler chainsMessageHandler,
     LookupDispatcher lookupDispatcher,
     LookupRateLimiter lookupRateLimiter,
     ExceptionFactory exceptionFactory,
     TimeSpan timeout) : base(lookupDispatcher, lookupRateLimiter, exceptionFactory, timeout)
 {
     _chainsMessageHandler   = chainsMessageHandler;
     _chainsRequestFormatter = chainsRequestFormatter;
 }
        public void Should_Validate_RequestsPerSecond()
        {
            // Arrange
            var requestsPerSecond = 50;

            // Act
            var lookupRateLimiter = new LookupRateLimiter(requestsPerSecond);

            // Assert
            Assert.AreEqual(lookupRateLimiter.RequestsPerSecond, requestsPerSecond);
        }
 public NewsFacade(
     NewsRequestFormatter newsRequestFormatter,
     LookupDispatcher lookupDispatcher,
     LookupRateLimiter lookupRateLimiter,
     ExceptionFactory exceptionFactory,
     NewsMessageHandler newsMessageHandler,
     TimeSpan timeout) : base(lookupDispatcher, lookupRateLimiter, exceptionFactory, timeout)
 {
     _newsMessageHandler   = newsMessageHandler;
     _newsRequestFormatter = newsRequestFormatter;
 }
        public void Should_Dispose()
        {
            // Arrange
            var requestsPerSecond = 50;
            var lookupRateLimiter = new LookupRateLimiter(requestsPerSecond);

            // Act
            lookupRateLimiter.Dispose();

            // Assert
            Assert.False(lookupRateLimiter.IsRunning);
        }
        public LookupMessageFileHandler(
            LookupDispatcher lookupDispatcher,
            LookupRateLimiter lookupRateLimiter,
            ExceptionFactory exceptionFactory,
            TimeSpan timeout)
        {
            _endOfMsgBytes = Encoding.ASCII.GetBytes(IQFeedDefault.ProtocolEndOfMessageCharacters + IQFeedDefault.ProtocolDelimiterCharacter + IQFeedDefault.ProtocolTerminatingCharacters);

            _lookupDispatcher  = lookupDispatcher;
            _lookupRateLimiter = lookupRateLimiter;
            _exceptionFactory  = exceptionFactory;
            _timeout           = timeout;
        }
        public void Should_Validate_Interval()
        {
            // Arrange
            var requestsPerSecond = 50;

            // Act
            var lookupRateLimiter = new LookupRateLimiter(requestsPerSecond);

            // Assert
            var expectedInterval = TimeSpan.FromMilliseconds(1000 / requestsPerSecond);

            Assert.AreEqual(lookupRateLimiter.Interval, expectedInterval);
        }
 public HistoricalFacade(
     HistoricalRequestFormatter historicalRequestFormatter,
     LookupDispatcher lookupDispatcher,
     LookupRateLimiter lookupRateLimiter,
     ExceptionFactory exceptionFactory,
     IHistoricalMessageHandler historicalMessageHandler,
     HistoricalFileFacade historicalFileFacade,
     TimeSpan timeout) : base(lookupDispatcher, lookupRateLimiter, exceptionFactory, timeout)
 {
     _historicalMessageHandler   = historicalMessageHandler;
     _historicalRequestFormatter = historicalRequestFormatter;
     File = historicalFileFacade;
 }
        public void Should_Validate_MaxCount()
        {
            // Arrange
            var requestsPerSecond = 50;

            // Act
            var lookupRateLimiter = new LookupRateLimiter(requestsPerSecond);

            // Assert
            var expectedMaxCount = 25;

            Assert.AreEqual(lookupRateLimiter.MaxCount, expectedMaxCount);
        }
 public SymbolFacade(
     SymbolRequestFormatter symbolRequestFormatter,
     LookupDispatcher lookupDispatcher,
     LookupRateLimiter lookupRateLimiter,
     ExceptionFactory exceptionFactory,
     SymbolMessageHandler symbolMessageHandler,
     MarketSymbolReader marketSymbolReader,
     ExpiredOptionReader expiredOptionReader,
     FileDownloader fileDownloader,
     TimeSpan timeout) : base(lookupDispatcher, lookupRateLimiter, exceptionFactory, timeout)
 {
     _symbolRequestFormatter = symbolRequestFormatter;
     _symbolMessageHandler   = symbolMessageHandler;
     _expiredOptionReader    = expiredOptionReader;
     _marketSymbolReader     = marketSymbolReader;
     _fileDownloader         = fileDownloader;
 }
        public async Task Should_Rate_Limit_By_Throughput()
        {
            // Arrange
            var totalSeconds = TimeSpan.FromSeconds(15).TotalSeconds;
            var seconds      = 0;

            var requestsPerSecond = 50;
            var requestsCount     = 0;
            var requests          = new List <int>();

            var lookupRateLimiter = new LookupRateLimiter(requestsPerSecond);
            var cts = new CancellationTokenSource();

            // Act
            _ = Task.Run(async() =>
            {
                while (true)
                {
                    await lookupRateLimiter.WaitAsync();
                    Interlocked.Increment(ref requestsCount);
                }
            }, cts.Token);

            while (seconds < totalSeconds)
            {
                var sw = Stopwatch.StartNew();
                await Task.Delay(TimeSpan.FromSeconds(1));

                sw.Stop();

                Console.WriteLine($"requests: {requestsCount}/{sw.Elapsed.TotalMilliseconds}ms");
                requests.Add(requestsCount);
                Interlocked.Exchange(ref requestsCount, 0);
                seconds++;
            }

            cts.Cancel();
            cts.Dispose();

            // Assert
            Assert.That(requests.Average(), Is.EqualTo(requestsPerSecond).Within(2).Percent);
        }
        public async Task Should_Rate_Limit_By_Throughput()
        {
            // Arrange
            var debug             = false;
            var totalSeconds      = TimeSpan.FromSeconds(10).TotalSeconds;
            var requestsPerSecond = 50;
            var numberOfClients   = 15;
            var testResults       = new List <TestResult>();

            var lookupRateLimiter = new LookupRateLimiter(requestsPerSecond);
            var cts = new CancellationTokenSource();
            await Task.Delay(1000);

            var tasks = new Task[numberOfClients];
            var mutex = new object();

            var requestsCount = 0;
            var seconds       = 0;

            for (var i = 0; i < numberOfClients; i++)
            {
                var taskId = i;
                tasks[i] = new Task(async() =>
                {
                    while (true)
                    {
                        await lookupRateLimiter.WaitAsync().ConfigureAwait(false);
                        if (debug)
                        {
                            Console.WriteLine($"Executed task #{taskId}");
                        }
                        lock (mutex)
                            requestsCount++;
                    }
                }, cts.Token);
            }

            // Act
            for (var i = 0; i < numberOfClients; i++)
            {
                tasks[i].Start();
            }

            while (seconds < totalSeconds)
            {
                var sw = Stopwatch.StartNew();
                await Task.Delay(TimeSpan.FromSeconds(1));

                sw.Stop();

                Console.WriteLine($"requests: {requestsCount}/{sw.Elapsed.TotalMilliseconds}ms");
                lock (mutex)
                {
                    testResults.Add(new TestResult(requestsCount, sw.Elapsed.TotalMilliseconds));
                    requestsCount = 0;
                }
                seconds++;
            }

            cts.Cancel();
            cts.Dispose();

            // Assert

            // initial burst
            var initialBurst = testResults.First();
            var calcInitialBustRequestsPerSecond = initialBurst.NumberOfRequest * 1000 / initialBurst.TotalMilliseconds;
            var expectedInitialBurst             = lookupRateLimiter.RequestsPerSecond + lookupRateLimiter.MaxCount;

            Assert.That(calcInitialBustRequestsPerSecond, Is.LessThan(expectedInitialBurst).Within(5).Percent);
            Console.WriteLine($"Initial burst {calcInitialBustRequestsPerSecond} requests/second");

            // average
            var testResultsWithoutInitialBurst = testResults.Skip(1).ToList();
            var totalMs               = testResultsWithoutInitialBurst.Sum(x => x.TotalMilliseconds);
            var totalRequests         = testResultsWithoutInitialBurst.Sum(x => x.NumberOfRequest);
            var calcRequestsPerSecond = totalRequests * 1000 / totalMs;
            var variationPercentage   = Math.Abs(calcRequestsPerSecond - requestsPerSecond) / requestsPerSecond * 100;

            Console.WriteLine($"Average {calcRequestsPerSecond} requests/second");
            Console.WriteLine($"Variation {variationPercentage} %");
            Assert.That(calcRequestsPerSecond, Is.EqualTo(requestsPerSecond).Within(1).Percent);
        }