Search in sources :

Example 1 with RedisChannelWriter

use of io.lettuce.core.RedisChannelWriter in project lettuce-core by lettuce-io.

the class AtLeastOnceTest method commandRetriedChannelClosesWhileFlush.

@Test
void commandRetriedChannelClosesWhileFlush() {
    assumeTrue(Version.identify().get("netty-transport").artifactVersion().startsWith("4.0.2"));
    StatefulRedisConnection<String, String> connection = client.connect();
    RedisCommands<String, String> sync = connection.sync();
    RedisCommands<String, String> verificationConnection = client.connect().sync();
    RedisChannelWriter channelWriter = ConnectionTestUtil.getChannelWriter(connection);
    sync.set(key, "1");
    assertThat(verificationConnection.get(key)).isEqualTo("1");
    final CountDownLatch block = new CountDownLatch(1);
    ConnectionWatchdog connectionWatchdog = ConnectionTestUtil.getConnectionWatchdog(sync.getStatefulConnection());
    AsyncCommand<String, String, Object> command = getBlockOnEncodeCommand(block);
    channelWriter.write(command);
    connectionWatchdog.setReconnectSuspended(true);
    Channel channel = ConnectionTestUtil.getChannel(sync.getStatefulConnection());
    channel.unsafe().disconnect(channel.newPromise());
    assertThat(channel.isOpen()).isFalse();
    assertThat(command.isCancelled()).isFalse();
    assertThat(command.isDone()).isFalse();
    block.countDown();
    assertThat(command.await(2, TimeUnit.SECONDS)).isFalse();
    connectionWatchdog.setReconnectSuspended(false);
    connectionWatchdog.scheduleReconnect();
    assertThat(command.await(2, TimeUnit.SECONDS)).isTrue();
    assertThat(command.isCancelled()).isFalse();
    assertThat(command.isDone()).isTrue();
    assertThat(verificationConnection.get(key)).isEqualTo("2");
    assertThat(ConnectionTestUtil.getStack(sync.getStatefulConnection())).isEmpty();
    assertThat(ConnectionTestUtil.getCommandBuffer(sync.getStatefulConnection())).isEmpty();
    sync.getStatefulConnection().close();
    verificationConnection.getStatefulConnection().close();
}
Also used : ConnectionWatchdog(io.lettuce.core.protocol.ConnectionWatchdog) Channel(io.netty.channel.Channel) RedisChannelWriter(io.lettuce.core.RedisChannelWriter) CountDownLatch(java.util.concurrent.CountDownLatch) AbstractRedisClientTest(io.lettuce.core.AbstractRedisClientTest) Test(org.junit.jupiter.api.Test)

Example 2 with RedisChannelWriter

use of io.lettuce.core.RedisChannelWriter in project lettuce-core by lettuce-io.

the class AtLeastOnceTest method commandFailsWhenFailOnEncode.

@Test
void commandFailsWhenFailOnEncode() {
    RedisCommands<String, String> connection = client.connect().sync();
    RedisChannelWriter channelWriter = ConnectionTestUtil.getChannelWriter(connection.getStatefulConnection());
    RedisCommands<String, String> verificationConnection = client.connect().sync();
    connection.set(key, "1");
    AsyncCommand<String, String, String> working = new AsyncCommand<>(new Command<>(CommandType.INCR, new IntegerOutput(StringCodec.UTF8), new CommandArgs<>(StringCodec.UTF8).addKey(key)));
    channelWriter.write(working);
    assertThat(working.await(2, TimeUnit.SECONDS)).isTrue();
    assertThat(connection.get(key)).isEqualTo("2");
    AsyncCommand<String, String, Object> command = new AsyncCommand(new Command<>(CommandType.INCR, new IntegerOutput(StringCodec.UTF8), new CommandArgs<>(StringCodec.UTF8).addKey(key))) {

        @Override
        public void encode(ByteBuf buf) {
            throw new IllegalStateException("I want to break free");
        }
    };
    channelWriter.write(command);
    assertThat(command.await(2, TimeUnit.SECONDS)).isTrue();
    assertThat(command.isCancelled()).isFalse();
    assertThat(getException(command)).isInstanceOf(EncoderException.class);
    assertThat(verificationConnection.get(key)).isEqualTo("2");
    assertThat(ConnectionTestUtil.getStack(connection.getStatefulConnection())).isNotEmpty();
    connection.getStatefulConnection().close();
}
Also used : AsyncCommand(io.lettuce.core.protocol.AsyncCommand) IntegerOutput(io.lettuce.core.output.IntegerOutput) RedisChannelWriter(io.lettuce.core.RedisChannelWriter) ByteBuf(io.netty.buffer.ByteBuf) AbstractRedisClientTest(io.lettuce.core.AbstractRedisClientTest) Test(org.junit.jupiter.api.Test)

