private async Task <CustomerRewardsProfile> GetCacheDataAsync(Guid customerId) { CustomerRewardsProfile result = null; try { logger.LogInformation($"Retrieving data for {LoyaltyConstants.CUSTOMER_ID}:{customerId} from cache data source."); result = await cacheDataSource.GetRewardsInfoAsync(customerId).TimeoutAfter(this.cacheDataTimeout); logger.LogInformation($"Received data from cache data source for {LoyaltyConstants.CUSTOMER_ID}:{customerId}."); } catch (Exception e) { logger.LogError(e, "Exception encountered while trying to get data from cache."); } // If we have a cache miss. Fetch data from live source and backfill cache. // TODO: ADD A CONFIG FLAG HERE SO WE CAN CONTROLL THE FALLBACK BEHAVIOR, SO THAT THE FALLBACK MECHANISM WILL NOT BRING DOWN OUR VENDOR'S DB. // Without fallback, return will be null with cache miss. if (result == null) { logger.LogWarning($"Unable to retrieve data for {LoyaltyConstants.CUSTOMER_ID}:{customerId} from cache. Attempt to retrieve data from live data source and backfill cache."); try { logger.LogInformation($"Retrieving data for {LoyaltyConstants.CUSTOMER_ID}:{customerId} from live data source."); result = await liveDataSource.GetRewardsInfoAsync(customerId).TimeoutAfter(this.liveDataTimeout); logger.LogInformation($"Received data from live data source for {LoyaltyConstants.CUSTOMER_ID}:{customerId}. Backfilling cache.."); var cacheUpdateResult = await cacheUpdater.UpdateRewardsInfoAsync(result).ConfigureAwait(false); logger.LogInformation($"Cache data for {LoyaltyConstants.CUSTOMER_ID}:{customerId} is backfilled:{cacheUpdateResult}"); return(result); } catch (TimeoutException te) { var errorMsg = $"Unable to retrieve data from live data source to backfill cache for {LoyaltyConstants.CUSTOMER_ID}:{customerId}. Timed out after {this.liveDataTimeout.TotalMilliseconds}ms."; logger.LogError(te, errorMsg); //TODO: POSSIBILY CREATE A CUSTOM EXCEPTION FOR BETTER TRACKING/HANDLING throw new TimeoutException(errorMsg, te); } catch (Exception e) { logger.LogError(e, "Exception encountered while trying to get data from live data source as a fallback mechanism."); throw; } } return(result); }
/// <summary> /// Mapper function to transform vendor's model to our model /// </summary> /// <param name="vendorData"></param> /// <returns></returns> /// <remarks>In real code, mapper libraries will be used.</remarks> private CustomerRewardsProfile TransformData(VendorXRewardsData vendorData) { var mappedData = new CustomerRewardsProfile() { LevelInformation = new RewardsLevel() { Level = vendorData.Level, PointsEarnedYTD = vendorData.PointsEarnedYTD, PointsEarnedLifetime = vendorData.PointsEarnedLifetime }, NotesInformation = vendorData.Notes }; return(mappedData); }
public Task <bool> UpdateRewardsInfoAsync(CustomerRewardsProfile customerId) { //TODO: IMPLEMENT THE REAL CACHE UPDATE LOGIC return(Task.FromResult(true)); }