Exemplo n.º 1
0
        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();
                }
            }
        }
Exemplo n.º 2
0
        /// <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);
            }
        }