use of org.redisson.misc.RedisURI in project redisson by redisson.
the class CommandDecoder method decode.
protected void decode(ByteBuf in, CommandData<Object, Object> data, List<Object> parts, Channel channel, boolean skipConvertor, List<CommandData<?, ?>> commandsData) throws IOException {
int code = in.readByte();
if (code == '+') {
String result = readString(in);
handleResult(data, parts, result, skipConvertor);
} else if (code == '-') {
String error = readString(in);
if (error.startsWith("MOVED")) {
String[] errorParts = error.split(" ");
int slot = Integer.valueOf(errorParts[1]);
String addr = errorParts[2];
data.tryFailure(new RedisMovedException(slot, new RedisURI(scheme + "://" + addr)));
} else if (error.startsWith("ASK")) {
String[] errorParts = error.split(" ");
int slot = Integer.valueOf(errorParts[1]);
String addr = errorParts[2];
data.tryFailure(new RedisAskException(slot, new RedisURI(scheme + "://" + addr)));
} else if (error.startsWith("TRYAGAIN")) {
data.tryFailure(new RedisTryAgainException(error + ". channel: " + channel + " data: " + data));
} else if (error.startsWith("LOADING")) {
data.tryFailure(new RedisLoadingException(error + ". channel: " + channel + " data: " + data));
} else if (error.startsWith("OOM")) {
data.tryFailure(new RedisOutOfMemoryException(error.split("OOM ")[1] + ". channel: " + channel + " data: " + data));
} else if (error.contains("-OOM ")) {
data.tryFailure(new RedisOutOfMemoryException(error.split("-OOM ")[1] + ". channel: " + channel + " data: " + data));
} else if (error.startsWith("NOAUTH")) {
data.tryFailure(new RedisAuthRequiredException(error + ". channel: " + channel + " data: " + data));
} else if (error.startsWith("CLUSTERDOWN")) {
data.tryFailure(new RedisClusterDownException(error + ". channel: " + channel + " data: " + data));
} else if (error.startsWith("BUSY")) {
data.tryFailure(new RedisBusyException(error + ". channel: " + channel + " data: " + data));
} else {
if (data != null) {
data.tryFailure(new RedisException(error + ". channel: " + channel + " command: " + LogHelper.toString(data)));
} else {
log.error("Error message from Redis: {} channel: {}", error, channel);
}
}
} else if (code == ':') {
Long result = readLong(in);
handleResult(data, parts, result, false);
} else if (code == '$') {
ByteBuf buf = readBytes(in);
Object result = null;
if (buf != null) {
Decoder<Object> decoder = selectDecoder(data, parts);
result = decoder.decode(buf, state());
}
handleResult(data, parts, result, false);
} else if (code == '*') {
long size = readLong(in);
List<Object> respParts = new ArrayList<Object>(Math.max((int) size, 0));
state().incLevel();
decodeList(in, data, parts, channel, size, respParts, skipConvertor, commandsData);
state().decLevel();
} else {
String dataStr = in.toString(0, in.writerIndex(), CharsetUtil.UTF_8);
throw new IllegalStateException("Can't decode replay: " + dataStr);
}
}
use of org.redisson.misc.RedisURI in project redisson by redisson.
the class RedisExecutor method checkAttemptPromise.
protected void checkAttemptPromise(CompletableFuture<R> attemptFuture, CompletableFuture<RedisConnection> connectionFuture) {
timeout.cancel();
if (attemptFuture.isCancelled()) {
return;
}
try {
mainPromiseListener = null;
Throwable cause = cause(attemptFuture);
if (cause instanceof RedisMovedException && !ignoreRedirect) {
RedisMovedException ex = (RedisMovedException) cause;
if (source.getRedirect() == Redirect.MOVED) {
mainPromise.completeExceptionally(new RedisException("MOVED redirection loop detected. Node " + source.getAddr() + " has further redirect to " + ex.getUrl()));
return;
}
onException();
CompletableFuture<RedisURI> ipAddrFuture = connectionManager.resolveIP(ex.getUrl());
ipAddrFuture.whenComplete((ip, e) -> {
if (e != null) {
handleError(connectionFuture, e);
return;
}
source = new NodeSource(ex.getSlot(), ip, Redirect.MOVED);
execute();
});
return;
}
if (cause instanceof RedisAskException && !ignoreRedirect) {
RedisAskException ex = (RedisAskException) cause;
onException();
CompletableFuture<RedisURI> ipAddrFuture = connectionManager.resolveIP(ex.getUrl());
ipAddrFuture.whenComplete((ip, e) -> {
if (e != null) {
handleError(connectionFuture, e);
return;
}
source = new NodeSource(ex.getSlot(), ip, Redirect.ASK);
execute();
});
return;
}
if (cause instanceof RedisLoadingException || cause instanceof RedisTryAgainException || cause instanceof RedisClusterDownException || cause instanceof RedisBusyException) {
if (attempt < attempts) {
onException();
connectionManager.newTimeout(timeout -> {
attempt++;
execute();
}, retryInterval, TimeUnit.MILLISECONDS);
return;
}
}
free();
handleResult(attemptFuture, connectionFuture);
} catch (Exception e) {
handleError(connectionFuture, e);
}
}
use of org.redisson.misc.RedisURI in project redisson by redisson.
the class SentinelConnectionManager method performSentinelDNSCheck.
private void performSentinelDNSCheck(FutureListener<List<InetSocketAddress>> commonListener) {
for (RedisURI host : sentinelHosts) {
Future<List<InetSocketAddress>> allNodes = sentinelResolver.resolveAll(InetSocketAddress.createUnresolved(host.getHost(), host.getPort()));
allNodes.addListener((FutureListener<List<InetSocketAddress>>) future -> {
if (!future.isSuccess()) {
log.error("Unable to resolve " + host.getHost(), future.cause());
return;
}
future.getNow().stream().map(addr -> toURI(addr)).filter(uri -> !sentinels.containsKey(uri)).forEach(uri -> registerSentinel(uri, getConfig(), host.getHost()));
});
if (commonListener != null) {
allNodes.addListener(commonListener);
}
}
}
use of org.redisson.misc.RedisURI in project redisson by redisson.
the class SentinelConnectionManager method checkSentinelsChange.
private CompletionStage<Void> checkSentinelsChange(SentinelServersConfig cfg, RedisConnection connection) {
if (!cfg.isSentinelsDiscovery()) {
return CompletableFuture.completedFuture(null);
}
RFuture<List<Map<String, String>>> sentinelsFuture = connection.async(StringCodec.INSTANCE, RedisCommands.SENTINEL_SENTINELS, cfg.getMasterName());
return sentinelsFuture.thenCompose(list -> {
if (list.isEmpty()) {
return CompletableFuture.completedFuture(null);
}
List<CompletableFuture<RedisURI>> newUris = list.stream().filter(m -> {
String flags = m.getOrDefault("flags", "");
String masterLinkStatus = m.getOrDefault("master-link-status", "");
if (!m.isEmpty() && !isSlaveDown(flags, masterLinkStatus)) {
return true;
}
return false;
}).map(m -> {
String ip = m.get("ip");
String port = m.get("port");
return toURI(scheme, ip, port);
}).map(addr -> {
CompletionStage<RedisURI> f = resolveIP(addr);
return f.exceptionally(ex -> {
log.error("unable to resolve hostname", ex);
return null;
}).toCompletableFuture();
}).collect(Collectors.toList());
CompletableFuture<Void> futures = CompletableFuture.allOf(newUris.toArray(new CompletableFuture[0]));
return futures.whenComplete((r, ex) -> {
List<RedisURI> uris = newUris.stream().map(u -> {
try {
return u.getNow(null);
} catch (Exception exc) {
return null;
}
}).filter(u -> u != null).collect(Collectors.toList());
InetSocketAddress addr = connection.getRedisClient().getAddr();
RedisURI currentAddr = toURI(addr);
uris.add(currentAddr);
updateSentinels(uris);
});
});
}
use of org.redisson.misc.RedisURI in project redisson by redisson.
the class SentinelConnectionManager method checkMasterChange.
private CompletionStage<RedisURI> checkMasterChange(SentinelServersConfig cfg, RedisConnection connection) {
RFuture<RedisURI> masterFuture = connection.async(StringCodec.INSTANCE, masterHostCommand, cfg.getMasterName());
return masterFuture.thenCompose(u -> resolveIP(scheme, u)).whenComplete((newMaster, e) -> {
if (e != null) {
return;
}
RedisURI current = currentMaster.get();
if (!newMaster.equals(current) && currentMaster.compareAndSet(current, newMaster)) {
CompletableFuture<RedisClient> changeFuture = changeMaster(singleSlotRange.getStartSlot(), newMaster);
changeFuture.exceptionally(ex -> {
currentMaster.compareAndSet(newMaster, current);
return null;
});
}
});
}
Aggregations