-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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(boot): implement Service booter #1652
Conversation
}; | ||
|
||
function isServiceProvider(cls: Constructor<{}>): cls is ServiceProviderClass { | ||
return /Provider$/.test(cls.name); |
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.
I think we should check the existence of value()
.
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.
Sounds good, I add that check to the existing name check.
(IMO, checking just for value
is not enough, as there may be other classes/interfaces that contain value
method too.)
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.
There should be documentation stating that the Booter is expecting Provider
to be a part of the class name.
greet(whom: string = 'world') { | ||
return Promise.resolve(`Hello ${whom}`); | ||
} | ||
} |
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.
Are we going to bind plain service class during boot? I don't see the logic.
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.
Not yet. The logic here is to ensure that the booter is picking only Providers and excludes regular classes, there is an integration test for that.
Suggestions are welcome on how to make this more obvious to people reading this code.
Maybe it's a sign that I should enhance ServiceMixin
and the booter to handle both app.serviceProvider(GeocoderServiceProvider)
and app.service(GreeterService)
cases, even though app.service
may not be used by any real LB4 app? IDK.
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.
For now, let's just add a comment to GreeterService
saying it will be excluded from discovery as we only allow providers so far.
this.discovered = await discoverFiles(this.glob, this.projectRoot); | ||
|
||
if (debug.enabled) { |
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.
Why have a check here? Doesn't debug only log if the debugger is enabled?
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.
Because JSON.stringify is expensive. The parameters will be calculated before invoking debug itself.
import {promisify} from 'util'; | ||
const glob = promisify(require('glob')); | ||
|
||
const debug = debugFactory('loopback:boot:base-artifact-booter'); |
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.
Should this be loopback:boot:booter-utils
?
}; | ||
|
||
function isServiceProvider(cls: Constructor<{}>): cls is ServiceProviderClass { | ||
return /Provider$/.test(cls.name); |
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.
There should be documentation stating that the Booter is expecting Provider
to be a part of the class name.
Allow TestSandbox consumers to access the path of the sandbox directory. Clean up the code by moving "validateInst" check into "path" getter, thus avoiding the need to explicitly call "validateInst" in every public API method.
9098ad3
to
10eb11b
Compare
Make it easier to troubleshoot the situation when a booter is not recognizing artifact files and/or classes exported by those files. To make debug logs easy to read, absolute paths are converted to project-relative paths in debug logs. This change required a refactoring of Booter design, where "projectRoot" becomes a required constructor argument. While making these changes, I changed "options" to be a required constructor argument too, and chaged both "options" and "projectRoot" to readonly properties.
- address review comments - use ServiceBooter in example apps - update tutorial pages - update docs
10eb11b
to
cc0e108
Compare
I have addressed your review comments and finished updates of example apps and docs - see 36a8eac. The pull request is ready for the final review and landing. @raymondfeng @virkt25 PTAL again. |
|
||
**IMPORTANT:** For a class to be recognized by `ServiceBooter` as a service | ||
provider, its name must end with `Provider` suffix and its prototype must have a | ||
`value()` method. |
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.
To me, this is a sign that we should have something like #992 to make it possible to explicit.
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.
Makes sense 👍
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.
+1 for #992, it's certainly needed.
@@ -12,12 +12,14 @@ Let's start by creating the initial application by running the following | |||
command: | |||
|
|||
```sh | |||
lb4 app soap-calculator --enableRepository | |||
lb4 app soap-calculator --enableRepository --enableServices |
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.
Hmm, now we have enableRepository
vs enableServices
. The naming is inconsistent.
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.
Yeah. Should we rename --enableRepository
to --enableRepositories
? I can do that in a follow-up pull request.
Implement automatic discovery and registration of Service providers - see #1439 for the full context and #1649 for the first step on that journey.
This pull request has three parts/commits, the first two are preparations making the actual implementation easier to make and troubleshoot.
feat(testlab): expose "sandbox.path" property (4e86b08)
Allow TestSandbox consumers to access the path of the sandbox directory.
Clean up the code by moving "validateInst" check into "path" getter,
thus avoiding the need to explicitly call "validateInst" in every
public API method.
feat(boot): add debug logs for better troubleshooting (f88e776)
Make it easier to troubleshoot the situation when a booter is not
recognizing artifact files and/or classes exported by those files.
To make debug logs easy to read, absolute paths are converted to
project-relative paths in debug logs. This change required a refactoring
of Booter design, where "projectRoot" becomes a required constructor
argument.
While making these changes, I changed "options" to be a required
constructor argument too, and chaged both "options" and "projectRoot"
feat(boot): implement Service booter
The main change.
Checklist
npm test
passes on your machinepackages/cli
were updatedexamples/*
were updated