Example usage for io.netty.util.concurrent Future addListener

List of usage examples for io.netty.util.concurrent Future addListener

Introduction

In this page you can find the example usage for io.netty.util.concurrent Future addListener.

Prototype

Future<V> addListener(GenericFutureListener<? extends Future<? super V>> listener);

Source Link

Document

Adds the specified listener to this future.

Usage

From source file:org.redisson.connection.DNSMonitor.java

License:Apache License

private void monitorSlaves(AtomicInteger counter) {
    for (Entry<RedisURI, InetSocketAddress> entry : slaves.entrySet()) {
        Future<InetSocketAddress> resolveFuture = resolver.resolve(
                InetSocketAddress.createUnresolved(entry.getKey().getHost(), entry.getKey().getPort()));
        resolveFuture.addListener(new FutureListener<InetSocketAddress>() {
            @Override//from ww w .ja va 2s. com
            public void operationComplete(Future<InetSocketAddress> future) throws Exception {
                if (counter.decrementAndGet() == 0) {
                    monitorDnsChange();
                }

                if (!future.isSuccess()) {
                    log.error("Unable to resolve " + entry.getKey().getHost(), future.cause());
                    return;
                }

                InetSocketAddress currentSlaveAddr = entry.getValue();
                InetSocketAddress newSlaveAddr = future.getNow();
                if (!newSlaveAddr.getAddress().equals(currentSlaveAddr.getAddress())) {
                    log.info("Detected DNS change. Slave {} has changed ip from {} to {}",
                            entry.getKey().getHost(), currentSlaveAddr.getAddress().getHostAddress(),
                            newSlaveAddr.getAddress().getHostAddress());
                    for (MasterSlaveEntry masterSlaveEntry : connectionManager.getEntrySet()) {
                        if (!masterSlaveEntry.hasSlave(currentSlaveAddr)) {
                            continue;
                        }

                        if (masterSlaveEntry.hasSlave(newSlaveAddr)) {
                            masterSlaveEntry.slaveUp(newSlaveAddr, FreezeReason.MANAGER);
                            masterSlaveEntry.slaveDown(currentSlaveAddr, FreezeReason.MANAGER);
                        } else {
                            RFuture<Void> addFuture = masterSlaveEntry.addSlave(newSlaveAddr, entry.getKey());
                            addFuture.onComplete((res, e) -> {
                                if (e != null) {
                                    log.error("Can't add slave: " + newSlaveAddr, e);
                                    return;
                                }

                                masterSlaveEntry.slaveDown(currentSlaveAddr, FreezeReason.MANAGER);
                            });
                        }
                        break;
                    }
                    slaves.put(entry.getKey(), newSlaveAddr);
                }
            }
        });
    }
}

From source file:org.redisson.connection.MasterSlaveConnectionManager.java

License:Apache License

@Override
public Future unsubscribe(String channelName) {
    final PubSubConnectionEntry entry = name2PubSubConnection.remove(channelName);
    if (entry == null) {
        return group.next().newSucceededFuture(null);
    }//from   w  ww .  jav a  2  s .c  o m

    Future future = entry.unsubscribe(channelName);
    future.addListener(new FutureListener() {
        @Override
        public void operationComplete(Future future) throws Exception {
            synchronized (entry) {
                if (entry.tryClose()) {
                    returnSubscribeConnection(-1, entry);
                }
            }
        }
    });
    return future;
}

From source file:org.redisson.connection.PubSubConnectionEntry.java

License:Apache License

public Future unsubscribe(final String channel) {
    Queue<RedisPubSubListener> listeners = channelListeners.get(channel);
    if (listeners != null) {
        for (RedisPubSubListener listener : listeners) {
            removeListener(channel, listener);
        }/*from   w w w . ja  va2  s .com*/
    }

    Future future = conn.unsubscribe(channel);
    future.addListener(new FutureListener() {
        @Override
        public void operationComplete(Future future) throws Exception {
            subscribedChannelsAmount.release();
        }
    });
    return future;
}

