Learn about our RFC process, Open RFC meetings & more.Join in the discussion! »

lock-qweue

1.0.2 • Public • Published

Lock Qweue

Inter-process multi-resource locking queue. It has a server-client architecture. If you are looking for local (single-process) multi-resource locking, check out async-lock as it has been out there for longer.

Requirements

  • Node.js at least v7.6.0 or higher for ES2015 and async function support

Install

npm i lock-qweue

List of classes

  • Server (Lock qweue server)
  • Client (Lock qweue client)
  • LockSpace (Space where names of resources must be unique)

Server class

Functions

  • constructor(options) → returns Server instance
  • listen(port)
  • close()
  • io() → returns underlying Socket.io server

Examples

Start a server:

const Server = require('lock-qweue/server');
 
let server = new Server({
    port: 3000,
    token: 'secret', // (optional) Authentication token.
    maxPending: 100, // (optional) Max pending lock requests per namespace.
    logInfo: console.log, // (optional) Info logs function.
    logSuccess: console.log, // (optional) Success logs function.
    logError: console.error, // (optional) Error logs function.
});

or

const Server = require('lock-qweue/server');
 
let server = new Server();
server.listen(3000);
 

Client class

Functions

  • constructor(options) → returns Client instance
  • async lockRequest(resources, options) → returns Request instance
  • async tryLock(resources, options) → boolean (lock acquired flag)
  • async release(resources, options) → boolean (all released resources were locked flag)
  • async abort(requestId, options) → boolean (request id was found flag)
  • async lock(resources, fn, options)
  • io() → returns underlying Socket.io client

Examples

Connect a client:

const Client = require('lock-qweue/client');
 
let client = new Client({
    host: 'http://localhost:3000',
    namespace: 'name', // (optional) Namespace that will be used by default. Can be overridden with options.
    name: 'client1', // (optional) Client name.
    token: 'secret', // (optional) Authentication token.
    logError: console.error, // (optional) Error logs function.
});

Execute a function while resource lock is acquired:

await client.lock(['resource A', 'resource B'], async () => {
    // ... function here
})

or

await client.lockRequest(['resource A', 'resource B']).promise;
 
// ... function here
 
await client.release(['resource A', 'resource B']);

Try to lock resources:

let resourcesLocked = await client.tryLock(['resource A', 'resource B']);

Abort a lock request:

let request = await client.lockRequest(['resource A', 'resource B'], {
    namespace: 'name', // (optional) Override the default client namespace.
});
 
// ... some code here
 
await request.abort();

Lock request with timeout:

let request = await client.lockRequest(['resource A', 'resource B'], {
    timeout: 1000, // (optional) Timeout in milliseconds.
});
await request.promise; // If time runs out, this will throw an error.

LockSpace class

You can use this class if you want to lock resources locally (single-process).

Functions

  • default(maxPending) → returns the default LockSpace instance
  • tryLock(resources) → boolean (lock acquired flag)
  • lock(resources, options) → string request id
  • async lockAsync(resources, fn, timeout)
  • abort(requestId) → boolean (request id was found flag)
  • release(resources) → boolean (all released resources were locked flag)
  • isEmpty() → boolean (true if the requests queue is empty and there are no locked resources)

Examples

Execute a function while resource lock is acquired:

const LockSpace = require('lock-qweue/lock-space');
 
let space = new LockSpace();
 
await space.lockAsync(['resource A', 'resource B'], async () => {
    // ... function here
});

or

const LockSpace = require('lock-qweue/lock-space');
 
let space = new LockSpace();
 
await space.waitLock(['resource A', 'resource B'], 1000); // Lock resources with an optional 1000ms timeout.
 
// ... Your code here ...
// NOTE: If needed wrap your code in a try catch statement to make sure the resources get released.
 
// Do not forget to release the resources.
space.release(['resource A', 'resource B']);
 

or

const LockSpace = require('lock-qweue/lock-space');
 
let space = new LockSpace();
 
await space.lock(['resource A', 'resource B'], {
    resolve: () => {
        // ... function here
 
        space.release(['resource A', 'resource B']);
    },
    reject: (error) => {
        space.release(['resource A', 'resource B']);
        console.error(error.message);
    },
    timeout: 1000, // (optional) Timeout in milliseconds.
});

Development

Node.js libraries used

System that was used for development

  • OS: Ubuntu 18.04
  • Node.js: v8.11.3

Optional requirements for development

  • docker
  • npm package manager for JavaScript
  • VS Code for Node.js development and debugging

Ideas for further development

  • authentication to support multiple tokens and ip whitelisting
  • optimizing the multi-resource locking queue algorithm
  • support for REDIS

Install

npm i lock-qweue

DownloadsWeekly Downloads

4

Version

1.0.2

License

MIT

Unpacked Size

43.8 kB

Total Files

11

Last publish

Collaborators

  • avatar