https://github.com/metamx/zk-lock
distributed lock using zookeeper
https://github.com/metamx/zk-lock
distributed-locking lock locking node nodejs zookeeper
Last synced: 22 days ago
JSON representation
distributed lock using zookeeper
- Host: GitHub
- URL: https://github.com/metamx/zk-lock
- Owner: metamx
- Created: 2015-12-07T19:32:36.000Z (about 10 years ago)
- Default Branch: master
- Last Pushed: 2023-01-11T12:44:39.000Z (about 3 years ago)
- Last Synced: 2025-11-03T22:21:35.823Z (3 months ago)
- Topics: distributed-locking, lock, locking, node, nodejs, zookeeper
- Language: TypeScript
- Homepage:
- Size: 111 KB
- Stars: 11
- Watchers: 40
- Forks: 1
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# zk-lock
Distributed locking using [node-zookeeper-client](https://github.com/alexguan/node-zookeeper-client), following the
recipe in the [zookeeper documentation](https://zookeeper.apache.org/doc/r3.1.2/recipes.html#sc_recipes_Locks).
The library exposes a single class, `ZookeeperLock` which is both the lock object, and provides static methods for
initializing the configuration and acquiring locks which are already locked.
All locks are stored in a top level zookeeper folder `locks/`, can have an optional path prefix, and take a key argument
which indicates the resource that should be locked.
Locks must be explicitly released with the `unlock` method in order to allow other processes to obtain the lock. `unlock` will also close the zookeeper connection.
## Configuration
`serverLocator: () => Promise` serverLocator is a service discovery/location resolving library such as [locators](https://github.com/metamx/locators),
or anything which implements a function which takes no arguments and can return a promise of a `Location` object that has properties `host` and `port` which specify
where the zookeeper server can be discovered.
`pathPrefix: string` This is a prefix to add to any key which is to be locked. Note: all locks will
start with the path `locks/`, so with a prefix of `foo/bar`, when locking the key `baz` the zookeeper
path will be of the form `locks/foo/bar/baz`.
`sessionTimeout: number` node-zookeeper-client `sessionTimeout` parameter that is passed down to the zookeeper client.
`spinDelay: number` node-zookeeper-client `spinDelay` parameter that is passed down to the zookeeper client.
`retries: number` node-zookeeper-client `retries` parameter that is passed down to the zookeeper client.
`failImmediate: boolean` when set to true, instead of a blocking call to `.lock`, it will fail immediately throwing a `ZookeeperLockAlreadyLockedError`
`maxConcurrentHolders: number` allow multiple calls to `.lock` to grab a lock, allowing the lock to control the number of participants in an action
## ZookeeperLock
### constructor
usage:
```
var lock = new ZookeeperLock(config);
```
### Static methods
#### initialize
usage: `ZookeeperLock.initialize(config);`
Initialize a global configuration for zookeeper locks.
#### lockFactory
usage:
```
var lock = ZookeeperLock.lockFactory();
```
#### lock
usage:
```
ZookeeperLock.lock('key').then(function (lock) {
... do stuff
});
```
### Instance methods
#### lock
usage:
```
var lock = ZookeeperLock.lockFactory();
lock.lock('key').then(function() {
... do stuff
});
```
#### unlock
usage;
```
var lock = ZookeeperLock.lockFactory();
lock.lock('key').then(function() {
... do stuff
lock.unlock().then(function () {
...
});
});
```
### Session timeouts
Due to the nature of zookeeper, this locking strategy is susceptible to a situation when `sessionTimeout` occurs that a lock holder can still think that they own the lock, but the key has been lost on the zookeeper server. To handle this, `ZookeeperLock` exposes a `signal` property that emits a `lost` event when a `sessionTimeout` occurs, which MUST be handled by the lock holder to terminate execution.
usage:
```
var lock = ZookeeperLock.lockFactory();
lock.lock('key').then(function() {
lock.on('lost', function () {
... handle losing the lock, i.e. restart locking cycle.
});
});
```
## Development
`npm run build` to compile.
The tests currently require a local installation of zookeeper to run successfully, specified
by the `zkServerCommandPath` variable which is defined near the beginning of the tests.