Search in sources :

Example 6 with RPromise

use of org.redisson.misc.RPromise in project redisson by redisson.

the class RedisConnection method await.

public <R> R await(RFuture<R> future) {
    final CountDownLatch l = new CountDownLatch(1);
    future.addListener(new FutureListener<R>() {

        @Override
        public void operationComplete(Future<R> future) throws Exception {
            l.countDown();
        }
    });
    try {
        if (!l.await(redisClient.getCommandTimeout(), TimeUnit.MILLISECONDS)) {
            RPromise<R> promise = (RPromise<R>) future;
            RedisTimeoutException ex = new RedisTimeoutException("Command execution timeout for " + redisClient.getAddr());
            promise.tryFailure(ex);
            throw ex;
        }
        if (!future.isSuccess()) {
            if (future.cause() instanceof RedisException) {
                throw (RedisException) future.cause();
            }
            throw new RedisException("Unexpected exception while processing command", future.cause());
        }
        return future.getNow();
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        return null;
    }
}
Also used : RPromise(org.redisson.misc.RPromise) CountDownLatch(java.util.concurrent.CountDownLatch) RedissonShutdownException(org.redisson.RedissonShutdownException)

Example 7 with RPromise

use of org.redisson.misc.RPromise in project redisson by redisson.

the class RedissonTransferQueue method tryTransferAsync.

public RFuture<Boolean> tryTransferAsync(V v, long timeout, TimeUnit unit) {
    RPromise<Boolean> result = new RedissonPromise<>();
    result.setUncancellable();
    RemotePromise<Void> future = (RemotePromise<Void>) service.invoke(v).toCompletableFuture();
    long remainTime = unit.toMillis(timeout);
    long startTime = System.currentTimeMillis();
    Timeout timeoutFuture = commandExecutor.getConnectionManager().newTimeout(tt -> {
        if (!future.getAddFuture().cancel(false)) {
            future.cancelAsync(false);
        }
    }, remainTime, TimeUnit.MILLISECONDS);
    future.whenComplete((res, exc) -> {
        if (future.isCancelled()) {
            result.trySuccess(false);
            return;
        }
        timeoutFuture.cancel();
        if (exc != null) {
            result.tryFailure(exc);
            return;
        }
        result.trySuccess(true);
    });
    future.getAddFuture().whenComplete((added, e) -> {
        if (future.getAddFuture().isCancelled()) {
            result.trySuccess(false);
            return;
        }
        if (e != null) {
            timeoutFuture.cancel();
            result.tryFailure(e);
            return;
        }
        if (!added) {
            timeoutFuture.cancel();
            result.trySuccess(false);
            return;
        }
        Runnable task = () -> {
            future.cancelAsync(false).whenComplete((canceled, ex) -> {
                if (ex != null) {
                    timeoutFuture.cancel();
                    result.tryFailure(ex);
                    return;
                }
                if (canceled) {
                    timeoutFuture.cancel();
                    result.trySuccess(false);
                }
            });
        };
        long time = remainTime - (System.currentTimeMillis() - startTime);
        if (time > 0) {
            commandExecutor.getConnectionManager().newTimeout(tt -> {
                task.run();
            }, time, TimeUnit.MILLISECONDS);
        } else {
            task.run();
        }
    });
    return result;
}
Also used : RPromise(org.redisson.misc.RPromise) Timeout(io.netty.util.Timeout) CommandAsyncExecutor(org.redisson.command.CommandAsyncExecutor) java.util(java.util) Codec(org.redisson.client.codec.Codec) RemoteServiceRequest(org.redisson.remote.RemoteServiceRequest) java.util.concurrent(java.util.concurrent) RedissonPromise(org.redisson.misc.RedissonPromise) ObjectListReplayDecoder(org.redisson.client.protocol.decoder.ObjectListReplayDecoder) RedissonListIterator(org.redisson.iterator.RedissonListIterator) RRemoteService(org.redisson.api.RRemoteService) RRemoteAsync(org.redisson.api.annotation.RRemoteAsync) Convertor(org.redisson.client.protocol.convertor.Convertor) ListDrainToDecoder(org.redisson.connection.decoder.ListDrainToDecoder) RemoteInvocationOptions(org.redisson.api.RemoteInvocationOptions) RFuture(org.redisson.api.RFuture) Consumer(java.util.function.Consumer) CompletableFutureWrapper(org.redisson.misc.CompletableFutureWrapper) RemotePromise(org.redisson.executor.RemotePromise) ByteBuf(io.netty.buffer.ByteBuf) ImmediateEventExecutor(io.netty.util.concurrent.ImmediateEventExecutor) RedisStrictCommand(org.redisson.client.protocol.RedisStrictCommand) RedisCommand(org.redisson.client.protocol.RedisCommand) RTransferQueue(org.redisson.api.RTransferQueue) RedissonPromise(org.redisson.misc.RedissonPromise) Timeout(io.netty.util.Timeout) RemotePromise(org.redisson.executor.RemotePromise)

