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

Allow usage in linked modules #5

Merged
merged 3 commits into from
Mar 9, 2017
Merged

Allow usage in linked modules #5

merged 3 commits into from
Mar 9, 2017

Conversation

karlhorky
Copy link
Contributor

@karlhorky karlhorky commented Feb 16, 2017

request-local-storage throws RLS() access outside of request! when used in both a parent module and a linked module.

This PR works around the issue by adding a key to the global namespace and exporting that same key if it already exists (singleton style).

Example error / repo: karlhorky/react-server-bike-share-example#2

src/index.js Outdated
module.exports = { getNamespace, getCountNamespaces, startRequest, bind, patch };
module.exports = global.requestLocalStorage || { getNamespace, getCountNamespaces, startRequest, bind, patch };

if (!global.requestLocalStorage) global.requestLocalStorage = module.exports;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a little risky. If I have two packages that depend on different versions of RequestLocalStorage then one or the other of them is in for a surprise. This package has been pretty stable for a while now, but if we ever find and fix a bug or add a useful feature then this patch could lead to maddening behavior.

Really RequestLocalStorage, like React, needs to be a singleton. Currently it throws an explicit error if multiple copies are used. This patch would make it succeed with undefined behavior.

I appreciate the convenience this provides, though. What about a version check? If the global copy is the same version as the currently initializing copy then return a reference to the global. Otherwise throw a require time error?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really RequestLocalStorage, like React, needs to be a singleton.

So why not check that instead? Something like

const path = require('path');
const matches = Object.keys(require.cache).filter(p => p.includes('request-local-storage');
if (matches.length > 1 || matches[0] !== path.join(__dirname, __filename)) {
  throw new Error('request-local-storage must be a singleton');
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does that address the issue @karlhorky is having?

I had thought he was in a situation where two packages each had their own copy of RLS.

Copy link
Contributor Author

@karlhorky karlhorky Feb 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm not sure that @doug-wade's solution alone would address the original problem.

However, maybe we could use the require.cache along with the idea of versioning? I'll update the PR.

@karlhorky
Copy link
Contributor Author

@gigabo @doug-wade ok, I've added versioning to the singleton (via gulp build step). How does this look?


module.exports = global.requestLocalStorage[REQUEST_LOCAL_STORAGE_VERSION] || { getNamespace, getCountNamespaces, startRequest, bind, patch };

if (!global.requestLocalStorage[REQUEST_LOCAL_STORAGE_VERSION]) global.requestLocalStorage[REQUEST_LOCAL_STORAGE_VERSION] = module.exports;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this looks safer.

The build-time replacement of REQUEST_LOCAL_STORAGE_VERSION is a neat trick, but the cost of just looking it up at run-time isn't really that great. Might be a case where simplicity is worth it. Either way eslint is choking on it, so you'll need to do something to get ci passing. :)

@karlhorky
Copy link
Contributor Author

karlhorky commented Feb 26, 2017

Ah sorry, I need to remember to check the tests before pushing 😛 I've added REQUEST_LOCAL_STORAGE_VERSION as a global in the .eslintrc config file.

Might be a case where simplicity is worth it.

I'm not sure I understood this suggestion, which led me to the quick fix instead of doing more.

If you meant that we should have a version number directly in this src/index.js file, we could do that, but it could be potentially fragile (if someone forgets to update it while releasing a new version). Of course we could always just write a test to make sure that it's the same in the package.json and in the src/index.js, but that seems like it could be a bit roundabout...

@gigabo
Copy link
Contributor

gigabo commented Mar 9, 2017

I'm not sure I understood this suggestion

I just meant we could check require("./package.json").version at run-time. If it were at the module level the require cache would mean we're only checking once, so it wouldn't be a huge cost.

Oh well, though, this seems fine to me. 👍

@karlhorky
Copy link
Contributor Author

we could check require("./package.json").version at run-time

Ah yeah this was my first idea, but I read from user Pathogen that this could be a security concern: http://stackoverflow.com/a/10855054/1268612

@gigabo
Copy link
Contributor

gigabo commented Mar 9, 2017

@karlhorky Thanks for the link. Not so concerned about the security implications of exposing RLS's package.json (it's open source), but the require would increase bundle size, which would be a bummer. Hadn't considered that.

Nice improvement. 👍

@gigabo gigabo merged commit c0d2ad1 into redfin:master Mar 9, 2017
gigabo added a commit to gigabo/react-server that referenced this pull request Mar 9, 2017
@karlhorky
Copy link
Contributor Author

Thanks!

@karlhorky karlhorky deleted the patch-1 branch March 10, 2017 08:38
gigabo added a commit to redfin/react-server that referenced this pull request Mar 17, 2017
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

Successfully merging this pull request may close these issues.

3 participants