Search code examples
node.jsasynchronouspromiselocking

What is the best practice of writing an asynchronous safe singleton?


I am trying to have some sort of singleton/semaphore mechanisms that will be "async-safe".

My goal is to have only one instance of an IPFS node is being created in the entire lifetime of my node.js app.

At the moment what I am doing is the following which is absolutely unsafe for some cases.

const IPFS = import('ipfs-core');

const getIPFSNode = async () => {
  if (module.exports.ipfsNode === undefined) {
    ipfs = await IPFS;
    const node = await ipfs.create();
    module.exports.ipfsNode = node;
  }
  return module.exports.ipfsNode;
};

How could I assure only one instance of IFPS node is being created? Is there a way to create the creation an atomic operation or protect it with a semaphore/mutex?


Solution

  • Something like this would work, although it has a kind of unexpected side effect of yielding on every call, even once the promise is settled.

    const IPFS = import('ipfs-core');
    
    let promise;
    const getIPFSNode = () => {
      if (promise === undefined) {
        promise = IPFS.create();
      }
      return promise;
    };