Example 3 with RedisChannelWriter

use of io.lettuce.core.RedisChannelWriter in project lettuce-core by lettuce-io.

the class AtMostOnceTest method commandFailsDuringDecode.

@Test
void commandFailsDuringDecode() {
    StatefulRedisConnection<String, String> connection = client.connect();
    RedisCommands<String, String> sync = connection.sync();
    RedisChannelWriter channelWriter = ConnectionTestUtil.getChannelWriter(connection);
    RedisCommands<String, String> verificationConnection = client.connect().sync();
    sync.set(key, "1");
    AsyncCommand<String, String, String> command = new AsyncCommand<>(new Command<>(CommandType.INCR, new StatusOutput<>(StringCodec.UTF8), new CommandArgs<>(StringCodec.UTF8).addKey(key)));
    channelWriter.write(command);
    assertThat(command.await(2, TimeUnit.SECONDS)).isTrue();
    assertThat(command.isCancelled()).isFalse();
    assertThat(getException(command)).isInstanceOf(UnsupportedOperationException.class);
    assertThat(verificationConnection.get(key)).isEqualTo("2");
    assertThat(sync.get(key)).isEqualTo("2");
    connection.close();
}
Also used : AsyncCommand(io.lettuce.core.protocol.AsyncCommand) RedisChannelWriter(io.lettuce.core.RedisChannelWriter) StatusOutput(io.lettuce.core.output.StatusOutput) AbstractRedisClientTest(io.lettuce.core.AbstractRedisClientTest) Test(org.junit.jupiter.api.Test)

Example 4 with RedisChannelWriter

use of io.lettuce.core.RedisChannelWriter in project lettuce-core by lettuce-io.

the class ClusterDistributionChannelWriter method write.

@SuppressWarnings("unchecked")
@Override
public <K, V> Collection<RedisCommand<K, V, ?>> write(Collection<? extends RedisCommand<K, V, ?>> commands) {
    LettuceAssert.notNull(commands, "Commands must not be null");
    if (closed) {
        commands.forEach(it -> it.completeExceptionally(new RedisException("Connection is closed")));
        return (Collection<RedisCommand<K, V, ?>>) commands;
    }
    List<ClusterCommand<K, V, ?>> clusterCommands = new ArrayList<>(commands.size());
    List<ClusterCommand<K, V, ?>> defaultCommands = new ArrayList<>(commands.size());
    Map<SlotIntent, List<ClusterCommand<K, V, ?>>> partitions = new HashMap<>();
    // TODO: Retain order or retain Intent preference?
    // Currently: Retain order
    Intent intent = getIntent(commands);
    for (RedisCommand<K, V, ?> cmd : commands) {
        if (cmd instanceof ClusterCommand) {
            clusterCommands.add((ClusterCommand) cmd);
            continue;
        }
        CommandArgs<K, V> args = cmd.getArgs();
        ByteBuffer firstEncodedKey = args != null ? args.getFirstEncodedKey() : null;
        if (firstEncodedKey == null) {
            defaultCommands.add(new ClusterCommand<>(cmd, this, executionLimit));
            continue;
        }
        int hash = getSlot(args.getFirstEncodedKey());
        List<ClusterCommand<K, V, ?>> commandPartition = partitions.computeIfAbsent(SlotIntent.of(intent, hash), slotIntent -> new ArrayList<>());
        commandPartition.add(new ClusterCommand<>(cmd, this, executionLimit));
    }
    for (Map.Entry<SlotIntent, List<ClusterCommand<K, V, ?>>> entry : partitions.entrySet()) {
        SlotIntent slotIntent = entry.getKey();
        RedisChannelHandler<K, V> connection = (RedisChannelHandler<K, V>) clusterConnectionProvider.getConnection(slotIntent.intent, slotIntent.slotHash);
        RedisChannelWriter channelWriter = connection.getChannelWriter();
        if (channelWriter instanceof ClusterDistributionChannelWriter) {
            ClusterDistributionChannelWriter writer = (ClusterDistributionChannelWriter) channelWriter;
            channelWriter = writer.defaultWriter;
        }
        if (channelWriter != null && channelWriter != this && channelWriter != defaultWriter) {
            channelWriter.write(entry.getValue());
        }
    }
    clusterCommands.forEach(this::write);
    defaultCommands.forEach(defaultWriter::write);
    return (Collection) commands;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) RedisChannelHandler(io.lettuce.core.RedisChannelHandler) RedisException(io.lettuce.core.RedisException) ArrayList(java.util.ArrayList) List(java.util.List) RedisChannelWriter(io.lettuce.core.RedisChannelWriter) Intent(io.lettuce.core.cluster.ClusterConnectionProvider.Intent) ByteBuffer(java.nio.ByteBuffer) DefaultEndpoint(io.lettuce.core.protocol.DefaultEndpoint) Collection(java.util.Collection) HashMap(java.util.HashMap) Map(java.util.Map)

