Conversation
lib/executor.js
Outdated
| useEnvVars: true, | ||
| }; | ||
| obj = getUpdatedConfigObject(app, obj, opts); | ||
| obj.lazyConnect = true; |
There was a problem hiding this comment.
Now we defer connect to a later phase. When will connect be triggered?
There was a problem hiding this comment.
I tried with local db, I think the connect will be triggered when data query happens, like hitting endpoint from Explorer. And also be triggered when datasource.ping() is called.
Hmm...actually I am confused when it should be triggered?
There was a problem hiding this comment.
@raymondfeng I think my previous answer is for "when connect will be called" but not "when connect will be triggered in initialize".
So, for "when connect will be triggered in initialize", for example if user create a datasource from boot script, it will be triggered, since lazyConnect is undefined.
var myDS = new DataSource(dsName, dsConfig);
// will trigger connect in initialize
There was a problem hiding this comment.
I think boot should trigger connect by default. We can set an option to disable it so that swagger generation doesn't depend on live database connections.
7e5befb to
1793276
Compare
lib/executor.js
Outdated
| useEnvVars: true, | ||
| }; | ||
| obj = getUpdatedConfigObject(app, obj, opts); | ||
| obj.lazyConnect = process.env.LB_LAZYCONNECT_DATASOURCES; |
There was a problem hiding this comment.
When the env var is not set, this ads lazyConnect variable with undefined value. I think this may surprise users when debugging. Also if lazyConnect was set in datasources.json, then you will re-set it back to whatever is provided by the env variable.
I am proposing a safer approach: 1) change the value only when the ENV var is set and also 2) handle "false" and "0" values as false
var lazyConnect = process.env.LB_LAZYCONNECT_DATASOURCES;
if (lazyConnect) {
obj.lazyConnect = lazyConnect === 'false' || lazyConnect === '0' ? false : true;
}There was a problem hiding this comment.
makes sense. I should take care of undefined. Thanks!
|
@jannyHou please add unit-tests to verify the implementation works as intended. I'd like to review & approve this pull request myself. |
test/executor.test.js
Outdated
| }); | ||
|
|
||
| describe('when booting with lazy connect', function() { | ||
| it.only('should report error', function(done) { |
There was a problem hiding this comment.
Forgotten it.only, please fix to it.
|
IMO, depending on loopback-connector-mongodb will make the tests slow and brittle. I am proposing to create a custom connector used by tests only, this connector should be very simple - throw when |
|
You can register a custom connector by calling // this can be configured in a beforeEach hook
app.connector('throwOnConnect', {
initialize: function(dataSource, callback) {
if (dataSource.settings.lazyConnect) callback();
else callback(new Error('CANNOT CONNECT'));
}
});
// and then use the connector in tests:
app.boot(someInstructions({ dataSources: {
'db': { connector: 'throwOnConnect', lazyConnect: false }
}}); |
c6e46fd to
fc0f9a9
Compare
|
@bajtos I create a custom connector for test, and simply throw new error in
The error emitted in |
test/executor.test.js
Outdated
| var DATASOURCE_THROWING_CONNECTION_ERROR = { | ||
| lazyConnector: { | ||
| host: 'invalid-host', | ||
| port: 80, |
There was a problem hiding this comment.
I believe host and port are not needed by tests, please remove.
|
I agree it should be enough to test that var lazyConnect;
beforeEach(function() {
app.connector('reportLazyConnect', {
initialize: function(dataSource, callback) {
lazyConnect = dataSource.settings.lazyConnect;
},
});
});
var REPORT_LAZY_CONNECT_INSTRUCTIONS = someInstructions({ ... });
it('does not set lazyConnect by default', function() {
delete process.env.LB_LAZYCONNECT_DATASOURCES;
boot.execute(app, REPORT_LAZY_CONNECT_INSTRUCTIONS);
expect(lazyConnect).to.equal(undefined);
});
it('sets lazyConnect:true when LB_LAZYCONNECT_DATASOURCES=true', function() {
process.env.LB_LAZYCONNECT_DATASOURCES = 'true';
boot.execute(app, REPORT_LAZY_CONNECT_INSTRUCTIONS);
expect(lazyConnect).to.equal(undefined);
});
// etc, check for cases when lazyConnect is set to "false"
}); |
|
@bajtos I applied the boolean flag to test cases and copied your question from slack:
It will execute DataSource.prototype._setupConnector = function() {
this.connector = this.connector || this.adapter; // The legacy JugglingDB adapter will set up `adapter` property
this.adapter = this.connector; // Keep the adapter as an alias to connector
if (this.connector) {
if (!this.connector.dataSource) {
// Set up the dataSource if the connector doesn't do so
this.connector.dataSource = this;
}
var dataSource = this;
this.connector.log = function(query, start) {
dataSource.log(query, start);
};
this.connector.logger = function(query) {
var t1 = Date.now();
var log = this.log;
return function(q) {
log(q || query, t1);
};
};
// Configure the connector instance to mix in observer functions
jutil.mixin(this.connector, OberserverMixin);
}
}; |
test/executor.test.js
Outdated
| }); | ||
| }); | ||
|
|
||
| describe.only('when booting with lazy connect', function() { |
There was a problem hiding this comment.
Forgotten only, please remove. BTW if you want to run a subset of tests only, you can use mocha's command-line flag -g:
$ mocha -g "lazy connect"That way you don't need to change code.
test/executor.test.js
Outdated
| it('should trigger connect', function(done) { | ||
| boot.execute(app, someInstructions({ | ||
| dataSources: DATASOURCE_THROWING_CONNECTION_ERROR, | ||
| })); |
There was a problem hiding this comment.
To avoid repetition, please extract someInstructions({ dataSources: DATASOURCE_THROWING_CONNECTION_ERROR }); into a shared constant. Then you can remove DATASOURCE_THROWING_CONNECTION_ERROR entirely (inline it in the new constant).
Let's try the following and if you cannot get it working in under 30 minutes then leave the code as it is now and move on. // somewhere on the top of the file, assuming var loopback = require('loopback')
var Connector = loopback.Connector;
// in your initialize function
initialize: function(dataSource, callback) {
dataSource.connector = new Connector(dataSource.options);
if (dataSource.settings.lazyConnect) {
connectTriggered = false;
}
} |
b48a73f to
7404125
Compare
|
@bajtos i add the other two test cases. And i think let's just don't trigger |
test/executor.test.js
Outdated
| }); | ||
|
|
||
| describe('when booting with lazy connect', function() { | ||
| var sampleInstruction = someInstructions({ |
There was a problem hiding this comment.
Please rename to indicate that this should be treated as an immutable constant, e.g. SAMPLE_INSTRUCTIONS.
|
Few more details to improve, the patch LGTM otherwise. No more reviews are needed. |
388002a to
d334425
Compare
Connect to strongloop/loopback#2242
Add flag var lazyConnect to ds config