Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

144
Visualizações
Detecting an in-flight request to an API in Nodejs

I am writing a service in Nodejs in which I fetch prices from an Api and the call to the API might take over a minute so one of the things that can happen is that a request for a specific item can happen and the same item can be requested before the first item is returned and I want to detect if there is an in-flight request for a specified item and, if there is one, I need to wait for this request to be finished and return the same response for both requests.

An example diagram would be:

00.000 getCost('123') #1 call
00.001 getExternalCost('123') query
01.000 getCost('123') #2 call
90.001 getExternalCost('123') response
90.002 getCost('123') #1 response
90.003 getCost('123') #2 response

This is the code I have written so far, which simply fetches the cost of the item.

let cache = new Map();
let addToCache = (key,val) => {
  if(!cache.has(key)){
    cache.set(key,val);
  }
}

const getCost = async (itemId) => {

  if(cache.has(itemId)){
    return cache.get(itemId);
  }

  const price = await getExternalCost(itemId);
  addToCache(itemId,price);
  
  return cost;
}
about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

This can be done if you add promises to the cache rather than awaiting them. By doing this an incoming query can be redirected to receive the value of a similar query pending in the cache.

const MAX_AGE = 1000;
const cache = new Map();

const cacheContainsKey = key => {
  if (!cache.has(key)) {
    return false;
  }

  const {
    _ts
  } = cache.get(key);
  const age = Date.now() - _ts;
  if (age <= MAX_AGE) {
    return true;
  }

  console.log(`key ${key} age exceeds MAX_AGE: ${age}. Deleting key from cache.`);
  cache.delete(key);
  return false;
};

const addToCache = (key, val) => {
  cache.set(key, {
    _ts: Date.now(),
    val
  });
};

const retrieveFromCache = async(itemId) => {
  try {
    const start = Date.now();
    const price = await cache.get(itemId).val;
    const end = Date.now();
    console.log(`Query for ${itemId}. Price: ${price}. Time spent: ${(end - start) / 1000} seconds.`);
    return price;
  } catch (err) {
    /*
      If required insert logic here to remove the itemId from the cache to
      allow new attempts to getExternalCost on this itemId.
    */
    return err;
  }
};

const getCost = async(itemId) => {
  if (cacheContainsKey(itemId)) {
    const price = await retrieveFromCache(itemId);
    return price;
  }

  const pricePromise = getExternalCost(itemId);
  addToCache(itemId, pricePromise);

  // all queries go through the cache
  const price = await retrieveFromCache(itemId);
  return price;
};


// example code
function getExternalCost(itemId) {
  return new Promise((resolve, __reject) => {
    setTimeout(() => {
      resolve(itemId * 100);
    }, 1000);
  });
}

let counter = 0;
const itemIds = [10, 10, 12, 12, 10, 1];

// mimic incoming queries
let interval = setInterval(() => {
  getCost(itemIds[counter++]);
  if (counter === itemIds.length) {
    clearInterval(interval);
  }
}, 500);

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda