Search in sources :

Example 16 with RFuture

use of org.redisson.api.RFuture in project redisson by redisson.

the class RedissonKeys method deleteAsync.

@Override
public RFuture<Long> deleteAsync(String... keys) {
    if (!commandExecutor.getConnectionManager().isClusterMode()) {
        return commandExecutor.writeAsync(null, RedisCommands.DEL, keys);
    }
    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;
}
Also used : FutureListener(io.netty.util.concurrent.FutureListener) HashMap(java.util.HashMap) CommandBatchService(org.redisson.command.CommandBatchService) AtomicReference(java.util.concurrent.atomic.AtomicReference) 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) ArrayList(java.util.ArrayList) List(java.util.List)

Example 17 with RFuture

use of org.redisson.api.RFuture in project redisson by redisson.

the class RedissonBlockingFairQueue method tryPollAsync.

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);
        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);
                        }
                    }
                }
            }
        }

        ;
    });
}
Also used : FutureListener(io.netty.util.concurrent.FutureListener) Timeout(io.netty.util.Timeout) AtomicReference(java.util.concurrent.atomic.AtomicReference) RFuture(org.redisson.api.RFuture) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) TimerTask(io.netty.util.TimerTask) RFuture(org.redisson.api.RFuture) Future(io.netty.util.concurrent.Future)

Example 18 with RFuture

use of org.redisson.api.RFuture in project redisson by redisson.

the class RedissonSemaphore method tryAcquireAsync.

@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
        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;
}
Also used : FutureListener(io.netty.util.concurrent.FutureListener) Timeout(io.netty.util.Timeout) AtomicReference(java.util.concurrent.atomic.AtomicReference) RFuture(org.redisson.api.RFuture) AtomicLong(java.util.concurrent.atomic.AtomicLong) TimerTask(io.netty.util.TimerTask) RFuture(org.redisson.api.RFuture) Future(io.netty.util.concurrent.Future) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean)

Example 19 with RFuture

use of org.redisson.api.RFuture in project redisson by redisson.

the class RedissonLock method tryLockAsync.

public RFuture<Boolean> tryLockAsync(final long waitTime, final long leaseTime, final TimeUnit unit, final long currentThreadId) {
    final RPromise<Boolean> result = newPromise();
    final AtomicLong time = new AtomicLong(unit.toMillis(waitTime));
    final long currentTime = System.currentTimeMillis();
    RFuture<Long> ttlFuture = tryAcquireAsync(leaseTime, unit, currentThreadId);
    ttlFuture.addListener(new FutureListener<Long>() {

        @Override
        public void operationComplete(Future<Long> future) throws Exception {
            if (!future.isSuccess()) {
                result.tryFailure(future.cause());
                return;
            }
            Long ttl = future.getNow();
            // lock acquired
            if (ttl == null) {
                if (!result.trySuccess(true)) {
                    unlockAsync(currentThreadId);
                }
                return;
            }
            long elapsed = System.currentTimeMillis() - currentTime;
            time.addAndGet(-elapsed);
            if (time.get() <= 0) {
                trySuccessFalse(currentThreadId, result);
                return;
            }
            final long current = System.currentTimeMillis();
            final AtomicReference<Timeout> futureRef = new AtomicReference<Timeout>();
            final RFuture<RedissonLockEntry> subscribeFuture = subscribe(currentThreadId);
            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);
                    tryLockAsync(time, leaseTime, unit, subscribeFuture, result, currentThreadId);
                }
            });
            if (!subscribeFuture.isDone()) {
                Timeout scheduledFuture = commandExecutor.getConnectionManager().newTimeout(new TimerTask() {

                    @Override
                    public void run(Timeout timeout) throws Exception {
                        if (!subscribeFuture.isDone()) {
                            subscribeFuture.cancel(false);
                            trySuccessFalse(currentThreadId, result);
                        }
                    }
                }, time.get(), TimeUnit.MILLISECONDS);
                futureRef.set(scheduledFuture);
            }
        }
    });
    return result;
}
Also used : FutureListener(io.netty.util.concurrent.FutureListener) Timeout(io.netty.util.Timeout) AtomicReference(java.util.concurrent.atomic.AtomicReference) RFuture(org.redisson.api.RFuture) AtomicLong(java.util.concurrent.atomic.AtomicLong) TimerTask(io.netty.util.TimerTask) AtomicLong(java.util.concurrent.atomic.AtomicLong) RFuture(org.redisson.api.RFuture) Future(io.netty.util.concurrent.Future) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean)

