in common/lib/plugins/aurora_initial_connection_strategy_plugin.ts [178:261]
async getVerifiedReaderClient<T>(props: Map<string, any>, isInitialConnection: boolean, connectFunc: () => Promise<T>): Promise<any> {
if (!this.hostListProviderService) {
throw new AwsWrapperError(Messages.get("HostListProviderService.notFound")); // should not be reached
}
const retryDelayMs = WrapperProperties.OPEN_CONNECTION_RETRY_INTERVAL_MS.get(props);
const endTimeMs = Date.now() + WrapperProperties.OPEN_CONNECTION_RETRY_TIMEOUT_MS.get(props);
let readerCandidateClient: any;
let readerCandidate: HostInfo | void | null;
while (Date.now() < endTimeMs) {
readerCandidateClient = null;
readerCandidate = null;
try {
readerCandidate = this.getReader(props);
// convert into null if undefined
readerCandidate = readerCandidate ?? null;
if (readerCandidate === null || this.rdsUtils.isRdsClusterDns(readerCandidate.host)) {
// Reader is not found. It seems that topology is outdated.
readerCandidateClient = await connectFunc();
await this.pluginService.forceRefreshHostList(readerCandidateClient);
readerCandidate = await this.pluginService.identifyConnection(readerCandidateClient);
if (readerCandidate) {
if (readerCandidate.role !== HostRole.READER) {
if (this.hasNoReaders()) {
// It seems that cluster has no readers. Simulate Aurora reader cluster endpoint logic
// and return the current (writer) client.
if (isInitialConnection) {
this.hostListProviderService.setInitialConnectionHostInfo(readerCandidate);
}
return readerCandidateClient;
}
await this.pluginService.abortTargetClient(readerCandidateClient);
await sleep(retryDelayMs);
continue;
}
// Reader connection is valid and verified.
if (isInitialConnection) {
this.hostListProviderService.setInitialConnectionHostInfo(readerCandidate);
}
} else {
logger.debug("Reader candidate not found");
}
return readerCandidateClient;
}
readerCandidateClient = await this.pluginService.connect(readerCandidate, props);
if ((await this.pluginService.getHostRole(readerCandidateClient)) !== HostRole.READER) {
// If the new connection resolves to a writer instance, this means the topology is outdated.
// Force refresh to update the topology.
await this.pluginService.forceRefreshHostList(readerCandidateClient);
if (this.hasNoReaders()) {
// It seems that cluster has no readers. Simulate Aurora reader cluster endpoint logic
// and return the current (writer) client.
if (isInitialConnection) {
this.hostListProviderService.setInitialConnectionHostInfo(readerCandidate);
}
return readerCandidateClient;
}
await this.pluginService.abortTargetClient(readerCandidateClient);
await sleep(retryDelayMs);
continue;
}
// Reader connection is valid and verified.
if (isInitialConnection) {
this.hostListProviderService.setInitialConnectionHostInfo(readerCandidate);
}
return readerCandidateClient;
} catch (error: any) {
await this.pluginService.abortTargetClient(readerCandidateClient);
if (this.pluginService.isLoginError(error) || !readerCandidate) {
throw error;
} else if (readerCandidate) {
this.pluginService.setAvailability(readerCandidate.allAliases, HostAvailability.NOT_AVAILABLE);
}
}
}
}