Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

namespace set values are getting lost in http socket close callback #145

Open
queston02 opened this issue Sep 4, 2020 · 2 comments
Open

Comments

@queston02
Copy link

We are creating the namespace and setting a variable called gtid in one of the middle ware and then trying to read that value for logging. We are getting the values in most of the places but some places it's undefined. One of the place is in the callback of the socket close event. Below is the code to provide some context.

var express = require('express');
var app = express();
var http = require('http');
var continuationLocalStorage = require('continuation-local-storage');
var namespace = continuationLocalStorage.createNamespace('namespace');

app.use(function (req, res, next) {
    namespace.run(function () {
        namespace.set('gtid', 'some unique value');
        return next();
    });
});

var req = protocol.request(request, function (response) {
    response.setEncoding('utf-8');
    var responseBody = '';

    response.on('data', function (data) {
        responseBody += data;
    });

    response.on('error', function (e) {
        e.code = response.statusCode;
        return callback(e);
    });

    response.on('end', function () {
        return callback(null, responseBody);
    });
});

req.on('socket', function (socket) {
    if (!socket.name) {
        socket.name = new Date().getTime();

        socket.on('close', function () {
            var namespace = getNamespace('namespace');
            console.log(namespace.get('gtid'))
        });
    }
});

req.on('error', function (e) {
    return callback(e);
});

if (request.body) {
    req.write(request.body);
}
req.end();
@queston02
Copy link
Author

There is one more place where variable set in namespace is coming as undefined. It's in the callbacks defined in the express.router. Please see below for some context.

const express = require('express');
const router = express.Router();

router.post('/dummy', sessionValidator, setJson.bind(dummyProduct, 'getDummyProducts'));

function sessionValidator(req, res, next) {
    var namespace = getNamespace('namespace');
    console.log(namespace.get('gtid'))
}

@avico81
Copy link

avico81 commented Nov 10, 2020

I encountered the same issue. The problem is that next callback finishes before the other stuff get called, so I looked at the Namespace.prototype.run source and took what I needed from it.
Beware though, I'm reusing the same namespace without destroying it which means that there's a small chance for a race condition, in which a request overwrites the 'req' value before the previous request is done with it (for me it wasn't a concern):

const CLS = require('continuation-local-storage');

function cls(req, res, next) {
  let namespace = CLS.getNamespace('api') || CLS.createNamespace('api');
  let context = namespace.createContext();
  namespace.enter(context);
  try{
    namespace.set('req', req);
    namespace.set('res', res);
    return next();
  } catch (e) {
    console.log('CLS ERR: ' + e);
  }
}

...
app.use('/api/*', cls);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants