Skip to content

Commit d1648ca

Browse files
update the timeout mechanism
1 parent fff727e commit d1648ca

File tree

1 file changed

+12
-29
lines changed

1 file changed

+12
-29
lines changed

src/ConfigurationClientManager.ts

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ const SECRET_KEY_NAME = "Secret";
1818
const TRUSTED_DOMAIN_LABELS = [".azconfig.", ".appconfig."];
1919
const FALLBACK_CLIENT_REFRESH_EXPIRE_INTERVAL = 60 * 60 * 1000; // 1 hour in milliseconds
2020
const MINIMAL_CLIENT_REFRESH_INTERVAL = 30 * 1000; // 30 seconds in milliseconds
21-
const SRV_QUERY_TIMEOUT = 30 * 1000; // 30 seconds in milliseconds
21+
const DNS_RESOLVER_TIMEOUT = 1_000; // 1 second in milliseconds
22+
const DNS_RESOLVER_TRIES = 2;
23+
const MAX_RESOLVESRV_TIMES = 15;
2224

2325
export class ConfigurationClientManager {
2426
#isFailoverable: boolean;
@@ -35,7 +37,6 @@ export class ConfigurationClientManager {
3537
#replicaCount: number = 0;
3638
#lastFallbackClientRefreshTime: number = 0;
3739
#lastFallbackClientRefreshAttempt: number = 0;
38-
#srvQueryPending: boolean = false;
3940

4041
constructor (
4142
connectionStringOrEndpoint?: string | URL,
@@ -144,34 +145,16 @@ export class ConfigurationClientManager {
144145
}
145146

146147
async #discoverFallbackClients(host: string) {
147-
if (this.#srvQueryPending) {
148-
return;
149-
}
150-
this.#srvQueryPending = true;
151-
let result, timeoutId;
148+
let result: string[];
152149
try {
153-
// Promise.race will not terminate the pending promises.
154-
// This is a known issue in JavaScript and there is no good solution for it.
155-
// We need to make sure the scale of the potential memory leak is controllable.
156-
const srvQueryPromise = this.#querySrvTargetHost(host);
157-
// There is no way to check the promise status synchronously, so we need to set the flag through the callback.
158-
srvQueryPromise.finally(() => this.#srvQueryPending = false)
159-
// If the srvQueryPromise is rejected before timeout, the error will be caught in the catch block.
160-
// Otherwise, the timeout error will be caught in the catch block and the srvQueryPromise rejection will be ignored.
161-
result = await Promise.race([
162-
new Promise((_, reject) =>
163-
timeoutId = setTimeout(() => reject(new Error("SRV record query timed out.")), SRV_QUERY_TIMEOUT)),
164-
srvQueryPromise
165-
]);
150+
result = await this.#querySrvTargetHost(host);
166151
} catch (error) {
167152
console.warn(`Failed to build fallback clients, ${error.message}`);
168153
this.#lastFallbackClientRefreshTime = Date.now();
169-
return; // silently fail when SRV record query times out
170-
} finally {
171-
clearTimeout(timeoutId);
172-
}
154+
return; // swallow the error when srv query fails
155+
}
173156

174-
const srvTargetHosts = shuffleList(result) as string[];
157+
const srvTargetHosts = shuffleList(result);
175158
const newDynamicClients: ConfigurationClientWrapper[] = [];
176159
for (const host of srvTargetHosts) {
177160
if (isValidEndpoint(host, this.#validDomain)) {
@@ -198,8 +181,9 @@ export class ConfigurationClientManager {
198181
const results: string[] = [];
199182

200183
try {
184+
const resolver = new this.#dns.Resolver({timeout: DNS_RESOLVER_TIMEOUT, tries: DNS_RESOLVER_TRIES});
201185
// Look up SRV records for the origin host
202-
const originRecords = await this.#dns.resolveSrv(`${TCP_ORIGIN_KEY_NAME}.${host}`);
186+
const originRecords = await resolver.resolveSrv(`${TCP_ORIGIN_KEY_NAME}.${host}`);
203187
if (originRecords.length === 0) {
204188
return results;
205189
}
@@ -210,10 +194,9 @@ export class ConfigurationClientManager {
210194

211195
// Look up SRV records for alternate hosts
212196
let index = 0;
213-
// eslint-disable-next-line no-constant-condition
214-
while (true) {
197+
while (index < MAX_RESOLVESRV_TIMES) {
215198
const currentAlt = `${ALT_KEY_NAME}${index}`;
216-
const altRecords = await this.#dns.resolveSrv(`${currentAlt}.${TCP_KEY_NAME}.${originHost}`);
199+
const altRecords = await resolver.resolveSrv(`${currentAlt}.${TCP_KEY_NAME}.${originHost}`);
217200
if (altRecords.length === 0) {
218201
break; // No more alternate records, exit loop
219202
}

0 commit comments

Comments
 (0)