1.0.2 • Published 5 years ago

lock-qweue v1.0.2

Weekly downloads
2
License
MIT
Repository
github
Last release
5 years ago

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