Example 20 with RFuture

use of org.redisson.api.RFuture in project redisson by redisson.

the class RedissonMultiLock method tryLock.

public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {
    long newLeaseTime = -1;
    if (leaseTime != -1) {
        newLeaseTime = waitTime * 2;
    }
    long time = System.currentTimeMillis();
    long remainTime = -1;
    if (waitTime != -1) {
        remainTime = unit.toMillis(waitTime);
    }
    int failedLocksLimit = failedLocksLimit();
    List<RLock> lockedLocks = new ArrayList<RLock>(locks.size());
    for (ListIterator<RLock> iterator = locks.listIterator(); iterator.hasNext(); ) {
        RLock lock = iterator.next();
        boolean lockAcquired;
        try {
            if (waitTime == -1 && leaseTime == -1) {
                lockAcquired = lock.tryLock();
            } else {
                long awaitTime = unit.convert(remainTime, TimeUnit.MILLISECONDS);
                lockAcquired = lock.tryLock(awaitTime, newLeaseTime, unit);
            }
        } catch (Exception e) {
            lockAcquired = false;
        }
        if (lockAcquired) {
            lockedLocks.add(lock);
        } else {
            if (locks.size() - lockedLocks.size() == failedLocksLimit()) {
                break;
            }
            if (failedLocksLimit == 0) {
                unlockInner(lockedLocks);
                if (waitTime == -1 && leaseTime == -1) {
                    return false;
                }
                failedLocksLimit = failedLocksLimit();
                lockedLocks.clear();
                // reset iterator
                while (iterator.hasPrevious()) {
                    iterator.previous();
                }
            } else {
                failedLocksLimit--;
            }
        }
        if (remainTime != -1) {
            remainTime -= (System.currentTimeMillis() - time);
            time = System.currentTimeMillis();
            if (remainTime <= 0) {
                unlockInner(lockedLocks);
                return false;
            }
        }
    }
    if (leaseTime != -1) {
        List<RFuture<Boolean>> futures = new ArrayList<RFuture<Boolean>>(lockedLocks.size());
        for (RLock rLock : lockedLocks) {
            RFuture<Boolean> future = rLock.expireAsync(unit.toMillis(leaseTime), TimeUnit.MILLISECONDS);
            futures.add(future);
        }
        for (RFuture<Boolean> rFuture : futures) {
            rFuture.syncUninterruptibly();
        }
    }
    return true;
}
Also used : ArrayList(java.util.ArrayList) RLock(org.redisson.api.RLock) RFuture(org.redisson.api.RFuture)

Aggregations

RFuture (org.redisson.api.RFuture)29 FutureListener (io.netty.util.concurrent.FutureListener)23 Future (io.netty.util.concurrent.Future)21 ArrayList (java.util.ArrayList)9 AtomicReference (java.util.concurrent.atomic.AtomicReference)9 Timeout (io.netty.util.Timeout)7 TimerTask (io.netty.util.TimerTask)7 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)7 RedisConnection (org.redisson.client.RedisConnection)7 AtomicLong (java.util.concurrent.atomic.AtomicLong)6 RedisConnectionException (org.redisson.client.RedisConnectionException)6 RedisException (org.redisson.client.RedisException)6 MasterSlaveEntry (org.redisson.connection.MasterSlaveEntry)6 ScheduledFuture (io.netty.util.concurrent.ScheduledFuture)5 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)5 Collection (java.util.Collection)4 RPromise (org.redisson.misc.RPromise)4 ChannelFuture (io.netty.channel.ChannelFuture)3 ChannelFutureListener (io.netty.channel.ChannelFutureListener)3 URL (java.net.URL)3