Skip to content

Commit

Permalink
Initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
overlookmotel committed Apr 9, 2016
1 parent eddd513 commit 3004e14
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 5 deletions.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,41 @@

## Usage

Runs a callback asynchronously, but *outside* of current CLS context.

### loseCls( callback )

`callback` is called in next tick. As opposed to `setImmediate`, `process.nextTick()` etc, the [continuation-local-storage](https://www.npmjs.com/package/continuation-local-storage) context is not maintained.

### Why?

Primarily, this module exists to facilitate testing of node.js libraries / applications that use [continuation-local-storage](https://www.npmjs.com/package/continuation-local-storage).

This module is a lightweight way to test what happens when CLS context is lost (which many libraries e.g. `redis` do) and to ensure that your own code handles this correctly, perhaps by re-binding with `namespace.bind()`.

### Example

```js
var cls = require('continuation-local-storage');
var namespace = cls.createNamespace('test');

var loseCls = require('lose-cls-context');

namespace.run(function() {
namespace.set('value', 123);

setImmediate(function() {
var value = namespace.get('value');
// CLS context is maintained - value === 123
});

loseCls(function() {
var value = namespace.get('value');
// CLS context has been lost - value === undefined
});
});
```

## Tests

Use `npm test` to run the tests. Use `npm run cover` to check coverage.
Expand Down
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Changelog

## Next

* Initial release
28 changes: 26 additions & 2 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,30 @@
// lose-cls-context module
// --------------------

// exports
module.exports = function() {
// init queue
var queue = [];

// runs fns in queue
function clearQueue() {
// get item at front of queue and call fn
var fn = queue.shift();
if (fn) fn();

// run again on next tick
clearQueueLater();
}

// schedules running fns in queue on next tick
function clearQueueLater() {
setImmediate(clearQueue);
}

// start running queue
clearQueueLater();

// add fn to queue
module.exports = function(fn) {
if (!fn || typeof fn != 'function') throw new Error('fn must be a function');

queue.push(fn.bind(this));
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"url": "https://github.com/overlookmotel/lose-cls-context/issues"
},
"dependencies": {
"continuation-local-storage": "^3.1.6"
},
"devDependencies": {
"mocha": "^2.4.5",
Expand Down
33 changes: 30 additions & 3 deletions test/all.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,43 @@ var chai = require('chai'),
expect = chai.expect,
lose = require('../lib/');

var cls = require('continuation-local-storage');

// init
chai.config.includeStack = true;

// init CLS
var namespace = cls.createNamespace('test');

// tests

/* jshint expr: true */
/* global describe, it */

describe('Tests', function() {
it.skip('all', function() {
expect(lose).to.be.ok;
describe('lose-cls-context', function() {
it('calls fn asynchronously', function(done) {
var order = [];

lose(function() {
order.push('cb');

expect(order).to.deep.equal(['after', 'cb']);

done();
});

order.push('after');
});

it('loses CLS context', function(done) {
namespace.run(function() {
namespace.set('value', 123);

lose(function() {
var value = namespace.get('value');
expect(value).to.not.equal(123);
done();
});
});
});
});

0 comments on commit 3004e14

Please sign in to comment.