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

Add AsyncLocalStorage driver #39

Merged
merged 16 commits into from
Oct 19, 2023

Conversation

Aareksio
Copy link

@Aareksio Aareksio commented Jun 3, 2023

So I decided to spent the day implementing AsyncLocalStorage driver... Resolves #22

The PR is best read commit after commit, as I tried to make incremental changes:

  • implemented StorageDriver abstraction layer to use the adapter / strategy pattern
  • implemented cls-hooked driver, all tests green
  • implemented AsyncLocalStorage driver, all tests green
  • added storageDriver option, defaults to cls-hooked
  • added TEST_STORAGE_DRIVER env variable to use different driver in tests

Need to figure out a way to test both drivers on the same suite. It seems infeasible to copy-and-paste cases, or worse prepare some specific cases for drivers. Best to run everything twice to ensure 100% combability. The lib sadly stores some information in memory (eg. dataSources map) and there is currently no way to clean it up between runs, so .each fails. Therefore I temporarily added TEST_STORAGE_DRIVER environment variable that can be defined before tests run:

TEST_STORAGE_DRIVER=ASYNC_LOCAL_STORAGE npm run test

As I use newer version of npm, the package-lock.json got updated. There is one new dependency, semver. It could probably be removed if we decided on custom implementation, but I worried about the compatibility with older runtimes which may use unexpected version format.

Considerations:

  • Once the PR is reviewed I suggest the default storageDriver option to be set to AUTO. For now it is set to CLS_HOOKED avoiding breaking change. By default package works as before, the new driver is opt-in.
  • bindEmitter was removed; no tests indicated it's usefulness. Reading the implementation I haven't found any sensible scenario in which it would be required as part of this package. It is possible to recreate (not very hard) if needed, please provide test case.
  • To make it easily testable some changes to internal data structures would be necessarily. Either the data should be bound to some user-controlled instance, or perhaps a reset() method could be provided - even if only for tests. Did not want to make too big of a change.

Aareksio added 12 commits June 3, 2023 14:06
After doing research on what `bindEmitter` does, I could not see the
benefits of using it. At the time the hooks run, the transaction is already
over. There seem to be no reason to preserve store context for userland
use.

All current tests pass. There is no mention of preserved context in the
README, therefore this should be treated as internal change.

This change is motivated by the fact AsyncLocalStorage does not support
`bindEmitter` out of the box and without understanding the end goal it
is not feasible to properly reimplement it.

If at any point in the future a viable use-case is provided, the bindEmitter
can easily be restored.
This change introduces a concept of StorageLayer, an interface which
can be implemented using various storage providers. Currently the
implementations include AsyncLocalStorage and cls-hooked.
This commit abstracts the use of cls-hooked to StorageLayer.

It also updates the StorageLayer provider to always use cls-hooked
implementation, as AsyncLocalStorage implementation
does not pass tests yet.
The change implements AsyncLocalStorage driver, which passes
all existing tests. As the actual logic relies on cls-hooked behavior
a Store class is introduces to emulate it within AsyncLocalStorage.
Separating name refactor out of previous commit for readability
@Aliheym
Copy link
Owner

Aliheym commented Jun 23, 2023

Hi, it looks cool. Let me check it on these weekends.

@ghost
Copy link

ghost commented Jun 24, 2023

Happy to test and start using it, once merged!

@vsamofal
Copy link

vsamofal commented Oct 1, 2023

@Aliheym @Aareksio love this feature,

is this lib abandoned, and it's better to host it on our own to get this feature?

@Aliheym
Copy link
Owner

Aliheym commented Oct 1, 2023

Hi guys, sorry for such delay. It's been a busy period at work. I'll get it done today or tomorrow morning.

Copy link
Owner

@Aliheym Aliheym left a comment

Choose a reason for hiding this comment

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

That's just great work. Thank you very much.

I have also checked this functionality on the improved tests I worked recentrly

@Aliheym
Copy link
Owner

Aliheym commented Oct 2, 2023

All tests have successfully passed. However, as rightly mentioned above, the current code does not allow for convenient testing of this feature without running it with different TEST_STORAGE_DRIVER env.

We need to modify the internal data structure, but this would be beyond the scope of the current PR. I believe we can roll out this feature and then I can focus on the necessary internal modifications.

Additionally, I also think we need to use AUTO as the default value

@Aareksio
Copy link
Author

Aareksio commented Oct 2, 2023

For tests, alternatively, you could run CI with different environments using matrix feature.

As for AUTO, I am not sure what is the best rollout strategy here - to release minor keeping cls hooked the default and change to AUTO with next major. Or release major right away.

@vsamofal
Copy link

vsamofal commented Oct 2, 2023

Let me know if I can help with it

@Aliheym
Copy link
Owner

Aliheym commented Oct 2, 2023

For tests, alternatively, you could run CI with different environments using matrix feature.

I will check, thanks.

As for AUTO, I am not sure what is the best rollout strategy here - to release minor keeping cls hooked the default and change to AUTO with next major. Or release major right away.

Hard question 🙃. Actually, I'm not thinking about a major version yet. In my opinion it would be better to release the minor version first with cls hooked the default as it is now. Next major, as you said, we can change to AUTO.

@Aliheym Aliheym merged commit 14daba3 into Aliheym:master Oct 19, 2023
@Aliheym
Copy link
Owner

Aliheym commented Oct 19, 2023

Thank you for your patience guys. I've merged this PR.

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.

Support for AsyncLocalStorage?
3 participants