-
Notifications
You must be signed in to change notification settings - Fork 15
refactor: Improve the refresh to allow connectors to close, part of #421. #424
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
Conversation
…nd return immediately. This avoids the situation where a refresh process is forced to start but may never finish, causing the node process to hang indefiniately awaiting the refresh promise that does not resolve. This also adds a new method used in the test cases: CloudSqlInstance.refreshComplete() which returns a promise that will resolve when the refresh operation has finished.
8743264 to
51dfbe4
Compare
src/connector.ts
Outdated
| // The Connector class is the main public API to interact | ||
| // with the Cloud SQL Node.js Connector. | ||
| export class Connector { | ||
| private closed = false; |
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.
is closed really needed at the Connector level? Instance makes sense but what is the benefit for Connector level...
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.
This isn't necessary. I removed it.
src/cloud-sql-instance.ts
Outdated
| // refreshComplete Returns a promise that resolves when the current refresh | ||
| // cycle has completed, either with success or failure. If no refresh is | ||
| // in progress, the promise will resolve immediately. | ||
| refreshComplete(): Promise<void> { |
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 don't fully understand this... how is this different then awaiting the promise of forceRefresh?
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.
Good point. I've updated forceRefresh() to include all the logic.
Basically, forceRefresh() only needs to return a promise for testing. forceRefresh is used as fire-and-forget in the main connector code.
In tests, the promise should resolve regardless of whether it succeeds or fails. Otherwise, it could cause tests cases to hang where refresh fails.
51dfbe4 to
75fdb37
Compare
src/connector.ts
Outdated
| // The Connector class is the main public API to interact | ||
| // with the Cloud SQL Node.js Connector. | ||
| export class Connector { | ||
| private closed = false; |
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.
This isn't necessary. I removed it.
| }); | ||
| tlsSocket.once('error', async () => { | ||
| await cloudSqlInstance.forceRefresh(); | ||
| tlsSocket.once('error', () => { |
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.
This should not be async. Otherwise it will block the exit of the connector until the refresh is successful. This causes some failure test cases to hang and never exit.
src/cloud-sql-instance.ts
Outdated
| // refreshComplete Returns a promise that resolves when the current refresh | ||
| // cycle has completed, either with success or failure. If no refresh is | ||
| // in progress, the promise will resolve immediately. | ||
| refreshComplete(): Promise<void> { |
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.
Good point. I've updated forceRefresh() to include all the logic.
Basically, forceRefresh() only needs to return a promise for testing. forceRefresh is used as fire-and-forget in the main connector code.
In tests, the promise should resolve regardless of whether it succeeds or fails. Otherwise, it could cause tests cases to hang where refresh fails.
54ef048 to
d838204
Compare
src/cloud-sql-instance.ts
Outdated
| this.scheduleRefresh(0); | ||
|
|
||
| return new Promise(resolve => { | ||
| // setImmediate() to yield execution to allow other refresh background |
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.
this comment references setImmediate but we are using setTimeout...
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.
Fixed. setTimeout() is the correct function.
src/cloud-sql-instance.ts
Outdated
| // performRefresh() could be delayed by the rate limiter. So | ||
| // this instance may have been closed. |
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.
Can we update this wording a bit. "So this instance may have been closed" is a bit ambiguous...
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.
Fixed.
| // starts a new refresh cycle but do not await on it | ||
| instance.close(); | ||
| await instance.forceRefresh(); | ||
| t.equal(metadataCount, 1, 'No refresh after close'); |
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.
does this mean we do not error on a closed instance?
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.
We don't throw an error from forceRefresh(). The node connector will throw an error when trying to call connect() on a closed instance, but that's coming in a later PR.
d838204 to
330c007
Compare
330c007 to
f4f69c1
Compare
|
Code Coverage / coverage decreased from 97% to 96% due to code paths in src/cloud-sql-instance.ts that are called after the CloudSQLInstance is closed. These code paths are impractical to test. |
jackwotherspoon
left a comment
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.
LGTM ✅
Add CloudSqlInstance.close() to stop the refresh cycle permanently.
Change CloudSqlInstance.forceRefresh() so that it schedules a refresh and returns immediately.
This should not return a promise. Update test cases to account for changes.