use of org.redisson.misc.AsyncCountDownLatch in project redisson by redisson.
the class RedissonTransaction method disableLocalCacheAsync.
private CompletableFuture<Map<HashKey, HashValue>> disableLocalCacheAsync(String requestId, Set<String> localCaches, List<TransactionalOperation> operations) {
if (localCaches.isEmpty()) {
return CompletableFuture.completedFuture(Collections.emptyMap());
}
CompletableFuture<Map<HashKey, HashValue>> result = new CompletableFuture<>();
Map<HashKey, HashValue> hashes = new HashMap<>(localCaches.size());
RedissonBatch batch = createBatch();
for (TransactionalOperation transactionalOperation : operations) {
if (localCaches.contains(transactionalOperation.getName())) {
MapOperation mapOperation = (MapOperation) transactionalOperation;
RedissonLocalCachedMap<?, ?> map = (RedissonLocalCachedMap<?, ?>) mapOperation.getMap();
HashKey hashKey = new HashKey(transactionalOperation.getName(), transactionalOperation.getCodec());
byte[] key = map.getLocalCacheView().toCacheKey(mapOperation.getKey()).getKeyHash();
HashValue value = hashes.get(hashKey);
if (value == null) {
value = new HashValue();
hashes.put(hashKey, value);
}
value.getKeyIds().add(key);
String disabledKeysName = RedissonObject.suffixName(transactionalOperation.getName(), RedissonLocalCachedMap.DISABLED_KEYS_SUFFIX);
RMultimapCacheAsync<LocalCachedMapDisabledKey, String> multimap = batch.getListMultimapCache(disabledKeysName, transactionalOperation.getCodec());
LocalCachedMapDisabledKey localCacheKey = new LocalCachedMapDisabledKey(requestId, options.getResponseTimeout());
multimap.putAsync(localCacheKey, ByteBufUtil.hexDump(key));
multimap.expireKeyAsync(localCacheKey, options.getResponseTimeout(), TimeUnit.MILLISECONDS);
}
}
RFuture<BatchResult<?>> batchListener = batch.executeAsync();
batchListener.onComplete((res, e) -> {
if (e != null) {
result.completeExceptionally(e);
return;
}
AsyncCountDownLatch latch = new AsyncCountDownLatch();
latch.latch(() -> {
result.complete(hashes);
}, hashes.size());
List<CompletableFuture<?>> subscriptionFutures = new ArrayList<>();
List<RTopic> topics = new ArrayList<>();
for (Entry<HashKey, HashValue> entry : hashes.entrySet()) {
String disabledAckName = RedissonObject.suffixName(entry.getKey().getName(), requestId + RedissonLocalCachedMap.DISABLED_ACK_SUFFIX);
RTopic topic = RedissonTopic.createRaw(LocalCachedMessageCodec.INSTANCE, commandExecutor, disabledAckName);
topics.add(topic);
RFuture<Integer> topicFuture = topic.addListenerAsync(Object.class, (channel, msg) -> {
AtomicInteger counter = entry.getValue().getCounter();
if (counter.decrementAndGet() == 0) {
latch.countDown();
}
});
subscriptionFutures.add(topicFuture.toCompletableFuture());
}
CompletableFuture<Void> subscriptionFuture = CompletableFuture.allOf(subscriptionFutures.toArray(new CompletableFuture[0]));
subscriptionFuture.whenComplete((r, ex) -> {
RedissonBatch publishBatch = createBatch();
for (Entry<HashKey, HashValue> entry : hashes.entrySet()) {
String disabledKeysName = RedissonObject.suffixName(entry.getKey().getName(), RedissonLocalCachedMap.DISABLED_KEYS_SUFFIX);
RMultimapCacheAsync<LocalCachedMapDisabledKey, String> multimap = publishBatch.getListMultimapCache(disabledKeysName, entry.getKey().getCodec());
LocalCachedMapDisabledKey localCacheKey = new LocalCachedMapDisabledKey(requestId, options.getResponseTimeout());
multimap.removeAllAsync(localCacheKey);
RTopicAsync topic = publishBatch.getTopic(RedissonObject.suffixName(entry.getKey().getName(), RedissonLocalCachedMap.TOPIC_SUFFIX), LocalCachedMessageCodec.INSTANCE);
RFuture<Long> publishFuture = topic.publishAsync(new LocalCachedMapDisable(requestId, entry.getValue().getKeyIds().toArray(new byte[entry.getValue().getKeyIds().size()][]), options.getResponseTimeout()));
publishFuture.onComplete((receivers, exc) -> {
if (ex != null) {
return;
}
AtomicInteger counter = entry.getValue().getCounter();
if (counter.addAndGet(receivers.intValue()) == 0) {
latch.countDown();
}
});
}
RFuture<BatchResult<?>> publishFuture = publishBatch.executeAsync();
publishFuture.onComplete((res2, ex2) -> {
result.whenComplete((res3, ex3) -> {
for (RTopic topic : topics) {
topic.removeAllListeners();
}
});
if (ex2 != null) {
result.completeExceptionally(ex2);
return;
}
commandExecutor.getConnectionManager().newTimeout(new TimerTask() {
@Override
public void run(Timeout timeout) throws Exception {
result.completeExceptionally(new TransactionTimeoutException("Unable to execute transaction within " + options.getResponseTimeout() + "ms"));
}
}, options.getResponseTimeout(), TimeUnit.MILLISECONDS);
});
});
});
return result;
}
use of org.redisson.misc.AsyncCountDownLatch in project redisson by redisson.
the class ReplicatedConnectionManager method checkNode.
private void checkNode(AsyncCountDownLatch latch, RedisURI uri, ReplicatedServersConfig cfg, Set<InetSocketAddress> slaveIPs) {
CompletionStage<RedisConnection> connectionFuture = connectToNode(cfg, uri, uri.getHost());
connectionFuture.whenComplete((connection, exc) -> {
if (exc != null) {
log.error(exc.getMessage(), exc);
latch.countDown();
return;
}
if (isShuttingDown()) {
return;
}
RFuture<Map<String, String>> result = connection.async(RedisCommands.INFO_REPLICATION);
result.whenComplete((r, ex) -> {
if (ex != null) {
log.error(ex.getMessage(), ex);
closeNodeConnection(connection);
latch.countDown();
return;
}
InetSocketAddress addr = connection.getRedisClient().getAddr();
Role role = Role.valueOf(r.get(ROLE_KEY));
if (Role.master.equals(role)) {
InetSocketAddress master = currentMaster.get();
if (master.equals(addr)) {
log.debug("Current master {} unchanged", master);
} else if (currentMaster.compareAndSet(master, addr)) {
CompletableFuture<RedisClient> changeFuture = changeMaster(singleSlotRange.getStartSlot(), uri);
changeFuture.exceptionally(e -> {
log.error("Unable to change master to " + addr, e);
currentMaster.compareAndSet(addr, master);
return null;
});
}
latch.countDown();
} else if (!config.checkSkipSlavesInit()) {
CompletableFuture<Void> f = slaveUp(addr, uri);
slaveIPs.add(addr);
f.whenComplete((res, e) -> {
latch.countDown();
});
}
});
});
}
use of org.redisson.misc.AsyncCountDownLatch in project redisson by redisson.
the class DNSMonitor method monitorDnsChange.
private void monitorDnsChange() {
dnsMonitorFuture = connectionManager.getGroup().schedule(new Runnable() {
@Override
public void run() {
if (connectionManager.isShuttingDown()) {
return;
}
AsyncCountDownLatch latch = new AsyncCountDownLatch();
latch.latch(() -> {
monitorDnsChange();
}, masters.size() + slaves.size());
monitorMasters(latch);
monitorSlaves(latch);
}
}, dnsMonitoringInterval, TimeUnit.MILLISECONDS);
}
Aggregations