docs: async function initLock({
    LOCKS_MAP = new Map(),
    LOCK_TIMEOUT = Infinity,
    delay,
    log = noop,
  }) {
    log('debug', 'Lock service initialized.');
  
    return {
      take,
      release,
    };
  
    /**
     * Take the lock on the given resource key
     * @param  {String}   key
     * A unique key for the locked resource
     * @return {Promise}
     * A promise to be resolved when the lock
     *  is gained or rejected if the lock release
     *  timeout is reached.
     */
    async function take(key) {
      const previousLocks = LOCKS_MAP.get(key) || [];
      let locksLength = previousLocks.length;
  
      log('debug', `Taking the lock on ${key} (queue length was ${locksLength})`);
  
      let release;
  
      const newLock = {
        releasePromise: new Promise(async (resolve, reject) => {
          release = resolve;
  
          if (LOCK_TIMEOUT !== Infinity) {
            await delay.create(LOCK_TIMEOUT);
  
            reject(new YError('E_LOCK_TIMEOUT'));
          }
        }),
        release,
      };
  
      previousLocks.push(newLock);
      locksLength++;
  
      if (locksLength > 1) {
        await previousLocks[locksLength - 1].releasePromise;
      } else {
        LOCKS_MAP.set(key, previousLocks);
      }
    }
  
    /**
     * Release the lock on the given resource key
     * @param  {String}   key  A unique key for the resource to release
     * @return {void}
     */
    async function release(key) {
      const previousLocks = LOCKS_MAP.get(key) || [];
      const locksLength = previousLocks.length;
  
      log(
        'debug',
        `Releasing the lock on ${key} (queue length was ${locksLength})`,
      );
      previousLocks.pop().release();
    }
  }