From source file:org.redisson.connection.SubscribesConnectionEntry.java

License:Apache License

public Future<RedisPubSubConnection> connectPubSub(MasterSlaveServersConfig config) {
    Future<RedisPubSubConnection> future = super.connectPubSub(config);
    future.addListener(new FutureListener<RedisPubSubConnection>() {
        @Override/*  w ww .j a v  a2  s . co m*/
        public void operationComplete(Future<RedisPubSubConnection> future) throws Exception {
            if (!future.isSuccess()) {
                return;
            }
            RedisPubSubConnection conn = future.getNow();
            allSubscribeConnections.add(conn);
        }
    });
    return future;
}

From source file:org.redisson.core.RedissonMultiLock.java

License:Apache License

private void lock(final Promise<Void> promise, final long waitTime, final long leaseTime, final TimeUnit unit)
        throws InterruptedException {
    final AtomicInteger tryLockRequestsAmount = new AtomicInteger();
    final Map<Future<Boolean>, RLock> tryLockFutures = new HashMap<Future<Boolean>, RLock>(locks.size());

    FutureListener<Boolean> listener = new FutureListener<Boolean>() {

        AtomicBoolean unlock = new AtomicBoolean();

        @Override//from  w  w w . j av  a2s.co m
        public void operationComplete(Future<Boolean> future) throws Exception {
            if (!future.isSuccess()) {
                // unlock once
                if (unlock.compareAndSet(false, true)) {
                    for (RLock lock : locks) {
                        lock.unlockAsync();
                    }

                    promise.setFailure(future.cause());
                }
                return;
            }

            Boolean res = future.getNow();
            // unlock once
            if (!res && unlock.compareAndSet(false, true)) {
                for (RLock lock : locks) {
                    lock.unlockAsync();
                }

                RLock lock = tryLockFutures.get(future);
                lock.lockAsync().addListener(new FutureListener<Void>() {
                    @Override
                    public void operationComplete(Future<Void> future) throws Exception {
                        if (!future.isSuccess()) {
                            promise.setFailure(future.cause());
                            return;
                        }

                        lock(promise, waitTime, leaseTime, unit);
                    }
                });
            }
            if (!unlock.get() && tryLockRequestsAmount.decrementAndGet() == 0) {
                promise.setSuccess(null);
            }
        }
    };

    for (RLock lock : locks) {
        if (lock.isHeldByCurrentThread()) {
            continue;
        }

        tryLockRequestsAmount.incrementAndGet();
        if (waitTime > 0 || leaseTime > 0) {
            tryLockFutures.put(lock.tryLockAsync(waitTime, leaseTime, unit), lock);
        } else {
            tryLockFutures.put(lock.tryLockAsync(), lock);
        }
    }

    for (Future<Boolean> future : tryLockFutures.keySet()) {
        future.addListener(listener);
    }
}

From source file:org.redisson.EvictionScheduler.java

License:Apache License

public void runCleanTask(final String name, String timeoutSetName, long currentDate) {

    final Long lastExpired = lastExpiredTime.get(name);
    long now = System.currentTimeMillis();
    if (lastExpired == null) {
        if (lastExpiredTime.putIfAbsent(name, now) != null) {
            return;
        }//  w ww .  ja v a2 s  .c  o m
    } else if (lastExpired + expireTaskExecutionDelay >= now) {
        if (!lastExpiredTime.replace(name, lastExpired, now)) {
            return;
        }
    } else {
        return;
    }

    Future<Integer> future = cleanupExpiredEntires(name, timeoutSetName, null, valuesAmountToClean);

    future.addListener(new FutureListener<Integer>() {
        @Override
        public void operationComplete(Future<Integer> future) throws Exception {
            executor.getConnectionManager().getGroup().schedule(new Runnable() {
                @Override
                public void run() {
                    lastExpiredTime.remove(name, lastExpired);
                }
            }, expireTaskExecutionDelay * 3, TimeUnit.SECONDS);

            if (!future.isSuccess()) {
                log.warn("Can't execute clean task for expired values. RSetCache name: " + name,
                        future.cause());
                return;
            }
        }
    });
}

