use of org.redisson.client.RedisConnection in project redisson by redisson.
the class ConnectionPool method scheduleCheck.
private void scheduleCheck(final ClientConnectionsEntry entry) {
connectionManager.getConnectionEventsHub().fireDisconnect(entry.getClient().getAddr());
connectionManager.newTimeout(new TimerTask() {
@Override
public void run(Timeout timeout) throws Exception {
if (entry.getFreezeReason() != FreezeReason.RECONNECT || !entry.isFreezed()) {
return;
}
RFuture<RedisConnection> connectionFuture = entry.getClient().connectAsync();
connectionFuture.addListener(new FutureListener<RedisConnection>() {
@Override
public void operationComplete(Future<RedisConnection> future) throws Exception {
if (entry.getFreezeReason() != FreezeReason.RECONNECT || !entry.isFreezed()) {
return;
}
if (!future.isSuccess()) {
scheduleCheck(entry);
return;
}
final RedisConnection c = future.getNow();
if (!c.isActive()) {
c.closeAsync();
scheduleCheck(entry);
return;
}
final FutureListener<String> pingListener = new FutureListener<String>() {
@Override
public void operationComplete(Future<String> future) throws Exception {
try {
if (entry.getFreezeReason() != FreezeReason.RECONNECT || !entry.isFreezed()) {
return;
}
if (future.isSuccess() && "PONG".equals(future.getNow())) {
entry.resetFailedAttempts();
RPromise<Void> promise = connectionManager.newPromise();
promise.addListener(new FutureListener<Void>() {
@Override
public void operationComplete(Future<Void> future) throws Exception {
if (entry.getNodeType() == NodeType.SLAVE) {
masterSlaveEntry.slaveUp(entry.getClient().getAddr().getHostName(), entry.getClient().getAddr().getPort(), FreezeReason.RECONNECT);
log.info("slave {} successfully reconnected", entry.getClient().getAddr());
} else {
synchronized (entry) {
if (entry.getFreezeReason() == FreezeReason.RECONNECT) {
entry.setFreezed(false);
entry.setFreezeReason(null);
log.info("host {} successfully reconnected", entry.getClient().getAddr());
}
}
}
}
});
initConnections(entry, promise, false);
} else {
scheduleCheck(entry);
}
} finally {
c.closeAsync();
}
}
};
if (entry.getConfig().getPassword() != null) {
RFuture<Void> temp = c.async(RedisCommands.AUTH, config.getPassword());
FutureListener<Void> listener = new FutureListener<Void>() {
@Override
public void operationComplete(Future<Void> future) throws Exception {
ping(c, pingListener);
}
};
temp.addListener(listener);
} else {
ping(c, pingListener);
}
}
});
}
}, config.getReconnectionTimeout(), TimeUnit.MILLISECONDS);
}
use of org.redisson.client.RedisConnection in project redisson by redisson.
the class CommandBatchService method execute.
private void execute(final Entry entry, final NodeSource source, final RPromise<Void> mainPromise, final AtomicInteger slots, final int attempt, final boolean noResult) {
if (mainPromise.isCancelled()) {
return;
}
if (!connectionManager.getShutdownLatch().acquire()) {
mainPromise.tryFailure(new IllegalStateException("Redisson is shutdown"));
return;
}
final RPromise<Void> attemptPromise = connectionManager.newPromise();
final AsyncDetails details = new AsyncDetails();
final RFuture<RedisConnection> connectionFuture;
if (entry.isReadOnlyMode()) {
connectionFuture = connectionManager.connectionReadOp(source, null);
} else {
connectionFuture = connectionManager.connectionWriteOp(source, null);
}
final TimerTask retryTimerTask = new TimerTask() {
@Override
public void run(Timeout timeout) throws Exception {
if (attemptPromise.isDone()) {
return;
}
if (connectionFuture.cancel(false)) {
connectionManager.getShutdownLatch().release();
} else {
if (connectionFuture.isSuccess()) {
ChannelFuture writeFuture = details.getWriteFuture();
if (writeFuture != null && !writeFuture.cancel(false) && writeFuture.isSuccess()) {
return;
}
}
}
if (mainPromise.isCancelled()) {
attemptPromise.cancel(false);
return;
}
if (attempt == connectionManager.getConfig().getRetryAttempts()) {
if (details.getException() == null) {
details.setException(new RedisTimeoutException("Batch command execution timeout"));
}
attemptPromise.tryFailure(details.getException());
return;
}
if (!attemptPromise.cancel(false)) {
return;
}
int count = attempt + 1;
execute(entry, source, mainPromise, slots, count, noResult);
}
};
Timeout timeout = connectionManager.newTimeout(retryTimerTask, connectionManager.getConfig().getRetryInterval(), TimeUnit.MILLISECONDS);
details.setTimeout(timeout);
connectionFuture.addListener(new FutureListener<RedisConnection>() {
@Override
public void operationComplete(Future<RedisConnection> connFuture) throws Exception {
checkConnectionFuture(entry, source, mainPromise, attemptPromise, details, connectionFuture, noResult);
}
});
attemptPromise.addListener(new FutureListener<Void>() {
@Override
public void operationComplete(Future<Void> future) throws Exception {
details.getTimeout().cancel();
if (future.isCancelled()) {
return;
}
if (future.cause() instanceof RedisMovedException) {
RedisMovedException ex = (RedisMovedException) future.cause();
entry.clearErrors();
execute(entry, new NodeSource(ex.getSlot(), ex.getAddr(), Redirect.MOVED), mainPromise, slots, attempt, noResult);
return;
}
if (future.cause() instanceof RedisAskException) {
RedisAskException ex = (RedisAskException) future.cause();
entry.clearErrors();
execute(entry, new NodeSource(ex.getSlot(), ex.getAddr(), Redirect.ASK), mainPromise, slots, attempt, noResult);
return;
}
if (future.cause() instanceof RedisLoadingException) {
entry.clearErrors();
execute(entry, source, mainPromise, slots, attempt, noResult);
return;
}
if (future.cause() instanceof RedisTryAgainException) {
entry.clearErrors();
connectionManager.newTimeout(new TimerTask() {
@Override
public void run(Timeout timeout) throws Exception {
execute(entry, source, mainPromise, slots, attempt, noResult);
}
}, 1, TimeUnit.SECONDS);
return;
}
if (future.isSuccess()) {
if (slots.decrementAndGet() == 0) {
mainPromise.trySuccess(future.getNow());
}
} else {
mainPromise.tryFailure(future.cause());
}
}
});
}
use of org.redisson.client.RedisConnection in project redisson by redisson.
the class ClientConnectionsEntry method addReconnectListener.
private <T extends RedisConnection> void addReconnectListener(RPromise<T> connectionFuture, T conn) {
addFireEventListener(conn, connectionFuture);
conn.setReconnectListener(new ReconnectListener() {
@Override
public void onReconnect(RedisConnection conn, RPromise<RedisConnection> connectionFuture) {
addFireEventListener(conn, connectionFuture);
}
});
}
use of org.redisson.client.RedisConnection in project redisson by redisson.
the class MasterSlaveEntry method slaveDown.
private boolean slaveDown(ClientConnectionsEntry entry, boolean temporaryDown) {
// add master as slave if no more slaves available
if (config.getReadMode() == ReadMode.SLAVE && slaveBalancer.getAvailableClients() == 0) {
InetSocketAddress addr = masterEntry.getClient().getAddr();
if (slaveUp(addr.getHostName(), addr.getPort(), FreezeReason.SYSTEM)) {
log.info("master {}:{} used as slave", addr.getHostName(), addr.getPort());
}
}
// close all connections
while (true) {
final RedisConnection connection = entry.pollConnection();
if (connection == null) {
break;
}
connection.closeAsync().addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
reattachBlockingQueue(connection);
}
});
}
// close all pub/sub connections
while (true) {
RedisPubSubConnection connection = entry.pollSubscribeConnection();
if (connection == null) {
break;
}
connection.closeAsync();
}
for (RedisPubSubConnection connection : entry.getAllSubscribeConnections()) {
reattachPubSub(connection, temporaryDown);
}
entry.getAllSubscribeConnections().clear();
return true;
}
use of org.redisson.client.RedisConnection in project redisson by redisson.
the class ReplicatedConnectionManager method shutdown.
@Override
public void shutdown() {
monitorFuture.cancel(true);
super.shutdown();
for (RedisConnection connection : nodeConnections.values()) {
connection.getRedisClient().shutdown();
}
}
Aggregations