flexlock-cb
A locking library like [`mutexify`](https://github.com/mafintosh/mutexify), [`mutex-js`](https://github.com/danielglennross/mutex-js), [`await-lock`](https://www.npmjs.com/package/await-lock), and [many more](https://www.npmjs.com/search?q=promise+lock),
Last updated a month ago by leichtgewicht .
MIT · Repository · Bugs · Original npm · Tarball · package.json
$ cnpm install flexlock-cb 
SYNC missed versions from official npm registry.

flexlock-cb

Build Status JavaScript Style Guide Maintainability Test Coverage

flexlock-cb is a very small, memory-concious, flexible locking library without dependencies but with typescript definitions (see in the bottom). Optimized even further than flexlock for the use with callbacks instead of promises.

npm i flexlock-cb --save

It is similar to other in-memory locking library like mutexify, mutex-js, await-lock, and many more, but with more flexibility in how to use it.

This makes it sturdier and more practical in many cases.

simple basic API

const { createLockCb } = require('flexlock-cb')

const lock = createLockCb()

lock(unlock => {
  // done before the next block
  unlock()
})
lock(unlock => {
  // will wait for the 
  unlock()
})

Propagation of errors and results to a callback

function callback (err, data) {
  // err === null
  // data === 'important'
}

lock(
  unlock => unlock(null, 'important'),
  callback
)

Promises are returned if no callback is added

const promise = lock(unlock => {
  unlock(null, 'important')
}) // Without passing in a callback, promises will be created

promise
  .catch(err => {})
  .then(data => {})
  // This way you can support both callback and promise based APIs

Timeouts in case anther lock never returns

function neverUnlock (unlock) { /* Due to a bug it never unlocks */ }
function neverCalled () {}

lock(neverUnlock)
lock(neverCalled, 500, err => {
  err.code === 'ETIMEOUT'
})

release handlers both once and for every release

function onEveryRelease () {}
function onNextRelease () {}

const lock = createLockCb(onEveryRelease) // Called everytime the lock is released
lock.released(onNextRelease) // Called next time the lock is released

await lock.released() // Promise API available as well

Like for Promises, two separate callbacks can be specified

function onSuccess (data) {}
function onError (err) {}

lock(unlock => unlock(), onSucess, onError)

sync handlers, for when you want to make sure that other locks are done

const lock = createLockCb()

const result = await lock.sync(() => {
  // no unlock function (automatically unlocked after method is done)
  return 123
})

result === 123 // the result is passed to the callback

In case you need it, a reference to the lock is also passed in:

const result = await lock.sync(lock => { /* ... */ })

Its also possible to wrap a method into a sync lock:

const fn = lock.syncWrap((foo, bar) => {
  /**
   - No unlock function.
   - Arguments are passed-through.
   - Executed will be asynchronously.
   - Return value will be ignored.
   */
  foo === 'hello'
  bar === 'world'
})
fn('hello', 'world')

Be aware that any errors that might occur will by-default result in uncaught exceptions!

You can handle those errors by passing an error handler when creating the lock:

const lock = createLockCb(null, err => {
  // Here you can handle any error, for example: emit('error', err)
})
const fn = lock.syncWrap(() => {
  throw new Error('error')
})

... or by adding a error handler directly when wrapping:

const fn2 = lock.syncWrap(() => {
  throw new Error('error')
}, err => {
  // Handle an error thrown in the sync-wrap
})

Destroying locks

When closing down an application you may want to also close all operations and prevent future operations:

import { createLockCb } from 'flexlock-cb'

const lock = createLockCb()
lock.destroy(new Error('lock destroyed') /* optional */)
try {
  lock(cb => {
    // will not be executed
  })
} catch (err) {
  // err ... will be the error passed-in to .destroy()
}

Typescript recommendation

Figuring out the proper typing was quite tricky for flexlock-cb. To make things easier for users, it exports a Callbacks type that can be used to reduce

import { Callbacks, createLockCb } from 'flexlock-cb'

const lock = createLockCb()

//
// Overloading for the two use cases (return type void or Promise)
// If you would like to improve this, vote for
// https://github.com/Microsoft/TypeScript/issues/29182
//
function fn (foo: string, bar: number, ...cb: Callbacks<string>): void
function fn (foo: string, bar: number): Promise<string>
function fn (foo: string, bar: number, ...cb) {
  return lock(() => `${foo} ${bar}`, 0, ...cb)
}

// Separate definitions with the support for timeouts
import { CallbacksWithTimeout } from 'flexlock-cb'

function fnTime (foo: string, bar: number, ...cb: CallbacksWithTimeout<string>): void
function fnTime (foo: string, bar: number, timeout?: number): Promise<string>
function fnTime (foo: string, bar: number, ...cb) {
  return lock(() => `${foo} ${bar}`, ...cb)
}

License

MIT

Current Tags

  • 2.2.1                                ...           latest (a month ago)

10 Versions

  • 2.2.1                                ...           a month ago
  • 2.2.0                                ...           7 months ago
  • 2.1.1                                ...           8 months ago
  • 2.1.0                                ...           8 months ago
  • 2.0.2                                ...           8 months ago
  • 2.0.1                                ...           2 years ago
  • 2.0.0                                ...           2 years ago
  • 1.2.0                                ...           2 years ago
  • 1.1.0                                ...           2 years ago
  • 1.0.0                                ...           2 years ago
Maintainers (1)
Downloads
Today 0
This Week 0
This Month 0
Last Day 0
Last Week 0
Last Month 34
Dependencies (0)
None
Dev Dependencies (3)

Copyright 2014 - 2016 © taobao.org |