Search in sources :

Example 1 with CommandsData

use of org.redisson.client.protocol.CommandsData in project redisson by redisson.

the class CommandDecoder method decode.

@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
    QueueCommand data = ctx.channel().attr(CommandsQueue.CURRENT_COMMAND).get();
    if (log.isTraceEnabled()) {
        log.trace("channel: {} message: {}", ctx.channel(), in.toString(0, in.writerIndex(), CharsetUtil.UTF_8));
    }
    if (state() == null) {
        boolean makeCheckpoint = data != null;
        if (data != null) {
            if (data instanceof CommandsData) {
                makeCheckpoint = false;
            } else {
                CommandData<Object, Object> cmd = (CommandData<Object, Object>) data;
                if (cmd.getCommand().getReplayMultiDecoder() != null && (NestedMultiDecoder.class.isAssignableFrom(cmd.getCommand().getReplayMultiDecoder().getClass()) || SlotsDecoder.class.isAssignableFrom(cmd.getCommand().getReplayMultiDecoder().getClass()) || ListMultiDecoder.class.isAssignableFrom(cmd.getCommand().getReplayMultiDecoder().getClass()))) {
                    makeCheckpoint = false;
                }
            }
        }
        state(new State(makeCheckpoint));
    }
    state().setDecoderState(null);
    if (data == null) {
        decode(in, null, null, ctx.channel());
    } else if (data instanceof CommandData) {
        CommandData<Object, Object> cmd = (CommandData<Object, Object>) data;
        try {
            if (state().getLevels().size() > 0) {
                decodeFromCheckpoint(ctx, in, data, cmd);
            } else {
                decode(in, cmd, null, ctx.channel());
            }
        } catch (Exception e) {
            cmd.tryFailure(e);
        }
    } else if (data instanceof CommandsData) {
        CommandsData commands = (CommandsData) data;
        try {
            decodeCommandBatch(ctx, in, data, commands);
        } catch (Exception e) {
            commands.getPromise().tryFailure(e);
        }
        return;
    }
    ctx.pipeline().get(CommandsQueue.class).sendNextCommand(ctx.channel());
    state(null);
}
Also used : QueueCommand(org.redisson.client.protocol.QueueCommand) ListMultiDecoder(org.redisson.client.protocol.decoder.ListMultiDecoder) CommandsData(org.redisson.client.protocol.CommandsData) CommandData(org.redisson.client.protocol.CommandData) RedisException(org.redisson.client.RedisException) RedisMovedException(org.redisson.client.RedisMovedException) RedisAskException(org.redisson.client.RedisAskException) RedisOutOfMemoryException(org.redisson.client.RedisOutOfMemoryException) RedisLoadingException(org.redisson.client.RedisLoadingException) RedisTryAgainException(org.redisson.client.RedisTryAgainException) IOException(java.io.IOException) RedisTimeoutException(org.redisson.client.RedisTimeoutException)

Example 2 with CommandsData

use of org.redisson.client.protocol.CommandsData in project redisson by redisson.

the class RedisCommonBatchExecutor method sendCommand.

