/** Close the connection. */
 public synchronized void close() {
   if (!closed && channel != null) {
     ConnectionWatchdog watchdog = channel.getPipeline().get(ConnectionWatchdog.class);
     watchdog.setReconnect(false);
     closed = true;
     channel.close();
   }
 }
  @Override
  public synchronized void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
      throws Exception {
    channel = ctx.getChannel();

    List<Command<K, V, ?>> tmp = new ArrayList<Command<K, V, ?>>(queue.size() + 2);

    if (password != null) {
      CommandArgs<K, V> args = new CommandArgs<K, V>(codec).add(password);
      tmp.add(new Command<K, V, String>(AUTH, new StatusOutput<K, V>(codec), args, false));
    }

    if (db != 0) {
      CommandArgs<K, V> args = new CommandArgs<K, V>(codec).add(db);
      tmp.add(new Command<K, V, String>(SELECT, new StatusOutput<K, V>(codec), args, false));
    }

    tmp.addAll(queue);
    queue.clear();

    for (Command<K, V, ?> cmd : tmp) {
      if (!cmd.isCancelled()) {
        queue.add(cmd);
        channel.write(cmd);
      }
    }

    tmp.clear();
  }
  public synchronized <T> Command<K, V, T> dispatch(
      CommandType type, CommandOutput<K, V, T> output, CommandArgs<K, V> args) {
    Command<K, V, T> cmd = new Command<K, V, T>(type, output, args, multi != null);

    try {
      if (multi != null) {
        multi.add(cmd);
      }
      System.out.println("key:" + args.key);
      queue.put(cmd);

      if (channel != null) {
        channel.write(cmd);
      }
    } catch (NullPointerException e) {
      throw new RedisException("Connection is closed");
    } catch (InterruptedException e) {
      throw new RedisCommandInterruptedException(e);
    }

    return cmd;
  }