Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

zipkin-context-cls

Package Overview
Dependencies
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

zipkin-context-cls - npm Package Compare versions

Comparing version 0.19.0 to 0.19.2-alpha.7

LICENSE

25

lib/CLSContext.js
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _require = require('continuation-local-storage'),
createNamespace = _require.createNamespace,
getNamespace = _require.getNamespace;
var cls = require('continuation-local-storage');
var clsHooked = require('cls-hooked');
module.exports =

@@ -18,7 +18,11 @@ /*#__PURE__*/

var namespace = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'zipkin';
var supportAsyncAwait = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
(0, _classCallCheck2["default"])(this, CLSContext);
_classCallCheck(this, CLSContext);
if (supportAsyncAwait) {
this._session = clsHooked.getNamespace(namespace) || clsHooked.createNamespace(namespace);
} else {
this._session = cls.getNamespace(namespace) || cls.createNamespace(namespace);
}
this._session = getNamespace(namespace) || createNamespace(namespace);
var defaultContext = this._session.createContext();

@@ -29,3 +33,3 @@

_createClass(CLSContext, [{
(0, _createClass2["default"])(CLSContext, [{
key: "setContext",

@@ -69,4 +73,3 @@ value: function setContext(ctx) {

}]);
return CLSContext;
}();
{
"name": "zipkin-context-cls",
"version": "0.19.0",
"version": "0.19.2-alpha.7+86c4493",
"description": "A Context API implementation that uses continuation-local-storage under the hood",

@@ -16,5 +16,10 @@ "main": "lib/CLSContext.js",

"dependencies": {
"@babel/runtime": "^7.8.4",
"cls-hooked": "^4.2.2",
"continuation-local-storage": "^3.1.7"
},
"gitHead": "579e12b642b7e0b486dd2b78193ec0a798e82a7a"
"devDependencies": {
"@babel/plugin-transform-runtime": "^7.8.3"
},
"gitHead": "86c4493611a11ff4079419b6d2d019a8a9a7ec2c"
}

@@ -15,3 +15,3 @@ # zipkin-context-cls

ctxImpl: new CLSContext('zipkin'),
recorder, // typically Kafka or Scribe
recorder, // typically HTTP or Kafka
localServiceName: 'service-a' // name of this application

@@ -28,4 +28,17 @@ });

This package is not suitable if your code inside the context uses promises. The context is then not properly propagated. There is work underway called [async_hooks](https://nodejs.org/api/async_hooks.html), but is at the time of this writing (node v10) in Experimental state.
By default, this package is not suitable if your code inside the context uses promises, however you can enable an experimental feature for async/await support by using [cls_hooked](https://github.com/jeff-lewis/cls-hooked) library which underneath uses [async_hooks](https://nodejs.org/api/async_hooks.html).
```javascript
const CLSContext = require('zipkin-context-cls');
const tracer = new Tracer({
ctxImpl: new CLSContext('zipkin', true),
recorder,
localServiceName: 'service-a'
});
```
At the time of this writing, `async_hooks` [have some performance implications](https://github.com/DataDog/dd-trace-js/issues/695) whose effect may vary depending on the node version.
The underneath implementation for async_hooks may change, that is why we hide that with the opt-in parameter.
## A note on the workings of CLS context

@@ -32,0 +45,0 @@

@@ -1,6 +0,11 @@

const {createNamespace, getNamespace} = require('continuation-local-storage');
const cls = require('continuation-local-storage');
const clsHooked = require('cls-hooked');
module.exports = class CLSContext {
constructor(namespace = 'zipkin') {
this._session = getNamespace(namespace) || createNamespace(namespace);
constructor(namespace = 'zipkin', supportAsyncAwait = false) {
if (supportAsyncAwait) {
this._session = clsHooked.getNamespace(namespace) || clsHooked.createNamespace(namespace);
} else {
this._session = cls.getNamespace(namespace) || cls.createNamespace(namespace);
}
const defaultContext = this._session.createContext();

@@ -7,0 +12,0 @@ this._session.enter(defaultContext);

const CLSContext = require('../');
describe('CLSContext', () => {
const namespace = 'mynamespace';
function CLSContextPerAsync(supportAsync) {
it('should start with context null', () => {
const ctx = new CLSContext();
const ctx = new CLSContext(namespace, supportAsync);
expect(ctx.getContext()).to.equal(null);

@@ -10,13 +12,14 @@ });

it('should set an inner context', () => {
const ctx = new CLSContext();
ctx.letContext('foo', () => {
expect(ctx.getContext()).to.equal('foo');
const ctx = new CLSContext(namespace, supportAsync);
ctx.letContext('tres-leches', () => {
expect(ctx.getContext()).to.equal('tres-leches');
});
ctx.setContext(null);
});
it('should set an inner context with setContext', () => {
const ctx = new CLSContext();
const ctx = new CLSContext(namespace, supportAsync);
ctx.scoped(() => {
ctx.setContext('bla');
expect(ctx.getContext()).to.equal('bla');
ctx.setContext('tiramisú');
expect(ctx.getContext()).to.equal('tiramisú');
});

@@ -27,4 +30,4 @@ expect(ctx.getContext()).to.equal(null);

it('should return the inner value', () => {
const ctx = new CLSContext();
const returnValue = ctx.letContext('foo', () => 123);
const ctx = new CLSContext(namespace, supportAsync);
const returnValue = ctx.letContext('cheesecake', () => 123);
expect(returnValue).to.equal(123);

@@ -34,4 +37,4 @@ });

it('should be reset after the callback', () => {
const ctx = new CLSContext();
ctx.letContext('foo', () => {
const ctx = new CLSContext(namespace, supportAsync);
ctx.letContext('combinado', () => {
// do nothing

@@ -43,8 +46,8 @@ });

it('should reset after error in callback', () => {
const ctx = new CLSContext();
const ctx = new CLSContext(namespace, supportAsync);
let error;
try {
ctx.letContext('buy-smoothie', () => {
throw new Error('no smoothies. try our cake');
ctx.letContext('buy-red-velvet', () => {
throw new Error('no red velvet. try our cake');
});

@@ -56,3 +59,3 @@ } catch (err) {

// sanity check
expect(error.message).to.eql('no smoothies. try our cake');
expect(error.message).to.eql('no red velvet. try our cake');

@@ -63,11 +66,11 @@ // context wasn't leaked

it('support nested contexts', () => {
const ctx = new CLSContext();
const finalReturnValue = ctx.letContext('foo', () => {
expect(ctx.getContext()).to.equal('foo');
const innerReturnValue = ctx.letContext('bar', () => {
expect(ctx.getContext()).to.equal('bar');
it('supports nested contexts', () => {
const ctx = new CLSContext(namespace, supportAsync);
const finalReturnValue = ctx.letContext('lemon-pie', () => {
expect(ctx.getContext()).to.equal('lemon-pie');
const innerReturnValue = ctx.letContext('pannacotta', () => {
expect(ctx.getContext()).to.equal('pannacotta');
return 1;
});
expect(ctx.getContext()).to.equal('foo');
expect(ctx.getContext()).to.equal('lemon-pie');
return innerReturnValue + 2;

@@ -80,11 +83,51 @@ });

it('supports CLS contexts (setTimeout etc)', (done) => {
const ctx = new CLSContext();
const ctx = new CLSContext(namespace, supportAsync);
function callback() {
expect(ctx.getContext()).to.equal('foo');
expect(ctx.getContext()).to.equal('brownie');
ctx.setContext(null);
done();
}
ctx.letContext('foo', () => {
ctx.letContext('brownie', () => {
setTimeout(callback, 10);
});
});
}
describe('CLSContext', () => {
describe('without async-await support', () => {
CLSContextPerAsync(false);
});
describe('with async-await support', () => {
CLSContextPerAsync(true);
it('supports async-await contexts', async() => {
const ctx = new CLSContext(namespace, true);
ctx.setContext('arroz-con-leche');
async function stall(stallTime) {
await new Promise(resolve => setTimeout(resolve, stallTime));
}
async function getCtx() {
const durationInMs = Math.random() + 0.1;
await stall(durationInMs * 500);
return ctx.getContext();
}
async function callback() {
const obtainedContext = await getCtx();
return obtainedContext;
}
async function fn() {
const ctx1 = await ctx.letContext('budin', () => callback());
const ctx2 = await ctx.letContext('torta-helada', () => callback());
expect(ctx1).to.equal('budin');
expect(ctx2).to.equal('torta-helada');
}
await fn(); // eslint-disable-line
});
});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc