Example usage for io.netty.util TimerTask TimerTask

List of usage examples for io.netty.util TimerTask TimerTask

Introduction

In this page you can find the example usage for io.netty.util TimerTask TimerTask.

Prototype

TimerTask

Source Link

Usage

From source file:org.redisson.RedissonBlockingFairQueue.java

License:Apache License

private void tryPollAsync(final long startTime, final long timeout, final TimeUnit unit,
        final RFuture<RedissonLockEntry> subscribeFuture, final RPromise<V> promise) {
    if (promise.isDone()) {
        unsubscribe(subscribeFuture);/*from  w  ww  .  j  a v a  2s .c o m*/
        return;
    }

    long spentTime = System.currentTimeMillis() - startTime;
    long remainTime = unit.toMillis(timeout) - spentTime;
    if (remainTime <= 0) {
        unsubscribe(subscribeFuture);
        promise.trySuccess(null);
        return;
    }

    RFuture<Long> tryAcquireFuture = tryAcquireAsync();
    tryAcquireFuture.addListener(new FutureListener<Long>() {
        @Override
        public void operationComplete(Future<Long> future) throws Exception {
            if (!future.isSuccess()) {
                unsubscribe(subscribeFuture);
                promise.tryFailure(future.cause());
                return;
            }

            Long currentTimeout = future.getNow();
            if (currentTimeout == null) {
                long spentTime = System.currentTimeMillis() - startTime;
                long remainTime = unit.toMillis(timeout) - spentTime;
                if (remainTime > 0) {
                    final RFuture<V> pollFuture = RedissonBlockingFairQueue.super.pollAsync(remainTime,
                            TimeUnit.MILLISECONDS);
                    pollFuture.addListener(new FutureListener<V>() {
                        @Override
                        public void operationComplete(Future<V> future) throws Exception {
                            unsubscribe(subscribeFuture);
                            if (!future.isSuccess()) {
                                promise.tryFailure(future.cause());
                                return;
                            }

                            promise.trySuccess(future.getNow());
                        }
                    });
                } else {
                    unsubscribe(subscribeFuture);
                    promise.trySuccess(null);
                }
            } else {
                final RedissonLockEntry entry = getEntry();
                synchronized (entry) {
                    if (entry.getLatch().tryAcquire()) {
                        tryPollAsync(startTime, timeout, unit, subscribeFuture, promise);
                    } else {
                        final AtomicBoolean executed = new AtomicBoolean();
                        final AtomicReference<Timeout> futureRef = new AtomicReference<Timeout>();
                        final Runnable listener = new Runnable() {
                            @Override
                            public void run() {
                                executed.set(true);
                                if (futureRef.get() != null) {
                                    futureRef.get().cancel();
                                }

                                tryPollAsync(startTime, timeout, unit, subscribeFuture, promise);
                            }
                        };
                        entry.addListener(listener);

                        if (!executed.get()) {
                            long spentTime = System.currentTimeMillis() - startTime;
                            long remainTime = unit.toMillis(timeout) - spentTime;
                            Timeout scheduledFuture = commandExecutor.getConnectionManager()
                                    .newTimeout(new TimerTask() {
                                        @Override
                                        public void run(Timeout t) throws Exception {
                                            synchronized (entry) {
                                                if (entry.removeListener(listener)) {
                                                    tryPollAsync(startTime, timeout, unit, subscribeFuture,
                                                            promise);
                                                }
                                            }
                                        }
                                    }, remainTime, TimeUnit.MILLISECONDS);
                            futureRef.set(scheduledFuture);
                        }
                    }
                }
            }
        };
    });
}

From source file:org.redisson.RedissonBlockingFairQueue.java

License:Apache License

@Override
public RFuture<V> pollLastAndOfferFirstToAsync(final String queueName, final long timeout,
        final TimeUnit unit) {
    final long startTime = System.currentTimeMillis();
    final RPromise<V> promise = newPromise();

    RFuture<Long> tryAcquireFuture = tryAcquireAsync();
    tryAcquireFuture.addListener(new FutureListener<Long>() {
        @Override//from w w w .  j  a  v  a  2  s .  c o m
        public void operationComplete(Future<Long> future) throws Exception {
            if (!future.isSuccess()) {
                promise.tryFailure(future.cause());
                return;
            }

            Long currentTimeout = future.getNow();
            if (currentTimeout == null) {
                long spentTime = System.currentTimeMillis() - startTime;
                long remainTime = unit.toMillis(timeout) - spentTime;
                if (remainTime > 0) {
                    final RFuture<V> pollFuture = RedissonBlockingFairQueue.super.pollLastAndOfferFirstToAsync(
                            queueName, remainTime, TimeUnit.MILLISECONDS);
                    pollFuture.addListener(new FutureListener<V>() {
                        @Override
                        public void operationComplete(Future<V> future) throws Exception {
                            if (!future.isSuccess()) {
                                promise.tryFailure(future.cause());
                                return;
                            }

                            promise.trySuccess(future.getNow());
                        }
                    });
                } else {
                    promise.trySuccess(null);
                }
            } else {
                long spentTime = System.currentTimeMillis() - startTime;
                long remainTime = unit.toMillis(timeout) - spentTime;
                remainTime = Math.min(remainTime, currentTimeout);
                if (remainTime <= 0) {
                    promise.trySuccess(null);
                    return;
                }

                final RFuture<RedissonLockEntry> subscribeFuture = subscribe();
                final AtomicReference<Timeout> futureRef = new AtomicReference<Timeout>();
                subscribeFuture.addListener(new FutureListener<RedissonLockEntry>() {
                    @Override
                    public void operationComplete(Future<RedissonLockEntry> future) throws Exception {
                        if (!future.isSuccess()) {
                            promise.tryFailure(future.cause());
                            return;
                        }

                        if (futureRef.get() != null) {
                            futureRef.get().cancel();
                        }

                        tryPollLastAndOfferFirstToAsync(startTime, timeout, unit, subscribeFuture, promise,
                                queueName);
                    }
                });
                if (!subscribeFuture.isDone()) {
                    Timeout scheduledFuture = commandExecutor.getConnectionManager()
                            .newTimeout(new TimerTask() {
                                @Override
                                public void run(Timeout timeout) throws Exception {
                                    if (!subscribeFuture.isDone()) {
                                        subscribeFuture.cancel(false);
                                        promise.trySuccess(null);
                                    }
                                }
                            }, remainTime, TimeUnit.MILLISECONDS);
                    futureRef.set(scheduledFuture);
                }
            }
        }
    });

    return promise;
}

From source file:org.redisson.RedissonBlockingFairQueue.java

License:Apache License

