Skip to content

Expected behaviour with .then() attached to resolved promise #63

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

Closed
overlookmotel opened this issue Apr 20, 2016 · 1 comment
Closed

Comments

@overlookmotel
Copy link
Contributor

@othiym23 can I ask your opinion on something? (this isn't an issue about CLS per se)

I've been having some problems using CLS, bluebird and co together, with CLS context sometimes getting lost. By way of trying to narrow down the problem, I've written a set of tests which run against various different bluebird CLS shims to see how they all behave in different circumstances.

Please see: https://www.github.com/overlookmotel/cls-bluebird-test

There's one weird case...

(NB cls-bluebird2 is the beginnings of an attempt at a new cls-bluebird shim)

var Promise = require('bluebird');
var cls = require('continuation-local-storage');
var clsBluebird = require('cls-bluebird2');
var assert = require('assert');

var ns = cls.createNamespace('test');
clsBluebird(ns, Promise);

// CASE 1
var promise;
ns.run(function() {
    ns.set('test', 123);
    promise = Promise.resolve().then(function() {
        assert(ns.get('test') == 123);
    });
});

promise.then(function() {
    assert(ns.get('test') == 123);
});

Both assert statements pass in this case. I think that's the correct behaviour - the .then() outside of ns.run() should inherit CLS context from the previous promise in the chain.

But how about this:

// CASE 2
var promise;
ns.run(function() {
    ns.set('test', 123);
    promise = Promise.resolve();
});

promise.then(function() {
    assert(ns.get('test') == 123);
});

In this 2nd case, the assert statement fails.

Should it? My first thought was that it should execute in the context of the promise chain, in the same way as case 1. On the other hand, it's chaining onto a promise which is already resolved. So in what sense is it "following on from" that promise in the way that a node callback "follows on" immediately from the function that calls it?

What's your opinion?

More generally speaking, there are quite a lot of subtleties in reasoning the desired behaviour of CLS context passing with promises. async-listener's shim of native promises takes the view that it's all about following the chain of execution down the promise chain (and so both the above cases pass), whereas cls-bluebird executes code in a .then() in the context in which .then() was called (so both above cases fail).

Has anyone written down any kind of spec, or made a set of tests to define desired behaviour?

@overlookmotel
Copy link
Contributor Author

A more complete discussion here: #64

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

1 participant