use of org.redisson.connection.NodeSource in project redisson by redisson.
the class CommandAsyncService method checkAttemptFuture.
private <R, V> void checkAttemptFuture(final NodeSource source, final AsyncDetails<V, R> details, Future<R> future) {
details.getTimeout().cancel();
if (future.isCancelled()) {
return;
}
if (future.cause() instanceof RedisMovedException) {
RedisMovedException ex = (RedisMovedException) future.cause();
async(details.isReadOnlyMode(), new NodeSource(ex.getSlot(), ex.getAddr(), Redirect.MOVED), details.getCodec(), details.getCommand(), details.getParams(), details.getMainPromise(), details.getAttempt());
AsyncDetails.release(details);
return;
}
if (future.cause() instanceof RedisAskException) {
RedisAskException ex = (RedisAskException) future.cause();
async(details.isReadOnlyMode(), new NodeSource(ex.getSlot(), ex.getAddr(), Redirect.ASK), details.getCodec(), details.getCommand(), details.getParams(), details.getMainPromise(), details.getAttempt());
AsyncDetails.release(details);
return;
}
if (future.cause() instanceof RedisLoadingException) {
async(details.isReadOnlyMode(), source, details.getCodec(), details.getCommand(), details.getParams(), details.getMainPromise(), details.getAttempt());
AsyncDetails.release(details);
return;
}
if (future.cause() instanceof RedisTryAgainException) {
connectionManager.newTimeout(new TimerTask() {
@Override
public void run(Timeout timeout) throws Exception {
async(details.isReadOnlyMode(), source, details.getCodec(), details.getCommand(), details.getParams(), details.getMainPromise(), details.getAttempt());
}
}, 1, TimeUnit.SECONDS);
AsyncDetails.release(details);
return;
}
if (future.isSuccess()) {
R res = future.getNow();
if (res instanceof RedisClientResult) {
InetSocketAddress addr = source.getAddr();
if (addr == null) {
addr = details.getConnectionFuture().getNow().getRedisClient().getAddr();
}
((RedisClientResult) res).setRedisClient(addr);
}
if (isRedissonReferenceSupportEnabled()) {
handleReference(details.getMainPromise(), res);
} else {
details.getMainPromise().trySuccess(res);
}
} else {
details.getMainPromise().tryFailure(future.cause());
}
AsyncDetails.release(details);
}
use of org.redisson.connection.NodeSource in project redisson by redisson.
the class CommandAsyncService method readAsync.
@Override
public <T, R> RFuture<R> readAsync(InetSocketAddress client, String key, Codec codec, RedisCommand<T> command, Object... params) {
RPromise<R> mainPromise = connectionManager.newPromise();
int slot = connectionManager.calcSlot(key);
async(true, new NodeSource(slot, client), codec, command, params, mainPromise, 0);
return mainPromise;
}
use of org.redisson.connection.NodeSource 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.connection.NodeSource in project redisson by redisson.
the class CommandAsyncService method evalAllAsync.
public <T, R> RFuture<R> evalAllAsync(boolean readOnlyMode, RedisCommand<T> command, final SlotCallback<T, R> callback, String script, List<Object> keys, Object... params) {
final RPromise<R> mainPromise = connectionManager.newPromise();
final Set<MasterSlaveEntry> entries = connectionManager.getEntrySet();
final AtomicInteger counter = new AtomicInteger(entries.size());
FutureListener<T> listener = new FutureListener<T>() {
@Override
public void operationComplete(Future<T> future) throws Exception {
if (!future.isSuccess()) {
mainPromise.tryFailure(future.cause());
return;
}
callback.onSlotResult(future.getNow());
if (counter.decrementAndGet() == 0 && !mainPromise.isDone()) {
mainPromise.trySuccess(callback.onFinish());
}
}
};
List<Object> args = new ArrayList<Object>(2 + keys.size() + params.length);
args.add(script);
args.add(keys.size());
args.addAll(keys);
args.addAll(Arrays.asList(params));
for (MasterSlaveEntry entry : entries) {
RPromise<T> promise = connectionManager.newPromise();
promise.addListener(listener);
async(readOnlyMode, new NodeSource(entry), connectionManager.getCodec(), command, args.toArray(), promise, 0);
}
return mainPromise;
}
use of org.redisson.connection.NodeSource in project redisson by redisson.
the class CommandAsyncService method writeAsync.
@Override
public <T, R> RFuture<R> writeAsync(MasterSlaveEntry entry, Codec codec, RedisCommand<T> command, Object... params) {
RPromise<R> mainPromise = connectionManager.newPromise();
async(false, new NodeSource(entry), codec, command, params, mainPromise, 0);
return mainPromise;
}
Aggregations