Example #1
0
  final ChannelFuture initAndRegister() {
    final Channel channel = channelFactory().newChannel();
    try {
      init(channel);
    } catch (Throwable t) {
      channel.unsafe().closeForcibly();
      // as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor
      return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t);
    }

    ChannelFuture regFuture = group().register(channel);
    if (regFuture.cause() != null) {
      if (channel.isRegistered()) {
        channel.close();
      } else {
        channel.unsafe().closeForcibly();
      }
    }

    // If we are here and the promise is not failed, it's one of the following cases:
    // 1) If we attempted registration from the event loop, the registration has been completed at
    // this point.
    //    i.e. It's safe to attempt bind() or connect() now because the channel has been registered.
    // 2) If we attempted registration from the other thread, the registration request has been
    // successfully
    //    added to the event loop's task queue for later execution.
    //    i.e. It's safe to attempt bind() or connect() now:
    //         because bind() or connect() will be executed *after* the scheduled registration task
    // is executed
    //         because register(), bind(), and connect() are all bound to the same thread.

    return regFuture;
  }
Example #2
0
  @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();
  }
  @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();
  }