{"id":16250963,"url":"https://github.com/ndustrialio/node-distributed-lock","last_synced_at":"2025-03-30T04:30:51.024Z","repository":{"id":37033119,"uuid":"347188712","full_name":"ndustrialio/node-distributed-lock","owner":"ndustrialio","description":"Enables distributed locking for sequencing actions across node applications","archived":false,"fork":false,"pushed_at":"2025-03-17T16:42:05.000Z","size":2001,"stargazers_count":6,"open_issues_count":5,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-28T08:06:25.426Z","etag":null,"topics":["database","distributed","library","locking","nodejs","postgresql","sequelize"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ndustrialio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-12T20:24:18.000Z","updated_at":"2025-03-10T15:18:41.000Z","dependencies_parsed_at":"2023-12-18T16:00:38.802Z","dependency_job_id":"dc162a1d-f2f3-4d0d-b8b9-15a7dc536ca7","html_url":"https://github.com/ndustrialio/node-distributed-lock","commit_stats":{"total_commits":247,"total_committers":4,"mean_commits":61.75,"dds":"0.23886639676113364","last_synced_commit":"073d21ef417b36f462c81579e2c2913a86f2e611"},"previous_names":["ndustrialio/sequelize-distributed-lock"],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndustrialio%2Fnode-distributed-lock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndustrialio%2Fnode-distributed-lock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndustrialio%2Fnode-distributed-lock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndustrialio%2Fnode-distributed-lock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ndustrialio","download_url":"https://codeload.github.com/ndustrialio/node-distributed-lock/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246277352,"owners_count":20751548,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","distributed","library","locking","nodejs","postgresql","sequelize"],"created_at":"2024-10-10T15:08:16.899Z","updated_at":"2025-03-30T04:30:50.467Z","avatar_url":"https://github.com/ndustrialio.png","language":"JavaScript","readme":"# Node Distributed Lock\n\n[![Build](https://github.com/ndustrialio/node-distributed-lock/actions/workflows/build.yaml/badge.svg)](https://github.com/ndustrialio/node-distributed-lock/actions/workflows/build.yaml)\n[![Package on npm](https://img.shields.io/npm/v/@ndustrial/node-distributed-lock.svg?style=flat)](https://www.npmjs.com/package/@ndustrial/node-distributed-lock)\n[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n\nNode 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.\n\nUnlike 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.\n\n_**Note:** A lock table will be created to store the locks in the database._\n\nCurrently, the following database clients/ORMs are supported. Please open an issue or contribute with your own PR to help grow the list:\n\n| Database Client                                     | Supported |\n| --------------------------------------------------- |   :---:   |\n| [Sequelize](https://github.com/sequelize/sequelize) | X         |\n| [KnexJs](http://knexjs.org/)                        | X         |\n| [node-postgres - Pool](https://node-postgres.com/)  | X         |\n\nCurrently, the following dialects are supported. Please open an issue or contribute with your own PR to help grow the list:\n\n| Database Dialect      | Supported |\n| --------------------- |   :---:   |\n| PostgreSQL            | X         |\n| MySQL                 |           |\n| MariaDB               |           |\n| SQLite                |           |\n| Microsoft SQL Server  |           |\n\n## Installation\n\n```sh\nnpm install @ndustrial/node-distributed-lock\n```\n\n## Highlights\n\n- Works with the popular ORM Sequelize out of the box\n- Supports other query interfaces/database clients\n- Does not enforce same-transaction locking\n- Supports independent locks (locks are named)\n\n## Simple Example\n\n### Sequelize\n\n```js\n// index.js\nconst Sequelize = require('sequelize');\nconst DistributedLock = require('@ndustrialio/node-distributed-lock');\n\nconst sequelize = new Sequelize({...});\n\nconst importantLogic = async () =\u003e {\n  // will never run at the same time\n}\n\nconst importantLock = new DistributedLock('my-important-logic-lock', {\n  queryInterface: sequelize.queryInterface\n});\n\nimportantLock\n  .lock(importantLogic) // Ensures importantLogic is run by a single node at a time\n  .then(() =\u003e {\n    console.log('Done!');\n  });\n```\n\n### KnexJS\n```js\n// index.js\nconst KnexJs = require('knex');\nconst DistributedLock = require('@ndustrialio/node-distributed-lock');\n\nconst knex = new KnexJs({...});\n\nconst importantLogic = async () =\u003e {\n  // will never run at the same time\n}\n\nconst importantLock = new DistributedLock('my-important-logic-lock', {\n  queryInterface: knex\n});\n\nimportantLock\n  .lock(importantLogic) // Ensures importantLogic is run by a single node at a time\n  .then(() =\u003e {\n    console.log('Done!');\n  });\n```\n\n### PG Pool\n```js\n// index.js\nconst { Pool } = require('pg');\nconst DistributedLock = require('@ndustrialio/node-distributed-lock');\n\nconst pool = new Pool({...});\n\nconst importantLogic = async () =\u003e {\n  // will never run at the same time\n}\n\nconst importantLock = new DistributedLock('my-important-logic-lock', {\n  queryInterface: pool\n});\n\nimportantLock\n  .lock(importantLogic) // Ensures importantLogic is run by a single node at a time\n  .then(() =\u003e {\n    console.log('Done!');\n  });\n```\n\nIf the above code was scaled to \u003e1 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.\n\nIt 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.\n\n## Configuration\n\nThe  `DistributedLock(lockName, params)` constructure allows some configuration to alter the behavior of the locking mechanism.\n\nFirst 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.\n\nThe following values are passed in via the `params` argument.\n\n| Configuration Name | Description                                                         | Required | Default            |\n| ------------------ | ------------------------------------------------------------------- |   :---:  |        :---:       |\n| queryInterface     | The query interface database client                                 | X        |                    |\n| queryInterfaceName | The name of the query database client (i.e. `sequelize`, `knex`)    |          |                    |\n| lockTableName      | The name of the table that will hold locks                          |          | `distributed_lock` |\n| lockTTLSeconds     | The time (seconds) after which locks should expire                  |          | 1200               |\n| skipIfObtained     | Whether subsequent lock calls to an obtained lock should exit early |          | `false`            |\n\n**NOTE:** If you omit the `queryInterfaceName`, NDL will attempt to determine it based on the interface object.\n\n**NOTE:** You can specify a database schema for the lock table by passing it as a prefix to the `lockTableName` (i.e. `public.table`). This `schema` will be created if it does not exist.\n### Single Execution\n\nAn 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.\n\nCallers that have exited early due to this flag will resolve a result equal to the symbol `DistributedLock.EXECUTION_SKIPPED`.\n\n## License\n\nSee the [LICENSE](./LICENSE).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fndustrialio%2Fnode-distributed-lock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fndustrialio%2Fnode-distributed-lock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fndustrialio%2Fnode-distributed-lock/lists"}