Example 5 with RedisChannelWriter

use of io.lettuce.core.RedisChannelWriter in project lettuce-core by lettuce-io.

the class AtLeastOnceTest method commandFailsDuringDecode.

@Test
void commandFailsDuringDecode() {
    RedisCommands<String, String> connection = client.connect().sync();
    RedisChannelWriter channelWriter = ConnectionTestUtil.getChannelWriter(connection.getStatefulConnection());
    RedisCommands<String, String> verificationConnection = client.connect().sync();
    connection.set(key, "1");
    AsyncCommand<String, String, String> command = new AsyncCommand(new Command<>(CommandType.INCR, new StatusOutput<>(StringCodec.UTF8), new CommandArgs<>(StringCodec.UTF8).addKey(key)));
    channelWriter.write(command);
    assertThat(command.await(2, TimeUnit.SECONDS)).isTrue();
    assertThat(command.isCancelled()).isFalse();
    assertThat(command.isDone()).isTrue();
    assertThat(getException(command)).isInstanceOf(UnsupportedOperationException.class);
    assertThat(verificationConnection.get(key)).isEqualTo("2");
    assertThat(connection.get(key)).isEqualTo("2");
    connection.getStatefulConnection().close();
    verificationConnection.getStatefulConnection().close();
}
Also used : AsyncCommand(io.lettuce.core.protocol.AsyncCommand) RedisChannelWriter(io.lettuce.core.RedisChannelWriter) StatusOutput(io.lettuce.core.output.StatusOutput) AbstractRedisClientTest(io.lettuce.core.AbstractRedisClientTest) Test(org.junit.jupiter.api.Test)

Aggregations

RedisChannelWriter (io.lettuce.core.RedisChannelWriter)8 AbstractRedisClientTest (io.lettuce.core.AbstractRedisClientTest)7 Test (org.junit.jupiter.api.Test)7 AsyncCommand (io.lettuce.core.protocol.AsyncCommand)5 IntegerOutput (io.lettuce.core.output.IntegerOutput)3 ByteBuf (io.netty.buffer.ByteBuf)3 Channel (io.netty.channel.Channel)3 CountDownLatch (java.util.concurrent.CountDownLatch)3 StatusOutput (io.lettuce.core.output.StatusOutput)2 ConnectionWatchdog (io.lettuce.core.protocol.ConnectionWatchdog)2 RedisChannelHandler (io.lettuce.core.RedisChannelHandler)1 RedisException (io.lettuce.core.RedisException)1 Intent (io.lettuce.core.cluster.ClusterConnectionProvider.Intent)1 DefaultEndpoint (io.lettuce.core.protocol.DefaultEndpoint)1 ByteBuffer (java.nio.ByteBuffer)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1