From source file:org.redisson.misc.ConnectionPool.java

License:Apache License

private void initConnections(final ClientConnectionsEntry entry, final Promise<Void> initPromise,
        boolean checkFreezed) {
    int minimumIdleSize = getMinimumIdleSize(entry);

    if (minimumIdleSize == 0 || (checkFreezed && entry.isFreezed())) {
        initPromise.setSuccess(null);//from   w w w .ja va2  s. co m
        return;
    }

    final AtomicInteger initializedConnections = new AtomicInteger(minimumIdleSize);
    for (int i = 0; i < minimumIdleSize; i++) {
        if ((checkFreezed && entry.isFreezed()) || !tryAcquireConnection(entry)) {
            Throwable cause = new RedisConnectionException(
                    "Can't init enough connections amount! " + initializedConnections.get() + " from "
                            + minimumIdleSize + " was initialized. Server: " + entry.getClient().getAddr());
            initPromise.tryFailure(cause);
            return;
        }

        Future<T> promise = connectTo(entry);
        promise.addListener(new FutureListener<T>() {
            @Override
            public void operationComplete(Future<T> future) throws Exception {
                if (future.isSuccess()) {
                    T conn = future.getNow();
                    releaseConnection(entry, conn);
                }
                releaseConnection(entry);
                if (!future.isSuccess()) {
                    Throwable cause = new RedisConnectionException(
                            "Can't init enough connections amount! from " + entry.getClient().getAddr());
                    initPromise.tryFailure(cause);
                    return;
                }

                if (initializedConnections.decrementAndGet() == 0) {
                    initPromise.setSuccess(null);
                }
            }
        });
    }
}

From source file:org.redisson.misc.ConnectionPool.java

License:Apache License

private Future<T> connectTo(final ClientConnectionsEntry entry) {
    T conn = poll(entry);/*from   w  w  w .ja v a 2 s .c  o m*/
    if (conn != null) {
        if (!conn.isActive()) {
            return promiseFailure(entry, conn);
        }

        return promiseSuccessful(entry, conn);
    }

    final Promise<T> promise = connectionManager.newPromise();
    Future<T> connFuture = connect(entry);
    connFuture.addListener(new FutureListener<T>() {
        @Override
        public void operationComplete(Future<T> future) throws Exception {
            if (!future.isSuccess()) {
                releaseConnection(entry);

                promiseFailure(entry, promise, future.cause());
                return;
            }

            T conn = future.getNow();
            if (!conn.isActive()) {
                promiseFailure(entry, promise, conn);
                return;
            }

            promiseSuccessful(entry, promise, conn);
        }
    });
    return promise;
}

From source file:org.redisson.misc.ConnectionPool.java

License:Apache License

