Search in sources :

Example 1 with CommandData

use of org.redisson.client.protocol.CommandData 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 CommandData

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

the class CommandsQueue method sendData.

private void sendData(Channel ch) {
    QueueCommandHolder command = queue.peek();
    if (command != null && command.trySend()) {
        QueueCommand data = command.getCommand();
        List<CommandData<Object, Object>> pubSubOps = data.getPubSubOperations();
        if (!pubSubOps.isEmpty()) {
            for (CommandData<Object, Object> cd : pubSubOps) {
                for (Object channel : cd.getParams()) {
                    ch.pipeline().get(CommandDecoder.class).addPubSubCommand(channel.toString(), cd);
                }
            }
        } else {
            ch.attr(CURRENT_COMMAND).set(data);
        }
        command.getChannelPromise().addListener(listener);
        ch.writeAndFlush(data, command.getChannelPromise());
    }
}
Also used : QueueCommandHolder(org.redisson.client.protocol.QueueCommandHolder) QueueCommand(org.redisson.client.protocol.QueueCommand) CommandData(org.redisson.client.protocol.CommandData)

Example 3 with CommandData

use of org.redisson.client.protocol.CommandData 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 4 with CommandData

use of org.redisson.client.protocol.CommandData 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 5 with CommandData

use of org.redisson.client.protocol.CommandData 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)

Aggregations

CommandData (org.redisson.client.protocol.CommandData)9 CommandsData (org.redisson.client.protocol.CommandsData)6 ArrayList (java.util.ArrayList)5 QueueCommand (org.redisson.client.protocol.QueueCommand)4 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 QueueCommandHolder (org.redisson.client.protocol.QueueCommandHolder)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