Exemplo n.º 1
0
        /// <summary>
        /// Saves the single quote query result or updates it if it already exists.
        /// </summary>
        /// <param name="query"><see cref="SingleQuoteQuery"/> to upsert data for.</param>
        /// <param name="queryResult"><see cref="SingleQuoteQueryResult"/> stock data results to save.</param>
        /// <remarks>
        /// Will update the database and then <see cref="SingleQuoteCache"/> if it was successful.
        /// Error results will be ignored.
        /// </remarks>
        public async Task UpsertSingleQuoteData(SingleQuoteQuery query, SingleQuoteQueryResult queryResult)
        {
            if (queryResult.HasError)
            {
                return;
            }

            _logger.LogTrace("Query SymbolId {id} added to cache", query.SymbolId);

            const int primaryKeyViolationCode = 2627;

            try
            {
                bool successfulSave = await _stockDataRepository.UpsertSingleQuoteData(new UpsertSingleQuoteData(query.SymbolId, queryResult.Data));

                _logger.LogTrace("Query SymbolId {id} saved to database", query.SymbolId);

                if (!successfulSave)
                {
                    throw new ArgumentException($"query for symbolId {query.SymbolId} was not able to be updated");
                }
            }
            catch (SqlException ex) when(ex.ErrorCode == primaryKeyViolationCode)
            {
                _logger.LogError("Query SymbolId {id} was duplicate insert in database", query.SymbolId);

                // Ignore the error since it means a race condition where we tried insert twice.
                // But that's fine since the stock data is unlikely to be different if it's that close in time.
                // This is more performant than adding locks as this case should be very exceptional.
            }

            // Only insert into cache if it successfully saved into database.
            _singleQuoteCache.Upsert(query.SymbolId, queryResult);
        }
Exemplo n.º 2
0
        public async Task GetSingleQuoteData_ShouldGetValueFromCache()
        {
            var query       = new SingleQuoteQuery(1);
            var queryResult = new SingleQuoteQueryResult("MSFT", _singleQuoteData);

            _cache.Upsert(query.SymbolId, queryResult);

            StockSingleQuoteDataDTO data = await _service.GetSingleQuoteData(query.SymbolId);

            Assert.Equal(queryResult.Data, data.Data);
            _stockDataRepository.Verify(s => s.GetSingleQuoteData(It.IsAny <int>()), Times.Never);
        }