我知道当RPC调用失败时,指数退避是一件好事。到目前为止,在我的GAE / P应用程序中,我通过使用任务队列实现了指数退避:
function urlReplace(url, params) {
return url.replace(/:([^\/]+)/g, function(match, key) {
return params[key];
});
}
var url = urlReplace("http://example.com/api/get_nearest_places/:en_type_id/:longtude/:latitude", {
longtude: 33.42432,
latitude: 42.3243,
en_type_id: 1
});
console.log(url);
如果执行RPC调用的函数引发异常,那么任务队列的指数退避处理它,我不必担心它。
然而,一个问题是deferred.defer本身就是一个失败的RPC调用!我有时会收到这个错误:
DeadlineExceededError:API调用taskqueue.BulkAdd()花了太长时间 回应并被取消。
所以我似乎不再懒惰,必须实现自己的指数退避。 :(
我正在考虑使用deferred.defer(function_that_makes_RPC_call)
围绕deferred.defer
设置一个使用backoff实现指数退避的包装器,如下所示:
@backoff.on_exception(backoff.expo,
(exception1, exception2, ...),
max_tries=8)
def defer_wrapper(function_that_makes_RPC_call):
deferred.defer(function_that_makes_RPC_call)
这里,装饰器实现了退避,当引发其中一个枚举异常(例如,exception1,exception2,...)时,重试就会发生。
有几个问题:
我知道拥有自己的指数退避然后提交到任务队列有点多余,但我认为deferred.defer
应该比其他RPC调用更少失败并且我想回复请求尽快。
答案 0 :(得分:1)
特别是对于selections.map(cart => /*do stuff*/)
尝试排队延迟任务我只做后退重试而不是使用指数退避 - 由于截止时间间隔到期本身无论如何,尝试将间隔5秒,在请求本身达到截止日期之前,最多可以重试12次。
但是对于其他类型的失败可能是一个好主意。