npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

rwlockfile

v2.0.25

Published

lockfile utility with reader/writers

Downloads

13,021

Readme

rwlockfile

code style: prettier Greenkeeper badge codecov CircleCI Build status npm npm npm

node utility for read/write lockfiles

This is the only node package as of this writing I'm aware of that allows you to have read/write lockfiles. If you're looking for a simpler solution, check out proper-lockfile. Use this package if you need read/write lock support.

This follows the standard Readers-Writers Lock design pattern. Any number of readers are allowed at one time. 1 writer is allowed at one time iff there are no current readers.

Usage

const {RWLockfile} = require('rwlockfile')

// 'myfile' is the path to a file to use as the base for the lockfile
// it will add '.lock' to the end for the actual lockfile, so in this case 'myfile.lock'
let lock = new RWLockfile('myfile', {
  // how long to wait until timeout. Default: 30000
  timeout: 30000,
  // mininum time to wait between checking for locks
  // automatically adds some noise and duplicates this number each check
  retryInterval: 10,
})

// add a reader async or synchronously. If the count is >= 1 it creates a read lock (see note below)
await lock.add('read')
lock.addSync('read')

// remove a reader async or synchronously. If the count == 0 it creates removes the read lock
await lock.remove('read')
lock.removeSync('read')

// add a writer async or synchronously
await lock.add('write')
lock.addSync('write')

Behavior Note

The use of .add() and .remove() may be a bit misleading but allow me to attempt to explain what it means. It's designed to make it easy to add try/finally steps around locking. Each instance of RWLockfile has a count of readers and writers. The file itself has it's own count of readers and writers. When you increment the count, what you're doing is adding to the count of just that instance.

In other words, you can do lock.add('write') multiple times on the same instance. That instance will create the write lock if the count is greater than 1 but no other instances will be allowed to increase the count above 0.

Why? Because this way you can have functions in your code like this:

async function doAThing() {
  await lock.add('write')
  try {
    // do something while locked
    doAnotherThing()
  } finally {
    await lock.remove('write')
  }
}

async function doAnotherThing() {
  await lock.add('write')
  try {
    // do something else while locked
  } finally {
    await lock.remove('write')
  }
}

This will only create a single write lock which will be removed after doAThing() is done. This way you can call doAnotherThing() and it ensures it has a lock if it doesn't exist, but will only remove the write lock if nothing it's using also has a write lock.

I've found this behavior to be perfect for working with, but this sort of nesting lock logic is a little difficult to explain.