我正在尝试回写处理特定API请求的最终功能,但此API具有一些限制性配额,尤其是对于请求/秒。我想创建API抽象层,如果请求/ s太多,它能够延迟函数执行,所以它的工作原理如下:
我在等待队列长度方面没有任何限制。请求是带有node.js回调的函数调用,作为响应数据的最后一个参数。
我想到为每个请求添加延迟,这将等于请求之间的最小可能时隙(表示为最小毫秒/请求),但它可能有点低效(总是在发送响应之前延迟函数)。
您知道任何可以为我提供此类功能的库或简单解决方案吗?
答案 0 :(得分:0)
保存最后一个请求的时间戳。
每当有新的传入请求时,检查自那时起是否经过了最小间隔,如果没有,则将该函数放入队列然后安排作业(除非已经安排了一个):
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
from kivy.clock import Clock
Builder.load_string("""
<MyWidget>:
MyTextInput:
MyTextInput:
""")
class MyTextInput(TextInput):
def copy(self, data=''):
# wrap copied text with ---
if data:
data = "--- {} ---".format(data)
else:
data = "--- {} ---".format(self.selection_text)
return super(MyTextInput, self).copy(data)
class MyWidget(BoxLayout):
pass
class ClientApp(App):
def build(self):
return MyWidget()
if __name__ == '__main__':
ClientApp().run()
cut()
从队列前面(setTimeout(
processItemFromQueue,
(lastTime + minInterval - new Date()).getTime()
)
)接受一个作业,然后重新安排自己,除非队列为空。
答案 1 :(得分:0)
这个问题(以及最好的问题)的明确答案来自API文档本身。我们使用它几个月,它完全解决了我的问题。
在这种情况下,不是编写一些复杂的队列代码,最好的方法是利用JS处理异步代码的可能性,或者自己编写简单的 backoff ,或者使用众多优秀的库中的一个来使用如此。
因此,如果您偶然发现任何API限制(例如,配额,5xx等),您应该使用退避再次递归运行查询,但延迟时间越来越多(可以在此处找到更多有关退避的信息:https://en.wikipedia.org/wiki/Exponential_backoff )。并且,如果最终,在给定次数之后您再次失败 - 优雅地返回关于API不可用的错误。
以下使用示例(取自https://www.npmjs.com/package/backoff):
var call = backoff.call(get, 'https://someaddress', function(err, res) {
console.log('Num retries: ' + call.getNumRetries());
if (err) {
// Put your error handling code here.
// Called ONLY IF backoff fails to help
console.log('Error: ' + err.message);
} else {
// Put your success code here
console.log('Status: ' + res.statusCode);
}
});
/*
* When to retry. Here - 503 error code returned from the API
*/
call.retryIf(function(err) { return err.status == 503; });
/*
* This lib offers two strategies - Exponential and Fibonacci.
* I'd suggest using the first one in most of the cases
*/
call.setStrategy(new backoff.ExponentialStrategy());
/*
* Info how many times backoff should try to post request
* before failing permanently
*/
call.failAfter(10);
// Triggers backoff to execute given function
call.start();
NodeJS有许多退避库,利用Promise风格,回调风格甚至事件风格的退避处理(上面的例子是上面提到的第二个)。如果您了解退避算法本身,它们真的很容易使用。由于退避参数可以存储在配置中,如果退避失败太频繁,可以调整它们以获得更好的结果。