请求限制器使用的setTimeout逻辑有什么不正确?

时间:2017-08-14 09:35:01

标签: javascript node.js queue throttling rate-limiting

我正在尝试使用以下代码模拟HTTP请求限制。 (内部步骤2)

如果请求的发送时间小于300毫秒,我想对请求进行排队。后来我需要出队但在提出请求时保持300毫秒的相同约束。

代码工作正常,但我在出列逻辑中的位置不正确。在出列过程中我无法保持300毫秒的约束。有时,当设置超时设置为lastRequestMade时,now300 + x之间的差异小于300毫秒。这可能是什么原因?

const moment = require('moment');
const crypto = require('crypto');

let lastRequestMade = null;
let queue = [];
let requestIdList = [];
let lastRequestEq = null;
let timeoutInterval = 0;

// STEP 1
for (let x = 0; x < 100; x++) {
    // Init the request queue with the request ids
    requestIdList.push(crypto.randomBytes(8).toString('hex'));
}

// STEP 2 
for (let x = 0; x < 100; x++) {

    if (lastRequestMade && moment().diff(lastRequestMade) < 300) { // Rate limit to 300 milliseconds 
        // If the last request made was less than 300 milliseconds
        // queue the request
        queue.push(requestIdList[x]);
        console.log(`Enqueue ${requestIdList[x]}`);

        timeoutInterval += 300;

        setTimeout(() => {
            let rid = queue.splice(0, 1);
            sendRequest(...rid);
            if (queue.length == 0)
                console.log('No request left in the queue');
        }, timeoutInterval);

    } else {
        sendRequest(requestIdList[x]);
    }
}

/**
 * Request maker
 */
function sendRequest(requestId) {
    if (lastRequestMade && moment().diff(lastRequestMade) < 300)
        console.log('Attempted before 300 ms', moment().diff(lastRequestMade));
    // Make a request
    lastRequestMade = moment();
    console.log(`Request with ${requestId} made !!`);
}

有些请求是在不到300秒的时间内完成的。我使用setTimeout延迟每个请求,并使乘数保持等于当前队列长度。

0 个答案:

没有答案