Search in sources :

Example 36 with RFuture

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

the class RedissonBaseAdder method resetAsync.

public RFuture<Void> resetAsync(long timeout, TimeUnit timeUnit) {
    String id = generateId();
    RFuture<Long> future = topic.publishAsync(CLEAR_MSG + ":" + id);
    RSemaphore semaphore = getSemaphore(id);
    CompletionStage<Void> f = future.thenCompose(r -> tryAcquire(semaphore, timeout, timeUnit, r.intValue())).thenCompose(r -> semaphore.deleteAsync().thenApply(res -> null));
    return new CompletableFutureWrapper<>(f);
}
Also used : RFuture(org.redisson.api.RFuture) CompletableFutureWrapper(org.redisson.misc.CompletableFutureWrapper) ByteBufUtil(io.netty.buffer.ByteBufUtil) CommandAsyncExecutor(org.redisson.command.CommandAsyncExecutor) Logger(org.slf4j.Logger) StringCodec(org.redisson.client.codec.StringCodec) java.util.concurrent(java.util.concurrent) RTopic(org.redisson.api.RTopic) LoggerFactory(org.slf4j.LoggerFactory) RSemaphore(org.redisson.api.RSemaphore) RedissonClient(org.redisson.api.RedissonClient) CompletableFutureWrapper(org.redisson.misc.CompletableFutureWrapper) RSemaphore(org.redisson.api.RSemaphore)

Example 37 with RFuture

use of org.redisson.api.RFuture 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 38 with RFuture

use of org.redisson.api.RFuture 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 39 with RFuture

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

the class CommandBatchService method executeAsync.

public RFuture<BatchResult<?>> executeAsync() {
    if (executed.get()) {
        throw new IllegalStateException("Batch already executed!");
    }
    if (commands.isEmpty()) {
        executed.set(true);
        BatchResult<Object> result = new BatchResult<>(Collections.emptyList(), 0);
        return RedissonPromise.newSucceededFuture(result);
    }
    if (isRedisBasedQueue()) {
        return executeRedisBasedQueue();
    }
    if (this.options.getExecutionMode() != ExecutionMode.IN_MEMORY) {
        for (Entry entry : commands.values()) {
            BatchCommandData<?, ?> multiCommand = new BatchCommandData(RedisCommands.MULTI, new Object[] {}, index.incrementAndGet());
            entry.getCommands().addFirst(multiCommand);
            BatchCommandData<?, ?> execCommand = new BatchCommandData(RedisCommands.EXEC, new Object[] {}, index.incrementAndGet());
            entry.getCommands().add(execCommand);
        }
    }
    if (this.options.isSkipResult()) {
        for (Entry entry : commands.values()) {
            BatchCommandData<?, ?> offCommand = new BatchCommandData(RedisCommands.CLIENT_REPLY, new Object[] { "OFF" }, index.incrementAndGet());
            entry.getCommands().addFirst(offCommand);
            BatchCommandData<?, ?> onCommand = new BatchCommandData(RedisCommands.CLIENT_REPLY, new Object[] { "ON" }, index.incrementAndGet());
            entry.getCommands().add(onCommand);
        }
    }
    if (this.options.getSyncSlaves() > 0) {
        for (Entry entry : commands.values()) {
            BatchCommandData<?, ?> waitCommand = new BatchCommandData(RedisCommands.WAIT, new Object[] { this.options.getSyncSlaves(), this.options.getSyncTimeout() }, index.incrementAndGet());
            entry.getCommands().add(waitCommand);
        }
    }
    RPromise<BatchResult<?>> promise = new RedissonPromise<>();
    CompletableFuture<Void> voidPromise = new CompletableFuture<>();
    if (this.options.isSkipResult() && this.options.getSyncSlaves() == 0) {
        voidPromise.whenComplete((res, ex) -> {
            executed.set(true);
            if (ex != null) {
                for (Entry e : commands.values()) {
                    e.getCommands().forEach(t -> t.tryFailure(ex));
                }
                promise.tryFailure(ex);
                commands.clear();
                nestedServices.clear();
                return;
            }
            commands.clear();
            nestedServices.clear();
            promise.trySuccess(new BatchResult<>(Collections.emptyList(), 0));
        });
    } else {
        voidPromise.whenComplete((res, ex) -> {
            executed.set(true);
            if (ex != null) {
                for (Entry e : commands.values()) {
                    e.getCommands().forEach(t -> t.tryFailure(ex));
                }
                promise.tryFailure(ex);
                commands.clear();
                nestedServices.clear();
                return;
            }
            List<BatchCommandData> entries = new ArrayList<BatchCommandData>();
            for (Entry e : commands.values()) {
                entries.addAll(e.getCommands());
            }
            Collections.sort(entries);
            List<Object> responses = new ArrayList<Object>(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()) && !this.options.isSkipResult()) {
                    if (commandEntry.getPromise().isCancelled()) {
                        continue;
                    }
                    Object entryResult = commandEntry.getPromise().getNow(null);
                    try {
                        if (objectBuilder != null) {
                            entryResult = objectBuilder.tryHandleReference(entryResult, referenceType);
                        }
                    } catch (ReflectiveOperationException exc) {
                        log.error("Unable to handle reference from " + entryResult, exc);
                    }
                    responses.add(entryResult);
                }
            }
            BatchResult<Object> result = new BatchResult<Object>(responses, syncedSlaves);
            promise.trySuccess(result);
            commands.clear();
            nestedServices.clear();
        });
    }
    AtomicInteger slots = new AtomicInteger(commands.size());
    for (Map.Entry<RFuture<?>, List<CommandBatchService>> entry : nestedServices.entrySet()) {
        slots.incrementAndGet();
        for (CommandBatchService service : entry.getValue()) {
            service.executeAsync();
        }
        entry.getKey().whenComplete((res, e) -> {
            handle(voidPromise, slots, entry.getKey());
        });
    }
    for (Map.Entry<MasterSlaveEntry, Entry> e : commands.entrySet()) {
        RedisCommonBatchExecutor executor = new RedisCommonBatchExecutor(new NodeSource(e.getKey()), voidPromise, connectionManager, this.options, e.getValue(), slots, referenceType, false);
        executor.execute();
    }
    return promise;
}
Also used : 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) MasterSlaveEntry(org.redisson.connection.MasterSlaveEntry) RFuture(org.redisson.api.RFuture) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Example 40 with RFuture

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

