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

enqueue-server

v1.0.1

Published

Node Enqueue Server

Downloads

6

Readme

enqueue-server

Node enqueue server is a clean NodeJS implementation for providing locking and concurrency controls on business object level. It supports 4 types of locks:

  1. Shared lock
  2. Exclusive Lock
  3. Exclusive but not cumulative Lock
  4. Optimistic Lock

Example

User A is editing a product master data, while user B also attempts to edit the same product. On the UI of product mater data maintenance, B is told that the product is currently locked by A, and he can only display it. This is a very usual case of pessimistic lock, and it can be easily achieved using enqueue-server's exclusive lock.

var lockClient = require('enqueue-client');
var lock = {"name":"product","argument":["Computer"],"mode":"E","owner":"B"};

lockClient.lock(lock, function(lockUUID,RC,OWNER){
   if(RC === '0'){ //Lock is acquired
     //Allow Editing
     lockClient.unlock(lockUUID); //Unlock the object after finish editing
   }else{
     //Report message: "The product Computer is now locked by <OWNER>"
   }  
});    

Architecture and Deployment

Enqueue server is started in one single Node process. It can be either deployed in the same server with your application, or be deployed in a standalone server. In both cases, it can be shared among multiple application server processes.

Enqueue Server is behind application server process

To Begin

  1. Install it:

    $ npm install -g enqueue-server 
  2. Start the enqueue server:

    CD to the install path of EnqueueServer

    $ node index.js 
  3. Test to connect:

    Download the enqueue-client, and execute following javascript in NodeJS.

    var lockClient = require('enqueue-client');
    lockClient.setEnqueueServerConnection('127.0.0.1', 3721);
       
    var lock = {"name":"product","argument":["Computer"],"mode":"E","owner":"B"};
    lockClient.lock(lock, function(lockUUID,RC,OWNER){
       console.log('Lock is acquired with lock UUID: '+lockUUID);
      
    });

Lock Types

4 lock types are supported.

Shared Lock (S)

Several users (transactions) can access locked data at the same time in display mode. Requests from further shared locks are accepted, even if they are from different users.

An exclusive lock (E) set by another user on an object that already has a shared lock will be rejected. Every extended exclusive lock (X) will also be rejected.

Exclusive Locks (E)

An exclusive lock protects the locked object against all types of locks from other transactions. Only the same lock owner can reset the lock (accumulate).

eXclusive non-cumulative (X)

Whereas exclusive locks can be requested several times by the same transaction and released one by one, an exclusive, non-cumulative lock can only be requested once by the same transaction. Each further lock request will be rejected.

Optimistic Lock (O)

Optimistic locks initially behave like shared locks and can be converted into exclusive locks.

Elementary Lock

An elementary lock contains following attributes:

name: lock object name, usually you can use the database table name.

argument: the key of the object, it is an array, as the object key may be combined with several fields. For example, an object has the key combined with 3 fields. The argument ['A', 'B', '@'] stands for the object with first 2 key fields equals 'A' and 'B', the wildcard letter represented here by '@'.

mode: 4 lock types: S, E, X, O.

owner: the owner who holds the lock, it can be a login user ID.

waitTime: time to wait until the lock is acquired, default is 0.

timeout: the time to hold the lock, after which the elementary lock will be released automatically. Default is 15 minutes.

APIs

5 APIs are provided in the enqueue-client.

lockClient.lock(elementaryLock, callback)

Acquire a lock for the elementaryLock. The callback will be called once the result is received.

var elementaryLock = {"name":"product","argument":["Computer"],"mode":"E","owner":"B"};
lockClient.lock(elementaryLock, function(lockUUID,RC,MSG){
   //lockUUID is a unique id for the acquired lock, you must record it so that you can unlock it afterward;
   //RC stands for the return code. 0:Success, 1:Fail, 3:Error in client, 4:Error in server;
   //MSG returns the detail error message if RC is 3 or 4, and the lock owner if RC is 1;      
});

lockClient.unlock(lockUUID [,callback])

Release the lock with the specified lock UUID. The callback is optional.

lockClient.unlock(lockUUID, function(RC,MSG){
   //RC: 0:Success, 4:Error in server;
   //MSG returns the detail error message if RC is 4;      
});

lockClient.promote(lockUUID, callback)

Promote the optimistic lock with the specified lock UUID. The callback receives the response from server.

lockClient.promote(lockUUID, function(RC,MSG){
   //RC: 0:Success, 2:Fail, 3:Error in client, 4:Error in server;
   //MSG returns the detail error message if RC is 3 or 4, and the existing lock owner if RC is 2;      
});

lockClient.getLocksBy(lockName, lockOwner, callback)

Get a list of existing locks in the enqueue server by lockName and lockOwner. The callback receives an array of locks. If you give both lockName and lockOwner, it filters with both. If you only give either lockName or lockOwner, it filters with one of the given. If you assign null for both, it return the complete lock list.

lockClient.getLocksBy(null, null, function(RC,locks){
   //RC: 0:Success, 3:Error in client;
   //locks is an array contains the locks if RC is 0 , and an error message if RC is 2;      
});

lockClient.setEnqueueServerConnection(host, port)

Set the remote enqueue server's host and port. The method is optional if the enqueue server lies on the same server as the lock client. As the default host and port are "127.0.0.1" and "3721".

Tests

You can find all the unit tests in the test folder, and run them by:

$ npm run test 

Performance

Performance is tested to support around 3000 lock/unlock requests per second.

License

The MIT License