private void FetchProfileIfNeeded(CultureInfo culture) { if (_fetchedCultures.Contains(culture)) { return; } lock (_lock) { if (!_fetchedCultures.Contains(culture) && _dataRouterManager != null) { var task = Task.Run(async() => await _dataRouterManager.GetCompetitorAsync(Id, culture, null).ConfigureAwait(false)); task.Wait(); } } }
/// <summary> /// Asynchronously gets <see cref="CompetitorCI" /> representing the profile for the specified competitor /// </summary> /// <param name="competitorId">A <see cref="URN" /> specifying the id of the competitor for which to get the profile</param> /// <param name="cultures"> /// A <see cref="IEnumerable{CultureInfo}" /> specifying languages in which the information should /// be available /// </param> /// <returns>A <see cref="Task{PlayerProfileCI}" /> representing the asynchronous operation</returns> /// <exception cref="CacheItemNotFoundException"> /// The requested item was not found in cache and could not be obtained from /// the API /// </exception> public async Task <CompetitorCI> GetCompetitorProfileAsync(URN competitorId, IEnumerable <CultureInfo> cultures) { Contract.Requires(competitorId != null); Contract.Requires(cultures != null && cultures.Any()); Metric.Context("CACHE").Meter("ProfileCache->GetCompetitorProfileAsync", Unit.Calls); await _semaphore.WaitAsync().ConfigureAwait(false); CompetitorCI cachedItem; try { cachedItem = (CompetitorCI)_cache.Get(competitorId.ToString()); var missingLanguages = LanguageHelper.GetMissingCultures(cultures, cachedItem?.Names.Keys).ToList(); if (!missingLanguages.Any()) { return(cachedItem); } var cultureTasks = missingLanguages.ToDictionary(c => c, c => _dataRouterManager.GetCompetitorAsync(competitorId, c, null)); await Task.WhenAll(cultureTasks.Values).ConfigureAwait(false); cachedItem = (CompetitorCI)_cache.Get(competitorId.ToString()); } catch (Exception ex) { if (ex is CommunicationException || ex is DeserializationException || ex is MappingException) { throw new CacheItemNotFoundException( "An error occurred while fetching competitor profile not found in cache", competitorId.ToString(), ex); } throw; } finally { if (!_isDisposed) { _semaphore.Release(); } } return(cachedItem); }
public async Task <PlayerProfileCI> GetPlayerProfileAsync(URN playerId, IEnumerable <CultureInfo> cultures) { Guard.Argument(playerId, nameof(playerId)).NotNull(); Guard.Argument(cultures, nameof(cultures)).NotNull(); if (!cultures.Any()) { throw new ArgumentOutOfRangeException(nameof(cultures)); } var timerOptions = new TimerOptions { Context = "ProfileCache", Name = "GetPlayerProfileAsync", MeasurementUnit = Unit.Requests }; using (SdkMetricsFactory.MetricsRoot.Measure.Timer.Time(timerOptions, $"{playerId}")) { await _semaphorePlayer.WaitAsync().ConfigureAwait(false); PlayerProfileCI cachedItem; try { cachedItem = (PlayerProfileCI)_cache.Get(playerId.ToString()); var wantedCultures = cultures.ToList(); var missingLanguages = LanguageHelper.GetMissingCultures(wantedCultures, cachedItem?.Names.Keys).ToList(); if (!missingLanguages.Any()) { return(cachedItem); } // try to fetch for competitor, to avoid requests by each player if (cachedItem?.CompetitorId != null) { var competitorCI = (CompetitorCI)_cache.Get(cachedItem.CompetitorId.ToString()); if (competitorCI != null && (competitorCI.LastTimeCompetitorProfileFetched < DateTime.Now.AddSeconds(-30) || LanguageHelper.GetMissingCultures(wantedCultures, competitorCI.CultureCompetitorProfileFetched).Any())) { ExecutionLog.LogDebug($"Fetching competitor profile for competitor {competitorCI.Id} instead of player {cachedItem.Id} for languages=[{string.Join(",", missingLanguages.Select(s => s.TwoLetterISOLanguageName))}]."); try { await _semaphoreCompetitor.WaitAsync().ConfigureAwait(false); var cultureTasks = missingLanguages.ToDictionary(c => c, c => _dataRouterManager.GetCompetitorAsync(competitorCI.Id, c, null)); await Task.WhenAll(cultureTasks.Values).ConfigureAwait(false); } catch (Exception) { // ignored } finally { if (!_isDisposed) { _semaphoreCompetitor.Release(); } } cachedItem = (PlayerProfileCI)_cache.Get(playerId.ToString()); missingLanguages = LanguageHelper.GetMissingCultures(wantedCultures, cachedItem?.Names.Keys).ToList(); if (!missingLanguages.Any()) { return(cachedItem); } } } var cultureTaskDictionary = missingLanguages.ToDictionary(c => c, c => _dataRouterManager.GetPlayerProfileAsync(playerId, c, null)); await Task.WhenAll(cultureTaskDictionary.Values).ConfigureAwait(false); cachedItem = (PlayerProfileCI)_cache.Get(playerId.ToString()); } catch (Exception ex) { if (ex is DeserializationException || ex is MappingException) { throw new CacheItemNotFoundException($"An error occurred while fetching player profile for player {playerId} in cache", playerId.ToString(), ex); } throw; } finally { if (!_isDisposed) { _semaphorePlayer.Release(); } } return(cachedItem); } }