Search in sources :

Example 1 with MasterSlaveEntry

use of org.redisson.connection.MasterSlaveEntry 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;
}
Also used : FutureListener(io.netty.util.concurrent.FutureListener) ChannelFutureListener(io.netty.channel.ChannelFutureListener) ArrayList(java.util.ArrayList) NodeSource(org.redisson.connection.NodeSource) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) MasterSlaveEntry(org.redisson.connection.MasterSlaveEntry) RFuture(org.redisson.api.RFuture) ChannelFuture(io.netty.channel.ChannelFuture) Future(io.netty.util.concurrent.Future)

Example 2 with MasterSlaveEntry

use of org.redisson.connection.MasterSlaveEntry in project redisson by redisson.

the class ClusterConnectionManager method addMasterEntry.

private RFuture<Collection<RFuture<Void>>> addMasterEntry(final ClusterPartition partition, final ClusterServersConfig cfg) {
    if (partition.isMasterFail()) {
        RedisException e = new RedisException("Failed to add master: " + partition.getMasterAddress() + " for slot ranges: " + partition.getSlotRanges() + ". Reason - server has FAIL flag");
        if (partition.getSlotRanges().isEmpty()) {
            e = new RedisException("Failed to add master: " + partition.getMasterAddress() + ". Reason - server has FAIL flag");
        }
        return newFailedFuture(e);
    }
    final RPromise<Collection<RFuture<Void>>> result = newPromise();
    RFuture<RedisConnection> connectionFuture = connect(cfg, partition.getMasterAddress());
    connectionFuture.addListener(new FutureListener<RedisConnection>() {

        @Override
        public void operationComplete(Future<RedisConnection> future) throws Exception {
            if (!future.isSuccess()) {
                log.error("Can't connect to master: {} with slot ranges: {}", partition.getMasterAddress(), partition.getSlotRanges());
                result.tryFailure(future.cause());
                return;
            }
            final RedisConnection connection = future.getNow();
            RFuture<Map<String, String>> clusterFuture = connection.async(RedisCommands.CLUSTER_INFO);
            clusterFuture.addListener(new FutureListener<Map<String, String>>() {

                @Override
                public void operationComplete(Future<Map<String, String>> future) throws Exception {
                    if (!future.isSuccess()) {
                        log.error("Can't execute CLUSTER_INFO for " + connection.getRedisClient().getAddr(), future.cause());
                        result.tryFailure(future.cause());
                        return;
                    }
                    Map<String, String> params = future.getNow();
                    if ("fail".equals(params.get("cluster_state"))) {
                        RedisException e = new RedisException("Failed to add master: " + partition.getMasterAddress() + " for slot ranges: " + partition.getSlotRanges() + ". Reason - cluster_state:fail");
                        log.error("cluster_state:fail for " + connection.getRedisClient().getAddr());
                        result.tryFailure(e);
                        return;
                    }
                    MasterSlaveServersConfig config = create(cfg);
                    config.setMasterAddress(partition.getMasterAddress());
                    final MasterSlaveEntry e;
                    List<RFuture<Void>> futures = new ArrayList<RFuture<Void>>();
                    if (config.getReadMode() == ReadMode.MASTER) {
                        e = new SingleEntry(partition.getSlotRanges(), ClusterConnectionManager.this, config);
                    } else {
                        config.setSlaveAddresses(partition.getSlaveAddresses());
                        e = new MasterSlaveEntry(partition.getSlotRanges(), ClusterConnectionManager.this, config);
                        List<RFuture<Void>> fs = e.initSlaveBalancer(partition.getFailedSlaveAddresses());
                        futures.addAll(fs);
                        if (!partition.getSlaveAddresses().isEmpty()) {
                            log.info("slaves: {} added for slot ranges: {}", partition.getSlaveAddresses(), partition.getSlotRanges());
                            if (!partition.getFailedSlaveAddresses().isEmpty()) {
                                log.warn("slaves: {} is down for slot ranges: {}", partition.getFailedSlaveAddresses(), partition.getSlotRanges());
                            }
                        }
                    }
                    RFuture<Void> f = e.setupMasterEntry(config.getMasterAddress().getHost(), config.getMasterAddress().getPort());
                    final RPromise<Void> initFuture = newPromise();
                    futures.add(initFuture);
                    f.addListener(new FutureListener<Void>() {

                        @Override
                        public void operationComplete(Future<Void> future) throws Exception {
                            if (!future.isSuccess()) {
                                log.error("Can't add master: {} for slot ranges: {}", partition.getMasterAddress(), partition.getSlotRanges());
                                initFuture.tryFailure(future.cause());
                                return;
                            }
                            for (Integer slot : partition.getSlots()) {
                                addEntry(slot, e);
                                lastPartitions.put(slot, partition);
                            }
                            log.info("master: {} added for slot ranges: {}", partition.getMasterAddress(), partition.getSlotRanges());
                            if (!initFuture.trySuccess(null)) {
                                throw new IllegalStateException();
                            }
                        }
                    });
                    if (!result.trySuccess(futures)) {
                        throw new IllegalStateException();
                    }
                }
            });
        }
    });
    return result;
}
Also used : ArrayList(java.util.ArrayList) MasterSlaveEntry(org.redisson.connection.MasterSlaveEntry) RedisException(org.redisson.client.RedisException) FutureListener(io.netty.util.concurrent.FutureListener) SingleEntry(org.redisson.connection.SingleEntry) MasterSlaveServersConfig(org.redisson.config.MasterSlaveServersConfig) RFuture(org.redisson.api.RFuture) RedisException(org.redisson.client.RedisException) RedisConnectionException(org.redisson.client.RedisConnectionException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Collection(java.util.Collection) ScheduledFuture(io.netty.util.concurrent.ScheduledFuture) RFuture(org.redisson.api.RFuture) Future(io.netty.util.concurrent.Future) RedisConnection(org.redisson.client.RedisConnection)

Example 3 with MasterSlaveEntry

use of org.redisson.connection.MasterSlaveEntry in project redisson by redisson.

the class ClusterConnectionManager method checkSlaveNodesChange.

private void checkSlaveNodesChange(Collection<ClusterPartition> newPartitions) {
    for (ClusterPartition newPart : newPartitions) {
        for (ClusterPartition currentPart : getLastPartitions()) {
            if (!newPart.getMasterAddress().equals(currentPart.getMasterAddress())) {
                continue;
            }
            MasterSlaveEntry entry = getEntry(currentPart.getMasterAddr());
            // should be invoked first in order to remove stale failedSlaveAddresses
            Set<URL> addedSlaves = addRemoveSlaves(entry, currentPart, newPart);
            // Do some slaves have changed state from failed to alive?
            upDownSlaves(entry, currentPart, newPart, addedSlaves);
            break;
        }
    }
}
Also used : MasterSlaveEntry(org.redisson.connection.MasterSlaveEntry) URL(java.net.URL)

Example 4 with MasterSlaveEntry

use of org.redisson.connection.MasterSlaveEntry in project redisson by redisson.

the class ClusterConnectionManager method checkSlotsChange.

private void checkSlotsChange(ClusterServersConfig cfg, Collection<ClusterPartition> newPartitions, String nodes) {
    Collection<Integer> newPartitionsSlots = slots(newPartitions);
    if (newPartitionsSlots.size() == lastPartitions.size() && lastPartitions.size() == MAX_SLOT) {
        return;
    }
    Set<Integer> removedSlots = new HashSet<Integer>(lastPartitions.keySet());
    removedSlots.removeAll(newPartitionsSlots);
    lastPartitions.keySet().removeAll(removedSlots);
    if (!removedSlots.isEmpty()) {
        log.info("{} slots found to remove", removedSlots.size());
    }
    for (Integer slot : removedSlots) {
        MasterSlaveEntry entry = removeMaster(slot);
        entry.removeSlotRange(slot);
        if (entry.getSlotRanges().isEmpty()) {
            entry.shutdownMasterAsync();
            log.info("{} master and slaves for it removed", entry.getClient().getAddr());
        }
    }
    Set<Integer> addedSlots = new HashSet<Integer>(newPartitionsSlots);
    addedSlots.removeAll(lastPartitions.keySet());
    if (!addedSlots.isEmpty()) {
        log.info("{} slots found to add", addedSlots.size());
    }
    for (final Integer slot : addedSlots) {
        ClusterPartition partition = find(newPartitions, slot);
        for (MasterSlaveEntry entry : getEntrySet()) {
            if (entry.getClient().getAddr().equals(partition.getMasterAddr())) {
                addEntry(slot, entry);
                lastPartitions.put(slot, partition);
                break;
            }
        }
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) MasterSlaveEntry(org.redisson.connection.MasterSlaveEntry) HashSet(java.util.HashSet)

Example 5 with MasterSlaveEntry

use of org.redisson.connection.MasterSlaveEntry in project redisson by redisson.

the class RedissonKeys method deleteByPatternAsync.

@Override
public RFuture<Long> deleteByPatternAsync(String pattern) {
    if (!commandExecutor.getConnectionManager().isClusterMode()) {
        return commandExecutor.evalWriteAsync((String) null, null, RedisCommands.EVAL_LONG, "local keys = redis.call('keys', ARGV[1]) " + "local n = 0 " + "for i=1, #keys,5000 do " + "n = n + redis.call('del', unpack(keys, i, math.min(i+4999, table.getn(keys)))) " + "end " + "return n;", Collections.emptyList(), pattern);
    }
    final RPromise<Long> result = commandExecutor.getConnectionManager().newPromise();
    final AtomicReference<Throwable> failed = new AtomicReference<Throwable>();
    final AtomicLong count = new AtomicLong();
    Set<MasterSlaveEntry> entries = commandExecutor.getConnectionManager().getEntrySet();
    final AtomicLong executed = new AtomicLong(entries.size());
    final FutureListener<Long> listener = new FutureListener<Long>() {

        @Override
        public void operationComplete(Future<Long> future) throws Exception {
            if (future.isSuccess()) {
                count.addAndGet(future.getNow());
            } else {
                failed.set(future.cause());
            }
            checkExecution(result, failed, count, executed);
        }
    };
    for (MasterSlaveEntry entry : entries) {
        RFuture<Collection<String>> findFuture = commandExecutor.readAsync(entry, null, RedisCommands.KEYS, pattern);
        findFuture.addListener(new FutureListener<Collection<String>>() {

            @Override
            public void operationComplete(Future<Collection<String>> future) throws Exception {
                if (!future.isSuccess()) {
                    failed.set(future.cause());
                    checkExecution(result, failed, count, executed);
                    return;
                }
                Collection<String> keys = future.getNow();
                if (keys.isEmpty()) {
                    checkExecution(result, failed, count, executed);
                    return;
                }
                RFuture<Long> deleteFuture = deleteAsync(keys.toArray(new String[keys.size()]));
                deleteFuture.addListener(listener);
            }
        });
    }
    return result;
}
Also used : FutureListener(io.netty.util.concurrent.FutureListener) AtomicReference(java.util.concurrent.atomic.AtomicReference) RFuture(org.redisson.api.RFuture) RedisException(org.redisson.client.RedisException) AtomicLong(java.util.concurrent.atomic.AtomicLong) MasterSlaveEntry(org.redisson.connection.MasterSlaveEntry) AtomicLong(java.util.concurrent.atomic.AtomicLong) RFuture(org.redisson.api.RFuture) Future(io.netty.util.concurrent.Future) Collection(java.util.Collection)

Aggregations

MasterSlaveEntry (org.redisson.connection.MasterSlaveEntry)15 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)8 NodeSource (org.redisson.connection.NodeSource)7 Future (io.netty.util.concurrent.Future)6 FutureListener (io.netty.util.concurrent.FutureListener)6 ArrayList (java.util.ArrayList)6 RFuture (org.redisson.api.RFuture)6 ChannelFuture (io.netty.channel.ChannelFuture)3 ChannelFutureListener (io.netty.channel.ChannelFutureListener)3 Collection (java.util.Collection)3 RedisAskException (org.redisson.client.RedisAskException)3 RedisException (org.redisson.client.RedisException)3 RedisLoadingException (org.redisson.client.RedisLoadingException)3 RedisMovedException (org.redisson.client.RedisMovedException)3 RedisTimeoutException (org.redisson.client.RedisTimeoutException)3 RedisTryAgainException (org.redisson.client.RedisTryAgainException)3 WriteRedisConnectionException (org.redisson.client.WriteRedisConnectionException)3 HashSet (java.util.HashSet)2 List (java.util.List)2 ConcurrentMap (java.util.concurrent.ConcurrentMap)2