Example 8 with RPromise

use of org.redisson.misc.RPromise in project redisson by redisson.

the class CommandBatchService method executeRedisBasedQueue.

private <R> RFuture<R> executeRedisBasedQueue() {
    RPromise<R> resultPromise = new RedissonPromise<R>();
    long responseTimeout;
    if (options.getResponseTimeout() > 0) {
        responseTimeout = options.getResponseTimeout();
    } else {
        responseTimeout = connectionManager.getConfig().getTimeout();
    }
    Timeout timeout = connectionManager.newTimeout(new TimerTask() {

        @Override
        public void run(Timeout timeout) throws Exception {
            connections.values().forEach(c -> {
                c.getCancelCallback().run();
            });
            resultPromise.tryFailure(new RedisTimeoutException("Response timeout for queued commands " + responseTimeout + ": " + commands.values().stream().flatMap(e -> e.getCommands().stream().map(d -> d.getCommand())).collect(Collectors.toList())));
        }
    }, responseTimeout, TimeUnit.MILLISECONDS);
    CompletableFuture<Void> allFutures = CompletableFuture.allOf(commands.values().stream().flatMap(m -> m.getCommands().stream().map(c -> ((BatchPromise) c.getPromise()).getSentPromise())).toArray(CompletableFuture[]::new));
    allFutures.whenComplete((fr, exc) -> {
        if (!timeout.cancel()) {
            return;
        }
        for (Entry entry : commands.values()) {
            for (BatchCommandData<?, ?> command : entry.getCommands()) {
                if (command.getPromise().isDone() && command.getPromise().isCompletedExceptionally()) {
                    resultPromise.tryFailure(cause(command.getPromise()));
                    break;
                }
            }
        }
        if (resultPromise.isDone()) {
            return;
        }
        Map<MasterSlaveEntry, List<Object>> result = new ConcurrentHashMap<>();
        List<CompletableFuture<Void>> futures = new ArrayList<>(commands.size());
        for (Map.Entry<MasterSlaveEntry, Entry> entry : commands.entrySet()) {
            RFuture<List<Object>> execPromise = async(entry.getValue().isReadOnlyMode(), new NodeSource(entry.getKey()), connectionManager.getCodec(), RedisCommands.EXEC, new Object[] {}, false, false);
            CompletionStage<Void> f = execPromise.thenCompose(r -> {
                BatchCommandData<?, Integer> lastCommand = (BatchCommandData<?, Integer>) entry.getValue().getCommands().peekLast();
                result.put(entry.getKey(), r);
                if (RedisCommands.WAIT.getName().equals(lastCommand.getCommand().getName())) {
                    return lastCommand.getPromise().thenApply(i -> null);
                }
                return CompletableFuture.completedFuture(null);
            });
            futures.add(f.toCompletableFuture());
        }
        CompletableFuture<Void> future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
        future.whenComplete((res, ex) -> {
            executed.set(true);
            if (ex != null) {
                resultPromise.tryFailure(ex);
                return;
            }
            try {
                for (java.util.Map.Entry<MasterSlaveEntry, List<Object>> entry : result.entrySet()) {
                    Entry commandEntry = commands.get(entry.getKey());
                    Iterator<Object> resultIter = entry.getValue().iterator();
                    for (BatchCommandData<?, ?> data : commandEntry.getCommands()) {
                        if (data.getCommand().getName().equals(RedisCommands.EXEC.getName())) {
                            break;
                        }
                        CompletableFuture<Object> promise = (CompletableFuture<Object>) data.getPromise();
                        if (resultIter.hasNext()) {
                            promise.complete(resultIter.next());
                        } else {
                            // fix for https://github.com/redisson/redisson/issues/2212
                            promise.complete(null);
                        }
                    }
                }
                List<BatchCommandData> entries = new ArrayList<>();
                for (Entry e : commands.values()) {
                    entries.addAll(e.getCommands());
                }
                Collections.sort(entries);
                List<Object> responses = new ArrayList<>(entries.size());
                int syncedSlaves = 0;
                for (BatchCommandData<?, ?> commandEntry : entries) {
                    if (isWaitCommand(commandEntry)) {
                        syncedSlaves += (Integer) commandEntry.getPromise().getNow(null);
                    } else if (!commandEntry.getCommand().getName().equals(RedisCommands.MULTI.getName()) && !commandEntry.getCommand().getName().equals(RedisCommands.EXEC.getName())) {
                        Object entryResult = commandEntry.getPromise().getNow(null);
                        if (objectBuilder != null) {
                            entryResult = objectBuilder.tryHandleReference(entryResult, referenceType);
                        }
                        responses.add(entryResult);
                    }
                }
                BatchResult<Object> r = new BatchResult<>(responses, syncedSlaves);
                resultPromise.trySuccess((R) r);
            } catch (Exception e) {
                resultPromise.tryFailure(e);
            }
        });
    });
    return resultPromise;
}
Also used : RPromise(org.redisson.misc.RPromise) java.util(java.util) RedisConnection(org.redisson.client.RedisConnection) Codec(org.redisson.client.codec.Codec) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ExecutionMode(org.redisson.api.BatchOptions.ExecutionMode) RFuture(org.redisson.api.RFuture) NodeSource(org.redisson.connection.NodeSource) CompletableFutureWrapper(org.redisson.misc.CompletableFutureWrapper) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TimerTask(io.netty.util.TimerTask) BatchCommandData(org.redisson.client.protocol.BatchCommandData) Timeout(io.netty.util.Timeout) ConnectionManager(org.redisson.connection.ConnectionManager) java.util.concurrent(java.util.concurrent) RedissonPromise(org.redisson.misc.RedissonPromise) CommandData(org.redisson.client.protocol.CommandData) BatchOptions(org.redisson.api.BatchOptions) RedisTimeoutException(org.redisson.client.RedisTimeoutException) Collectors(java.util.stream.Collectors) BatchResult(org.redisson.api.BatchResult) RedisCommands(org.redisson.client.protocol.RedisCommands) ReferenceCountUtil(io.netty.util.ReferenceCountUtil) MasterSlaveEntry(org.redisson.connection.MasterSlaveEntry) RedisCommand(org.redisson.client.protocol.RedisCommand) RedissonObjectBuilder(org.redisson.liveobject.core.RedissonObjectBuilder) RedissonPromise(org.redisson.misc.RedissonPromise) BatchCommandData(org.redisson.client.protocol.BatchCommandData) BatchResult(org.redisson.api.BatchResult) NodeSource(org.redisson.connection.NodeSource) MasterSlaveEntry(org.redisson.connection.MasterSlaveEntry) TimerTask(io.netty.util.TimerTask) MasterSlaveEntry(org.redisson.connection.MasterSlaveEntry) Timeout(io.netty.util.Timeout) RedisTimeoutException(org.redisson.client.RedisTimeoutException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) RedisTimeoutException(org.redisson.client.RedisTimeoutException)

