std::map<std::string, std::set<MessageQueue> > RebalanceImpl::buildProcessQueueTableByBrokerName() { std::map<std::string, std::set<MessageQueue> > result ; std::map<MessageQueue, ProcessQueue*>::iterator it = m_processQueueTable.begin(); for ( ; it != m_processQueueTable.end();) { MessageQueue mq = it->first; std::map<std::string, std::set<MessageQueue> >::iterator itm = result.find(mq.getBrokerName()); if (itm == result.end()) { std::set<MessageQueue> mqs ; mqs.insert(mq); result[mq.getBrokerName()] = mqs; } else { itm->second.insert(mq); } } return result; }
void MQClientFactory::topicRouteData2TopicSubscribeInfo( std::string& topic, TopicRouteData* route, std::set<MessageQueue*>& mqList) { std::list<QueueData*>& qds = route->getQueueDatas(); std::list<QueueData*>::iterator it = qds.begin(); QueueData* qd = NULL; for(; it != qds.end(); it++) { qd = (*it); for(int i = 0; i < qd->getReadQueueNums(); i++) { MessageQueue* mq = new MessageQueue(topic, qd->getBrokerName(), i); std::cout << mq->getBrokerName() << std::endl; mqList.insert(mq); } } }
bool RebalanceImpl::lock(MessageQueue& mq) { FindBrokerResult findBrokerResult = m_pMQClientFactory->findBrokerAddressInSubscribe(mq.getBrokerName(), MixAll::MASTER_ID, true); if (!findBrokerResult.brokerAddr.empty()) { LockBatchRequestBody* requestBody = new LockBatchRequestBody(); requestBody->setConsumerGroup(m_consumerGroup); requestBody->setClientId(m_pMQClientFactory->getClientId()); requestBody->getMqSet().insert(mq); try { std::set<MessageQueue> lockedMq = m_pMQClientFactory->getMQClientAPIImpl()->lockBatchMQ( findBrokerResult.brokerAddr, requestBody, 1000); std::set<MessageQueue>::iterator it = lockedMq.begin(); for (; it != lockedMq.end(); it++) { kpr::ScopedLock<kpr::Mutex> lock(m_processQueueTableLock); MessageQueue mmqq = *it; std::map<MessageQueue, ProcessQueue*>::iterator itt = m_processQueueTable.find(mmqq); if (itt != m_processQueueTable.end()) { itt->second->setLocked(true); itt->second->setLastLockTimestamp(GetCurrentTimeMillis()); } } it = lockedMq.find(mq); if (it != lockedMq.end()) { return true; } //TODO log.info("the message queue lock {}, {} {}",// // (lockOK ? "OK" : "Failed"), // // this.consumerGroup, // // mq); return false; } catch (...) { //TODO log.error("lockBatchMQ exception, " + mq, e); } } return false; }
void RebalanceImpl::unlock(MessageQueue& mq, bool oneway) { FindBrokerResult findBrokerResult = m_pMQClientFactory->findBrokerAddressInSubscribe(mq.getBrokerName(), MixAll::MASTER_ID, true); if (!findBrokerResult.brokerAddr.empty()) { UnlockBatchRequestBody* requestBody = new UnlockBatchRequestBody(); requestBody->setConsumerGroup(m_consumerGroup); requestBody->setClientId(m_pMQClientFactory->getClientId()); requestBody->getMqSet().insert(mq); try { m_pMQClientFactory->getMQClientAPIImpl()->unlockBatchMQ(findBrokerResult.brokerAddr, requestBody, 1000, oneway); } catch (...) { //TODO log.error("unlockBatchMQ exception, " + mq, e); } } }
SendResult_ptr DefaultMQProducerImpl::sendDefaultImpl(Message_ptr msg, std::string& communicationMode, bool sendCallback) { long beginTimestamp = 0; long endTimestamp = beginTimestamp; TopicPublishInfo* topicPublishInfo = this->tryToFindTopicPublishInfo(msg->getTopic()); if (topicPublishInfo->ok()) { MessageQueue* mq = NULL; SendResult_var sendResult = new SendResult(); for (int times = 0; times < 3; times++) { std::string lastBrokerName; if(mq != NULL) { lastBrokerName = mq->getBrokerName(); } MessageQueue* tmpmq = topicPublishInfo->selectOneMessageQueue(lastBrokerName); if (tmpmq != NULL) { mq = tmpmq; sendResult = this->sendKernelImpl(msg, mq, communicationMode, sendCallback); endTimestamp = 12; if(communicationMode == CommunicationMode::SYNC) { if (sendResult->getSendStatus() != SendStatus::SEND_OK) { /* if (this->defaultMQProducer->isRetryAnotherBrokerWhenNotStoreOK()) { continue; } */ } return SendResult_var::Duplicate(sendResult); } } else { break; } } return SendResult_var::Duplicate(sendResult); } return NULL; }
bool RebalanceImpl::updateProcessQueueTableInRebalance(const std::string& topic, std::set<MessageQueue>& mqSet) { bool changed = false; // 将多余的队列删除 std::map<MessageQueue, ProcessQueue*>::iterator it = m_processQueueTable.begin(); for ( ; it != m_processQueueTable.end();) { MessageQueue mq = it->first; if (mq.getTopic() == topic) { std::set<MessageQueue>::iterator its = mqSet.find(mq); if (its == mqSet.end()) { changed = true; ProcessQueue* pq = it->second; if (pq != NULL) { pq->setDroped(true); removeUnnecessaryMessageQueue(mq, *pq); //TODO log.info("doRebalance, {}, remove unnecessary mq, {}", // consumerGroup, mq); } std::map<MessageQueue, ProcessQueue*>::iterator ittmp = it; it++; m_processQueueTable.erase(ittmp); } else { it++; } } else { it++; } } // 增加新增的队列 std::list<PullRequest> pullRequestList; std::set<MessageQueue>::iterator its = mqSet.begin(); for (; its != mqSet.end(); its++) { MessageQueue mq = *its; std::map<MessageQueue, ProcessQueue*>::iterator itm = m_processQueueTable.find(mq); if (itm == m_processQueueTable.end()) { PullRequest pullRequest; pullRequest.setConsumerGroup(m_consumerGroup); pullRequest.setMessageQueue(new MessageQueue(mq.getTopic(),mq.getBrokerName(),mq.getQueueId())); pullRequest.setProcessQueue(new ProcessQueue()); // 这个需要根据策略来设置 long long nextOffset = computePullFromWhere(mq); if (nextOffset >= 0) { pullRequest.setNextOffset(nextOffset); pullRequestList.push_back(pullRequest); changed = true; m_processQueueTable[mq] = pullRequest.getProcessQueue(); //TODO log.info("doRebalance, {}, add a new mq, {}", consumerGroup, mq); } else { // 等待此次Rebalance做重试 //TODO log.warn("doRebalance, {}, add new mq failed, {}", consumerGroup, mq); } } } dispatchPullRequest(pullRequestList); return changed; }