private void tryPollLastAndOfferFirstToAsync(final long startTime, final long timeout, final TimeUnit unit,
        final RFuture<RedissonLockEntry> subscribeFuture, final RPromise<V> promise, final String queueName) {
    if (promise.isDone()) {
        unsubscribe(subscribeFuture);/*from   w  w w . j a v a 2  s.co  m*/
        return;
    }

    long spentTime = System.currentTimeMillis() - startTime;
    long remainTime = unit.toMillis(timeout) - spentTime;
    if (remainTime <= 0) {
        unsubscribe(subscribeFuture);
        promise.trySuccess(null);
        return;
    }

    RFuture<Long> tryAcquireFuture = tryAcquireAsync();
    tryAcquireFuture.addListener(new FutureListener<Long>() {
        @Override
        public void operationComplete(Future<Long> future) throws Exception {
            if (!future.isSuccess()) {
                unsubscribe(subscribeFuture);
                promise.tryFailure(future.cause());
                return;
            }

            Long currentTimeout = future.getNow();
            if (currentTimeout == null) {
                long spentTime = System.currentTimeMillis() - startTime;
                long remainTime = unit.toMillis(timeout) - spentTime;
                if (remainTime > 0) {
                    final RFuture<V> pollFuture = RedissonBlockingFairQueue.super.pollLastAndOfferFirstToAsync(
                            queueName, remainTime, TimeUnit.MILLISECONDS);
                    pollFuture.addListener(new FutureListener<V>() {
                        @Override
                        public void operationComplete(Future<V> future) throws Exception {
                            unsubscribe(subscribeFuture);
                            if (!future.isSuccess()) {
                                promise.tryFailure(future.cause());
                                return;
                            }

                            promise.trySuccess(future.getNow());
                        }
                    });
                } else {
                    unsubscribe(subscribeFuture);
                    promise.trySuccess(null);
                }
            } else {
                final RedissonLockEntry entry = getEntry();
                synchronized (entry) {
                    if (entry.getLatch().tryAcquire()) {
                        tryPollAsync(startTime, timeout, unit, subscribeFuture, promise);
                    } else {
                        final AtomicBoolean executed = new AtomicBoolean();
                        final AtomicReference<Timeout> futureRef = new AtomicReference<Timeout>();
                        final Runnable listener = new Runnable() {
                            @Override
                            public void run() {
                                executed.set(true);
                                if (futureRef.get() != null) {
                                    futureRef.get().cancel();
                                }

                                tryPollLastAndOfferFirstToAsync(startTime, timeout, unit, subscribeFuture,
                                        promise, queueName);
                            }
                        };
                        entry.addListener(listener);

                        if (!executed.get()) {
                            long spentTime = System.currentTimeMillis() - startTime;
                            long remainTime = unit.toMillis(timeout) - spentTime;
                            Timeout scheduledFuture = commandExecutor.getConnectionManager()
                                    .newTimeout(new TimerTask() {
                                        @Override
                                        public void run(Timeout t) throws Exception {
                                            synchronized (entry) {
                                                if (entry.removeListener(listener)) {
                                                    tryPollLastAndOfferFirstToAsync(startTime, timeout, unit,
                                                            subscribeFuture, promise, queueName);
                                                }
                                            }
                                        }
                                    }, remainTime, TimeUnit.MILLISECONDS);
                            futureRef.set(scheduledFuture);
                        }
                    }
                }
            }
        };
    });
}

From source file:org.redisson.RedissonPermitExpirableSemaphore.java

License:Apache License

private void tryAcquireAsync(final AtomicLong time, final int permits,
        final RFuture<RedissonLockEntry> subscribeFuture, final RPromise<String> result, final long ttl,
        final TimeUnit timeUnit) {
    if (result.isDone()) {
        unsubscribe(subscribeFuture);/*w  ww . j  a  va2  s .  c  o m*/
        return;
    }

    if (time.get() <= 0) {
        unsubscribe(subscribeFuture);
        result.trySuccess(null);
        return;
    }

    long timeoutDate = calcTimeout(ttl, timeUnit);
    final long current = System.currentTimeMillis();
    RFuture<String> tryAcquireFuture = tryAcquireAsync(permits, timeoutDate);
    tryAcquireFuture.addListener(new FutureListener<String>() {
        @Override
        public void operationComplete(Future<String> future) throws Exception {
            if (!future.isSuccess()) {
                unsubscribe(subscribeFuture);
                result.tryFailure(future.cause());
                return;
            }

            final Long nearestTimeout;
            String permitId = future.getNow();
            if (permitId != null) {
                if (!permitId.startsWith(":")) {
                    unsubscribe(subscribeFuture);
                    if (!result.trySuccess(permitId)) {
                        releaseAsync(permitId);
                    }
                    return;
                } else {
                    nearestTimeout = Long.valueOf(permitId.substring(1)) - System.currentTimeMillis();
                }
            } else {
                nearestTimeout = null;
            }

            long elapsed = System.currentTimeMillis() - current;
            time.addAndGet(-elapsed);

            if (time.get() <= 0) {
                unsubscribe(subscribeFuture);
                result.trySuccess(null);
                return;
            }

            // waiting for message
            final long current = System.currentTimeMillis();
            final RedissonLockEntry entry = getEntry();
            synchronized (entry) {
                if (entry.getLatch().tryAcquire()) {
                    tryAcquireAsync(time, permits, subscribeFuture, result, ttl, timeUnit);
                } else {
                    final AtomicReference<Timeout> waitTimeoutFutureRef = new AtomicReference<Timeout>();

                    final Timeout scheduledFuture;
                    if (nearestTimeout != null) {
                        scheduledFuture = commandExecutor.getConnectionManager().newTimeout(new TimerTask() {
                            @Override
                            public void run(Timeout timeout) throws Exception {
                                if (waitTimeoutFutureRef.get() != null
                                        && !waitTimeoutFutureRef.get().cancel()) {
                                    return;
                                }

                                long elapsed = System.currentTimeMillis() - current;
                                time.addAndGet(-elapsed);

                                tryAcquireAsync(time, permits, subscribeFuture, result, ttl, timeUnit);
                            }
                        }, nearestTimeout, TimeUnit.MILLISECONDS);
                    } else {
                        scheduledFuture = null;
                    }

                    final Runnable listener = new Runnable() {
                        @Override
                        public void run() {
                            if (waitTimeoutFutureRef.get() != null && !waitTimeoutFutureRef.get().cancel()) {
                                entry.getLatch().release();
                                return;
                            }
                            if (scheduledFuture != null && !scheduledFuture.cancel()) {
                                entry.getLatch().release();
                                return;
                            }

                            long elapsed = System.currentTimeMillis() - current;
                            time.addAndGet(-elapsed);

                            tryAcquireAsync(time, permits, subscribeFuture, result, ttl, timeUnit);
                        }
                    };
                    entry.addListener(listener);

                    long t = time.get();
                    Timeout waitTimeoutFuture = commandExecutor.getConnectionManager()
                            .newTimeout(new TimerTask() {
                                @Override
                                public void run(Timeout timeout) throws Exception {
                                    if (scheduledFuture != null && !scheduledFuture.cancel()) {
                                        return;
                                    }

                                    synchronized (entry) {
                                        if (entry.removeListener(listener)) {
                                            long elapsed = System.currentTimeMillis() - current;
                                            time.addAndGet(-elapsed);

                                            tryAcquireAsync(time, permits, subscribeFuture, result, ttl,
                                                    timeUnit);
                                        }
                                    }
                                }
                            }, t, TimeUnit.MILLISECONDS);
                    waitTimeoutFutureRef.set(waitTimeoutFuture);
                }
            }
        }
    });

}