Example 9 with RPromise

use of org.redisson.misc.RPromise in project redisson by redisson.

the class BaseTransactionalMap method addAndGetOperationAsync.

protected RFuture<V> addAndGetOperationAsync(K key, Number value) {
    RPromise<V> result = new RedissonPromise<V>();
    long threadId = Thread.currentThread().getId();
    executeLocked(result, key, new Runnable() {

        @Override
        public void run() {
            HashValue keyHash = toKeyHash(key);
            MapEntry entry = state.get(keyHash);
            if (entry != null) {
                BigDecimal currentValue = BigDecimal.ZERO;
                if (entry != MapEntry.NULL) {
                    currentValue = (BigDecimal) entry.getValue();
                }
                BigDecimal res = currentValue.add(new BigDecimal(value.toString()));
                operations.add(new MapAddAndGetOperation(map, key, value, transactionId, threadId));
                state.put(keyHash, new MapEntry(key, res));
                if (deleted != null) {
                    deleted = false;
                }
                NumberConvertor convertor = new NumberConvertor(value.getClass());
                result.trySuccess((V) convertor.convert(res.toPlainString()));
                return;
            }
            map.getAsync(key).onComplete((r, e) -> {
                if (e != null) {
                    result.tryFailure(e);
                    return;
                }
                BigDecimal currentValue = new BigDecimal(r.toString());
                BigDecimal res = currentValue.add(new BigDecimal(value.toString()));
                operations.add(new MapAddAndGetOperation(map, key, value, transactionId, threadId));
                state.put(keyHash, new MapEntry(key, res));
                if (deleted != null) {
                    deleted = false;
                }
                NumberConvertor convertor = new NumberConvertor(value.getClass());
                result.trySuccess((V) convertor.convert(res.toPlainString()));
            });
        }
    });
    return result;
}
Also used : HashValue(org.redisson.misc.HashValue) RPromise(org.redisson.misc.RPromise) TransactionalOperation(org.redisson.transaction.operation.TransactionalOperation) Arrays(java.util.Arrays) CommandAsyncExecutor(org.redisson.command.CommandAsyncExecutor) UnlinkOperation(org.redisson.transaction.operation.UnlinkOperation) RedissonMultiLock(org.redisson.RedissonMultiLock) HashMap(java.util.HashMap) Hash(org.redisson.misc.Hash) org.redisson.transaction.operation.map(org.redisson.transaction.operation.map) RedisClient(org.redisson.client.RedisClient) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) RFuture(org.redisson.api.RFuture) RMap(org.redisson.api.RMap) BigDecimal(java.math.BigDecimal) RedissonObject(org.redisson.RedissonObject) ByteBuf(io.netty.buffer.ByteBuf) ScanResult(org.redisson.ScanResult) TouchOperation(org.redisson.transaction.operation.TouchOperation) RLock(org.redisson.api.RLock) Map(java.util.Map) RedissonMap(org.redisson.RedissonMap) MapScanResult(org.redisson.client.protocol.decoder.MapScanResult) Iterator(java.util.Iterator) Collection(java.util.Collection) RedissonPromise(org.redisson.misc.RedissonPromise) Set(java.util.Set) DeleteOperation(org.redisson.transaction.operation.DeleteOperation) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) NumberConvertor(org.redisson.client.protocol.convertor.NumberConvertor) Entry(java.util.Map.Entry) RedissonPromise(org.redisson.misc.RedissonPromise) NumberConvertor(org.redisson.client.protocol.convertor.NumberConvertor) HashValue(org.redisson.misc.HashValue) BigDecimal(java.math.BigDecimal)

Aggregations

RPromise (org.redisson.misc.RPromise)9 RFuture (org.redisson.api.RFuture)7 RedisConnection (org.redisson.client.RedisConnection)5 ArrayList (java.util.ArrayList)4 RedisClient (org.redisson.client.RedisClient)4 RedissonPromise (org.redisson.misc.RedissonPromise)4 ByteBuf (io.netty.buffer.ByteBuf)3 Timeout (io.netty.util.Timeout)3 Future (io.netty.util.concurrent.Future)3 FutureListener (io.netty.util.concurrent.FutureListener)3 List (java.util.List)3 RedisException (org.redisson.client.RedisException)3 CommandAsyncExecutor (org.redisson.command.CommandAsyncExecutor)3 TimerTask (io.netty.util.TimerTask)2 ScheduledFuture (io.netty.util.concurrent.ScheduledFuture)2 BigDecimal (java.math.BigDecimal)2 java.util (java.util)2 Arrays (java.util.Arrays)2 Collection (java.util.Collection)2 HashMap (java.util.HashMap)2