in src/main/java/org/mariadb/jdbc/internal/protocol/MastersSlavesProtocol.java [88:197]
public static void loop(
MastersSlavesListener listener,
final GlobalStateInfo globalInfo,
final List<HostAddress> addresses,
SearchFilter searchFilter)
throws SQLException {
MastersSlavesProtocol protocol;
ArrayDeque<HostAddress> loopAddresses = new ArrayDeque<>(addresses);
if (loopAddresses.isEmpty()) {
resetHostList(listener, loopAddresses);
}
int maxConnectionTry = listener.getRetriesAllDown();
SQLException lastQueryException = null;
boolean firstLoop = true;
while (!loopAddresses.isEmpty() || (!searchFilter.isFailoverLoop() && maxConnectionTry > 0)) {
protocol = getNewProtocol(listener.getProxy(), globalInfo, listener.getUrlParser());
if (listener.isExplicitClosed()
|| (!listener.isSecondaryHostFailReconnect() && !listener.isMasterHostFailReconnect())) {
return;
}
maxConnectionTry--;
try {
HostAddress host = loopAddresses.pollFirst();
if (host == null) {
loopAddresses.addAll(listener.getUrlParser().getHostAddresses());
host = loopAddresses.pollFirst();
}
protocol.setHostAddress(host);
protocol.connect();
if (listener.isExplicitClosed()) {
protocol.close();
return;
}
listener.removeFromBlacklist(protocol.getHostAddress());
if (listener.isMasterHostFailReconnect() && protocol.isMasterConnection()) {
if (foundMaster(listener, protocol, searchFilter)) {
return;
}
} else if (listener.isSecondaryHostFailReconnect() && !protocol.isMasterConnection()) {
if (foundSecondary(listener, protocol, searchFilter)) {
return;
}
} else {
protocol.close();
}
} catch (SQLException e) {
lastQueryException = e;
listener.addToBlacklist(protocol.getHostAddress());
}
if (!listener.isMasterHostFailReconnect() && !listener.isSecondaryHostFailReconnect()) {
return;
}
// in case master not found but slave is , and allowing master down
if (loopAddresses.isEmpty()
&& (listener.isMasterHostFailReconnect()
&& listener.urlParser.getOptions().allowMasterDownConnection
&& !listener.isSecondaryHostFailReconnect())) {
return;
}
// on connection and all slaves have been tested, use master if on
if (loopAddresses.isEmpty()
&& searchFilter.isInitialConnection()
&& !listener.isMasterHostFailReconnect()) {
return;
}
// if server has try to connect to all host, and there is remaining master or slave that fail
// add all servers back to continue looping until maxConnectionTry is reached
if (loopAddresses.isEmpty() && !searchFilter.isFailoverLoop() && maxConnectionTry > 0) {
resetHostList(listener, loopAddresses);
if (firstLoop) {
firstLoop = false;
} else {
try {
// wait 250ms before looping through all connection another time
Thread.sleep(250);
} catch (InterruptedException interrupted) {
// interrupted, continue
}
}
}
}
if (listener.isMasterHostFailReconnect() || listener.isSecondaryHostFailReconnect()) {
String error = "No active connection found for replica";
if (listener.isMasterHostFailReconnect()) {
error = "No active connection found for master";
}
if (lastQueryException != null) {
throw new SQLException(
error + " : " + lastQueryException.getMessage(),
lastQueryException.getSQLState(),
lastQueryException.getErrorCode(),
lastQueryException);
}
throw new SQLException(error);
}
}