@Test public void commandFailsDuringDecode() throws Exception { RedisCommands<String, String> connection = client.connect().sync(); RedisChannelWriter<String, String> channelWriter = getRedisChannelHandler(connection).getChannelWriter(); RedisCommands<String, String> verificationConnection = client.connect().sync(); connection.set(key, "1"); AsyncCommand<String, String, String> command = new AsyncCommand<>( new Command<>( CommandType.INCR, new StatusOutput<>(CODEC), new CommandArgs<>(CODEC).addKey(key))); channelWriter.write(command); assertThat(command.await(2, TimeUnit.SECONDS)).isTrue(); assertThat(command.isCancelled()).isFalse(); assertThat(command.isDone()).isTrue(); assertThat(getException(command)).isInstanceOf(IllegalStateException.class); assertThat(verificationConnection.get(key)).isEqualTo("2"); assertThat(connection.get(key)).isEqualTo("2"); connection.close(); }
@Test public void commandFailsWhenFailOnEncode() throws Exception { RedisCommands<String, String> connection = client.connect().sync(); RedisChannelWriter<String, String> channelWriter = getRedisChannelHandler(connection).getChannelWriter(); RedisCommands<String, String> verificationConnection = client.connect().sync(); connection.set(key, "1"); AsyncCommand<String, String, String> working = new AsyncCommand<>( new Command<>( CommandType.INCR, new IntegerOutput(CODEC), new CommandArgs<>(CODEC).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(CODEC), new CommandArgs<>(CODEC).addKey(key))) { @Override public void encode(ByteBuf buf) { throw new IllegalStateException("I want to break free"); } }; channelWriter.write(command); assertThat(command.isCancelled()).isFalse(); assertThat(command.isDone()).isFalse(); assertThat(verificationConnection.get(key)).isEqualTo("2"); assertThat(getQueue(getRedisChannelHandler(connection))).isNotEmpty(); connection.close(); }
@Test public void commandRetriedChannelClosesWhileFlush() throws Exception { assumeTrue(Version.identify().get("netty-transport").artifactVersion().startsWith("4.0.2")); RedisCommands<String, String> connection = client.connect().sync(); RedisCommands<String, String> verificationConnection = client.connect().sync(); RedisChannelWriter<String, String> channelWriter = getRedisChannelHandler(connection).getChannelWriter(); connection.set(key, "1"); assertThat(verificationConnection.get(key)).isEqualTo("1"); final CountDownLatch block = new CountDownLatch(1); ConnectionWatchdog connectionWatchdog = Connections.getConnectionWatchdog(connection.getStatefulConnection()); AsyncCommand<String, String, Object> command = getBlockOnEncodeCommand(block); channelWriter.write(command); connectionWatchdog.setReconnectSuspended(true); Channel channel = getChannel(getRedisChannelHandler(connection)); 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(getQueue(getRedisChannelHandler(connection))).isEmpty(); assertThat(getCommandBuffer(getRedisChannelHandler(connection))).isEmpty(); connection.close(); verificationConnection.close(); }
static void pingBeforeActivate( final AsyncCommand<?, ?, ?> cmd, final SettableFuture<Boolean> initializedFuture, final ChannelHandlerContext ctx, final List<ChannelHandler> handlers) throws Exception { cmd.handle( (o, throwable) -> { if (throwable == null) { initializedFuture.set(true); ctx.fireChannelActive(); } else { initializedFuture.setException(throwable); } return null; }); ctx.channel().writeAndFlush(cmd); }
@Test public void commandNotExecutedChannelClosesWhileFlush() throws Exception { RedisCommands<String, String> connection = client.connect().sync(); RedisCommands<String, String> verificationConnection = client.connect().sync(); RedisChannelWriter<String, String> channelWriter = getRedisChannelHandler(connection).getChannelWriter(); connection.set(key, "1"); assertThat(verificationConnection.get(key)).isEqualTo("1"); final CountDownLatch block = new CountDownLatch(1); AsyncCommand<String, String, Object> command = new AsyncCommand<String, String, Object>( new Command<>( CommandType.INCR, new IntegerOutput(CODEC), new CommandArgs<>(CODEC).addKey(key))) { @Override public void encode(ByteBuf buf) { try { block.await(); } catch (InterruptedException e) { } super.encode(buf); } }; channelWriter.write(command); Channel channel = getChannel(getRedisChannelHandler(connection)); 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)).isTrue(); assertThat(command.isCancelled()).isFalse(); assertThat(command.isDone()).isTrue(); assertThat(verificationConnection.get(key)).isEqualTo("1"); assertThat(getQueue(getRedisChannelHandler(connection))).isEmpty(); assertThat(getCommandBuffer(getRedisChannelHandler(connection))).isEmpty(); connection.close(); }