[英]Delay function execution (API call) to execute n times in time period
我正在嘗試寫回用於處理對特定API的請求的后端功能,但是此API具有一些限制性配額,尤其是對於請求/秒。 我想創建一個API抽象層,如果請求太多,它可以延遲函數執行,因此它的工作方式如下:
在等待隊列長度方面,我沒有任何限制。 請求是帶有node.js回調的函數調用,作為對數據進行響應的最后一個參數。
我想到了為每個請求添加延遲,這將等於請求之間的最小時間間隔(表示為最小毫秒/請求),但效率可能有點低下(總是在發送響應之前延遲功能)。
您知道可以為我提供此類功能的任何庫或簡單解決方案嗎?
保存上一個請求的時間戳。
每當有新的傳入請求時,請檢查此后是否經過了最小間隔;如果沒有,請將該函數放在隊列中,然后計划一個作業(除非已經安排了一個作業):
setTimeout(
processItemFromQueue,
(lastTime + minInterval - new Date()).getTime()
)
processItemFromQueue
從隊列的最前面開始執行任務( shift
),然后重新計划自身,除非隊列為空。
這個問題(也是最好的)的明確答案來自API文檔本身。 我們使用了幾個月,它完美地解決了我的問題。
在這種情況下,最好的方法是利用JS處理異步代碼的可能性,而不是編寫一些復雜的隊列代碼,或者自己編寫簡單的退避或使用許多優秀的庫之一來使用。
因此,如果偶然遇到任何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樣式,回調樣式甚至事件樣式的退避處理(上述示例為第二個)。 如果您了解退避算法本身,它們真的很容易使用。 並且由於退避參數可以存儲在配置中,因此如果退避失敗太多,則可以對其進行調整以獲得更好的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.