Read/Write Lockfile Utility

2.0.25 · active · verified Tue Apr 21

rwlockfile is a Node.js utility that provides a file-based readers-writers lock mechanism, allowing multiple readers or a single writer to access a resource. It is currently at version 2.0.25 and appears to be actively maintained as needed. A key differentiator is its explicit support for the standard Readers-Writers Lock design pattern, which the author claims is unique among Node.js packages. Unlike simpler lockfile solutions, rwlockfile allows for flexible, nested locking logic on a single `RWLockfile` instance, where `add()` and `remove()` methods manage an internal counter to ensure the physical lock is only held when needed and released only when all nested calls are complete. This makes it suitable for complex asynchronous workflows requiring fine-grained concurrency control over shared resources.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates basic synchronous and asynchronous usage of `RWLockfile` for establishing read and write locks, including an example of the instance-specific nested lock handling described in the documentation, showcasing how `add` and `remove` manage an internal counter before affecting the actual file lock.

import { RWLockfile } from 'rwlockfile';

async function runLockExample() {
  // 'lockfile-target' is the base path; '.lock' will be appended for the actual lock file.
  const lock = new RWLockfile('lockfile-target', {
    timeout: 5000, // Wait up to 5 seconds for a lock
    retryInterval: 50 // Check every 50ms
  });

  try {
    console.log('Attempting to acquire a write lock...');
    await lock.add('write');
    console.log('Write lock acquired. Performing critical write operation...');
    await new Promise(resolve => setTimeout(resolve, 1000)); // Simulate work
    console.log('Write operation complete. Releasing lock.');
  } finally {
    await lock.remove('write');
    console.log('Write lock released.');
  }

  console.log('\nAttempting to acquire a read lock...');
  await lock.add('read');
  try {
    console.log('Read lock acquired. Performing read operation...');
    await new Promise(resolve => setTimeout(resolve, 500)); // Simulate work
    console.log('Read operation complete. Releasing lock.');
  } finally {
    await lock.remove('read');
    console.log('Read lock released.');
  }

  // Demonstrate nested locking (instance-specific counting)
  async function nestedWrite() {
    await lock.add('write');
    try {
      console.log('  Nested write lock added by inner function.');
      await new Promise(resolve => setTimeout(resolve, 200));
    } finally {
      await lock.remove('write');
      console.log('  Nested write lock removed by inner function.');
    }
  }

  try {
    console.log('\nAttempting top-level write lock for nesting...');
    await lock.add('write');
    console.log('Top-level write lock acquired.');
    await nestedWrite(); // Call a function that also adds/removes a lock on the same instance
    console.log('Back in top-level. Main write operation continuing.');
    await new Promise(resolve => setTimeout(resolve, 300));
  } finally {
    await lock.remove('write');
    console.log('Top-level write lock finally released after all nested calls.');
  }
}

runLockExample().catch(console.error);

view raw JSON →