9

Mam skrypt aplikacji, w którym przepuszczam przez moje konto Google Analytics, aż dotrę do określonego profilu.
if (profileItems[i].getName() == "Dev Test")
niż w innej funkcji (patrz poniżej) dokonać połączenia do API Google Analytics i zawsze Wyjątek rzucony: Wyjątek: Kontyngent Błąd: Oceń użytkownika Przekroczono limit

Wyjątek: błąd limitu: limit użytkownika został przekroczony

function getReportDataForProfile(profileId) { 
var tableId = 'ga:' + profileId; 
var startDate = getLastNdays(14); // 2 weeks (a fortnight) ago. 
var endDate = getLastNdays(0);  // Today. 

var optArgs = { 
    'dimensions': 'ga:keyword',    // Comma separated list of dimensions. 
    'sort': '-ga:visits,ga:keyword',   // Sort by visits descending, then keyword. 
    'segment': 'dynamic::ga:isMobile==Yes', // Process only mobile traffic. 
    'filters': 'ga:source==google',   // Display only google traffic. 
    'start-index': '1', 
    'max-results': '250'      // Display the first 250 results. 
}; 

// 
//Exponential Backoff 
// 
for (var n=0; n<6; n++) { 
try { 
    var results = Analytics.Data.Ga.get(
    tableId,     // Table id (format ga:xxxxxx). 
    startDate,    // Start-date (format yyyy-MM-dd). 
    endDate,     // End-date (format yyyy-MM-dd). 
    'ga:visits,ga:pageviews', // Comma seperated list of metrics. 
    optArgs); 
} catch(e) { 
    if (n == 5) { 
    //var results = e; 
    //throw new Error('Quota ERROR'); 
    throw (e) 
    } 
    Utilities.sleep((Math.pow(2,n)*1000) + (Math.round(Math.random() * 1000))); 
    }  
} 
return results; 
} 
  • Zwiększyłem liczbę Limitu na użytkownika w konsoli API do 10.0
  • Zastosowany portyk to 6%
  • I zastosowano wykładniczej odczekania
  • Wierzę również, że po prostu z prośbą do odwiedzin i odsłon Nie ja przesadzam moje liczbę połączeń.

The full code

Wszelkie ideias co się dzieje?

Odpowiedz

2

To naprawdę dlatego, że nie masz uprawnień do wysyłania zapytań na więcej niż 10 żądań na sekundę. Jestem delegowania rozwiązanie tutaj (nawet jeśli to stare pytanie), ponieważ może to pomóc innym:

/** 
* CallLimiter 
* @param {Number} numberOfCalls how many calls per duration are we allowed to do 
* @param {Number} duration  duration in ms 
*/ 
function CallLimiter(numberOfCalls, duration){ 
    var lastCall = 0; 
    var tokens = 0; 

    return function limiter(f){ 
    var now = +new Date(); 

    if (now - lastCall > duration) { 
     tokens = numberOfCalls; 
    } 

    if (tokens <= 0) { 
     tokens = numberOfCalls; 
     // wait for `duration` before calling limiter(f) again 
     return setTimeout(limiter.bind(this, f), duration); 
    } 

    tokens--; 
    lastCall = now; 
    f(); 
    }; 
} 

A oto jak go używać:

// Stub... 
var Analytics = {Data: {Ga:{get:function(cb){ 
     cb(); 
}}}}; 

function app(){ 
    // Wrap the api call inside a limiter 
    limiter(function(){ 

    Analytics.Data.Ga.get(function(err, data){ 
     // do something with the data... 

     // ... then, loop if necessary 
     app(); 
    }); 

    }); 
} 

// Start 
app(); 

I tu jest blokowanie wersja Scala :

class CallLimiter(rate: Throttler.Rate) { 
    var lastCall  = 0 
    var duration  = rate.duration.toMillis 
    var current_tokens = 0 

    def apply[A](f:() => A): A = { 
    val d = new Date().getTime 

    if (d - lastCall > duration) { 
     current_tokens = rate.numberOfCalls 
    } 
    if (current_tokens <= 0) { 
     // wait for `duration` before calling f() 
     Thread.sleep(duration) 
     current_tokens = rate.numberOfCalls 
    } 
    current_tokens = current_tokens - 1 
    lastCall = d 
    f() 
    } 
} 

Zastosowanie:

import akka.contrib.throttle.Throttler 

val limiter = new CallLimiter(new Rate(10, Duration(1, TimeUnit.SECONDS))) 
val accounts = limiter(() => analytics.management().accounts().list().execute().getItems) 
+0

Twoje rozwiązanie jest dobre, ale jeśli mam 20 połączeń oczekujących na limicie 10 połączeń, Twój krytyczny odcinek kończy się wszystkie z nich są zwolnione od razu, uderzając limitu szybkości . –

Powiązane problemy