Skip to content

Commit 4387cad

Browse files
committed
refactor: CloudSqlInstance.forceRefresh() should schedule a refresh and 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.
1 parent 0d0adaf commit 4387cad

File tree

3 files changed

+31
-13
lines changed

3 files changed

+31
-13
lines changed

src/cloud-sql-instance.ts

+23-3
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,34 @@ export class CloudSQLInstance {
106106
}) as ReturnType<typeof pThrottle>;
107107
}
108108

109-
forceRefresh(): Promise<RefreshResult> {
109+
forceRefresh(){
110110
// if a refresh is already ongoing, just await for its promise to fulfill
111111
// so that a new instance info is available before reconnecting
112112
if (this.next) {
113-
return this.next;
113+
return;
114114
}
115115
this.cancelRefresh();
116-
return this.refresh();
116+
this.scheduleRefresh(0);
117+
}
118+
119+
// refreshComplete Returns a promise that resolves when the current refresh
120+
// cycle has completed, either with success or failure. If no refresh is
121+
// in progress, the promise will resolve immediately.
122+
refreshComplete(): Promise<void> {
123+
return new Promise((resolve) => {
124+
// setTimeout() to yield execution to allow other refresh background
125+
// tasks to start.
126+
setTimeout(()=> {
127+
if(this.next){
128+
// If there is a refresh promise in progress, resolve this promise
129+
// when the refresh is complete.
130+
this.next.finally(resolve)
131+
} else {
132+
// Else resolve immediately.
133+
resolve()
134+
}
135+
}, 0);
136+
});
117137
}
118138

119139
refresh(): Promise<RefreshResult> {

src/connector.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,8 @@ export class Connector {
230230
serverCaMode,
231231
dnsName,
232232
});
233-
tlsSocket.once('error', async () => {
234-
await cloudSqlInstance.forceRefresh();
233+
tlsSocket.once('error', () => {
234+
cloudSqlInstance.forceRefresh();
235235
});
236236
tlsSocket.once('secureConnect', async () => {
237237
cloudSqlInstance.setEstablishedConnection();

test/cloud-sql-instance.ts

+6-8
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,10 @@ t.test('CloudSQLInstance', async t => {
269269
await CloudSQLInstance.prototype.refresh.call(instance);
270270
instance.refresh = CloudSQLInstance.prototype.refresh;
271271
};
272-
await instance.forceRefresh();
272+
273+
instance.forceRefresh();
274+
await instance.refreshComplete();
275+
273276
t.ok(
274277
cancelRefreshCalled,
275278
'should cancelRefresh current refresh cycle on force refresh'
@@ -302,13 +305,8 @@ t.test('CloudSQLInstance', async t => {
302305
return CloudSQLInstance.prototype.refresh.call(instance);
303306
};
304307

305-
const forceRefreshPromise = instance.forceRefresh();
306-
t.strictSame(
307-
refreshPromise,
308-
forceRefreshPromise,
309-
'forceRefresh should return same promise ref from initial refresh call'
310-
);
311-
await forceRefreshPromise;
308+
instance.forceRefresh();
309+
await instance.refreshComplete()
312310

313311
t.ok(
314312
!cancelRefreshCalled,

0 commit comments

Comments
 (0)