private void sendCommand(RedisConnection connection, CompletableFuture<Void> attemptPromise, List<CommandData<?, ?>> list) {
    boolean isAtomic = options.getExecutionMode() != ExecutionMode.IN_MEMORY;
    boolean isQueued = options.getExecutionMode() == ExecutionMode.REDIS_READ_ATOMIC || options.getExecutionMode() == ExecutionMode.REDIS_WRITE_ATOMIC;
    CommandData<?, ?> lastCommand = connection.getLastCommand();
    if (lastCommand != null && options.isSkipResult()) {
        writeFuture = connection.getChannel().newPromise();
        lastCommand.getPromise().whenComplete((r, e) -> {
            CommandData<?, ?> currentLastCommand = connection.getLastCommand();
            if (lastCommand != currentLastCommand && currentLastCommand != null) {
                sendCommand(connection, attemptPromise, list);
                return;
            }
            ChannelFuture wf = connection.send(new CommandsData(attemptPromise, list, options.isSkipResult(), isAtomic, isQueued, options.getSyncSlaves() > 0));
            wf.addListener((ChannelFutureListener) future -> {
                if (future.isSuccess()) {
                    ((ChannelPromise) writeFuture).trySuccess(future.getNow());
                } else {
                    ((ChannelPromise) writeFuture).tryFailure(future.cause());
                }
            });
        });
        return;
    }
    writeFuture = connection.send(new CommandsData(attemptPromise, list, options.isSkipResult(), isAtomic, isQueued, options.getSyncSlaves() > 0));
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) RedisConnection(org.redisson.client.RedisConnection) Logger(org.slf4j.Logger) StringCodec(org.redisson.client.codec.StringCodec) ConnectionManager(org.redisson.connection.ConnectionManager) LoggerFactory(org.slf4j.LoggerFactory) CommandData(org.redisson.client.protocol.CommandData) CompletableFuture(java.util.concurrent.CompletableFuture) BatchOptions(org.redisson.api.BatchOptions) ExecutionMode(org.redisson.api.BatchOptions.ExecutionMode) Redirect(org.redisson.connection.NodeSource.Redirect) ChannelFuture(io.netty.channel.ChannelFuture) RedisCommands(org.redisson.client.protocol.RedisCommands) ArrayList(java.util.ArrayList) NodeSource(org.redisson.connection.NodeSource) List(java.util.List) ChannelPromise(io.netty.channel.ChannelPromise) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ChannelFutureListener(io.netty.channel.ChannelFutureListener) Entry(org.redisson.command.CommandBatchService.Entry) RedissonObjectBuilder(org.redisson.liveobject.core.RedissonObjectBuilder) CommandsData(org.redisson.client.protocol.CommandsData) CommandsData(org.redisson.client.protocol.CommandsData)

Example 3 with CommandsData

use of org.redisson.client.protocol.CommandsData in project redisson by redisson.

the class CommandAsyncService method async.

