Throttle Olist sync requests
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 57s

This commit is contained in:
Cauê Faleiros
2026-08-10 13:13:29 -03:00
parent 1a430d4fb0
commit 838354f784
4 changed files with 16 additions and 8 deletions

View File

@@ -44,7 +44,7 @@ module.exports = {
OLIST_TOKEN_ENCRYPTION_KEY: process.env.OLIST_TOKEN_ENCRYPTION_KEY || '',
OLIST_SYNC_ENABLED: process.env.OLIST_SYNC_ENABLED === 'true',
OLIST_SYNC_INTERVAL_MS: Number(process.env.OLIST_SYNC_INTERVAL_MS) || 24 * 60 * 60 * 1000,
OLIST_SYNC_REQUESTS_PER_MINUTE: Number(process.env.OLIST_SYNC_REQUESTS_PER_MINUTE) || 25,
OLIST_SYNC_REQUEST_DELAY_MS: Math.max(2_500, Number(process.env.OLIST_SYNC_REQUEST_DELAY_MS) || 2_500),
TURNSTILE_SITE_KEY,
TURNSTILE_SECRET
};

View File

@@ -6,7 +6,7 @@ const {
OLIST_FRONTEND_URL,
OLIST_REDIRECT_URI,
OLIST_SYNC_INTERVAL_MS,
OLIST_SYNC_REQUESTS_PER_MINUTE,
OLIST_SYNC_REQUEST_DELAY_MS,
OLIST_TOKEN_ENCRYPTION_KEY
} = require('../config');
const { upsertTinyProductComposition } = require('./productionOrderService');
@@ -18,6 +18,7 @@ const OAUTH_STATE_TTL_MS = 10 * 60 * 1000;
const RUN_LOCK_KEY = 8_371_204;
let activeSync = null;
let scheduledSync = null;
let nextOlistRequestAt = 0;
const normalizeText = (value) => String(value || '').trim();
const stateHash = (state) => crypto.createHash('sha256').update(state).digest('hex');
@@ -225,7 +226,17 @@ const getAccessToken = async (forceRefresh = false) => {
return token.access_token;
};
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const waitForOlistRequestSlot = async () => {
const now = Date.now();
const waitMs = Math.max(0, nextOlistRequestAt - now);
if (waitMs) await sleep(waitMs);
nextOlistRequestAt = Date.now() + OLIST_SYNC_REQUEST_DELAY_MS;
};
const olistRequest = async (path, retry = true) => {
await waitForOlistRequestSlot();
const response = await fetch(`${OLIST_API_URL}${path}`, {
headers: { Authorization: `Bearer ${await getAccessToken(!retry)}` }
});
@@ -239,8 +250,6 @@ const olistRequest = async (path, retry = true) => {
return data;
};
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const listOlistProducts = async () => {
const products = [];
let offset = 0;
@@ -307,8 +316,6 @@ const runOlistSync = async ({ trigger = 'manual', fullSync = false } = {}) => {
const candidates = changedAfter
? allProducts.filter(product => !product.dataAlteracao || new Date(product.dataAlteracao).getTime() >= changedAfter.getTime())
: allProducts;
const minimumDelay = Math.ceil(60_000 / Math.max(1, OLIST_SYNC_REQUESTS_PER_MINUTE));
for (const product of candidates) {
summary.productsScanned += 1;
try {
@@ -339,7 +346,6 @@ const runOlistSync = async ({ trigger = 'manual', fullSync = false } = {}) => {
summary.details.push({ productId: product.id, sku: product.sku || '', error: error.message });
}
}
await sleep(minimumDelay);
}
return await finishRun(run.id, summary);
} catch (error) {