withLock

Utility function to control concurrency.

withLock(key, callback [, options]) => Promise

The withLock function ensures only one process step into the critical section (callback).

const { withLock } from 'mongodash';

function updateUser (userId, data) {
  return withLock(`user-update-${userId}`, async () => {
  	
    const user = await getUserFromDatabase(userId);
    
    user.setData(data);
    
    await saveUserToDatabase(user);
    
    return user;
  });
}

// all calls are triggered in parallel,
// the withLock ensures they will be processed one by one
updateUser(1, { name: 'Joe' });
updateUser(1, { surname: 'Doe' });
updateUser(1, { nick: 'J' });

The withLock function uses busy wait with a combination of sleep if the lock is occupied. The sleep time is determined by the exponential backoff strategy.

The key is always converted to a string internally, so 100 and "100" are considered as the same key.

The lock is acquired for an amount of time (see expireIn option). If the callback lasts too long, the lock is prolonged automatically.

👍

Usable even in scalable (multi-instance) applications thanks to lock registration in MongoDB.

Mongodash will ensure only one execution process step into the callback.

Options

OptionDescriptionDefault value
maxWaitForLockMaximum waiting time (in milliseconds) for lock acquisition.3000 [ms]
startingDelayInitial sleep time before the first retry for acquiring the lock.50 [ms]
expireInA time for which is the lock acquired. The time is automatically increased for long-lasting callbacks, but if something go wrong and Node process is terminated, the lock is automatically released by the expiration time.15000 [ms]