protected <V, R> void async(final boolean readOnlyMode, final NodeSource source, final Codec codec, final RedisCommand<V> command, final Object[] params, final RPromise<R> mainPromise, final int attempt) {
    if (mainPromise.isCancelled()) {
        return;
    }
    if (!connectionManager.getShutdownLatch().acquire()) {
        mainPromise.tryFailure(new RedissonShutdownException("Redisson is shutdown"));
        return;
    }
    final AsyncDetails<V, R> details = AsyncDetails.acquire();
    if (isRedissonReferenceSupportEnabled()) {
        try {
            for (int i = 0; i < params.length; i++) {
                RedissonReference reference = redisson != null ? RedissonObjectFactory.toReference(redisson, params[i]) : RedissonObjectFactory.toReference(redissonReactive, params[i]);
                params[i] = reference == null ? params[i] : reference;
            }
        } catch (Exception e) {
            connectionManager.getShutdownLatch().release();
            mainPromise.tryFailure(e);
            return;
        }
    }
    final RFuture<RedisConnection> connectionFuture;
    if (readOnlyMode) {
        connectionFuture = connectionManager.connectionReadOp(source, command);
    } else {
        connectionFuture = connectionManager.connectionWriteOp(source, command);
    }
    final RPromise<R> attemptPromise = connectionManager.newPromise();
    details.init(connectionFuture, attemptPromise, readOnlyMode, source, codec, command, params, mainPromise, attempt);
    final TimerTask retryTimerTask = new TimerTask() {

        @Override
        public void run(Timeout t) throws Exception {
            if (details.getAttemptPromise().isDone()) {
                return;
            }
            if (details.getConnectionFuture().cancel(false)) {
                connectionManager.getShutdownLatch().release();
            } else {
                if (details.getConnectionFuture().isSuccess()) {
                    ChannelFuture writeFuture = details.getWriteFuture();
                    if (writeFuture != null && !writeFuture.cancel(false) && writeFuture.isSuccess()) {
                        return;
                    }
                }
            }
            if (details.getMainPromise().isCancelled()) {
                if (details.getAttemptPromise().cancel(false)) {
                    AsyncDetails.release(details);
                }
                return;
            }
            if (details.getAttempt() == connectionManager.getConfig().getRetryAttempts()) {
                if (details.getException() == null) {
                    details.setException(new RedisTimeoutException("Command execution timeout for command: " + command + " with params: " + LogHelper.toString(details.getParams())));
                }
                details.getAttemptPromise().tryFailure(details.getException());
                return;
            }
            if (!details.getAttemptPromise().cancel(false)) {
                return;
            }
            int count = details.getAttempt() + 1;
            if (log.isDebugEnabled()) {
                log.debug("attempt {} for command {} and params {}", count, details.getCommand(), Arrays.toString(details.getParams()));
            }
            async(details.isReadOnlyMode(), details.getSource(), details.getCodec(), details.getCommand(), details.getParams(), details.getMainPromise(), count);
            AsyncDetails.release(details);
        }
    };
    Timeout timeout = connectionManager.newTimeout(retryTimerTask, connectionManager.getConfig().getRetryInterval(), TimeUnit.MILLISECONDS);
    details.setTimeout(timeout);
    connectionFuture.addListener(new FutureListener<RedisConnection>() {

        @Override
        public void operationComplete(Future<RedisConnection> connFuture) throws Exception {
            if (connFuture.isCancelled()) {
                return;
            }
            if (!connFuture.isSuccess()) {
                connectionManager.getShutdownLatch().release();
                details.setException(convertException(connectionFuture));
                return;
            }
            if (details.getAttemptPromise().isDone() || details.getMainPromise().isDone()) {
                releaseConnection(source, connectionFuture, details.isReadOnlyMode(), details.getAttemptPromise(), details);
                return;
            }
            final RedisConnection connection = connFuture.getNow();
            if (details.getSource().getRedirect() == Redirect.ASK) {
                List<CommandData<?, ?>> list = new ArrayList<CommandData<?, ?>>(2);
                RPromise<Void> promise = connectionManager.newPromise();
                list.add(new CommandData<Void, Void>(promise, details.getCodec(), RedisCommands.ASKING, new Object[] {}));
                list.add(new CommandData<V, R>(details.getAttemptPromise(), details.getCodec(), details.getCommand(), details.getParams()));
                RPromise<Void> main = connectionManager.newPromise();
                ChannelFuture future = connection.send(new CommandsData(main, list));
                details.setWriteFuture(future);
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("aquired connection for command {} and params {} from slot {} using node {}", details.getCommand(), Arrays.toString(details.getParams()), details.getSource(), connection.getRedisClient().getAddr());
                }
                ChannelFuture future = connection.send(new CommandData<V, R>(details.getAttemptPromise(), details.getCodec(), details.getCommand(), details.getParams()));
                details.setWriteFuture(future);
            }
            details.getWriteFuture().addListener(new ChannelFutureListener() {

                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    checkWriteFuture(details, connection);
                }
            });
            releaseConnection(source, connectionFuture, details.isReadOnlyMode(), details.getAttemptPromise(), details);
        }
    });
    attemptPromise.addListener(new FutureListener<R>() {

        @Override
        public void operationComplete(Future<R> future) throws Exception {
            checkAttemptFuture(source, details, future);
        }
    });
}
Also used : RPromise(org.redisson.misc.RPromise) TimerTask(io.netty.util.TimerTask) List(java.util.List) ArrayList(java.util.ArrayList) CommandsData(org.redisson.client.protocol.CommandsData) ChannelFuture(io.netty.channel.ChannelFuture) RedissonReference(org.redisson.RedissonReference) Timeout(io.netty.util.Timeout) ChannelFutureListener(io.netty.channel.ChannelFutureListener) RedisAskException(org.redisson.client.RedisAskException) RedisLoadingException(org.redisson.client.RedisLoadingException) RedisTimeoutException(org.redisson.client.RedisTimeoutException) RedisException(org.redisson.client.RedisException) RedisMovedException(org.redisson.client.RedisMovedException) WriteRedisConnectionException(org.redisson.client.WriteRedisConnectionException) RedisTryAgainException(org.redisson.client.RedisTryAgainException) RedissonShutdownException(org.redisson.RedissonShutdownException) RedisTimeoutException(org.redisson.client.RedisTimeoutException) RedissonShutdownException(org.redisson.RedissonShutdownException) CommandData(org.redisson.client.protocol.CommandData) RedisConnection(org.redisson.client.RedisConnection)

Example 4 with CommandsData

use of org.redisson.client.protocol.CommandsData in project redisson by redisson.

the class CommandBatchService method checkConnectionFuture.