private void scheduleCheck(final ClientConnectionsEntry entry) {

    connectionManager.getConnectionEventsHub().fireDisconnect(entry.getClient().getAddr());

    connectionManager.newTimeout(new TimerTask() {
        @Override/*from w ww.ja  v a2 s  . c o m*/
        public void run(Timeout timeout) throws Exception {
            if (entry.getFreezeReason() != FreezeReason.RECONNECT || !entry.isFreezed()) {
                return;
            }

            Future<RedisConnection> connectionFuture = entry.getClient().connectAsync();
            connectionFuture.addListener(new FutureListener<RedisConnection>() {
                @Override
                public void operationComplete(Future<RedisConnection> future) throws Exception {
                    if (entry.getFreezeReason() != FreezeReason.RECONNECT || !entry.isFreezed()) {
                        return;
                    }

                    if (!future.isSuccess()) {
                        scheduleCheck(entry);
                        return;
                    }
                    final RedisConnection c = future.getNow();
                    if (!c.isActive()) {
                        c.closeAsync();
                        scheduleCheck(entry);
                        return;
                    }

                    Future<String> f = c.asyncWithTimeout(null, RedisCommands.PING);
                    f.addListener(new FutureListener<String>() {
                        @Override
                        public void operationComplete(Future<String> future) throws Exception {
                            try {
                                if (entry.getFreezeReason() != FreezeReason.RECONNECT || !entry.isFreezed()) {
                                    return;
                                }

                                if (future.isSuccess() && "PONG".equals(future.getNow())) {
                                    entry.resetFailedAttempts();
                                    Promise<Void> promise = connectionManager.newPromise();
                                    promise.addListener(new FutureListener<Void>() {
                                        @Override
                                        public void operationComplete(Future<Void> future) throws Exception {
                                            if (entry.getNodeType() == NodeType.SLAVE) {
                                                masterSlaveEntry.slaveUp(
                                                        entry.getClient().getAddr().getHostName(),
                                                        entry.getClient().getAddr().getPort(),
                                                        FreezeReason.RECONNECT);
                                            } else {
                                                synchronized (entry) {
                                                    if (entry.getFreezeReason() == FreezeReason.RECONNECT) {
                                                        entry.setFreezed(false);
                                                        entry.setFreezeReason(null);
                                                    }
                                                }
                                            }
                                        }
                                    });
                                    initConnections(entry, promise, false);
                                } else {
                                    scheduleCheck(entry);
                                }
                            } finally {
                                c.closeAsync();
                            }
                        }
                    });
                }
            });
        }
    }, config.getReconnectionTimeout(), TimeUnit.MILLISECONDS);
}

From source file:org.redisson.RedissonKeys.java

License:Apache License

@Override
public RFuture<Long> deleteAsync(String... keys) {
    if (!commandExecutor.getConnectionManager().isClusterMode()) {
        return commandExecutor.writeAsync(null, RedisCommands.DEL, keys);
    }/*  w w  w . ja va  2  s.c o m*/

    Map<MasterSlaveEntry, List<String>> range2key = new HashMap<MasterSlaveEntry, List<String>>();
    for (String key : keys) {
        int slot = commandExecutor.getConnectionManager().calcSlot(key);
        for (MasterSlaveEntry entry : commandExecutor.getConnectionManager().getEntrySet()) {
            List<String> list = range2key.get(entry);
            if (list == null) {
                list = new ArrayList<String>();
                range2key.put(entry, list);
            }
            list.add(key);
        }
    }

    final RPromise<Long> result = commandExecutor.getConnectionManager().newPromise();
    final AtomicReference<Throwable> failed = new AtomicReference<Throwable>();
    final AtomicLong count = new AtomicLong();
    final AtomicLong executed = new AtomicLong(range2key.size());
    FutureListener<List<?>> listener = new FutureListener<List<?>>() {
        @Override
        public void operationComplete(Future<List<?>> future) throws Exception {
            if (future.isSuccess()) {
                List<Long> result = (List<Long>) future.get();
                for (Long res : result) {
                    count.addAndGet(res);
                }
            } else {
                failed.set(future.cause());
            }

            checkExecution(result, failed, count, executed);
        }
    };

    for (Entry<MasterSlaveEntry, List<String>> entry : range2key.entrySet()) {
        // executes in batch due to CROSSLOT error
        CommandBatchService executorService = new CommandBatchService(commandExecutor.getConnectionManager());
        for (String key : entry.getValue()) {
            executorService.writeAsync(entry.getKey(), null, RedisCommands.DEL, key);
        }

        RFuture<List<?>> future = executorService.executeAsync();
        future.addListener(listener);
    }

    return result;
}