public void prepareMsg() {
    while (true) {
      BatchMessage msgTuple = null;
      try {
        msgTuple = super.getBatchQueue().poll(1, TimeUnit.MILLISECONDS);
      } catch (InterruptedException e) {
        return;
      }
      if (msgTuple == null) {
        return;
      }

      if (msgTuple.getMsgList().size() == 0) {
        super.finish(msgTuple.getBatchId());
        return;
      }

      BatchMsgsTag partTag = new BatchMsgsTag();
      Set<String> msgIds = partTag.getMsgIds();
      for (MessageExt msg : msgTuple.getMsgList()) {
        String msgId = msg.getMsgId();
        msgIds.add(msgId);
        MessageCacheItem item =
            new MessageCacheItem(msgTuple.getBatchId(), msg, msgTuple.getMessageStat());
        msgCache.put(msgId, item);
        msgQueue.offer(item);
      }
      batchMsgsMap.put(msgTuple.getBatchId(), partTag);
    }
  }
  public void finish(String msgId) {
    MessageCacheItem cacheItem = (MessageCacheItem) msgCache.remove(msgId);
    if (cacheItem == null) {
      LOG.warn("Failed to get from cache {} !", msgId);
      return;
    }

    UUID batchId = cacheItem.getId();
    BatchMsgsTag partTag = batchMsgsMap.get(batchId);
    if (partTag == null) {
      throw new RuntimeException("In partOffset map, no entry of " + batchId);
    }

    Set<String> msgIds = partTag.getMsgIds();

    msgIds.remove(msgId);

    if (msgIds.size() == 0) {
      batchMsgsMap.remove(batchId);
      super.finish(batchId);
    }
  }