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

feat: add an example for multi-tenancy #5087

Merged
merged 3 commits into from
Apr 17, 2020
Merged

Conversation

raymondfeng
Copy link
Contributor

@raymondfeng raymondfeng commented Apr 10, 2020

See #5056

Checklist

👉 Read and sign the CLA (Contributor License Agreement) 👈

  • npm test passes on your machine
  • New tests added or existing tests modified to cover all changes
  • Code conforms with the style guide
  • API Documentation in code was updated
  • Documentation in /docs/site was updated
  • Affected artifact templates in packages/cli were updated
  • Affected example projects in examples/* were updated

👉 Check out how to submit a PR 👈

@raymondfeng raymondfeng force-pushed the example-multi-tenancy branch from 0c99edb to 5317f45 Compare April 10, 2020 21:50
@raymondfeng raymondfeng force-pushed the example-multi-tenancy branch from 5317f45 to 750f84c Compare April 11, 2020 04:25
Copy link
Contributor

@emonddr emonddr left a comment

Choose a reason for hiding this comment

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

Great stuff, @raymondfeng .

@hacksparrow
Copy link
Contributor

hacksparrow commented Apr 15, 2020

We simply rebind datasources.db to a tenant specific datasource to select the
right datasource for UserRepository.

@raymondfeng So, if I understand correctly, multitenancy is achieved by switching the datasource to the one configured for the tenant.

At what point is the switch done? As soon as a request arrives? What if there is a long running query for a tenant and a new request arrives for another one? What if there was some code to be executed after query was a successful; is it guaranteed that this code will not be executed for another tenant?

@raymondfeng
Copy link
Contributor Author

@raymondfeng So, if I understand correctly, multitenancy is achieved by switching the datasource to the one configured for the tenant.

At what point is the switch done? As soon as a request arrives? What if there is a long running query for a tenant and a new request arrives for another one? What if there was some code to be executed after query was a successful; is it guaranteed that this code will not be executed for another tenant?

Please note that we create a new RequestContext per request. The switch happens at per request level. The req/res processing is fully isolated from each other with our dependency injections for stateful artifacts.

@hacksparrow
Copy link
Contributor

Yes, there's a new RequestContext per request, however, datasources.db is shared by all, isn't it?

@bajtos thoughts?

@raymondfeng
Copy link
Contributor Author

raymondfeng commented Apr 16, 2020

Yes, there's a new RequestContext per request, however, datasources.db is shared by all, isn't it?

datasources.db by default a singleton with connection pool to the backend DB. It's bound at application level by app.boot. We are rebinding it to a new alias at RequestContext level so that there is a tenant specific DS for the given request.

request 1 with tenant `abc`:
abc: Request context (datasources.db -> datasources.db.abc: DB for abc)
         Application (datasources.db -> default DB)

request 2 with tenant `xyz`:
xyz: Request context (datasources.db -> datasources.db.xyz: DB for xyz)
         Application (datasources.db -> default DB)

The assumption is that downstream controllers/repositories/services have TRANSIENT scope and they are resolved and instantiated per request. A binding at child level shadows the one with same key at parent/ancestor levels.

@raymondfeng raymondfeng merged commit 0f93dc1 into master Apr 17, 2020
@raymondfeng raymondfeng deleted the example-multi-tenancy branch April 17, 2020 20:42
@Dainiu5
Copy link

Dainiu5 commented Jan 12, 2021

Hi, great stuff! 👍
From my understanding, in this current implementation one can switch between pre-defined data sources based on the tenant id. However, what could be done to switch between database schemas using a specific postgres datasource?
Any hint or suggestions how it could be done would be highly appreciated.
Thanks!

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

Successfully merging this pull request may close these issues.

4 participants