Я использую express
для создания API, который должен использоваться внутри компании.Один из запросов запускает тяжелый процесс на сервере и должен вернуть CSV из этого.Этот процесс может занять более 10 минут.
Чтобы не перегружать сервер, я хочу ограничить вызов этого API и сделать так, чтобы, поскольку процесс не завершен, мы не могли запросить то же самоеURL снова.
Для этого я попытался использовать express-rate-limit
со следующей конфигурацией:
new RateLimit({
windowMs: 30 * 60 * 1000, // 30 minutes
max: 1,
delayMs: 0, // disabled
message: 'Their is already a running execution of the request. You must wait for it to be finished before starting a new one.',
handler: function handler(req, res) {
logger.log('max request achieved');
logger.log(res);
},
});
Но, похоже, «максимальный запрос» достигается каждый разровно через 2 минуты, даже если я начну только один раз.Я подозреваю, что браузер повторяет запрос через 2 минуты, если не получает ответа, возможно ли это?
Мне бы хотелось, чтобы в этом запросе не было retry-strategy
, и это единственный способ, которым max request
достигается путем ручного запроса к серверу выполнить этот запрос 2 раза подряд.
Спасибо.
Редактировать
Вот мой полный код:
const app = express();
const port = process.env.API_PORT || 3000;
app.enable('trust proxy');
function haltOnTimedout(req, res, next) {
if (!req.timedout) { next(); }
}
app.use(timeout(30 * 60 * 1000)); // 30min
app.use(haltOnTimedout);
app.listen(port, () => {
logger.log(`Express server listening on port ${port}`);
});
// BILLING
const billingApiLimiter = new RateLimit({
windowMs: 30 * 60 * 1000, // 30 minutes
max: 1,
delayMs: 0, // disabled
message: 'Their is already a running execution of the request. You must wait for it to be finished before starting a new one.',
handler: function handler(req, res) {
logger.log('max request achieved');
},
});
app.use('/billing', billingApiLimiter);
app.use('/billing', BillingController);
И код моего route
:
router.get('/billableElements', async (request, response) => {
logger.log('Route [billableElements] called');
const { startDate } = request.query;
const { endDate } = request.query;
try {
const configDoc = await metadataBucket.getAsync(process.env.BILLING_CONFIG_FILE || 'CONFIG_BILLING');
const billableElements = await getBillableElements(startDate, endDate, configDoc.value);
const csv = await produceCSV(billableElements);
logger.log('csv produced');
response.status(200).send(`${csv}`);
} catch (err) {
logger.error('An error occured while getting billable elements.', err);
response.status(500).send('An internal error occured.');
}
});