use of org.redisson.misc.RPromise in project redisson by redisson.
the class RedisNodes method pingAll.
@Override
public boolean pingAll() {
List<RedisClientEntry> clients = new ArrayList<RedisClientEntry>(connectionManager.getClients());
final Map<RedisConnection, RFuture<String>> result = new ConcurrentHashMap<RedisConnection, RFuture<String>>(clients.size());
final CountDownLatch latch = new CountDownLatch(clients.size());
for (RedisClientEntry entry : clients) {
RFuture<RedisConnection> f = entry.getClient().connectAsync();
f.addListener(new FutureListener<RedisConnection>() {
@Override
public void operationComplete(Future<RedisConnection> future) throws Exception {
if (future.isSuccess()) {
final RedisConnection c = future.getNow();
RPromise<RedisConnection> connectionFuture = connectionManager.newPromise();
connectionManager.getConnectListener().onConnect(connectionFuture, c, null, connectionManager.getConfig());
connectionFuture.addListener(new FutureListener<RedisConnection>() {
@Override
public void operationComplete(Future<RedisConnection> future) throws Exception {
RFuture<String> r = c.async(connectionManager.getConfig().getPingTimeout(), RedisCommands.PING);
result.put(c, r);
latch.countDown();
}
});
} else {
latch.countDown();
}
}
});
}
long time = System.currentTimeMillis();
try {
latch.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
if (System.currentTimeMillis() - time >= connectionManager.getConfig().getConnectTimeout()) {
for (Entry<RedisConnection, RFuture<String>> entry : result.entrySet()) {
entry.getKey().closeAsync();
}
return false;
}
time = System.currentTimeMillis();
boolean res = true;
for (Entry<RedisConnection, RFuture<String>> entry : result.entrySet()) {
RFuture<String> f = entry.getValue();
f.awaitUninterruptibly();
if (!"PONG".equals(f.getNow())) {
res = false;
}
entry.getKey().closeAsync();
}
// true and no futures missed during client connection
return res && result.size() == clients.size();
}
use of org.redisson.misc.RPromise in project redisson by redisson.
the class BaseTransactionalMap method fastRemoveOperationAsync.
@SuppressWarnings("unchecked")
protected RFuture<Long> fastRemoveOperationAsync(K... keys) {
RPromise<Long> result = new RedissonPromise<Long>();
long threadId = Thread.currentThread().getId();
executeLocked(result, new Runnable() {
@Override
public void run() {
AtomicLong counter = new AtomicLong();
List<K> keyList = Arrays.asList(keys);
for (Iterator<K> iterator = keyList.iterator(); iterator.hasNext(); ) {
K key = iterator.next();
HashValue keyHash = toKeyHash(key);
MapEntry currentValue = state.get(keyHash);
if (currentValue != null && currentValue != MapEntry.NULL) {
operations.add(new MapFastRemoveOperation(map, key, transactionId, threadId));
state.put(keyHash, MapEntry.NULL);
counter.incrementAndGet();
iterator.remove();
}
}
// TODO optimize
map.getAllAsync(new HashSet<K>(keyList)).onComplete((res, e) -> {
if (e != null) {
result.tryFailure(e);
return;
}
for (K key : res.keySet()) {
HashValue keyHash = toKeyHash(key);
operations.add(new MapFastRemoveOperation(map, key, transactionId, threadId));
counter.incrementAndGet();
state.put(keyHash, MapEntry.NULL);
}
result.trySuccess(counter.get());
});
}
}, Arrays.asList(keys));
return result;
}
use of org.redisson.misc.RPromise in project redisson by redisson.
the class CommandAsyncService method async.
protected <V, R> void async(final boolean readOnlyMode, final NodeSource source, final Codec codec, final RedisCommand<V> command, final Object[] params, final RPromise<R> mainPromise, final int attempt) {
if (mainPromise.isCancelled()) {
return;
}
if (!connectionManager.getShutdownLatch().acquire()) {
mainPromise.tryFailure(new RedissonShutdownException("Redisson is shutdown"));
return;
}
final AsyncDetails<V, R> details = AsyncDetails.acquire();
if (isRedissonReferenceSupportEnabled()) {
try {
for (int i = 0; i < params.length; i++) {
RedissonReference reference = redisson != null ? RedissonObjectFactory.toReference(redisson, params[i]) : RedissonObjectFactory.toReference(redissonReactive, params[i]);
params[i] = reference == null ? params[i] : reference;
}
} catch (Exception e) {
connectionManager.getShutdownLatch().release();
mainPromise.tryFailure(e);
return;
}
}
final RFuture<RedisConnection> connectionFuture;
if (readOnlyMode) {
connectionFuture = connectionManager.connectionReadOp(source, command);
} else {
connectionFuture = connectionManager.connectionWriteOp(source, command);
}
final RPromise<R> attemptPromise = connectionManager.newPromise();
details.init(connectionFuture, attemptPromise, readOnlyMode, source, codec, command, params, mainPromise, attempt);
final TimerTask retryTimerTask = new TimerTask() {
@Override
public void run(Timeout t) throws Exception {
if (details.getAttemptPromise().isDone()) {
return;
}
if (details.getConnectionFuture().cancel(false)) {
connectionManager.getShutdownLatch().release();
} else {
if (details.getConnectionFuture().isSuccess()) {
ChannelFuture writeFuture = details.getWriteFuture();
if (writeFuture != null && !writeFuture.cancel(false) && writeFuture.isSuccess()) {
return;
}
}
}
if (details.getMainPromise().isCancelled()) {
if (details.getAttemptPromise().cancel(false)) {
AsyncDetails.release(details);
}
return;
}
if (details.getAttempt() == connectionManager.getConfig().getRetryAttempts()) {
if (details.getException() == null) {
details.setException(new RedisTimeoutException("Command execution timeout for command: " + command + " with params: " + LogHelper.toString(details.getParams())));
}
details.getAttemptPromise().tryFailure(details.getException());
return;
}
if (!details.getAttemptPromise().cancel(false)) {
return;
}
int count = details.getAttempt() + 1;
if (log.isDebugEnabled()) {
log.debug("attempt {} for command {} and params {}", count, details.getCommand(), Arrays.toString(details.getParams()));
}
async(details.isReadOnlyMode(), details.getSource(), details.getCodec(), details.getCommand(), details.getParams(), details.getMainPromise(), count);
AsyncDetails.release(details);
}
};
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 {
if (connFuture.isCancelled()) {
return;
}
if (!connFuture.isSuccess()) {
connectionManager.getShutdownLatch().release();
details.setException(convertException(connectionFuture));
return;
}
if (details.getAttemptPromise().isDone() || details.getMainPromise().isDone()) {
releaseConnection(source, connectionFuture, details.isReadOnlyMode(), details.getAttemptPromise(), details);
return;
}
final RedisConnection connection = connFuture.getNow();
if (details.getSource().getRedirect() == Redirect.ASK) {
List<CommandData<?, ?>> list = new ArrayList<CommandData<?, ?>>(2);
RPromise<Void> promise = connectionManager.newPromise();
list.add(new CommandData<Void, Void>(promise, details.getCodec(), RedisCommands.ASKING, new Object[] {}));
list.add(new CommandData<V, R>(details.getAttemptPromise(), details.getCodec(), details.getCommand(), details.getParams()));
RPromise<Void> main = connectionManager.newPromise();
ChannelFuture future = connection.send(new CommandsData(main, list));
details.setWriteFuture(future);
} else {
if (log.isDebugEnabled()) {
log.debug("aquired connection for command {} and params {} from slot {} using node {}", details.getCommand(), Arrays.toString(details.getParams()), details.getSource(), connection.getRedisClient().getAddr());
}
ChannelFuture future = connection.send(new CommandData<V, R>(details.getAttemptPromise(), details.getCodec(), details.getCommand(), details.getParams()));
details.setWriteFuture(future);
}
details.getWriteFuture().addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
checkWriteFuture(details, connection);
}
});
releaseConnection(source, connectionFuture, details.isReadOnlyMode(), details.getAttemptPromise(), details);
}
});
attemptPromise.addListener(new FutureListener<R>() {
@Override
public void operationComplete(Future<R> future) throws Exception {
checkAttemptFuture(source, details, future);
}
});
}
use of org.redisson.misc.RPromise in project redisson by redisson.
the class ClusterConnectionManager method connect.
private RFuture<RedisConnection> connect(ClusterServersConfig cfg, final URL addr) {
RedisConnection connection = nodeConnections.get(addr);
if (connection != null) {
return newSucceededFuture(connection);
}
RedisClient client = createClient(addr.getHost(), addr.getPort(), cfg.getConnectTimeout(), cfg.getRetryInterval() * cfg.getRetryAttempts());
final RPromise<RedisConnection> result = newPromise();
RFuture<RedisConnection> future = client.connectAsync();
future.addListener(new FutureListener<RedisConnection>() {
@Override
public void operationComplete(Future<RedisConnection> future) throws Exception {
if (!future.isSuccess()) {
result.tryFailure(future.cause());
return;
}
RedisConnection connection = future.getNow();
RPromise<RedisConnection> promise = newPromise();
connectListener.onConnect(promise, connection, null, config);
promise.addListener(new FutureListener<RedisConnection>() {
@Override
public void operationComplete(Future<RedisConnection> future) throws Exception {
if (!future.isSuccess()) {
result.tryFailure(future.cause());
return;
}
RedisConnection connection = future.getNow();
if (connection.isActive()) {
nodeConnections.put(addr, connection);
result.trySuccess(connection);
} else {
connection.closeAsync();
result.tryFailure(new RedisException("Connection to " + connection.getRedisClient().getAddr() + " is not active!"));
}
}
});
}
});
return result;
}
use of org.redisson.misc.RPromise in project redisson by redisson.
the class ReplicatedConnectionManager method connect.
private RFuture<RedisConnection> connect(BaseMasterSlaveServersConfig<?> cfg, final URL addr) {
RedisConnection connection = nodeConnections.get(addr);
if (connection != null) {
return newSucceededFuture(connection);
}
RedisClient client = createClient(addr.getHost(), addr.getPort(), cfg.getConnectTimeout(), cfg.getRetryInterval() * cfg.getRetryAttempts());
final RPromise<RedisConnection> result = newPromise();
RFuture<RedisConnection> future = client.connectAsync();
future.addListener(new FutureListener<RedisConnection>() {
@Override
public void operationComplete(Future<RedisConnection> future) throws Exception {
if (!future.isSuccess()) {
result.tryFailure(future.cause());
return;
}
RedisConnection connection = future.getNow();
RPromise<RedisConnection> promise = newPromise();
connectListener.onConnect(promise, connection, null, config);
promise.addListener(new FutureListener<RedisConnection>() {
@Override
public void operationComplete(Future<RedisConnection> future) throws Exception {
if (!future.isSuccess()) {
result.tryFailure(future.cause());
return;
}
RedisConnection connection = future.getNow();
if (connection.isActive()) {
nodeConnections.put(addr, connection);
result.trySuccess(connection);
} else {
connection.closeAsync();
result.tryFailure(new RedisException("Connection to " + connection.getRedisClient().getAddr() + " is not active!"));
}
}
});
}
});
return result;
}
Aggregations