-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
add continuation-local-storage (CLS) support #4162
Conversation
I agree, it was an inelegant solution to begin with, but passed our checks because there was basically no other easy option. This works, and if it's on track to be included in Node.js core, then I have no objections at all. |
How does this work in places where we don't have the req object, ie socket calls. We retrieve the uid and ip from the socket object in those places. |
@barisusakli i could add handler for socket connection and expose the socket the same way, .. on connection style - never tested, but will do.
|
Awesome, yeah please give this a shot. It would make our code more elegant, without having to explicitly pass in |
added websockets support - so now.. anywhere in the App or any plugin, var cls = require('/path/to/nodebb/src/middleware/cls'),
// ....
onWhatever: function () {
console.log( cls.get('http') ); // prints { req: req, res: res }
console.log( cls.get('ws') ); // prints { socket: socket, payload: payload /* if available */, event: event }
} |
Whoever merges will also need to add deprecation notices to all plugin hooks currently passing in |
i can add those first - and maybe some more documentation, where are the docs maintained ? |
This is really awesome 👍 |
You can edit the docs right on GH, there's a link on every page that takes you to the edit page. There's a hook set up that regenerates the docs after every change |
|
||
winston.warn('[plugins] hook `' + hook + '` \'s `params.req`, `params.res`, `params.uid` and `params.socket` are being deprecated, ' | ||
+ 'plugins should use the `middleware/cls` module instead to get a reference to the http-req/res and socket (which you can get the current `uid`) ' | ||
+ '- for more info, visit https://docs.nodebb.org/en/latest/plugins/create.html#getting-a-reference-to-req-res-socket-and-uid-within-any-plugin-hook'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that link here doesn't work yet, it's the expected link to be after you push nodebb-english live.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, please feel free to reword that long sentence or whatever.. i am not good at that stuff.
let me know what you think about this solution for the deprecation warnings - i am not too attached to it - there are too many files that needs to be touched otherwise - or we can do it on hook registrations but we'd have to make a manual list of them instead - which i could do i guess. |
I did a search for all instances of I think we should leave the I i guess, only Another note, for example, |
Okay, so what would this mean for plugins that currently subscribe to a hook that sent in these values that will be removed? |
This means plugins should not expect to get a reference of the As far as the nodebb deprecation goes, we could this in 2 ways, although I wouldn't make this breaking change for 1.0, maybe some 1.x or even 2.0 1if you merge, we could go around the something like: var cls = require('../middleware/cls');
// ....
Plugins.fireHook = function(hook, params, callback) {
// ......
if ( isHookParamsDeprecated(hook) ) {
params.req = cls.get('http').req;
params.res = cls.get('http').res;
params.socket = cls.get('ws').socket;
}
switch (hookType) {
....
}
}; 2if you merge, then you do nothing extra, until you decide to make the breaking change one day, then on that day, we do step 1, and remove all the |
Okay, good to merge in that case, as long as it is not a breaking change upon merge. More than willing to use deprecation notices for all This can be merged post v1.0.0 however. |
Ok I think this is ready for a re-review. The socket.io/index.js file might look like it was changed a lot, but it hasn't, i had to merge the latest here and I had to fix the circular dependency with CLS, so the tabbing/spaces will throw you off a bit. Sorry about that. var cls = module.parent.require('./middleware/cls'); // require cls once in your plugin.
var MyPlugin = {
myMethod: function(postData, callback) {
var request = cls.get('request'); // current http request object.
var uid = request.uid; // current user id
// ...
},
// let's say this one occurs on a websocket event,
myOtherMethod: function(somethingData) {
var request = cls.get('request'); // current returned from Sockets.reqFromSocket() object
var uid = request.uid; // current user id, if available
var payload = request.body; // socket payload data, if available
var event = request.method; // socket last event, if available, not sure if using method is cool here
var params = request.params; // socket last params, if available
// ...
}
};
module.exports = MyPlugin; |
Hmm, so what happens if a lot of socket events are coming in in a short period of time? Due to things being async I think there is a possibly that From what I understand cls only stores one instance of the data. |
It won't matter, if you
true, but per each request-call-stack, *the reason I call it the request-call-stack, because the usual JS call-stack we're used to, does not include timeouts and async calls, but CLS handles all that. so if // on some http or socket request.
doSomething() {
var r1 = cls.get('request');
setTimeout(function() {
// this timeout callback will not be on same JS call stack as doSomething, but it would be on the same request-call-stack
var r2 = cls.get('request');
console.log(r1 === r2); // true
}, 100)
} |
@psychobunny signed off earlier Once @barisusakli approves, this is good to merge. |
did i break the world? |
You're good :) Julian Lam Co-Founder, NodeBB Inc.
|
Ok hear me out.. you no longer need to plumb the
req
object through arguments, to anywhere, either for post create, or to a specificfilter/action
hook(s) so just you can have access toreq.ip
for example... all you have to do now, in ANY module, or ANY plugin is the following..read more about this here, most likely will become in node core eventually, or at least a very similar solution, as this extra dependency is a shim at the moment.
nodejs/node-v0.x-archive#5243
nodejs/node-v0.x-archive#6011
SHIM: https://github.com/othiym23/node-continuation-local-storage
I do not have any strong opinion on namespace name, storage key name.. or location of this extra
cls.js
.. please let me know what you think/feel about this.I just hate the fact that, "sometimes" we plumb through the req object, and sometimes we don't, and when we do, it's not really part of its sibling properties in the same data hash, it's just there because we needed access to the IP address or whatever..