From source file:org.redisson.RedissonPermitExpirableSemaphore.java

License:Apache License

private void acquireAsync(final int permits, final RFuture<RedissonLockEntry> subscribeFuture,
        final RPromise<String> result, final long ttl, final TimeUnit timeUnit) {
    if (result.isDone()) {
        unsubscribe(subscribeFuture);//from   w  w w  .j a  v  a  2 s .  c om
        return;
    }

    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()) {
                unsubscribe(subscribeFuture);
                result.tryFailure(future.cause());
                return;
            }

            final Long nearestTimeout;
            String permitId = future.getNow();
            if (permitId != null) {
                if (!permitId.startsWith(":")) {
                    unsubscribe(subscribeFuture);
                    if (!result.trySuccess(permitId)) {
                        releaseAsync(permitId);
                    }
                    return;
                } else {
                    nearestTimeout = Long.valueOf(permitId.substring(1)) - System.currentTimeMillis();
                }
            } else {
                nearestTimeout = null;
            }

            final RedissonLockEntry entry = getEntry();
            synchronized (entry) {
                if (entry.getLatch().tryAcquire(permits)) {
                    acquireAsync(permits, subscribeFuture, result, ttl, timeUnit);
                } else {
                    final Timeout scheduledFuture;
                    if (nearestTimeout != null) {
                        scheduledFuture = commandExecutor.getConnectionManager().newTimeout(new TimerTask() {
                            @Override
                            public void run(Timeout timeout) throws Exception {
                                acquireAsync(permits, subscribeFuture, result, ttl, timeUnit);
                            }
                        }, nearestTimeout, TimeUnit.MILLISECONDS);
                    } else {
                        scheduledFuture = null;
                    }

                    Runnable listener = new Runnable() {
                        @Override
                        public void run() {
                            if (scheduledFuture != null && !scheduledFuture.cancel()) {
                                entry.getLatch().release();
                                return;
                            }
                            acquireAsync(permits, subscribeFuture, result, ttl, timeUnit);
                        }
                    };
                    entry.addListener(listener);
                }
            }
        }
    });
}

From source file:org.redisson.RedissonPermitExpirableSemaphore.java

License:Apache License

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//  w w  w. j a v a2  s. c  om
        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;
}

From source file:org.redisson.RedissonSemaphore.java

License:Apache License

