• Stars
    star
    221
  • Rank 179,773 (Top 4 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 10 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An inter-process and inter-machine lockfile utility that works on a local or network file system.

proper-lockfile

NPM version Downloads Build Status Coverage Status Dependency status Dev Dependency status

An inter-process and inter-machine lockfile utility that works on a local or network file system.

Installation

$ npm install proper-lockfile

Design

There are various ways to achieve file locking.

This library utilizes the mkdir strategy which works atomically on any kind of file system, even network based ones. The lockfile path is based on the file path you are trying to lock by suffixing it with .lock.

When a lock is successfully acquired, the lockfile's mtime (modified time) is periodically updated to prevent staleness. This allows to effectively check if a lock is stale by checking its mtime against a stale threshold. If the update of the mtime fails several times, the lock might be compromised. The mtime is supported in almost every filesystem.

Comparison

This library is similar to lockfile but the latter has some drawbacks:

  • It relies on open with O_EXCL flag which has problems in network file systems. proper-lockfile uses mkdir which doesn't have this issue.

O_EXCL is broken on NFS file systems; programs which rely on it for performing locking tasks will contain a race condition.

  • The lockfile staleness check is done via ctime (creation time) which is unsuitable for long running processes. proper-lockfile constantly updates lockfiles mtime to do proper staleness check.

  • It does not check if the lockfile was compromised which can lead to undesirable situations. proper-lockfile checks the lockfile when updating the mtime.

  • It has a default value of 0 for the stale option which isn't good because any crash or process kill that the package can't handle gracefully will leave the lock active forever.

Compromised

proper-lockfile does not detect cases in which:

  • A lockfile is manually removed and someone else acquires the lock right after
  • Different stale/update values are being used for the same file, possibly causing two locks to be acquired on the same file

proper-lockfile detects cases in which:

  • Updates to the lockfile fail
  • Updates take longer than expected, possibly causing the lock to become stale for a certain amount of time

As you see, the first two are a consequence of bad usage. Technically, it was possible to detect the first two but it would introduce complexity and eventual race conditions.

Usage

.lock(file, [options])

Tries to acquire a lock on file or rejects the promise on error.

If the lock succeeds, a release function is provided that should be called when you want to release the lock. The release function also rejects the promise on error (e.g. when the lock was already compromised).

Available options:

  • stale: Duration in milliseconds in which the lock is considered stale, defaults to 10000 (minimum value is 5000)
  • update: The interval in milliseconds in which the lockfile's mtime will be updated, defaults to stale/2 (minimum value is 1000, maximum value is stale/2)
  • retries: The number of retries or a retry options object, defaults to 0
  • realpath: Resolve symlinks using realpath, defaults to true (note that if true, the file must exist previously)
  • fs: A custom fs to use, defaults to graceful-fs
  • onCompromised: Called if the lock gets compromised, defaults to a function that simply throws the error which will probably cause the process to die
  • lockfilePath: Custom lockfile path. e.g.: If you want to lock a directory and create the lock file inside it, you can pass file as <dir path> and options.lockfilePath as <dir path>/dir.lock
const lockfile = require('proper-lockfile');

lockfile.lock('some/file')
.then((release) => {
    // Do something while the file is locked

    // Call the provided release function when you're done,
    // which will also return a promise
    return release();
})
.catch((e) => {
    // either lock could not be acquired
    // or releasing it failed
    console.error(e)
});

// Alternatively, you may use lockfile('some/file') directly.

.unlock(file, [options])

Releases a previously acquired lock on file or rejects the promise on error.

Whenever possible you should use the release function instead (as exemplified above). Still there are cases in which it's hard to keep a reference to it around code. In those cases unlock() might be handy.

Available options:

  • realpath: Resolve symlinks using realpath, defaults to true (note that if true, the file must exist previously)
  • fs: A custom fs to use, defaults to graceful-fs
  • lockfilePath: Custom lockfile path. e.g.: If you want to lock a directory and create the lock file inside it, you can pass file as <dir path> and options.lockfilePath as <dir path>/dir.lock
const lockfile = require('proper-lockfile');

lockfile.lock('some/file')
.then(() => {
    // Do something while the file is locked

    // Later..
    return lockfile.unlock('some/file');
});

.check(file, [options])

Check if the file is locked and its lockfile is not stale, rejects the promise on error.

Available options:

  • stale: Duration in milliseconds in which the lock is considered stale, defaults to 10000 (minimum value is 5000)
  • realpath: Resolve symlinks using realpath, defaults to true (note that if true, the file must exist previously)
  • fs: A custom fs to use, defaults to graceful-fs
  • lockfilePath: Custom lockfile path. e.g.: If you want to lock a directory and create the lock file inside it, you can pass file as <dir path> and options.lockfilePath as <dir path>/dir.lock
const lockfile = require('proper-lockfile');

lockfile.check('some/file')
.then((isLocked) => {
    // isLocked will be true if 'some/file' is locked, false otherwise
});

.lockSync(file, [options])

Sync version of .lock().
Returns the release function or throws on error.

.unlockSync(file, [options])

Sync version of .unlock().
Throws on error.

.checkSync(file, [options])

Sync version of .check(). Returns a boolean or throws on error.

Graceful exit

proper-lockfile automatically removes locks if the process exits, except if the process is killed with SIGKILL or it crashes due to a VM fatal error (e.g.: out of memory).

Tests

$ npm test
$ npm test -- --watch during development

The test suite is very extensive. There's even a stress test to guarantee exclusiveness of locks.

License

Released under the MIT License.

More Repositories

1

node-cross-spawn

A cross platform solution to node's spawn and spawnSync
JavaScript
1,067
star
2

next-layout

Add persistent and nested layouts to your Next.js projects in a declarative way
JavaScript
257
star
3

node-promptly

Simple command line prompting utility for nodejs
JavaScript
148
star
4

gatsby-plugin-ipfs

Adds support for deploying Gatsby to IPFS by ensuring that assets are relative
JavaScript
113
star
5

next-router-scroll

Take control of when scroll is updated and restored in your Next.js projects.
JavaScript
105
star
6

next-with-moxy

MOXY's boilerplate to accelerate the setup of new Next.js based web applications
JavaScript
101
star
7

js-proper-url-join

Like path.join but for a URL
JavaScript
40
star
8

next-intl

Library to integrate react-intl with Next.js.
JavaScript
40
star
9

webpack-isomorphic-dev-middleware

The webpack-dev-middleware, but for isomorphic applications
JavaScript
39
star
10

react-with-moxy

MOXY's boilerplate to create isomorphic react applications
JavaScript
36
star
11

js-deep-for-each

Recursively iterates over collections arrays and objects
JavaScript
35
star
12

node-token-dealer

Circumvent API rate limits by having several API tokens and let the dealer manage and give them to you
JavaScript
24
star
13

react-native-with-moxy

MOXY's boilerplate to accelerate the setup of new React Native mobile apps
JavaScript
22
star
14

js-class-is

Enhances a JavaScript class by adding an is<Class> property to compare types between realms.
JavaScript
17
star
15

webpack-isomorphic-compiler

A compiler that makes your life easier if you are building isomorphic webpack powered apps, that is, single page applications with server-side rendering
JavaScript
16
star
16

react-page-swapper

An orchestrator that eases out the implementation of page transitions
JavaScript
15
star
17

eslint-config

MOXY eslint configuration to be used across several JavaScript projects
JavaScript
14
star
18

react-carousel

A React carousel component that aims to be as flexible as possible
JavaScript
14
star
19

react-contentful-image

A react image renderer that uses the Contentful Images API.
JavaScript
12
star
20

ugo

An extensible and composable cli
12
star
21

next-sitemaps

An API handler and a plugin that enables your Next.js application to have working sitemaps
JavaScript
12
star
22

js-keyboard-only-outlines

Disable outlines caused by navigation methods other than keyboard
JavaScript
11
star
23

next-common-files

Next.js plugins that configure webpack with loaders for common files
JavaScript
9
star
24

react-promiseful

A React component and hook to render children conditionally based on a promise state
JavaScript
9
star
25

postcss-preset

PostCSS preset to be used at MOXY
JavaScript
8
star
26

next-env

Next.js plugin to pass environment variables to Next.js's configuration
JavaScript
8
star
27

webpack-sane-compiler

A webpack compiler wrapper that provides a nicer API
JavaScript
8
star
28

react-lib-template

This template aims to make the implementation of react component packages easier and more methodic.
JavaScript
8
star
29

stylelint-config

MOXY stylelint configuration to be used across several CSS projects
JavaScript
8
star
30

next-pre-compression

Next.js plugin to compress static assets at build time and serve them instead of having to compress on-the-fly
JavaScript
8
star
31

node-gh-issues-stats

Collect statistical information about issues of a GitHub repository
JavaScript
8
star
32

next-link

A component that enables client-side transitions between routes as well as external URLs.
JavaScript
7
star
33

redux-mock-store-await-actions

Waits for specific actions to be dispatched or a timeout expires
JavaScript
7
star
34

webpack-isomorphic-compiler-reporter

Beautiful reporting for webpack-isomorphic-compiler compilation events
JavaScript
7
star
35

react-split-text

A react component that wraps each word of a sentence into a <span> element.
JavaScript
6
star
36

yargs-get-help

Get the help output from a yargs instance
JavaScript
6
star
37

js-chained-config

Use a chaining API to generate and simplify the modification of configs
JavaScript
5
star
38

babel-preset

Babel preset to be used at MOXY
JavaScript
5
star
39

yargs-unparser

Converts back a yargs argv object to its original array form
5
star
40

workshop-react

A workshop to introduce developers to React, presented in the Aveiro University
JavaScript
5
star
41

next-compile-node-modules

Next.js plugin to compile all node_modules using Babel
JavaScript
5
star
42

yargs-promise-handler

Adds support for promises to yargs handlers and allows them to be composable
JavaScript
5
star
43

react-wait-for-react

Easily render a splash screen and loader while your React app is not yet interactive, optionally waiting for a promise as well
JavaScript
5
star
44

react-app-rewire-css-modules-extensionless

Enables CSS modules without any special extension for CRA apps using react-app-rewired
JavaScript
5
star
45

react-keyboard-only-outlines

Disable outlines caused by navigation methods other than keyboard
JavaScript
4
star
46

webpack-sane-compiler-notifier

Notify webpack compilation status to your operating system when using webpack-sane-compiler
JavaScript
4
star
47

react-icon

A component to render svg icons.
JavaScript
4
star
48

next-rest-api

Aims to ease the development of REST APIs in Next.js
JavaScript
4
star
49

next-seo

Manage document head SEO metadata in your Next.js projects with a simple data structure.
JavaScript
4
star
50

node-fetch-coverage

Fetch the code coverage from an open-source GIT repository, using a variety of well-known coverage services
JavaScript
4
star
51

webpack-sane-compiler-reporter

Beautiful reporting for webpack-sane-compiler compilation events
JavaScript
4
star
52

react-modal

A modal, built on top of react-modal, that also fixes the scrollable body in iOS
JavaScript
3
star
53

node-is-regular-file

Checks if a path is a regular file
JavaScript
3
star
54

react-navigation

Set of react components, hooks and providers to easily kickoff a navigation environment in web projects.
JavaScript
3
star
55

webpack-isomorphic-compiler-notifier

Notify webpack compilation status to your operating system when using webpack-isomorphic-compiler
JavaScript
3
star
56

js-pico-signals

A very simple signal library inspired by the 'signals' package
JavaScript
3
star
57

react-svg

MOXY'S base SVG component.
JavaScript
3
star
58

next-button

A react button that doubles down as a link.
JavaScript
3
star
59

jest-config

MOXY's Jest configuration to be used across several JavaScript projects
JavaScript
3
star
60

react-contentful-rich-text

A react component that transforms a contentful rich text structure to html.
JavaScript
3
star
61

react-animate-text

A react component that animates text per word and/or per line.
JavaScript
2
star
62

react-with-moxy-scripts

This package includes scripts and configuration used by react-with-moxy
2
star
63

create-next-routes

A CLI to manage Next.js routes
JavaScript
2
star
64

react-redata

React data container for isomorphic applications, providing a unified and performant load & reload pattern
JavaScript
2
star
65

react-circle

MOXY's circle animation component
JavaScript
2
star
66

next-webpack-oneof

Wraps all webpack loader rules into a single oneOf rule
JavaScript
2
star
67

rfcs-oss

RFCs for additions or changes to MOXY open-source projects
2
star
68

workshop-leveling-up-with-redux

Redux workshop composed by an introductory section, followed by some advanced aspects.
JavaScript
2
star
69

react-ellipsis

Moxy's base Ellipsis component.
JavaScript
1
star
70

react-app-rewire-external-svg-loader

Enables external-svg-loader for CRA apps using react-app-rewired
JavaScript
1
star
71

react-accordion

MOXY's base Accordion component.
JavaScript
1
star
72

next-with-router-ref

An alternative to Next.js withRouter HOC that supports refs by forwarding them
JavaScript
1
star
73

react-dropdown

A Dropdown component for React, based on react-select.
JavaScript
1
star
74

express-ensure-content-type

Express middleware that ensures requests match the specified content-type.
JavaScript
1
star
75

workshop-the-hitchhikers-guide-to-react

React workshop composed by an introductory section, followed by some advanced aspects.
JavaScript
1
star
76

redux-await-actions

Waits for specific actions to be dispatched or a timeout expires.
JavaScript
1
star