private void checkConnectionFuture(final Entry entry, final NodeSource source, final RPromise<Void> mainPromise, final RPromise<Void> attemptPromise, final AsyncDetails details, RFuture<RedisConnection> connFuture, final boolean noResult) {
    if (attemptPromise.isDone() || mainPromise.isCancelled() || connFuture.isCancelled()) {
        return;
    }
    if (!connFuture.isSuccess()) {
        connectionManager.getShutdownLatch().release();
        details.setException(convertException(connFuture));
        return;
    }
    final RedisConnection connection = connFuture.getNow();
    List<CommandData<?, ?>> list = new ArrayList<CommandData<?, ?>>(entry.getCommands().size() + 1);
    if (source.getRedirect() == Redirect.ASK) {
        RPromise<Void> promise = connectionManager.newPromise();
        list.add(new CommandData<Void, Void>(promise, StringCodec.INSTANCE, RedisCommands.ASKING, new Object[] {}));
    }
    for (BatchCommandData<?, ?> c : entry.getCommands()) {
        if (c.getPromise().isSuccess()) {
            // skip successful commands
            continue;
        }
        list.add(c);
    }
    ChannelFuture future = connection.send(new CommandsData(attemptPromise, list, noResult));
    details.setWriteFuture(future);
    details.getWriteFuture().addListener(new ChannelFutureListener() {

        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
            checkWriteFuture(attemptPromise, details, connection, future, noResult);
        }
    });
    releaseConnection(source, connFuture, entry.isReadOnlyMode(), attemptPromise, details);
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) ArrayList(java.util.ArrayList) ChannelFutureListener(io.netty.channel.ChannelFutureListener) RedisMovedException(org.redisson.client.RedisMovedException) RedisAskException(org.redisson.client.RedisAskException) WriteRedisConnectionException(org.redisson.client.WriteRedisConnectionException) RedisLoadingException(org.redisson.client.RedisLoadingException) RedisTryAgainException(org.redisson.client.RedisTryAgainException) RedisTimeoutException(org.redisson.client.RedisTimeoutException) CommandsData(org.redisson.client.protocol.CommandsData) BatchCommandData(org.redisson.client.protocol.BatchCommandData) CommandData(org.redisson.client.protocol.CommandData) RedisConnection(org.redisson.client.RedisConnection)

Example 5 with CommandsData

use of org.redisson.client.protocol.CommandsData in project redisson by redisson.

the class RedisClientTest method testPipelineBigResponse.

@Test
public void testPipelineBigResponse() throws InterruptedException, ExecutionException {
    RedisConnection conn = redisClient.connect();
    List<CommandData<?, ?>> commands = new ArrayList<CommandData<?, ?>>();
    for (int i = 0; i < 1000; i++) {
        CommandData<String, String> cmd1 = conn.create(null, RedisCommands.PING);
        commands.add(cmd1);
    }
    CompletableFuture<Void> p = new CompletableFuture<Void>();
    conn.send(new CommandsData(p, commands, false, false));
    for (CommandData<?, ?> commandData : commands) {
        commandData.getPromise().get();
    }
    conn.sync(RedisCommands.FLUSHDB);
}
Also used : ArrayList(java.util.ArrayList) CommandsData(org.redisson.client.protocol.CommandsData) CommandData(org.redisson.client.protocol.CommandData)

Aggregations

CommandData (org.redisson.client.protocol.CommandData)6 CommandsData (org.redisson.client.protocol.CommandsData)6 ArrayList (java.util.ArrayList)5 ChannelFuture (io.netty.channel.ChannelFuture)3 ChannelFutureListener (io.netty.channel.ChannelFutureListener)3 RedisAskException (org.redisson.client.RedisAskException)3 RedisConnection (org.redisson.client.RedisConnection)3 RedisLoadingException (org.redisson.client.RedisLoadingException)3 RedisMovedException (org.redisson.client.RedisMovedException)3 RedisTimeoutException (org.redisson.client.RedisTimeoutException)3 RedisTryAgainException (org.redisson.client.RedisTryAgainException)3 List (java.util.List)2 RedisException (org.redisson.client.RedisException)2 WriteRedisConnectionException (org.redisson.client.WriteRedisConnectionException)2 ChannelPromise (io.netty.channel.ChannelPromise)1 Timeout (io.netty.util.Timeout)1 TimerTask (io.netty.util.TimerTask)1 IOException (java.io.IOException)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1