Example #1
0
    async Task <T> GetResponse <T>(YouTubeBaseServiceRequest <T> request)
    {
        void SetRequestKey()
        {
            if (AvailableKeys.Count == 0)
            {
                throw new InvalidOperationException("Ran out of quota for all available keys");
            }
            request.Key = AvailableKeys.First().Key;
        }

        SetRequestKey();
        return(await Policy
               // handle quote limits
               .Handle <GoogleApiException>(g => {
            var isQuotaError = g.HttpStatusCode == HttpStatusCode.Forbidden && g.Error.Errors.Any(e => e.Reason == "quotaExceeded");
            if (!isQuotaError)
            {
                Log.Debug(g, "YtApi - return error not detected as quota: {Errors}", g.Error.Errors.Join(", ", e => e.Reason));
                return false;
            }
            AvailableKeys.TryRemove(request.Key, out _);
            Log.Warning(g, "Quota exceeded, no longer using key {Key}", request.Key);
            SetRequestKey();
            return true;
        })
               .RetryForeverAsync()
               // wrap generic transient fault handling
               .WrapAsync(Policy
                          .Handle <HttpRequestException>()
                          .Or <GoogleApiException>(g => g.HttpStatusCode.IsTransientError())
                          .WaitAndRetryAsync(retryCount: 6, i => i.ExponentialBackoff(1.Seconds())))
               .ExecuteAsync(request.ExecuteAsync));
    }
Example #2
0
        async Task <T> GetResponse <T>(YouTubeBaseServiceRequest <T> request)
        {
            while (true)
            {
                try {
                    if (AvailableKeys.Count == 0)
                    {
                        throw new InvalidOperationException("Ran out of quota for all available keys");
                    }
                    request.Key = AvailableKeys.First(); // override key in case it has been changed by NextYtService()
                    var response = await request.ExecuteAsync();

                    return(response);
                }
                catch (GoogleApiException ex) {
                    if (ex.HttpStatusCode == HttpStatusCode.Forbidden)
                    {
                        AvailableKeys.Remove(request.Key);
                        Log.Error(ex, "Quota exceeded, no longer using key {Key}", request.Key);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }
Example #3
0
 /// <summary>
 /// Logs a YouTube service response
 /// </summary>
 /// <typeparam name="T">The type of the request</typeparam>
 /// <param name="request">The request to log</param>
 /// <param name="response">The response to log</param>
 protected void LogResponse <T>(YouTubeBaseServiceRequest <T> request, string response)
 {
     if (Logger.Level == LogLevel.Debug)
     {
         Logger.Log(LogLevel.Debug, "Rest API Request Complete: " + request.RestPath + " - " + response);
     }
 }
Example #4
0
 /// <summary>
 /// Logs a YouTube service response
 /// </summary>
 /// <typeparam name="T">The type of the request</typeparam>
 /// <param name="request">The request to log</param>
 /// <param name="response">The response to log</param>
 protected void LogResponse <T>(YouTubeBaseServiceRequest <T> request, IDirectResponseSchema response)
 {
     if (Logger.Level == LogLevel.Debug)
     {
         Logger.Log(LogLevel.Debug, "Rest API Request Complete: " + request.RestPath + " - " + JSONSerializerHelper.SerializeToString(response));
     }
 }
Example #5
0
 /// <summary>
 /// Logs a YouTube service request.
 /// </summary>
 /// <typeparam name="T">The type of the request</typeparam>
 /// <param name="request">The request to log</param>
 protected void LogRequest <T>(YouTubeBaseServiceRequest <T> request)
 {
     if (Logger.Level == LogLevel.Debug)
     {
         Logger.Log(LogLevel.Debug, "Rest API Request Sent: " + request.RestPath + " - " + JSONSerializerHelper.SerializeToString(request, propertiesToIgnore: requestPropertiesToIgnore));
     }
 }
Example #6
0
        async Task <T> GetResponse <T>(YouTubeBaseServiceRequest <T> request)
        {
            void SetRequestKey()
            {
                if (AvailableKeys.Count == 0)
                {
                    throw new InvalidOperationException("Ran out of quota for all available keys");
                }
                request.Key = AvailableKeys.First().Key;
            }

            SetRequestKey();
            return(await Policy
                   // handle quote limits
                   .Handle <GoogleApiException>(g => {
                if (g.HttpStatusCode != HttpStatusCode.Forbidden)
                {
                    return false;
                }
                AvailableKeys.TryRemove(request.Key, out var value);
                Log.Error(g, "Quota exceeded, no longer using key {Key}", request.Key);
                SetRequestKey();
                return true;
            })
                   .RetryForeverAsync()
                   // wrap generic transient fault handling
                   .WrapAsync(Policy
                              .Handle <HttpRequestException>()
                              .Or <GoogleApiException>(g => g.HttpStatusCode.IsTransient())
                              .WaitAndRetryAsync(3, i => i.ExponentialBackoff(1.Seconds())))
                   .ExecuteAsync(request.ExecuteAsync));
        }