问题
Abraham's answer to Google Calendar API : "Backend Error" code 503 exactly describes my situation. I get 503s at random places when looping through code that creates or deletes calendar entries.
However, I can't figure out how to follow the advice that he cites from Google, which is to catch the error and retry the transaction using exponential back off.
The code below is a loop that puts 8 new events into my calendar. It randomly experiences 503 errors, which are thrown from the Google API instead of my own code. Many times it works without an error.
The Google API code runs asynchronously from my loop, so none of the Google actions actually execute until my loop is done. The try-catch
block surrounding my code doesn't fire when the async code throws a 503. I can't put a catch
into the callback function without a try
, and that would narrow the scope of the catch
to exclude Google's code.
Any suggestions?
/* Special date string format for all-day Google Calendar events.
Time zone independent.
*/
Date.prototype.yyyy_mm_dd = function() {
var yyyy= this.getFullYear().toString();
var mm = (this.getMonth()+101).toString().slice(-2); //get leading 0
var dd = (this.getDate()+100).toString().slice(-2);
return yyyy+'-'+mm+'-'+dd;
}
var fastevent = {
'summary': 'Fast',
'organizer': {
'self': true,
'displayName': 'Wes Rishel',
'email': 'wrishel@gmail.com'},
'start': {'date': 'zzzz'}, // filled in for each instance
'end': {'date': 'zzzz'},
'colorId': '11',
}
function addFastEvents() {
try {
var eventDate = calendar.getLastFastDate() || new Date;
for (var eventCount = 0; eventCount < 8; eventCount++) {
// advance to next Tuesday or Friday
eventDate=eventDate.addDays(
[2, 1, 3, 2, 1, 4, 3][eventDate.getDay()]
);
fastevent.start.date = eventDate.yyyy_mm_dd();
fastevent.end.date = fastevent.start.date;
var request = gapi.client.calendar.events.insert({
'calendarId': 'primary',
'resource': fastevent
});
request.execute(function(fastevent) {});
calendar.getPage(eventDate);
calendar.setCellStyle(eventDate, 'fastingweekdaydata');
} // for
} catch(e) {
p(e.message, e.name)
}
}
回答1:
Exponential backoff is a fancy way of saying that at each attempt, you increase the wait time exponentially, for a certain number of times before giving up the request.
Implementing exponential backoff
Exponential backoff is a standard error handling strategy for network applications in which the client periodically retries a failed request over an increasing amount of time. If a high volume of requests or heavy network traffic causes the server to return errors, exponential backoff may be a good strategy for handling those errors
Here's a demo code in JS that might give you an idea:
console.log = consoleLog;
exponentialBackoff(sometimesFails, 10, 100, function(result) {
console.log('the result is',result);
});
// A function that keeps trying, "toTry" until it returns true or has
// tried "max" number of times. First retry has a delay of "delay".
// "callback" is called upon success.
function exponentialBackoff(toTry, max, delay, callback) {
console.log('max',max,'next delay',delay);
var result = toTry();
if (result) {
callback(result);
} else {
if (max > 0) {
setTimeout(function() {
exponentialBackoff(toTry, --max, delay * 2, callback);
}, delay);
} else {
console.log('we give up');
}
}
}
function sometimesFails() {
var percentFail = 0.8;
return Math.random() >= 0.8;
}
function consoleLog() {
var args = [].slice.apply(arguments);
document.querySelector('#result').innerHTML += '\n' + args.join(' - ');
}
来源:https://stackoverflow.com/questions/40065060/google-javascript-api-catching-http-errors