the class CommandAsyncService method evalAsync.

private <T, R> RFuture<R> evalAsync(NodeSource nodeSource, boolean readOnlyMode, Codec codec, RedisCommand<T> evalCommandType, String script, List<Object> keys, boolean noRetry, Object... params) {
    if (isEvalCacheActive() && evalCommandType.getName().equals("EVAL")) {
        CompletableFuture<R> mainPromise = new CompletableFuture<>();
        Object[] pps = copy(params);
        CompletableFuture<R> promise = new CompletableFuture<>();
        String sha1 = calcSHA(script);
        RedisCommand cmd;
        if (readOnlyMode && evalShaROSupported.get()) {
            cmd = new RedisCommand(evalCommandType, "EVALSHA_RO");
        } else {
            cmd = new RedisCommand(evalCommandType, "EVALSHA");
        }
        List<Object> args = new ArrayList<Object>(2 + keys.size() + params.length);
        args.add(sha1);
        args.add(keys.size());
        args.addAll(keys);
        args.addAll(Arrays.asList(params));
        RedisExecutor<T, R> executor = new RedisExecutor<>(readOnlyMode, nodeSource, codec, cmd, args.toArray(), promise, false, connectionManager, objectBuilder, referenceType, noRetry);
        executor.execute();
        promise.whenComplete((res, e) -> {
            if (e != null) {
                if (e.getMessage().startsWith("ERR unknown command")) {
                    evalShaROSupported.set(false);
                    free(pps);
                    RFuture<R> future = evalAsync(nodeSource, readOnlyMode, codec, evalCommandType, script, keys, noRetry, params);
                    transfer(future.toCompletableFuture(), mainPromise);
                } else if (e.getMessage().startsWith("NOSCRIPT")) {
                    RFuture<String> loadFuture = loadScript(executor.getRedisClient(), script);
                    loadFuture.whenComplete((r, ex) -> {
                        if (ex != null) {
                            free(pps);
                            mainPromise.completeExceptionally(ex);
                            return;
                        }
                        List<Object> newargs = new ArrayList<Object>(2 + keys.size() + params.length);
                        newargs.add(sha1);
                        newargs.add(keys.size());
                        newargs.addAll(keys);
                        newargs.addAll(Arrays.asList(pps));
                        NodeSource ns = nodeSource;
                        if (ns.getRedisClient() == null) {
                            ns = new NodeSource(nodeSource, executor.getRedisClient());
                        }
                        RFuture<R> future = async(readOnlyMode, ns, codec, cmd, newargs.toArray(), false, noRetry);
                        transfer(future.toCompletableFuture(), mainPromise);
                    });
                } else {
                    free(pps);
                    mainPromise.completeExceptionally(e);
                }
                return;
            }
            free(pps);
            mainPromise.complete(res);
        });
        return new CompletableFutureWrapper<>(mainPromise);
    }
    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));
    return async(readOnlyMode, nodeSource, codec, evalCommandType, args.toArray(), false, noRetry);
}
Also used : RedisException(org.redisson.client.RedisException) RPromise(org.redisson.misc.RPromise) java.util(java.util) NodeType(org.redisson.api.NodeType) Codec(org.redisson.client.codec.Codec) StringCodec(org.redisson.client.codec.StringCodec) ByteBufAllocator(io.netty.buffer.ByteBufAllocator) MessageDigest(java.security.MessageDigest) LoggerFactory(org.slf4j.LoggerFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) RedisClient(org.redisson.client.RedisClient) AtomicReference(java.util.concurrent.atomic.AtomicReference) RFuture(org.redisson.api.RFuture) NodeSource(org.redisson.connection.NodeSource) CompletableFutureWrapper(org.redisson.misc.CompletableFutureWrapper) ByteBuf(io.netty.buffer.ByteBuf) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) BiConsumer(java.util.function.BiConsumer) RedissonReference(org.redisson.RedissonReference) SlotCallback(org.redisson.SlotCallback) Logger(org.slf4j.Logger) LRUCacheMap(org.redisson.cache.LRUCacheMap) ConnectionManager(org.redisson.connection.ConnectionManager) RedissonPromise(org.redisson.misc.RedissonPromise) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) RedisCommands(org.redisson.client.protocol.RedisCommands) ExecutionException(java.util.concurrent.ExecutionException) AtomicLong(java.util.concurrent.atomic.AtomicLong) ByteBufUtil(io.netty.buffer.ByteBufUtil) RedisRedirectException(org.redisson.client.RedisRedirectException) CompletionStage(java.util.concurrent.CompletionStage) ReferenceCountUtil(io.netty.util.ReferenceCountUtil) MasterSlaveEntry(org.redisson.connection.MasterSlaveEntry) Entry(java.util.Map.Entry) RedisCommand(org.redisson.client.protocol.RedisCommand) RedissonObjectBuilder(org.redisson.liveobject.core.RedissonObjectBuilder) RFuture(org.redisson.api.RFuture) NodeSource(org.redisson.connection.NodeSource) CompletableFuture(java.util.concurrent.CompletableFuture) CompletableFutureWrapper(org.redisson.misc.CompletableFutureWrapper) RedisCommand(org.redisson.client.protocol.RedisCommand)

Aggregations

RFuture (org.redisson.api.RFuture)44 FutureListener (io.netty.util.concurrent.FutureListener)19 Future (io.netty.util.concurrent.Future)17 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)14 AtomicReference (java.util.concurrent.atomic.AtomicReference)12 CompletableFutureWrapper (org.redisson.misc.CompletableFutureWrapper)12 Logger (org.slf4j.Logger)12 LoggerFactory (org.slf4j.LoggerFactory)12 StringCodec (org.redisson.client.codec.StringCodec)11 MasterSlaveEntry (org.redisson.connection.MasterSlaveEntry)11 RPromise (org.redisson.misc.RPromise)11 RedissonPromise (org.redisson.misc.RedissonPromise)11 ArrayList (java.util.ArrayList)10 AtomicLong (java.util.concurrent.atomic.AtomicLong)10 RedisClient (org.redisson.client.RedisClient)10 RedisCommands (org.redisson.client.protocol.RedisCommands)10 java.util.concurrent (java.util.concurrent)9 CommandAsyncExecutor (org.redisson.command.CommandAsyncExecutor)9 Timeout (io.netty.util.Timeout)8 java.util (java.util)8