use of org.redisson.api.RFuture in project redisson by redisson.
the class RedissonPermitExpirableSemaphore method tryAcquireAsync.
private RFuture<String> tryAcquireAsync(final int permits, long waitTime, final long ttl, final TimeUnit timeUnit) {
final RPromise<String> result = newPromise();
final AtomicLong time = new AtomicLong(timeUnit.toMillis(waitTime));
final long current = System.currentTimeMillis();
long timeoutDate = calcTimeout(ttl, timeUnit);
RFuture<String> tryAcquireFuture = tryAcquireAsync(permits, timeoutDate);
tryAcquireFuture.addListener(new FutureListener<String>() {
@Override
public void operationComplete(Future<String> future) throws Exception {
if (!future.isSuccess()) {
result.tryFailure(future.cause());
return;
}
String permitId = future.getNow();
if (permitId != null && !permitId.startsWith(":")) {
if (!result.trySuccess(permitId)) {
releaseAsync(permitId);
}
return;
}
long elapsed = System.currentTimeMillis() - current;
time.addAndGet(-elapsed);
if (time.get() <= 0) {
result.trySuccess(null);
return;
}
final long current = System.currentTimeMillis();
final AtomicReference<Timeout> futureRef = new AtomicReference<Timeout>();
final RFuture<RedissonLockEntry> subscribeFuture = subscribe();
subscribeFuture.addListener(new FutureListener<RedissonLockEntry>() {
@Override
public void operationComplete(Future<RedissonLockEntry> future) throws Exception {
if (!future.isSuccess()) {
result.tryFailure(future.cause());
return;
}
if (futureRef.get() != null) {
futureRef.get().cancel();
}
long elapsed = System.currentTimeMillis() - current;
time.addAndGet(-elapsed);
tryAcquireAsync(time, permits, subscribeFuture, result, ttl, timeUnit);
}
});
if (!subscribeFuture.isDone()) {
Timeout scheduledFuture = commandExecutor.getConnectionManager().newTimeout(new TimerTask() {
@Override
public void run(Timeout timeout) throws Exception {
if (!subscribeFuture.isDone()) {
result.trySuccess(null);
}
}
}, time.get(), TimeUnit.MILLISECONDS);
futureRef.set(scheduledFuture);
}
}
});
return result;
}
use of org.redisson.api.RFuture 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.api.RFuture in project redisson by redisson.
the class ClusterConnectionManager method checkMasterNodesChange.
private RFuture<Void> checkMasterNodesChange(ClusterServersConfig cfg, Collection<ClusterPartition> newPartitions) {
List<ClusterPartition> newMasters = new ArrayList<ClusterPartition>();
for (final ClusterPartition newPart : newPartitions) {
boolean masterFound = false;
for (ClusterPartition currentPart : getLastPartitions()) {
if (!newPart.getMasterAddress().equals(currentPart.getMasterAddress())) {
continue;
}
masterFound = true;
// current master marked as failed
if (!newPart.isMasterFail()) {
continue;
}
for (Integer slot : currentPart.getSlots()) {
ClusterPartition newMasterPart = find(newPartitions, slot);
// does partition has a new master?
if (!newMasterPart.getMasterAddress().equals(currentPart.getMasterAddress())) {
log.info("changing master from {} to {} for {}", currentPart.getMasterAddress(), newMasterPart.getMasterAddress(), slot);
URL newUri = newMasterPart.getMasterAddress();
URL oldUri = currentPart.getMasterAddress();
changeMaster(slot, newUri.getHost(), newUri.getPort());
currentPart.setMasterAddress(newMasterPart.getMasterAddress());
}
}
break;
}
if (!masterFound && !newPart.getSlotRanges().isEmpty()) {
newMasters.add(newPart);
}
}
if (newMasters.isEmpty()) {
return newSucceededFuture(null);
}
final RPromise<Void> result = newPromise();
final AtomicInteger masters = new AtomicInteger(newMasters.size());
final Queue<RFuture<Void>> futures = new ConcurrentLinkedQueue<RFuture<Void>>();
for (ClusterPartition newPart : newMasters) {
RFuture<Collection<RFuture<Void>>> future = addMasterEntry(newPart, cfg);
future.addListener(new FutureListener<Collection<RFuture<Void>>>() {
@Override
public void operationComplete(Future<Collection<RFuture<Void>>> future) throws Exception {
if (future.isSuccess()) {
futures.addAll(future.getNow());
}
if (masters.decrementAndGet() == 0) {
final AtomicInteger nodes = new AtomicInteger(futures.size());
for (RFuture<Void> nodeFuture : futures) {
nodeFuture.addListener(new FutureListener<Void>() {
@Override
public void operationComplete(Future<Void> future) throws Exception {
if (nodes.decrementAndGet() == 0) {
result.trySuccess(null);
}
}
});
}
}
}
});
}
return result;
}
use of org.redisson.api.RFuture in project redisson by redisson.
the class LoadBalancerManager method add.
public RFuture<Void> add(final ClientConnectionsEntry entry) {
final RPromise<Void> result = connectionManager.newPromise();
FutureListener<Void> listener = new FutureListener<Void>() {
AtomicInteger counter = new AtomicInteger(2);
@Override
public void operationComplete(Future<Void> future) throws Exception {
if (!future.isSuccess()) {
result.tryFailure(future.cause());
return;
}
if (counter.decrementAndGet() == 0) {
addr2Entry.put(entry.getClient().getAddr(), entry);
result.trySuccess(null);
}
}
};
RFuture<Void> slaveFuture = slaveConnectionPool.add(entry);
slaveFuture.addListener(listener);
RFuture<Void> pubSubFuture = pubSubConnectionPool.add(entry);
pubSubFuture.addListener(listener);
return result;
}
use of org.redisson.api.RFuture in project redisson by redisson.
the class CommandAsyncService method readAllAsync.
@Override
public <T, R> RFuture<Collection<R>> readAllAsync(RedisCommand<T> command, Object... params) {
final RPromise<Collection<R>> mainPromise = connectionManager.newPromise();
final Set<MasterSlaveEntry> nodes = connectionManager.getEntrySet();
final List<R> results = new ArrayList<R>();
final AtomicInteger counter = new AtomicInteger(nodes.size());
FutureListener<R> listener = new FutureListener<R>() {
@Override
public void operationComplete(Future<R> future) throws Exception {
if (!future.isSuccess()) {
mainPromise.tryFailure(future.cause());
return;
}
R result = future.getNow();
if (result instanceof Collection) {
synchronized (results) {
results.addAll((Collection) result);
}
} else {
synchronized (results) {
results.add(result);
}
}
if (counter.decrementAndGet() == 0 && !mainPromise.isDone()) {
mainPromise.trySuccess(results);
}
}
};
for (MasterSlaveEntry entry : nodes) {
RPromise<R> promise = connectionManager.newPromise();
promise.addListener(listener);
async(true, new NodeSource(entry), connectionManager.getCodec(), command, params, promise, 0);
}
return mainPromise;
}
Aggregations