private void tryAcquireAsync(final AtomicLong time, final int permits,
        final RFuture<RedissonLockEntry> subscribeFuture, final RPromise<Boolean> result) {
    if (result.isDone()) {
        unsubscribe(subscribeFuture);//from   w  ww.ja v a 2  s .c  o m
        return;
    }

    if (time.get() <= 0) {
        unsubscribe(subscribeFuture);
        result.trySuccess(false);
        return;
    }

    final long current = System.currentTimeMillis();
    RFuture<Boolean> tryAcquireFuture = tryAcquireAsync(permits);
    tryAcquireFuture.addListener(new FutureListener<Boolean>() {
        @Override
        public void operationComplete(Future<Boolean> future) throws Exception {
            if (!future.isSuccess()) {
                unsubscribe(subscribeFuture);
                result.tryFailure(future.cause());
                return;
            }

            if (future.getNow()) {
                unsubscribe(subscribeFuture);
                if (!result.trySuccess(true)) {
                    releaseAsync(permits);
                }
                return;
            }

            long elapsed = System.currentTimeMillis() - current;
            time.addAndGet(-elapsed);

            if (time.get() <= 0) {
                unsubscribe(subscribeFuture);
                result.trySuccess(false);
                return;
            }

            // waiting for message
            final long current = System.currentTimeMillis();
            final RedissonLockEntry entry = getEntry();
            synchronized (entry) {
                if (entry.getLatch().tryAcquire()) {
                    tryAcquireAsync(time, permits, subscribeFuture, result);
                } else {
                    final AtomicBoolean executed = new AtomicBoolean();
                    final AtomicReference<Timeout> futureRef = new AtomicReference<Timeout>();
                    final Runnable listener = new Runnable() {
                        @Override
                        public void run() {
                            executed.set(true);
                            if (futureRef.get() != null && !futureRef.get().cancel()) {
                                entry.getLatch().release();
                                return;
                            }
                            long elapsed = System.currentTimeMillis() - current;
                            time.addAndGet(-elapsed);

                            tryAcquireAsync(time, permits, subscribeFuture, result);
                        }
                    };
                    entry.addListener(listener);

                    long t = time.get();
                    if (!executed.get()) {
                        Timeout scheduledFuture = commandExecutor.getConnectionManager()
                                .newTimeout(new TimerTask() {
                                    @Override
                                    public void run(Timeout timeout) throws Exception {
                                        synchronized (entry) {
                                            if (entry.removeListener(listener)) {
                                                long elapsed = System.currentTimeMillis() - current;
                                                time.addAndGet(-elapsed);

                                                tryAcquireAsync(time, permits, subscribeFuture, result);
                                            }
                                        }
                                    }
                                }, t, TimeUnit.MILLISECONDS);
                        futureRef.set(scheduledFuture);
                    }
                }
            }
        }
    });

}

From source file:org.redisson.RedissonSemaphore.java

License:Apache License

@Override
public RFuture<Boolean> tryAcquireAsync(final int permits, long waitTime, TimeUnit unit) {
    final RPromise<Boolean> result = newPromise();
    final AtomicLong time = new AtomicLong(unit.toMillis(waitTime));
    final long current = System.currentTimeMillis();
    RFuture<Boolean> tryAcquireFuture = tryAcquireAsync(permits);
    tryAcquireFuture.addListener(new FutureListener<Boolean>() {
        @Override//from   w w w.j a  v  a  2  s . c om
        public void operationComplete(Future<Boolean> future) throws Exception {
            if (!future.isSuccess()) {
                result.tryFailure(future.cause());
                return;
            }

            if (future.getNow()) {
                if (!result.trySuccess(true)) {
                    releaseAsync(permits);
                }
                return;
            }

            long elapsed = System.currentTimeMillis() - current;
            time.addAndGet(-elapsed);

            if (time.get() <= 0) {
                result.trySuccess(false);
                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);

                    if (time.get() < 0) {
                        unsubscribe(subscribeFuture);
                        result.trySuccess(false);
                        return;
                    }

                    tryAcquireAsync(time, permits, subscribeFuture, result);
                }
            });

            if (!subscribeFuture.isDone()) {
                Timeout scheduledFuture = commandExecutor.getConnectionManager().newTimeout(new TimerTask() {
                    @Override
                    public void run(Timeout timeout) throws Exception {
                        if (!subscribeFuture.isDone()) {
                            result.trySuccess(false);
                        }
                    }
                }, time.get(), TimeUnit.MILLISECONDS);
                futureRef.set(scheduledFuture);
            }
        }
    });

    return result;
}

