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

@ndustrial/sequelize-distributed-lock

v0.9.0

Published

Enables distributed locking for sequelize applications

Downloads

6,463

Readme

Node Distributed Lock

Build Status npm (stable) semantic-release

Node Distributed Lock (NDL) is a client- and dialect-agnostic distributed locking tool for NodeJS applications. It can be used to orchestrate database migrations in a distributed setting or as a general distributed locking capability for any use.

Unlike other popular distributed locking tools that enforce a specific migration library or provide same-transaction locking, NDL can be used to lock across distributed nodes for the duration of your arbitriary action, whether it be another database write, a cleanup job, or even triggering a lambda function.

Note: A lock table will be created to store the locks in the database.

Currently, the following database clients/ORMs are supported. Please open an issue or contribute with your own PR to help grow the list:

| Database Client | Supported | | --------------------------------------------------- | :---: | | Sequelize | X | | KnexJs | X |

Currently, the following dialects are supported. Please open an issue or contribute with your own PR to help grow the list:

| Database Dialect | Supported | | --------------------- | :---: | | PostgreSQL | X | | MySQL | | | MariaDB | | | SQLite | | | Microsoft SQL Server | |

Installation

npm install @ndustrial/sequelize-distributed-lock

Highlights

  • Works with the popular ORM Sequelize out of the box
  • Supports other query interfaces/database clients
  • Does not enforce same-transaction locking
  • Supports independent locks (locks are named)

Simple Example

Sequelize

// index.js
const Sequelize = require('sequelize');
const DistributedLock = require('@ndustrialio/sequelize-distributed-lock');

const sequelize = new Sequelize({...});

const importantLogic = async () => {
  // will never run at the same time
}

const importantLock = new DistributedLock('my-important-logic-lock', {
  queryInterface: sequelize.queryInterface
});

importantLock
  .lock(importantLogic) // Ensures importantLogic is run by a single node at a time
  .then(() => {
    console.log('Done!');
  });

KnexJS

// index.js
const KnexJs = require('knex');
const DistributedLock = require('@ndustrialio/sequelize-distributed-lock');

const knex = new KnexJs({...});

const importantLogic = async () => {
  // will never run at the same time
}

const importantLock = new DistributedLock('my-important-logic-lock', {
  queryInterface: knex
});

importantLock
  .lock(importantLogic) // Ensures importantLogic is run by a single node at a time
  .then(() => {
    console.log('Done!');
  });

If the above code was scaled to >1 nodes, each node will create its own instance of the distributed lock and call the .lock() method; however, only one node will run the method importantLock at the same time. Once the logic is completed on one node, the next node will be able to obtain the lock and call the method.

It is important to note that, with current functionality, the importantLock() method will be called by every node, just never at the same time. In the world of database migrations, this is expected functionality, as the migration table will be up-to-date after the first execution.

Configuration

The DistributedLock(lockName, params) constructure allows some configuration to alter the behavior of the locking mechanism.

First and foremost, the lockName is used to ensure all distributed locks are locking on the same mutex. This enables you to create multiple locks in the same deployment and manage them independently.

The following values are passed in via the params argument.

| Configuration Name | Description | Required | Default | | ------------------ | ------------------------------------------------------------------- | :---: | :---: | | queryInterface | The query interface database client | X | | | queryInterfaceName | The name of the query database client (i.e. sequelize, knex) | | | | lockTableName | The name of the table that will hold locks | | distributed_lock | | lockTTLSeconds | The time (seconds) after which locks should expire | | 1200 | | skipIfObtained | Whether subsequent lock calls to an obtained lock should exit early | | false |

NOTE: If you omit the queryInterfaceName, NDL will attempt to determine it based on the interface object.

Single Execution

An option called skipIfObtained can be set to true in order to indicate that simultaneous lock calls on the same mutext should exit early if the lock mutex has already been obtained. This can be used to ensure that a single caller gains access to running the logic at any given time and subsequent callers will not run it immediately after.

Callers that have exited early due to this flag will resolve a result equal to the symbol DistributedLock.EXECUTION_SKIPPED.

License

See the LICENSE.