コード例 #1
0
        /// <summary>
        /// </summary>
        /// <param name="type">
        /// </param>
        /// <param name="names">
        /// </param>
        /// <param name="limits">
        /// </param>
        /// <param name="methods">
        /// </param>
        /// <returns>
        /// </returns>
        public RateLimitBuilder AddRateLimitFor(LolUrlType type, List <LolApiName> names, List <ApiLimit> limits, params LolApiMethodName[] methods)
        {
            var rla  = new RLolApiName();
            var rlan = new RLolApiMethodName();

            rlan.Add(names, methods.Distinct().ToArray());
            rlan.AddLimit(limits.ToArray());
            rla.Add(rlan);
            if (!Limits.ContainsKey(type))
            {
                Limits.TryAdd(type, rla);
            }
            else
            {
                Limits[type].Add(rlan);
            }
            return(this);
        }
コード例 #2
0
        /// <summary>
        /// rate-limit main function
        /// </summary>
        /// <param name="prop">
        /// </param>
        private void Wait(RateLimitProperties prop)
        {
            TimeSpan          currentDelay = TimeSpan.Zero;
            RLolApiMethodName regionLimit  = Rates.Find(prop.Platform, prop.UrlType, prop.ApiName, prop.ApiMethod);

            if (regionLimit == null)
            {
                var snc = ApiSettings.ApiOptions.RateLimitOptions.All[prop.UrlType].DeepClone();
                //special rate-limiting for leagues
                var methodRateLeague = ApiSettings.ApiOptions.RateLimitOptions.FindLeagueApiLimit(prop.Platform);
                if (methodRateLeague != null)
                {
                    var app_rates = snc.Names.First().Limits.Where(p => p.LimitType == RateLimitType.AppRate);

                    List <ApiLimit> lmts = new List <ApiLimit>();
                    lmts.Add(methodRateLeague);
                    lmts.AddRange(app_rates);
                    snc.Add(new RLolApiMethodName(LolApiName.League, new List <LolApiMethodName>()
                    {
                        LolApiMethodName.ChallengerLeagues,
                        LolApiMethodName.Leagues,
                        LolApiMethodName.MasterLeagues,
                        LolApiMethodName.Positions
                    }, lmts.ToArray()));
                }

                //special rate-limiting for summoner
                var methodRateSummoner = ApiSettings.ApiOptions.RateLimitOptions.FindSummonerApiLimit(prop.Platform);
                if (methodRateSummoner != null)
                {
                    var app_rates = snc.Names.First().Limits.Where(p => p.LimitType == RateLimitType.AppRate);

                    List <ApiLimit> lmts = new List <ApiLimit>();
                    lmts.Add(methodRateSummoner);
                    lmts.AddRange(app_rates);
                    snc.Add(new RLolApiMethodName(LolApiName.Summoner, new List <LolApiMethodName>()
                    {
                        LolApiMethodName.Summoners
                    }, lmts.ToArray()));
                }
                //
                Add(prop.Platform, prop.UrlType, snc);
                regionLimit = Rates.Find(prop.Platform, prop.UrlType, prop.ApiName, prop.ApiMethod);
            }
            //lock (_lock)
            {
                if (regionLimit.IsRetryActive)
                {
                    currentDelay = (regionLimit.RetryAfter - DateTime.Now);
                    Debug.WriteLine($"Limit Exceeded Retry-After:{currentDelay}, Region:{prop.Platform}, ApiType:{prop.UrlType}, ApiName:{prop.ApiName}, ApiMethod:{prop.ApiMethod} Forced-Limit:{regionLimit.UsedRateLimitType}");
                }
                //special condition to check '/lol/summoner/v3/summoners/by-account/{accountId}'
                int limitForByAccount = -1;
                if (prop.ApiMethod == LolApiMethodName.Summoners && prop.ApiName == LolApiName.Summoner)
                {
                    if (prop.ApiPaths[0] == LolApiPath.ByAccount)
                    {
                        var limit = ApiSettings.ApiOptions.RateLimitOptions.SummonerAccountNameLimits;
                        limitForByAccount = limit["All"].Limit;
                    }
                }
                foreach (var limit in regionLimit.Limits)
                {
                    int bypassedLimit = limit.Limit;
                    if (limitForByAccount != -1)
                    {
                        if (limit.LimitType == RateLimitType.MethodRate)
                        {
                            bypassedLimit = limitForByAccount;
                        }
                    }
                    if (limit.Counter < bypassedLimit)
                    {
                        continue;
                    }

                    var largestDelay = limit.ChainStartTime.Add(limit.Time) - DateTime.Now;

                    Debug.WriteLine(
                        $"[{DateTime.Now:MM/dd/yyyy HH:mm:ss.fff}] limit:{bypassedLimit}\tregion:{prop.Platform}\ttype:{prop.UrlType}\tapiName:{prop.ApiName}\tmultipler:{limit.Time}\tcount:{limit.Counter}\t\tDelay:{largestDelay}");

                    if (largestDelay > currentDelay)
                    {
                        currentDelay = largestDelay;
                    }

                    break;
                }
                regionLimit.Limits.ForEach((limit) =>
                {
                    if (limit.ChainStartTime <= DateTime.Now.Add(currentDelay) - limit.Time)
                    {
                        limit.Counter = 0;
                    }

                    limit.ChainStartTime = DateTime.Now.Add(currentDelay);
                    limit.Counter++;
                });
            }
            Task.Delay(currentDelay).Wait();
        }