From source file:org.redisson.remote.BaseRemoteService.java

License:Apache License

protected <T> void scheduleCheck(String mapName, RequestId requestId, RPromise<T> cancelRequest) {
    commandExecutor.getConnectionManager().newTimeout(new TimerTask() {
        @Override/*from  ww  w . j  av a  2 s.  co  m*/
        public void run(Timeout timeout) throws Exception {
            if (cancelRequest.isDone()) {
                return;
            }

            RMap<String, T> canceledRequests = getMap(mapName);
            RFuture<T> future = canceledRequests.removeAsync(requestId.toString());
            future.onComplete((request, ex) -> {
                if (cancelRequest.isDone()) {
                    return;
                }
                if (ex != null) {
                    scheduleCheck(mapName, requestId, cancelRequest);
                    return;
                }

                if (request == null) {
                    scheduleCheck(mapName, requestId, cancelRequest);
                } else {
                    cancelRequest.trySuccess(request);
                }
            });
        }
    }, 3000, TimeUnit.MILLISECONDS);
}

From source file:org.redisson.transaction.RedissonTransaction.java

License:Apache License

private RFuture<Map<HashKey, HashValue>> disableLocalCacheAsync(String requestId, Set<String> localCaches,
        List<TransactionalOperation> operations) {
    if (localCaches.isEmpty()) {
        return RedissonPromise.newSucceededFuture(Collections.emptyMap());
    }//from w ww.  jav a  2  s  .c  om

    RPromise<Map<HashKey, HashValue>> result = new RedissonPromise<>();
    Map<HashKey, HashValue> hashes = new HashMap<>(localCaches.size());
    RedissonBatch batch = new RedissonBatch(null, commandExecutor.getConnectionManager(),
            BatchOptions.defaults());
    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.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.tryFailure(e);
            return;
        }

        CountableListener<Map<HashKey, HashValue>> listener = new CountableListener<>(result, hashes,
                hashes.size());
        RPromise<Void> subscriptionFuture = new RedissonPromise<>();
        CountableListener<Void> subscribedFutures = new CountableListener<>(subscriptionFuture, null,
                hashes.size());

        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 = new RedissonTopic(LocalCachedMessageCodec.INSTANCE, commandExecutor,
                    disabledAckName);
            topics.add(topic);
            RFuture<Integer> topicFuture = topic.addListenerAsync(Object.class, new MessageListener<Object>() {
                @Override
                public void onMessage(CharSequence channel, Object msg) {
                    AtomicInteger counter = entry.getValue().getCounter();
                    if (counter.decrementAndGet() == 0) {
                        listener.decCounter();
                    }
                }
            });
            topicFuture.onComplete((r, ex) -> {
                subscribedFutures.decCounter();
            });
        }

        subscriptionFuture.onComplete((r, ex) -> {
            RedissonBatch publishBatch = new RedissonBatch(null, commandExecutor.getConnectionManager(),
                    BatchOptions.defaults());
            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) {
                        listener.decCounter();
                    }
                });
            }

            RFuture<BatchResult<?>> publishFuture = publishBatch.executeAsync();
            publishFuture.onComplete((res2, ex2) -> {
                result.onComplete((res3, ex3) -> {
                    for (RTopic topic : topics) {
                        topic.removeAllListeners();
                    }
                });

                if (ex2 != null) {
                    result.tryFailure(ex2);
                    return;
                }

                commandExecutor.getConnectionManager().newTimeout(new TimerTask() {
                    @Override
                    public void run(Timeout timeout) throws Exception {
                        result.tryFailure(new TransactionTimeoutException(
                                "Unable to execute transaction within " + options.getResponseTimeout() + "ms"));
                    }
                }, options.getResponseTimeout(), TimeUnit.MILLISECONDS);
            });
        });
    });

    return result;
}