private void logToCatIfHasError(SendMessageResultCommand resultCmd) {
   for (Boolean sendSuccess : resultCmd.getSuccesses().values()) {
     if (!sendSuccess) {
       Cat.logEvent("Message.Produce.Error", m_topic, Event.SUCCESS, "");
     }
   }
 }
    @Override
    public void onSuccess(Map<Integer, Boolean> results) {
      m_result.addResults(results);

      if (m_result.isAllResultsSet()) {
        try {
          if (m_written.compareAndSet(false, true)) {
            logToCatIfHasError(m_result);
            m_result
                .getHeader()
                .addProperty("createTime", Long.toString(System.currentTimeMillis()));
            m_ctx.write(m_result);
          }
        } finally {
          m_ctx.getCommand().release();
        }
      }
    }
  @Override
  public void process(final CommandProcessorContext ctx) {
    SendMessageCommandV3 reqCmd = (SendMessageCommandV3) ctx.getCommand();

    Lease lease =
        m_leaseContainer.acquireLease(
            reqCmd.getTopic(), reqCmd.getPartition(), m_config.getSessionId());

    if (m_metaService.findTopicByName(reqCmd.getTopic()) != null) {
      if (lease != null) {
        if (log.isDebugEnabled()) {
          log.debug(
              "Send message reqeust arrived(topic={}, partition={}, msgCount={})",
              reqCmd.getTopic(),
              reqCmd.getPartition(),
              reqCmd.getMessageCount());
        }

        logElapseToCat(reqCmd);

        // FIXME if dumper's queue is full, reject it.
        writeAck(ctx, true);

        Map<Integer, MessageBatchWithRawData> rawBatches = reqCmd.getMessageRawDataBatches();

        bizLog(ctx, rawBatches, reqCmd.getPartition());

        final SendMessageResultCommand result =
            new SendMessageResultCommand(reqCmd.getMessageCount());
        result.correlate(reqCmd);

        FutureCallback<Map<Integer, Boolean>> completionCallback =
            new AppendMessageCompletionCallback(result, ctx, reqCmd.getTopic());

        for (Map.Entry<Integer, MessageBatchWithRawData> entry : rawBatches.entrySet()) {
          MessageBatchWithRawData batch = entry.getValue();
          Tpp tpp =
              new Tpp(reqCmd.getTopic(), reqCmd.getPartition(), entry.getKey() == 0 ? true : false);
          try {
            ListenableFuture<Map<Integer, Boolean>> future =
                m_queueManager.appendMessageAsync(
                    tpp, batch, m_systemClockService.now() + reqCmd.getTimeout());

            if (future != null) {
              Futures.addCallback(future, completionCallback);
            }
          } catch (Exception e) {
            log.error("Failed to append messages async.", e);
          }
        }

        return;

      } else {
        if (log.isDebugEnabled()) {
          log.debug(
              "No broker lease to handle client send message reqeust(topic={}, partition={})",
              reqCmd.getTopic(),
              reqCmd.getPartition());
        }
      }
    } else {
      if (log.isDebugEnabled()) {
        log.debug("Topic {} not found", reqCmd.getTopic());
      }
    }

    writeAck(ctx, false);
    reqCmd.release();
  }