Skip to content

Repository files navigation

Web Locks API CI Status npm version npm downloads/month npm downloads license

Web Locks API implementation for Node.js based on worker_threads, Atomics, SharedArrayBuffer, asynchronous functions, and queue.

See specification: wicg.github.io/web-locks/ and documentation: developer.mozilla.org/en-US/docs/Web/API/Lock

This implementation is a part of Metarhia technology stack, needed for the first pilot project of Node.js application server based on parallel programming and workload micro-isolation. Web Locks API is intended to be merged into Node.js in future.

Features

  • Simplest parallel programming primitive to solve a problem of data races and race conditions.
  • Node.js and worker_threads support.
  • Unified API for single-threaded asynchronous locks and multi-threaded locks.
  • Exclusive lock mode (default).
  • AbortSignal support to cancel a lock request while waiting.
  • TypeScript typings included.

Installation

$ npm install web-locks

Usage

const { locks, AbortController } = require('web-locks');

// Exclusive lock (default)
await locks.request('Resource name', async (lock) => {
  // use named resource; it is released after the callback settles
});

// Cancel a waiting request with AbortSignal
const controller = new AbortController();
const pending = locks.request(
  'Resource name',
  { signal: controller.signal },
  async () => {
    // critical section
  },
);
controller.abort(); // rejects pending with AbortError

Attach workers so locks are coordinated across threads:

const { Worker } = require('worker_threads');
const { locks } = require('web-locks');

const worker = new Worker('./worker.js');
locks.attach(worker);

API

locks.request(name, handler): Promise<undefined>

locks.request(name, options, handler): Promise<undefined>

  • name: string β€” resource name
  • options.mode?: 'exclusive' β€” only exclusive is supported
  • options.signal?: AbortSignal β€” abort waiting for the lock
  • handler: (lock: Lock) => void | Promise<void> β€” runs while holding the lock

Already-aborted signals reject immediately. Aborting while waiting cancels the queued request and rejects with AbortError (or signal.reason when set).

locks.query(): Promise<LockManagerSnapshot>

  • held: Array<LockInfo> β€” currently held locks
  • pending: Array<LockInfo> β€” queued lock requests

locks.attach(worker): void

Registers a worker_threads.Worker for cross-thread lock coordination.

Exports

  • locks: LockManager
  • AbortController, AbortSignal, AbortError β€” native when available, otherwise a small polyfill

License

This implementation of Web Locks API is MIT licensed.