Skip to content

Commit e431b36

Browse files
committed
DelegatingAuroraConnection: Allow more control on delegate choice
This allows you to specify more precise what type of logic should be used in picking a delegate connection. Previously the only control was through setting the readOnly status. This behavior is still defaulted as the `Smart` option. But in addition behaviors to use only the master, or only a secondary, or even distribute to specific secondary servers have been added. This can allow for more performant control over which connections to use, but can also allow options to make better use of the cluster. Please read the javadocs at the top of `DelegatingAuroraConnection` for more details on the different behaviors this now provides.
1 parent e2eec47 commit e431b36

File tree

6 files changed

+601
-31
lines changed

6 files changed

+601
-31
lines changed

arcCommon/src/main/java/org/threadly/db/aurora/AuroraClusterMonitor.java

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,24 +76,59 @@ protected AuroraClusterMonitor(SubmitterScheduler scheduler, long checkIntervalM
7676
clusterStateChecker = new ClusterChecker(scheduler, checkIntervalMillis, driver, clusterServers);
7777
replicaIndex = new AtomicLong();
7878
}
79+
80+
/**
81+
* Getter for the current number of healthy replicate servers known in the cluster. The master
82+
* server is not included in this count.
83+
*
84+
* @return The number of healthy replica servers in the cluster
85+
*/
86+
public int getHealthyReplicaCount() {
87+
return clusterStateChecker.secondaryServers.size();
88+
}
7989

8090
/**
8191
* Return a random read only replica server.
8292
*
8393
* @return Random read only replica server, or {@code null} if no servers are healthy
8494
*/
8595
public AuroraServer getRandomReadReplica() {
86-
long replicaIndex = this.replicaIndex.getAndIncrement();
87-
int secondaryCount;
88-
// may loop if secondary server becomes unhealthy during check
89-
while ((secondaryCount = clusterStateChecker.secondaryServers.size()) > 0) {
96+
while (true) {
97+
int secondaryCount = clusterStateChecker.secondaryServers.size();
9098
try {
91-
return clusterStateChecker.secondaryServers.get((int)(replicaIndex % secondaryCount));
99+
if (secondaryCount == 1) {
100+
return clusterStateChecker.secondaryServers.get(0);
101+
} else if (secondaryCount == 0) {
102+
return null;
103+
} else {
104+
long replicaIndex = this.replicaIndex.getAndIncrement();
105+
return clusterStateChecker.secondaryServers.get((int)(replicaIndex % secondaryCount));
106+
}
92107
} catch (IndexOutOfBoundsException e) {
93108
// secondary server was removed during check, loop and retry
94109
}
95110
}
96-
return null;
111+
}
112+
113+
/**
114+
* Return a read replica which corresponds to an index. A given index may not always provide the
115+
* same server depending on membership changes or other re-ordering that may occur. But should
116+
* provide a basic way to get varying servers when the internal randomization mechanism is not
117+
* desired.
118+
*
119+
* @param index Zero based index of replica to provide
120+
* @return Read only replica server, or {@code null} if no servers was at the provided index
121+
*/
122+
public AuroraServer getReadReplica(int index) {
123+
if (clusterStateChecker.secondaryServers.size() <= index) {
124+
return null;
125+
}
126+
try {
127+
return clusterStateChecker.secondaryServers.get(index);
128+
} catch (IndexOutOfBoundsException e) {
129+
// secondary server was removed after check
130+
return null;
131+
}
97132
}
98133

99134
/**

0 commit comments

Comments
 (0)