use of org.redisson.connection.SingleEntry in project redisson by redisson.
the class ClusterConnectionManager method addMasterEntry.
private RFuture<Collection<RFuture<Void>>> addMasterEntry(final ClusterPartition partition, final ClusterServersConfig cfg) {
if (partition.isMasterFail()) {
RedisException e = new RedisException("Failed to add master: " + partition.getMasterAddress() + " for slot ranges: " + partition.getSlotRanges() + ". Reason - server has FAIL flag");
if (partition.getSlotRanges().isEmpty()) {
e = new RedisException("Failed to add master: " + partition.getMasterAddress() + ". Reason - server has FAIL flag");
}
return newFailedFuture(e);
}
final RPromise<Collection<RFuture<Void>>> result = newPromise();
RFuture<RedisConnection> connectionFuture = connect(cfg, partition.getMasterAddress());
connectionFuture.addListener(new FutureListener<RedisConnection>() {
@Override
public void operationComplete(Future<RedisConnection> future) throws Exception {
if (!future.isSuccess()) {
log.error("Can't connect to master: {} with slot ranges: {}", partition.getMasterAddress(), partition.getSlotRanges());
result.tryFailure(future.cause());
return;
}
final RedisConnection connection = future.getNow();
RFuture<Map<String, String>> clusterFuture = connection.async(RedisCommands.CLUSTER_INFO);
clusterFuture.addListener(new FutureListener<Map<String, String>>() {
@Override
public void operationComplete(Future<Map<String, String>> future) throws Exception {
if (!future.isSuccess()) {
log.error("Can't execute CLUSTER_INFO for " + connection.getRedisClient().getAddr(), future.cause());
result.tryFailure(future.cause());
return;
}
Map<String, String> params = future.getNow();
if ("fail".equals(params.get("cluster_state"))) {
RedisException e = new RedisException("Failed to add master: " + partition.getMasterAddress() + " for slot ranges: " + partition.getSlotRanges() + ". Reason - cluster_state:fail");
log.error("cluster_state:fail for " + connection.getRedisClient().getAddr());
result.tryFailure(e);
return;
}
MasterSlaveServersConfig config = create(cfg);
config.setMasterAddress(partition.getMasterAddress());
final MasterSlaveEntry e;
List<RFuture<Void>> futures = new ArrayList<RFuture<Void>>();
if (config.getReadMode() == ReadMode.MASTER) {
e = new SingleEntry(partition.getSlotRanges(), ClusterConnectionManager.this, config);
} else {
config.setSlaveAddresses(partition.getSlaveAddresses());
e = new MasterSlaveEntry(partition.getSlotRanges(), ClusterConnectionManager.this, config);
List<RFuture<Void>> fs = e.initSlaveBalancer(partition.getFailedSlaveAddresses());
futures.addAll(fs);
if (!partition.getSlaveAddresses().isEmpty()) {
log.info("slaves: {} added for slot ranges: {}", partition.getSlaveAddresses(), partition.getSlotRanges());
if (!partition.getFailedSlaveAddresses().isEmpty()) {
log.warn("slaves: {} is down for slot ranges: {}", partition.getFailedSlaveAddresses(), partition.getSlotRanges());
}
}
}
RFuture<Void> f = e.setupMasterEntry(config.getMasterAddress().getHost(), config.getMasterAddress().getPort());
final RPromise<Void> initFuture = newPromise();
futures.add(initFuture);
f.addListener(new FutureListener<Void>() {
@Override
public void operationComplete(Future<Void> future) throws Exception {
if (!future.isSuccess()) {
log.error("Can't add master: {} for slot ranges: {}", partition.getMasterAddress(), partition.getSlotRanges());
initFuture.tryFailure(future.cause());
return;
}
for (Integer slot : partition.getSlots()) {
addEntry(slot, e);
lastPartitions.put(slot, partition);
}
log.info("master: {} added for slot ranges: {}", partition.getMasterAddress(), partition.getSlotRanges());
if (!initFuture.trySuccess(null)) {
throw new IllegalStateException();
}
}
});
if (!result.trySuccess(futures)) {
throw new IllegalStateException();
}
}
});
}
});
return result;
}
Aggregations