TransWikia.com

Mutexes at application logic level

Software Engineering Asked on December 24, 2021

In my node.js app I have a async function that fetches remote documents and caches them on the disk. Upon a retrieval request for a document first checks the disk, if found loads it from the disk otherwise initiates a network request.

async function getDoc(id){
    if (await diskCache.found(id)){
        return await diskCache.load(id);
    } else {
        const doc = await fetch(/* url */);
        await diskCache.save(doc);
        return doc;
    }
}

If this function gets called twice in a single tick for example:

getDoc(1);
getDoc(1);

and the cache doesn’t contain the document, it sends two network requests, which is’t intended. The second call should wait for the first one to complete then checks the cache.

How should I solve this problem?

One Answer

Your function getDoc maintains a list of outstanding requests. If the url is in that list then you wait for the running fetch to complete and the document to be saved, otherwise you add the URL to the list of outstanding requests And start the fetch.

All nicely synchronised, please.

The result might have a structure like this:

const inFlight = {};

async function getDoc(id) {
  // try to look up the cached value
  const value = await diskCache.tryLoad(id);
  if (value !== undefined) return value;

  // get or create a promise that fills the cache
  const promise = (inFlight[id] ||= (async () => {
    const doc = await fetch(...);
    await diskCache.save(doc);
    delete inFlight[id];
    return doc;
  })());

  return await promise;
}

Answered by gnasher729 on December 24, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP